個人のk8sだけども、デプロイ時のローリングアップデートでダウンタイムが発生してしまう件、解決したからブログ書こう。
— adachin👾SRE (@adachin0817) November 5, 2023
2ヶ月ぶりのブログとなります。「最近ブログ書いてなくないですか?あだちんさん何やってるんですか?」と思う方もいらっしゃると思いますが、ご安心ください。業務がAzureとKubernetesなので、覚えることも多くてヒーヒー言っております。最近は備忘録の方で(https://wiki.adachin.me)アウトプットをしております。業務でやってきたことなどは後ほどアドベントカレンダーでむちゃくちゃ書くのでしばしお待ちください!
[DigitalOcean][Kubernetes]WordPressコンテナをCircleCIで自動デプロイとローリングアップデートを実装してみた
さて、以前個人のKubernetes(https://wiki.adachin.me)でCircleCIを利用して自動デプロイと、ローリングアップデートを実装しました。しかし、ローリングアップデート時にダウンタイムが発生してしまうことが起き、一旦レプリカを2台にすることで解決しました。そこで、今回StatefulSetからDeploymentに移行し、ダウンタイムなしで改善することができたのでブログします。
懸念点とDeploymentに移行
https://kubernetes.io/ja/docs/concepts/workloads/controllers/statefulset/
https://kubernetes.io/ja/docs/concepts/workloads/controllers/deployment/
- 既存のデプロイフロー
1 2 3 4 |
$ kubectl get pods NAME READY STATUS RESTARTS AGE wiki-wordpress-0 1/1 Running 0 3m43s wiki-wordpress-1 1/1 Running 0 3m43s |
そもそもStatefulSetで運用していたということもあって、デプロイ、スケーリング、ローリングアップデートは順序付けされた動作の元に実行されるようになっています。さらに公式ではデータベースやキャッシュなどの持続的な状態の管理が必要な場合に適しているので、WordPressコンテナはWebサーバーなので、Developmentの方がふさわしいです。(そもそもなぜStatefulSetにしているのかは以下変更点で書いています)
以下リンクより、Kubernetesは新しいPodが起動したことまでは検知できますが、Running状態になったことを検知しないようで、ダウンタイムの発生がある前提のようです。
https://nilesh93.medium.com/enable-rolling-updates-in-kubernetes-with-zero-downtime-31d7ec388c81
また、対策としてはreadinessProbeによるヘルスチェックを設定すればStatefulSetでもレプリカ1台でいけるか!?と思いましたが、普通にダウンタイムになってしまったのと、通常時に2台ある前提ということもあり、用途もWebサーバーなので、Deploymentに移行しました。Deploymentであれば、ローリングアップデートのカスタマイズが豊富にあるので、色々と調整がしやすいことも分かりました。早速修正点を書いていきましょう。
変更点
- k8s/wiki/manifests/wordpress.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
--- apiVersion: apps/v1 kind: Deployment metadata: name: wiki-wordpress spec: replicas: 1 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 25% selector: matchLabels: app: wiki-wordpress template: metadata: labels: app: wiki-wordpress spec: containers: - name: wiki-wordpress image: registry.digitalocean.com/wiki-wordpress/wiki-wordpress:$COMMIT_SHA1 resources: requests: cpu: "100m" memory: "256Mi" limits: cpu: "1000m" memory: "2048Mi" ports: - containerPort: 80 name: http readinessProbe: tcpSocket: port: 80 initialDelaySeconds: 5 periodSeconds: 5 volumeMounts: - name: wordpress-data mountPath: /var/www/wiki.adachin.me volumes: - name: wordpress-data persistentVolumeClaim: claimName: wordpress-volume |
まずはkindからDeploymentにしていますが、11行目での maxSurge
は宣言したPod数で、レプリカ1台とmaxSurge1台でローリングアップデートをしていきます。 12行目の maxUnavailable
はアップデート時に許容したunavailableになるPod数でデフォルト値を指定しています。次は34行目の readinessProbe
によるヘルスチェックの設定ですが、今回はtcpSocketでのエンドポイントを指定しています。httpでのエンドポイントにしたかったのですが、うまくいかなかったので後ほど調査していきます。 initialDelaySeconds
ではコンテナが起動してからヘルスチェックを始めるまでを5秒にして、 periodSeconds
はヘルスチェックの間隔も5秒にしました。
ついでにKubernetesもバージョンアップして以下エラーが出たので、24行目でコンテナのリソース(CPU,Memory)も指定しました。
[Kubernetes]Set resource requests and limits for container `hoge` to prevent resource contention
Yeah!!!!!!!! pic.twitter.com/UvVlHcqvfM
— adachin👾SRE (@adachin0817) November 3, 2023
※ちなみに元々はDeploymentだったのが、2年前のバージョンアップで以下のエラーでStatefulSetに変更してしまったという…(知識がなかったんだな..)一旦エラーはそのまま出ていましたが、サービスの影響はないので、persistentVolumeClaimは指定したままにしました。今後はボリュームマウントを廃止してリポジトリをコピーしてbuildするように修正する予定です。
Pod referencing DOBS volumes must be owned by StatefulSet
[DigitalOcean]wiki.adachin.meのKubernetesをv1.15からv1.21にバージョンアップしました!
設定はこれで完了なので、デプロイしてみましょう。
動作確認
- Rolling Update
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ watch -n 1 "kubectl get pods" NAME READY STATUS RESTARTS AGE wiki-wordpress-65779dc6c9-lnqqd 1/1 Running 0 3m43s NAME READY STATUS RESTARTS AGE wiki-wordpress-65779dc6c9-lnqqd 1/1 Running 0 6m44s wiki-wordpress-9f9bcc9f7-p4lbk 0/1 ContainerCreating 0 17s NAME READY STATUS RESTARTS AGE wiki-wordpress-65779dc6c9-lnqqd 1/1 Running 0 6m51s wiki-wordpress-9f9bcc9f7-p4lbk 0/1 Running 0 24s NAME READY STATUS RESTARTS AGE wiki-wordpress-9f9bcc9f7-p4lbk 1/1 Running 0 35s |
ECSと比べると切り替わるスピードが早い..!30秒くらいかな?
まとめ
これで安全にリリースできるようになったのと、Pod数も1台になったのでリソースを削減することができました。しかしKubernetesは難しい….次回はボリュームマウントの廃止、WordPressコンテナのNginxを分離、PHP8.3にバージョンアップしていきます。NewRelicにも移行だ…
個人のインフラ環境やりたいことが多すぎて壮大過ぎる。
「Kubernetesの知識地図」届いた。ハンドブックで読みやすい!🙌 pic.twitter.com/hqwrtayj7K
— adachin👾SRE (@adachin0817) June 26, 2023
0件のコメント