用 podman-kube 來跑 WordPress (original) (raw)

西元2023年11月18日 - Kan-Ru Chen

上一篇寫了要怎麼用 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 叢集跑。▗


參考文章: