これは何
今までdocker stackを利用しており、ブランチ毎の最新のコードをそれぞれの環境にブランチ毎のコンテナイメージタグを付けてデプロイするという運用をしていました。
Kubernetesに移行した際に同じような運用を行おうとした時にハマりどころがあり、その解決方法について書きたいと思います。
前提
Kubernetesではlatest
タグイメージの運用は適切なロールバックを行うことが難しいので推奨されていません。
できる限りVersion、もしくはdigest値でのイメージ指定を行いましょう。
latest指定の問題点
通常、違うイメージタグを指定するのであれば公式に書いてあるような、kubectl set image
やkubectl rolling-update
でコンテナイメージの更新を行うことができます。
しかし、同じイメージタグの最新イメージを更新しようとするときは上記の操作では更新されません。
imagePullPolicy: Always
を設定すれば更新してくれるかと思いましたが、この設定値はpod
が起動するときのポリシーの設定です。
よって、pod
が起動するときにコンテナイメージリポジトリからlatest
がついているコンテナイメージをPullするような動作になります。
解決方法
pod
を手動で削除する方法
pod
を手動で削除すると、Deployment
は新規にpodを作成するので、その際にコンテナイメージリポジトリからlatest
がついている最新イメージをPullしてきます。しかしながら、手動でpod
を削除すると勿論通信障害が発生するのでありえません。
Deployment
のPodTemplate(.spec.template
)を書き換える方法
DeploymentのPodTemplateの変更は、rolloutのトリガーとなっているので、新しいpodへのアップデートが自動的に行われます。
新しいpodが作成される際にimagePullPolicy: Always
が動作するので、最新のコンテナイメージをPullしてきてくれます。
PodTemplateを書き換える値はメタデータのラベルでも良いので、実際にイメージを更新する際にはkubectl patch
コマンドを利用し、以下のようなコマンドで行うことができます。
kubectl patch -n ${Namespace} deployment ${DeploymentName} \
-p "{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"date\": \"$(date +'%s')\" }}}}}"
終わりに
パッケージとコンテナイメージは適切なバージョニングを行い、複数の環境毎にバージョン指定を行うと、現在動いている環境からソースコードまでたどり着くことが容易です。可能であれば適切なバージョニングを行うようにしましょう。