はじめに
この連載ではコンテナオーケストレーションツールである、 Kubernatesの使い方を学びます。
今回はReplicasetとDeploymentについて学習します。
サンプルコード
こちらに順次アップしていきますー。
連載記事一覧
ReplicaSet
ReplicaSetは同じPodを複数生成・管理するためのリソースです。一定以上の規模のアプリケーションの場合、同一のPodを複数並行して実行することで可用性を高める必要があります。
ReplicaSetを定義したマニフェストファイルsimple-replicaset.yamlを次のように作成します。
apiVersion: apps/v1 kind: ReplicaSet metadata: name: echo labels: app: echo spec: replicas: 3 selector: matchLabels: app: echo template: # template以下はPodリソースにおける定義と同じ metadata: labels: app: echo spec: containers: - name: nginx image: gihyodocker/nginx:latest env: - name: BACKEND_HOST value: localhost:8080 ports: - containerPort: 80 - name: echo image: gihyodocker/echo:latest ports: - containerPort: 8080
解説すると、
・kind: ReplicaSetでレプリカセットの定義であることを指定
・replicasで作成するPod数を指定
・templatesでPodの定義をする
結果としてtemplatesに定義したレプリカ(Pod)が3つ作成されることになります。
このReplicaSetを反映すると、Podが3つ作成されたことが確認できます。同一のPodが複製されるため、Pod名にはecho-bmc8hのようにランダムな識別子がサフィックスに付与されます。
$ kubectl apply -f simple-replicaset.yaml replicaset.apps/echo created
$ kubectl get pod NAME READY STATUS RESTARTS AGE echo-6gqb2 0/2 ContainerCreating 0 10s echo-mc8bm 0/2 ContainerCreating 0 10s echo-qbdsr 0/2 ContainerCreating 0 10s
simple-replicaset.yamlのreplicasの数値を2にしてapplyしてみましょう。
spec: replicas: 2
$ kubectl apply -f simple-replicaset.yaml replicaset.apps/echo configured $ kubectl get pod NAME READY STATUS RESTARTS AGE echo-6gqb2 2/2 Running 0 12m echo-qbdsr 2/2 Running 0 12m
作成したReplicaSetは、次のようにマニフェストファイルを利用して削除しておきます。ReplicaSetと、関連するPodが削除されます。
$ kubectl delete -f simple-replicaset.yaml
Deployment
Deploymentとはアプリケーションデプロイの基本単位となるリソースです。 ReplicaSetの上位のリソースとして提供されて言うます。
ReplicaSetは同一仕様Podのレプリカの数を管理・制御するためのリソースでした。
対して、DeploymentはReplicaSetを管理・操作するために提供されているリソースです。
Deploymentを定義したマニフェストファイルsimple-deployment.yamlを次のように作成します。
apiVersion: apps/v1 kind: Deployment metadata: name: echo labels: app: echo spec: replicas: 3 selector: matchLabels: app: echo template: # template以下はPodリソースにおけるspec定義と同じ metadata: labels: app: echo spec: containers: - name: nginx image: gihyodocker/nginx:latest env: - name: BACKEND_HOST value: localhost:8080 ports: - containerPort: 80 - name: echo image: gihyodocker/echo:latest ports: - containerPort: 8080
simple-replicaset.yamlとの違いがほとんどないことにお気づきでしょうか。
違いとしてはDeploymentがReplicaSetの世代管理を可能にする点です。
--recordオプションをつけてkubectlから反映しましょう。
実行したkubectlのコマンドが記録されます。
$ kubectl apply -f simple-deployment.yaml --record deployment "echo" created
kubectlで確認してみましょう。
Deploymentの他にも、ReplicaSet、Podが作成されています。
$ kubectl get pod,replicaset,deployment --selector app=echo NAME READY STATUS RESTARTS AGE pod/echo-679f89b546-95g9w 2/2 Running 0 61s pod/echo-679f89b546-gshlg 2/2 Running 0 61s pod/echo-679f89b546-k4brk 2/2 Running 0 61s NAME DESIRED CURRENT READY AGE replicaset.extensions/echo-679f89b546 3 3 3 61s NAME READY UP-TO-DATE AVAILABLE AGE deployment.extensions/echo 3/3 3 3 61s
ReplicaSetライフサイクル
KubernetesではDeploymentを1単位として、アプリケーションをデプロイしていきます。実運用ではReplicaSetを直接用いず、Deploymentのマニフェストファイルを扱うことがほとんどです。
Deploymentが管理するReplicaSetは指定されたPod数の確保や、新しいバージョンのPodへの入れ替え、以前のバージョンへのPodのロールバックといった重要な役割を担っています。
アプリケーションのデプロイを正しく運用していくには、Deploymentの中でReplicaSetがどのような挙動をするかを把握しておきましょう。
Deploymentの更新によってReplicaSetが新しく作成され、古いReplicaSetとの入れ替えが行われます。
Pod数のみを更新しても新規ReplicaSetは生まれない
まずはPod数だけを更新してみましょう。simple-deployment.yamlのreplicasを3から4に変更して反映してみます。
$ kubectl apply -f simple-deployment.yaml --record deployment.apps/echo configured
Podが1つ増えました。
$ kubectl get pod NAME READY STATUS RESTARTS AGE echo-679f89b546-95g9w 2/2 Running 0 11m echo-679f89b546-gshlg 2/2 Running 0 11m echo-679f89b546-k4brk 2/2 Running 0 11m echo-679f89b546-sc459 2/2 Running 0 77s
新しくReplicaSetが作成されていればリビジョン番号が2になっているはずですが、1のままです。 replicasの変更では新しいDeployment(Replicasetの入れ替え)は発生していません。
$ kubectl rollout history deployment echo deployment.extensions/echo REVISION CHANGE-CAUSE 1 kubectl apply --filename=simple-deployment.yaml --record=true
コンテナ定義を更新
コンテナのイメージを変更した場合は新しいDeployment(Replicasetの入れ替え)が発生するはずです。
simple-deployment.yamlのechoコンテナのイメージをgihyodocker/echo:patchedに変更します。
image: gihyodocker/echo:patched
$ kubectl apply -f simple-deployment.yaml --record deployment.apps/echo configured
podの状態を確認してみると、古いPodの削除と新しいPodの生成が段階的に行われているのがわかります。
$ kubectl get pod --selector app=echo NAME READY STATUS RESTARTS AGE echo-679f89b546-95g9w 2/2 Running 0 23m echo-679f89b546-gshlg 2/2 Running 0 23m echo-679f89b546-k4brk 2/2 Running 0 23m echo-679f89b546-sc459 2/2 Terminating 0 13m echo-6bd7755774-8q96s 0/2 ContainerCreating 0 8s echo-6bd7755774-qqlk6 0/2 ContainerCreating 0 8s
Deploymentのリビジョン、REVISION=2が作成されています。
$ kubectl rollout history deployment echo deployment.extensions/echo REVISION CHANGE-CAUSE 1 kubectl apply --filename=simple-deployment.yaml --record=true 2 kubectl apply --filename=simple-deployment.yaml --record=true
ロールバックを実行する
Deploymentの特定のリビジョンの内容を確認できます。
$ kubectl rollout history deployment echo --revision=1 deployment.extensions/echo with revision #1 Pod Template: Labels: app=echo pod-template-hash=679f89b546 Annotations: kubernetes.io/change-cause: kubectl apply --filename=simple-deployment.yaml --record=true Containers: nginx: Image: gihyodocker/nginx:latest Port: 80/TCP Host Port: 0/TCP Environment: BACKEND_HOST: localhost:8080 Mounts: <none> echo: Image: gihyodocker/echo:latest Port: 8080/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none>
undoを実行すれば直前の操作のリビジョンにDeploymentをロールバックができます。
$ kubectl rollout undo deployment echo deployment.extensions/echo rolled back
最後に、作成したDeploymentは、次のようにマニフェストファイル指定で削除しておきましょう。Deploymentと、関連するReplicastとPodが削除されます。
$ kubectl delete -f simple-deployment.yaml
まとめ
今回はReplicaSetとDeploymentについて学びました。 次回はServiceについて学びます。