kubernetesのコンテナの動作はControllerというレイヤで管理します。dockerインスタンスなどの個別のコンテナはPodという単位ですが、kubernetesはクラスタリング・ツールなので、Pod単体で管理するメリットは特にありません。
Controllerにはいくつかのバリエーションがありますが、基本的にはDeploymentを利用すれば足りそうです。
Deploymentは、コンテナイメージ更新の際の無停止ローリングアップデートやロールバックを取り扱えます。
※ ただし、persistentDiskをマウントしているコンテナの場合には、新イメージのPod起動時にマウントすべきディスクを獲得できず、”FailedMount AttachVolume.Attach failed”のようなエラーが出て操作完了しませんでした。このケースでは既存Podを先に停止させる必要がありそうです。
無停止アップデートの手順
Deploymentを利用した無停止アップデートの導入手順は以下のような流れです。
- Deploymentの構成ファイルを定義してコンテナ群を構築
- コンテナを更新する際に、構成ファイルの.spec.template以下の設定値を書き換える
kubectl apply -f some_config.yaml
を実行
.spec.templateの例として、 公式ドキュメントの解説では、dockerイメージのバージョンタグ(.spec.template.spec.containers.image)の書き換えを想定しています。
実際には、.spec.template.metadata.labels
に任意のラベル(バージョンなど)を設定して、その設定値更新でもPodコンテナのアップデートを実行できます。
各バージョンのDeploymentを定義するたびに、ReplicaSetが新たに作成され、直前まで実行していたReplicaSetが停止します。
過去のReplicaSetの設定は更新後も保持しているため、kubectl rollout undo
コマンドでロールバックできます。
Deploymentのリビジョン履歴は、kubectl rollout history
コマンドでリスト表示できます。
何らかの理由で新構成のPodを起動できなかった場合、旧Podが引き続き稼働しつづける挙動になっています。
Replication Controller→Deploymentへの移行
旧バージョンのControllerにはReplication Controllerしかなかったため、従来のユーザーはどこかのタイミングでDeploymentなどに切り替える必要性に直面します。
ただし、Replication ControllerとDeploymentの設定項目は互換性が高いため、Replication Controllerの設定ファイルをほぼ流用できます。
変更点は以下のとおりでした。
- apiVersion: apps/v1
- kind: Deployment
- spec.selectorはバリデーションエラーになるため削除
kubectl
による操作インターフェースも両者は基本的に同じです。Replication Controllerの設定ファイルをコピーしてDeploymentの設定ファイルを作成したとすると、以下のように delete -> create することで移行完了します。
$ kubectl delete -f some-replication-controller.yaml
$ kubectl create -f some-deployment.yaml
Chuma Takahiro