前回はReplicaSetの簡単な紹介を行いました。今回はそのReplicaSetの上位リソースである、Deploymentについて説明していきたいと思います。
Deploymentとは
Deploymentは、アプリケーションのデプロイや管理を行うためのリソースです。Deploymentを使用すると、
- デプロイ
- アップデート
- スケール
- ロールバック
などが簡単に実行できます。また、DeploymentはReplicaSetの上位リソースなので、ReplicaSetの機能(Podのセルフヒーリングなど)も利用できます。
ですので、ReplicaSetを作成するとPodが作成されたのと同様、Deploymentを作成すると、ReplicaSetとPodが作成されます。
実際にDeploymentを作成する手順は後述するとして、Deploymentを作成するとReplicaSetとPodも作成されていることを確認します。
以下のようなDeploymentがある場合、
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 13s
ReplicaSetの一覧を取得してみると、
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-6d6565499c 3 3 3 5m24s
このようにReplicaSetも作成されています。また、Podの一覧を確認してみると、
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-deployment-6d6565499c-jwfjw 1/1 Running 0 5m52s
nginx-deployment-6d6565499c-pnz6g 1/1 Running 0 5m52s
nginx-deployment-6d6565499c-vl2m2 1/1 Running 0 5m52s
このようにPodも作成されています。
Deploymentを作成してみる
ここからは実際にDeploymentを作成してみます。Deploymentはkubectl create deploy
コマンドで作成するか、マニフェストファイルから作成できます。
今回は、kubectl create deploy
コマンドを使ってマニフェストファイルのひな型を作成し、そのマニフェストファイルをクラスターに適用する方法で作成します。
kubectl create
コマンドは、-o yaml
オプションをつけることでyamlファイルとして構成情報を出力できます。--dry-run=client
オプションをつけると、リソースが作成されなくなるので、単純にマニフェストファイルを出力することができます。
$ kubectl create deploy nginx-deployment --image=nginx:1.14.2 --replicas=3 --dry-run=client -o yaml >> nginx-deployment.yaml
上記のコマンドを実行すると、カレントディレクトリに下記のようなnginx-deployment.yaml
が作成されます。
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx-deployment
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx-deployment
spec:
containers:
- image: nginx:1.14.2
name: nginx
resources: {}
status: {}
この中で今回不要な部分を削除します(削除しなくても問題はありません)。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deployment
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- image: nginx:1.14.2
name: nginx
このマニフェストファイルをクラスターに適用します。
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
これでDeploymentの作成は完了です。
作成されたかどうかは、kubectl get
コマンドで確認できます。
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 37s
Deploymentの機能を試してみる
Deploymentの機能として、
- デプロイ
- アップデート
- スケールアップ
- ロールバック
を挙げましたので、これらの機能を試してみたいと思います。
デプロイ
これは、Deploymentを作成した段階で行われています。--replicas
オプションに指定した数のPodがデプロイされていることが分かります。
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-deployment-75c7fcd9ff-8wzxv 1/1 Running 0 24s
nginx-deployment-75c7fcd9ff-8zqnf 1/1 Running 0 24s
nginx-deployment-75c7fcd9ff-m9cqs 1/1 Running 0 24s
アップデート
Deploymentは、新しいバージョンのアプリケーションをデプロイする際に、古いバージョンのPodを段階的に置き換えるローリングアップデートをサポートしています。これによって、ダウンタイムを最小限に抑えながらアップデートを行うことができます。
アップデートを行う場合、以下のような方法があります。
-
kubectl set
コマンドを使う - マニフェストファイルを変更して、
kubectl apply
を行う
kubectl set
コマンドでの更新は迅速に行えますが、マニフェストファイルとの差分が生じてしまい管理の手間が出てしまうため、基本的にはマニフェストファイルを用いた方法でアップデートを行います。ここでは、マニフェストファイルを編集してアップデートを行いたいと思います。
nginxのイメージを、nginx:1.14.2
からnginx:1.16.1
に更新します。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deployment
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- image: nginx:1.16.1
name: nginx
kubectl apply
コマンドでマニフェストファイルを適用します。
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment configured
kubectl rollout status
コマンドで、アップデートの状況を確認できます。
$ kubectl rollout status deployment/nginx-deployment
kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
このように、順番にPodがアップデートされていることが分かります。
Deploymentは、Podが更新されている間に特定の数のPodのみが停止状態になることを保証しています(ローリングアップデート)。デフォルトでは、目標とするPod数(今回は3)のうち、少なくとも75%が稼働状況であることを保証します。
スケールアップ
Deploymentのスケールは、以下の方法で行えます。
-
kubectl scale
コマンドを使う - マニフェストファイルを編集する
アップデートの時と同様の理由で、マニフェストファイルを編集してスケールアップしてみます。
以下のようにマニフェストファイルを変更します。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deployment
name: nginx-deployment
spec:
replicas: 10 # replicasを3 => 10に
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- image: nginx:1.16.1
name: nginx
クラスタに適用します。
$ kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment configured
スケールされたかを確認します。
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 10/10 10 10 18m
READY
が10/10
になっていることがわかります。一応、Podの方も確認してみます。
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-deployment-577ccfb786-9ffxg 1/1 Running 0 7m30s
nginx-deployment-577ccfb786-9fkf6 1/1 Running 0 77s
nginx-deployment-577ccfb786-cbbn9 1/1 Running 0 7m24s
nginx-deployment-577ccfb786-h69jh 1/1 Running 0 77s
nginx-deployment-577ccfb786-k7tmw 1/1 Running 0 7m35s
nginx-deployment-577ccfb786-lcfk7 1/1 Running 0 77s
nginx-deployment-577ccfb786-qrjhq 1/1 Running 0 77s
nginx-deployment-577ccfb786-sm4db 1/1 Running 0 77s
nginx-deployment-577ccfb786-vt4p8 1/1 Running 0 77s
nginx-deployment-577ccfb786-wnxls 1/1 Running 0 77s
元々作成されていたPodのAGE
が7分ほどであるのに対し、新たにスケールしたPodが77s
になっていることが分かります。
ロールバック
ロールバックは、マニフェストファイルからではなく、kubectl
コマンドを使用して行います。これは、kubectl rollout undo
コマンドを使って以前のリビジョンに戻すことができるためです。マニフェストファイルは、Gitなどで管理されていればそちらでリビジョンに合わせてバージョンを戻します。
以下のような手順でロールバックします。
- 現在のリビジョンを確認
- リビジョンを指定してロールバックを実行
- ロールバックの状態を確認
まずは、現在のリビジョンをkubectl rollout history
コマンドで確認します。
$ kubectl rollout history deployment.v1.apps/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
イメージをnginx:1.14.2
を使った時のリビジョンと、現在のnginx:1.16.1
を使った時のリビジョンがあります。
CHANGE-CAUSE
には、アップデート時のコメントが入ります。このコメントはマニフェストファイルのkubernetes.io/change-cause
アノテーションからリビジョンにコピーされますが、今回は指定していないので<none>
になっています。
リビジョンは数字が大きいほうが後の更新のものです。ですので、戻す対象のリビジョンは1になります。では、kubectl rollout undo
コマンドを使ってリビジョン1にロールバックしてみます。
$ kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=1
deployment.apps/nginx-deployment rolled back
ロールバックが成功したかどうか、kubectl get
で確認します。
$ kubectl get deploy nginx-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 10/10 10 10 32m
すべてのPodがREADYになっていることが確認できます。
また、イメージがnginx:1.14.2
になっているかどうか、kubectl describe
コマンドで確認してみます。
$ kubectl describe deploy nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Fri, 28 Jun 2024 04:57:23 +0000
Labels: app=nginx-deployment
Annotations: deployment.kubernetes.io/revision: 3
Selector: app=nginx-deployment
Replicas: 10 desired | 10 updated | 10 total | 10 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx-deployment
Containers:
nginx:
Image: nginx:1.14.2 <= 1.14.2になっている
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: nginx-deployment-577ccfb786 (0/0 replicas created)
NewReplicaSet: nginx-deployment-75c7fcd9ff (10/10 replicas created)
(以降省略)
nginx:1.14.2
になっていることが確認できます。
まとめ
今回はDeploymentの概要と、作成方法、Deploymentの基本機能の確認を行いました。次回は、これらの機能(Pod, ReplicaSet, Deployment, Service)を使ってウェブサイトをインターネットに公開してみたいと思います。