はじめに
こんにちは!
本記事は「本気で学ぶKubernetes」シリーズの第17回です。このシリーズでは、Kubernetesの基礎から実践まで、段階的に学んでいきます。
このシリーズは、第1回から順に読むことで体系的に学べる構成にしています。
まだご覧になっていない方は、ぜひ最初からご覧ください!
今回はKubernetesにおけるDeploymentの更新とロールバックについて学んでいきたいと思います。
この記事は人間がKubernetesの公式ドキュメントを読み漁りながら書いていますのでご安心ください!
TL;DR
忙しい方のために要点だけ図示しておきます!
アプリケーションのデプロイ手法について
一般的にアプリケーションを更新する際のデプロイ手法には、いくつかの代表的なものがあります。
In-place Deployment
既存の環境上で段階的にアプリケーションを置き換えていく方式です。
サーバーやコンテナを少しずつ新バージョンに入れ替えていくので、ダウンタイムを最小限に抑えることが可能で、KubernetesのRollingUpdateがまさにこの方式になります。
Blue/Green Deployment
本番環境(Blue)とは別に新バージョンの環境(Green)を用意して、切り替えるタイミングで一気にトラフィックを向け直すという方式です。
問題があればすぐにBlueに戻せるメリットがありますが、2つの環境を同時に用意する必要があるためその分コストがかかります。
Canary Deployment
新バージョンを一部のユーザーだけに公開して、問題がなければ徐々に全体に展開していくという方式です少数のユーザーで新バージョンを試すことができ、問題があった場合もその影響範囲が少なくなります。
Recreate Deployment
既存の環境を全て停止してから、新バージョンを一気にデプロイする方式です。シンプルでわかりやすいですが、切り替え時にダウンタイムが発生します。
開発環境や、複数バージョンが共存すると問題がある場合に使わレルかなと思います。
Kubernetesにおいては基本的にDeploymentでローリングアップデートを行う「In-place方式」、全てを一度に入れ替える「Recreate方式」をサポートしています。
もしBlue/GreenやCanaryによるデプロイを行いたい場合はService切り替えやIstioなどのサービスメッシュなどの別の仕組みを利用して実現する必要があります。
Deploymentの更新方法
Deploymentを更新する方法はいくつかあります。
- kubectl set imageコマンド
- マニフェストファイルの変更とapply
- kubectl edit
kubectl set imageコマンド
コンテナイメージのバージョンを直接変更したい時に使えるコマンドで、一番簡単に更新できる方法でもあります。
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
マニフェストファイルの変更とapply
マニフェストの宣言でimageを変更してから、kubectl applyで適用します。
spec:
containers:
- name: nginx
image: nginx:1.22 # 1.21 -> 1.22に変更
kubectl apply -f nginx-deployment.yaml
kubectl edit
エディタを開いて直接編集する方法です。
これはマニフェストとの差分が生まれるため基本的には推奨されないやり方です。
kubectl edit deployment nginx-deployment
実務ではGit等で変更履歴を管理できるためマニフェストファイルを変更するのが一般的と思います。
出典: Kubernetes公式ドキュメント - Updating a Deployment
Kubernetesにおけるデプロイ戦略
アプリケーションのデプロイ手法にて、KubernetesはRollingUpdateとRecreateをサポートしていると述べました。
それぞれどんな挙動になるのかを見ていきたいと思います。
RollingUpdate
こちらは新しいPodを段階的に作成しながら、古いPodを段階的に削除していく方式です。
そのためダウンタイムなしで更新できるのが特徴で、一時的に新旧両方のPodが共存することになります。
本番環境での通常のデプロイやダウンタイムを許容できない場合に使います。また用途としてはWebアプリケーションなど、複数バージョンが共存しても問題ない場合に適しています。
Recreate
既存のPodを全て削除してから、新しいPodを作成する方式です。
ダウンタイム発生しまいますが古いPodが残ることがありません。
例えば、データベースなど複数バージョンが共存してしまうと問題がある場合や、使用可能なリソースが限られている環境で使うことが多いと思います。
マニフェストではspec.strategy.typeでデプロイ方法を指定することで設定可能です。
spec:
strategy:
type: RollingUpdate # または Recreate
出典: Kubernetes公式ドキュメント - Strategy
RollingUpdateのパラメータについて
RollingUpdateは必ず押さえておくべきデプロイ手法のため、パラメータについても確認しておきます。
以下のマニュフェストではmacSurgeとmaxUnavailableを設定しています。
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 最大で何個余分にPodを作れるか
maxUnavailable: 0 # 最大で何個のPodが利用不可になっていいか
maxSurgeは希望しているPod数に対して、何個まで多くPodを余分に作成できるかを指定します。
例えば、replicas=4でmaxSurge=1の場合、更新中は4+1で最大5個のPodが起動してアップデートがされます。
maxUnavailable
maxUnavailableは希望するPod数に対して、何個までPodが利用不可になっていいかを指定します。
例えば、replicas=4でmaxUnavailable=1の場合、更新中は最低3個のPodが稼働しています。
基本的にはmaxSurge=1, maxUnavailable=0にしておくと、設定している必要なPod数を確保した上でローリングアップデートを行うことができますしリソースの無駄も少ないと思います。
ロールアウト履歴については以下のコマンドで確認が可能です。
kubectl rollout history deployment/nginx-deployment
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 update to nginx:1.22
出典: Kubernetes公式ドキュメント - Rolling Update Parameters
ロールバックについて
運用していると間違えて適用してしまったため、元の状態に戻したい場合も少なからずあるかと思います。
その場合もコマンドで過去のリビジョンにロールバックすることが可能です。
以下はロールバックする際のコマンド例です。
# 直前のリビジョンにロールバックする
kubectl rollout undo deployment/nginx-deployment
# deployment.apps/nginx-deployment rolled back
# 特定のリビジョンにロールバックする
kubectl rollout undo deployment/nginx-deployment --to-revision=2
# deployment.apps/nginx-deployment rolled back
出典: Kubernetes公式ドキュメント - Rolling Back a Deployment
まとめと次回予告
今回はKubernetesにおけるDeploymentの更新方法として「RollingUpdate」と「Recreate」の2つのデプロイ手法について触れてきました。
RollingUpdateのmaxSurge=1, maxUnavailable=0の概念はとても重要になってきますので必ず押さえておきましょう!
次回は、いよいよGoogle CloudのGoogle Kubernetes Engineについて学習していきたいと思います。
それでは、また次回!
