開発日報

窓際エンジニアの開発備忘。日報は嘘です。

【連載】Kubernates入門・GKEデプロイと発展的利用 第3回 ~ ReplicaSetとDeployment ~

はじめに

この連載ではコンテナオーケストレーションツールである、 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を管理・操作するために提供されているリソースです。

f:id:yuuu1993g:20191109124029p:plain

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について学びます。