用 podman-kube 來跑 WordPress

上一篇寫了要怎麼用 podman 的 systemd generator 來跑單一的 container,其實 podman 還有另外一個 pod 模式,也就是類似 Kubernetes 的 pod 一樣,可以把多個 container 跑在同一個 namespace 裡面。Podman 的 podman-kube-play(1) 指令可以接受一個 Kubernetes 的 YAML 設定檔然後跑起單一個 container 或是一整個 pod 與多個 container。同樣的,systemd generator 也可以用來管理整個 pod,變成 systemd service unit。

這次我要做的是把單一的 WordPress container 改成用 PHP-fpm 和 Caddy 兩個 container 的方式佈署。原本單一的 WordPress container 用的是 apache2 prefork mpm,同時處理多個 HTTP request 效率比較不好,換成兩個獨立的 container 後,可以把 PHP 與靜態檔案分別交給不同的 process 處理,這樣各自效率都比較好。當然也不一定要用 Caddy,其他像是 nginx 或是 apache2 event mpm 也可以。

Podman 的改版還滿快的,新的版本常常都會新增許多功能。這次我使用的是 Podman 4.7.0 版。因為我記不住要怎麼寫 Kubernetes 的 YAML,所以我用比較簡單的方法:先用指令產生好 pod 跟 container 後,再用 podman kube generate 來產生 YAML.

首先創造一個空的 pod 來:

podman pod create --network core --name wordpress-pod

Network 可以隨意設定,之後可以再改。接下來可以創造 File Server container:

podman create --pod wordpress-pod --name wordpress-php \
        -v /var/srv/wordpress:/var/www/html:Z \
        -e WORDPRESS_DB_HOST=wp-db \
        wordpress:fpm

最後,用 podman-kube 來產生 Kubernetes 的 YAML 設定檔:

podman kube generate wordpress-pod > wordpress-pod.yaml

產生出來的設定類似這樣:

# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-4.7.0
apiVersion: v1
kind: Pod
metadata:
  annotations:
    bind-mount-options: /var/srv/wordpress:Z
    bind-mount-options/wordpress-pod-wordpress-fs: /var/srv/wordpress:Z
    bind-mount-options/wordpress-pod-wordpress-php: /var/srv/wordpress:Z
  creationTimestamp: "2023-11-18T07:10:21Z"
  labels:
    app: wordpress-pod
  name: wordpress-pod
spec:
  containers:
  - image: docker.io/library/caddy:latest
    name: wordpress-pod-wordpress-fs
    volumeMounts:
    - mountPath: /etc/caddy/Caddyfile
      name: etc-caddy-wordpress-fs-host-0
    - mountPath: /var/www/html
      name: var-srv-wordpress-host-1
    - mountPath: /data
      name: wordpress-fs-data-pvc
  - args:
    - php-fpm
    env:
    - name: WORDPRESS_DB_HOST
      value: wp-db
    image: docker.io/library/wordpress:fpm
    name: wordpresss-pod-wordpress-php
    volumeMounts:
    - mountPath: /var/www/html
      name: var-srv-wordpress-host-0
  restartPolicy: Always
  volumes:
  - hostPath:
      path: /etc/caddy/wordpress-fs
      type: File
    name: etc-caddy-wordpress-fs-host-0
  - hostPath:
      path: /var/srv/wordpress
      type: Directory
    name: var-srv-wordpress-host-1
  - name: wordpress-fs-data-pvc
    persistentVolumeClaim:
      claimName: wordpreess-fs-data
  - hostPath:
      path: /var/srv/wordpress
      type: Directory
    name: var-srv-wordpress-host-0

最後就可以用 podman-kube-play 來測試:

podman kube play --network core wordpress-pod.yaml

滿意了就可以把設定弄成 systemd unit

# /etc/containers/systemd/wordpress-pod.kube
[Unit]
Description=WordPress website
After=network-online.target
Wants=network-online.target

[Kube]
Network=core
Yaml=/etc/containers/systemd/wordpress-pod.yaml

[Service]
Restart=always
TimeoutStartSec=900

[Install]
WantedBy=multi-user.target

整體而言算是相當簡單就可以設定好一個 pod,再加一些設定還可以做動自動更新或是自動佈署最新的設定,也可以把同樣的設定檔改一改就拿去大型的 Kubernetes 叢集跑。▗


參考文章: