Category: 実践編
2020.05.18
目次
はじめに
前回のブログでは、無事に WordPress サイトの公開までたどり着けました。
しかし、実際のサービスでは、構築したら終わりではなく、その後の運用のほうが大事です。そして、Kubernetes はむしろ、運用のほうで本領を発揮します。
今回は、運用のなかでも特に以下にポイントを絞って、Kubernetes の機能をみてみます。
- アプリケーションのアップデート
- Pod に障害が発生した際の自動復旧
- スケールイン、スケールアウト
アプリケーションのアップデート
本番環境で新しいアプリケーションをリリースすることは非常に大変な作業です。
システムやアプリケーションによっては、ダウンタイムが発生するために、メンテナンス時間を設けなくてはいけないこともあります。
Kubernetes では、ダウンタイムなく、安全にアプリケーションのアップデートを行うことができます。
一例として、公式のイメージに少しだけ修正を加えたものをリリースしてみます。
前回の記事では wp-content 以下を Azure Files による共有領域としました。
実は、WordPress の Docker イメージは毎回、起動時にドキュメントルート以下にファイルを展開するため、
共有領域内のファイルを上書きしてしまいます。
(デフォルトファイルに修正を加えていない限り、影響はありませんが。)
これを解消するために、公式の Docker イメージをカスタマイズしてみましょう。
Azure Container Registory の準備
カスタマイズしたイメージを保管するためのレジストリを用意しましょう。
今回は、Azure にて用意されている Azure Container Registory (以下、ACR) を利用します。
ACR の画面を開きます。
レジストリ名やリージョンを選択します。
できました。
最後に、AKS から ACR にアクセスできるようにします。
これにより、マニュフェストにてレジストリ内のイメージを指定するだけで、AKS 上にデプロイすることができます。
rworks@Azure:~/build$ az aks update -n wordpress-cluster -g wordpress --attach-acr rworks
イメージのカスタマイズ
Docker ライブラリから、Dockerfile と docker-entrypoint.sh をダウンロードします。
https://github.com/docker-library/wordpress/tree/bf85cc7bf33afbbfadd86ba79b3d8ad325289057/php7.3/apache
rworks@Azure:~/docker/wordpress$ ls docker-entrypoint.sh Dockerfile
docker-entrypoint.sh は、Docker の起動時に実行されるスクリプトです。
このなかに、WordPress の初期設定を行うコマンドが羅列してあります。
ここに、「展開する前のファイル群から wp-content ディレクトリを削除する」行を追記します。
if [ "$user" != '0' ]; then # avoid "tar: .: Cannot utime: Operation not permitted" and "tar: .: Cannot change mode to rwxr-xr-x: Operation not permitted" targetTarArgs+=( --no-overwrite-dir ) fi + rm -rf /usr/src/wordpress/wp-content tar "${sourceTarArgs[@]}" . | tar "${targetTarArgs[@]}"
編集した docker-entrypoint.sh を反映させたイメージを、ビルドして、ACR にプッシュします。
“az acr build” コマンドを利用すれば、Azure 側でビルドが行われ、そのまま ACR にプッシュしてくれます。
ローカルにビルドするための環境を用意する必要はありません。
rworks@Azure:~/build$ az acr build --image wordpress:v1 --registry rworks --file DockerFile . Packing source code into tar to upload... Uploading archived source code from '/tmp/build_archive_922bf1d4cc1a431f9250e90182156ebf.tar.gz'... Sending context (349.000 Bytes) to registry: rworks... Queued a build with ID: ce1 Waiting for an agent... 2020/04/13 14:53:56 Downloading source code... - image: registry: rworks.azurecr.io repository: wordpress tag: v1 digest: sha256:d9b24db8c01cf917cc17aeb48118a32293eb6fbf597a0b5154e9a51fd12c4257 runtime-dependency: registry: registry.hub.docker.com repository: library/wordpress tag: latest digest: sha256:191d5caf4ef5b8c57721ade777820f3267654325f7902b2ccd377ceeba1c3fe2 git: {} Run ID: ce1 was successful after 1m4s
“rworks.azurecr.io/wordpress:v1” を指定して pull できるようになりました。
カスタマイズしたイメージのデプロイ
deployment.yaml を書き換えて、新しいイメージをデプロイしてみましょう。
deployment.yaml の image を ACR 上のイメージに書き換えます。
spec: containers: #- image: wordpress - image: rworks.azurecr.io/wordpress:v1
deployment を更新します。
rworks@Azure:~$ kubectl apply -f deployment.yaml deployment.apps/wordpress configured
古い Pod が削除されるのと同時に、新しい Pod が作成されます。
既定では、このようにローリングアップデートが行われます。
# 一時的に、Pod が2倍になります rworks@Azure:~$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-5f59c6698b-cdjkq 0/1 ContainerCreating 0 0s # ← 新しい Pod wordpress-5f59c6698b-jh2r4 1/1 Running 0 5s # ← 新しい Pod wordpress-7b95946f7c-gdm8b 1/1 Running 0 88s # ← 古い Pod wordpress-7b95946f7c-vgnt4 1/1 Terminating 0 88s # ← 古い Pod rworks@Azure:~$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-5f59c6698b-cdjkq 1/1 Running 0 14s # ← 新しい Pod wordpress-5f59c6698b-jh2r4 1/1 Running 0 19s # ← 新しい Pod wordpress-7b95946f7c-gdm8b 1/1 Terminating 0 102s # ← 古い Pod wordpress-7b95946f7c-vgnt4 1/1 Terminating 0 102s # ← 古い Pod rworks@Azure:~$ kubectl get pod # 最終的に、Pod が入れ替わります rworks@Azure:~$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-5f59c6698b-cdjkq 1/1 Running 0 42s # ← 新しい Pod wordpress-5f59c6698b-jh2r4 1/1 Running 0 47s # ← 新しい Pod # レプリカセットは古いものも残ります。 rworks@Azure:~$ kubectl get rs NAME DESIRED CURRENT READY AGE wordpress-5f59c6698b 2 2 2 51s # ← image が wordpress:v1 のレプリカセット wordpress-7b95946f7c 0 0 0 2m14s # ← image が wordpress のレプリカセット
万が一、アプリケーションに問題が生じた場合は、簡単にロールバックができます。
マニュフェスト deployment.yaml を編集前のものに戻して、再度、kubectl apply を実行します。
spec: containers: - image: wordpress # - image: rworks.azurecr.io/wordpress:v1
deployment を更新します。
rworks@Azure:~$ kubectl apply -f deployment.yaml deployment.apps/wordpress configured
Pod は新しいものに置き換わっていますが、レプリカセットは一番初めのものに戻っていることが分かります。
# Pod は新しいものに入れ替わります rworks@Azure:~$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-7b95946f7c-d826x 1/1 Running 0 23s wordpress-7b95946f7c-q7b2l 1/1 Running 0 29s # レプリカセットがロールバックされています。 rworks@Azure:~$ kubectl get rs NAME DESIRED CURRENT READY AGE wordpress-5f59c6698b 0 0 0 11m # ← image が wordpress:v1 のレプリカセット wordpress-7b95946f7c 2 2 2 12m # ← image が wordpress のレプリカセット
このように、ダウンタイムのないアプリケーションのアップデートを簡単に行うことができます。
(削除される Pod と作成される Pod のタイミングによってはダウンタイムが発生することもあるので、パラメータは調整する必要があります。)
CI ツールと連携することで、アプリケーションのアップデートを完全自動化することも可能です。
Pod に障害が発生した際の自動復旧
Pod には Probe (ヘルスチェック) を設定することができ、Probe に失敗した際には自動で復旧させることができます。
Probe の方法には、”livenessProbe” と “readinessProbe” の2つのタイプがあります。
Probe 失敗後のアクションに違いがあり、前者は Pod の再作成が行われ、後者はサービスからのトラフィックが停止します。
デフォルトでは、livenessProbe が有効になっています。
今回は、livenessProbe を利用することにします。”httpGet” を指定することで、パス / の HTTP ステータスコードをチェックすることにします。
deployment.yaml の “template” 内に、以下の行を追加します。
template: metadata: labels: app: wordpress tier: frontend spec: containers: #- image: wordpress - image: rworks.azurecr.io/wordpress:v1 name: wordpress envFrom: # ← 接続情報と認証情報を key, value を全て読み込み - configMapRef: name: wp-configmap - secretRef: name: db-secret ports: - containerPort: 80 name: wordpress + livenessProbe: + httpGet: + path: / + port: 80 + scheme: HTTP + initialDelaySeconds: 30 # ← 初回の Probe は30秒待つ + periodSeconds: 10 # ← 10秒間隔で Probe を行う + timeoutSeconds: 5 # ← タイムアウトを5秒に
Pod と MySQL の間に何らかの問題が発生し、一時的に接続できなかった場合を想定します。
wp-config のデータベース接続情報を書き換え、擬似的にこの状況を再現してみます。
rworks@Azure:~$ kubectl exec -it wordpress-69b76dc56f-q4tgz /bin/bash root@wordpress-69b76dc56f-q4tgz:/var/www/html# sed -i 's/wordpress-db-rworks.mysql.database.azure.com/hoge/' wp-config.php root@wordpress-69b76dc56f-q4tgz:/var/www/html# grep HOST wp-config.php define( 'DB_HOST', 'hoge');
上記の変更後、すぐに自動的に Pod が再作成されました。
EVents を見てみると、HTTP ステータスコード 500 が返ってきたことにより、Probe が失敗したあと、コンテナの再作成が行われていることがわかります。
Pod はマニュフェストから再作成されますので、当然、wp-config.php も元の正しい設定になっています。
rworks@Azure:~$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-69b76dc56f-5srbh 1/1 Running 0 5m28s wordpress-69b76dc56f-q4tgz 1/1 Running 1 5m33s # ← RESTART がカウントアップしています rworks@Azure:~$ kubectl describe pod wordpress-69b76dc56f-q4tgz [省略] Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 2m10s default-scheduler Successfully assigned default/wordpress-69b76dc56f-q4tgz to aks-agentpool-23520908-vmss000000 Warning Unhealthy 20s (x3 over 40s) kubelet, aks-agentpool-23520908-vmss000000 Liveness probe failed: HTTP probe failed with statuscode: 500 Normal Killing 20s kubelet, aks-agentpool-23520908-vmss000000 Container wordpress failed liveness probe, will be restarted Normal Pulling 18s (x2 over 2m8s) kubelet, aks-agentpool-23520908-vmss000000 Pulling image "rworks.azurecr.io/wordpress:v1" Normal Pulled 18s (x2 over 2m6s) kubelet, aks-agentpool-23520908-vmss000000 Successfully pulled image "rworks.azurecr.io/wordpress:v1" Normal Created 17s (x2 over 2m6s) kubelet, aks-agentpool-23520908-vmss000000 Created container wordpress Normal Started 17s (x2 over 2m5s) kubelet, aks-agentpool-23520908-vmss000000 Started container wordpress
このように、Kubernetes は障害発生時に自動で復旧することが分かりました。
これにより、常にマニュフェストで定義したとおりの状態が保たれます。
スケールイン、スケールアウト
Pod のスケールイン、スケールアウトは簡単です。
deployment.yaml の replicass の値を変更するだけです。
spec: #replicas: 2 replicas: 4
deployment を更新します。
rworks@Azure:~$ kubectl apply -f deployment.yaml deployment.apps/wordpress configured
Pod が倍になりました。
rworks@Azure:~$ kubectl get pod NAME READY STATUS RESTARTS AGE wordpress-f6997b7bc-4fdzt 1/1 Running 0 7s wordpress-f6997b7bc-6ttrn 1/1 Running 0 7s wordpress-f6997b7bc-7tqnv 1/1 Running 0 15m wordpress-f6997b7bc-q4jth 1/1 Running 1 15m
今回は手動で Pod の数を調整しましたが、オートスケール設定を行うことも可能です。
まとめ
コンテナの運用する際にポイントとなる、3つの機能について見てみました。
このように、Kubernetes はコンテナの運用を行う上での強力なツールとなることが分かっていただけたのではないでしょうか。
実際に本番環境にて運用する際には、さらに細かい調整が必要になりますが、一連のブログで「Kubernetes とは何なのか」「Kubernetes では何が出来るのか」をいただき、Kubernetes 利用の手助けになれば幸いです。
Tag: コンテナ Kubernetes
Contactお問い合わせ
お見積もり・ご相談など、お気軽にお問い合わせください。