このセクションでは、複数の ReplicaSet を管理することで、Pod のローリングアップデートやロールバックなどを実現する Deployment リソースの作成について紹介します。

Deployment リソースを使うことで、新しい ReplicaSet 上でコンテナが起動したことやヘルスチェックが通っていることを確認しながら切り替えを行ってくれるため、基本的にはサービスを停止させることなく Pod のアップデートを行うことができます。Deployment ではなく ReplicaSet で作成した Pod の場合には、ローリングアップデートなどの機能は利用することができません。

サンプルのマニフェストファイルを新規作成し、以下コードを記述します。

[root@kube-master sample-deployment]# vi sample-deployment.yaml 

kind に Deployment を指定します。その他の記述は、ReplicaSet と基本的には同じです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.12
          ports:
            - containerPort: 80

Master サーバーから 作成したマニフェストを実行し、Kubernetes クラスタ上にリソースを作成します。 – – record オプションを付けておくことで、アップデートを行った際の履歴を保持しておくことが可能です。

[root@kube-master sample-deployment]# kubectl apply -f sample-deployment.yaml --record
deployment.apps/sample-deployment created [root@kube-master sample-deployment]#

Master サーバーから Kubernetes クラスタ上のリソースを確認します。ここでは、3つのPodのレプリカが稼働していることが確認できます。

[root@kube-master sample-deployment]# kubectl get pod
NAME                                 READY   STATUS    RESTARTS   AGE
sample-deployment-6c5948bf66-5r5dx   1/1     Running   0          3s
sample-deployment-6c5948bf66-dkcdk   1/1     Running   0          3s
sample-deployment-6c5948bf66-wb6qq   1/1     Running   0          3s
[root@kube-master sample-deployment]# 

Master サーバーから Kubernetes クラスタ上のレプリカの一覧を YAML 形式で表示します。 履歴は各 ReplicaSet の metadata.annotations.kubernetes.io/change-cause に保持されます。また、現在の ReplicaSet の Revision の番号も同様に metadata.annotations.deployment.kubernetes.io/revision に保持されます。

[root@kube-master sample-deployment]# kubectl get replicasets -o yaml | head
apiVersion: v1
items:
- apiVersion: extensions/v1beta1
  kind: ReplicaSet
  metadata:
    annotations:
      deployment.kubernetes.io/desired-replicas: "3"
      deployment.kubernetes.io/max-replicas: "4"
      deployment.kubernetes.io/revision: "1"
      kubernetes.io/change-cause: kubectl apply --filename=sample-deployment.yaml
[root@kube-master sample-deployment]# 

Master サーバーから Kubernetes クラスタ上の Deployment を確認します。

[root@kube-master sample-deployment]# kubectl get deployments
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
sample-deployment   3/3     3            3           92s
[root@kube-master sample-deployment]# 

Master サーバーから Kubernetes クラスタ上の ReplicaSet を確認します。

[root@kube-master sample-deployment]# kubectl get replicasets
NAME                           DESIRED   CURRENT   READY   AGE
sample-deployment-6c5948bf66   3         3         3       115s
[root@kube-master sample-deployment]# 

Master サーバーから Deployment で利用しているコンテナイメージを、nginx:1.12 から nginx:1.13 にアップデートしてみます。ここでは、イメージの更新に kubectl set image コマンドを使用します。

[root@kube-master sample-deployment]# kubectl set image deployment sample-deployment nginx-container=nginx:1.13
deployment.extensions/sample-deployment image updated
[root@kube-master sample-deployment]# 

Master サーバーからアップデートの状況を確認します。ここでは、3つの新しいレプリカをアップデートし作成し2つの古いレプリカを終了する処理をした後に、最後に残りの古い1つのレプリカを終了する動きをしアップデートが終了していることが確認できます。

[root@kube-master sample-deployment]# kubectl rollout status deployment sample-deployment
Waiting for deployment "sample-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "sample-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "sample-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "sample-deployment" successfully rolled out
[root@kube-master sample-deployment]# 

Master サーバーから Kubernetes クラスタ上の Deployment を確認します。

[root@kube-master sample-deployment]# kubectl get deployments
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
sample-deployment   3/3     3            3           5m19s
[root@kube-master sample-deployment]# 

Master サーバーから Kubernetes クラスタ上の ReplicaSet を確認します。ここでは、古い ReplicaSet( sample-deployment-6c5948bf66 )と新しい ReplicaSet( sample-deployment-7b4f67c7bc )が確認でき、新しい ReplicaSet に Pod が 3つ稼働していることが分かります。

[root@kube-master sample-deployment]# kubectl get replicasets
NAME                           DESIRED   CURRENT   READY   AGE
sample-deployment-6c5948bf66   0         0         0       5m24s
sample-deployment-7b4f67c7bc   3         3         3       23s
[root@kube-master sample-deployment]# 

Master サーバーから Kubernetes クラスタ上のリソースを確認します。ここでは、Pod Template Hash が再計算され、アップデート前とは異なる名前の3つのPodのレプリカが稼働していることが確認できます。

[root@kube-master sample-deployment]# kubectl get pod
NAME                                 READY   STATUS    RESTARTS   AGE
sample-deployment-7b4f67c7bc-bb5qn   1/1     Running   0          29s
sample-deployment-7b4f67c7bc-sgckx   1/1     Running   0          27s
sample-deployment-7b4f67c7bc-tbvn7   1/1     Running   0          30s
[root@kube-master sample-deployment]# 

Master サーバーから古い ReplicaSet( sample-deployment-6c5948bf66 )の ReplicaSet 情報を確認します。ここでは、ReplicaSet の Revision 番号が1、コンテナイメージが nginx:1.12 であったことが確認できます。

[root@kube-master sample-deployment]# kubectl get replicasets sample-deployment-6c5948bf66 -o yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  annotations:
    deployment.kubernetes.io/desired-replicas: "3"
    deployment.kubernetes.io/max-replicas: "4"
    deployment.kubernetes.io/revision: "1"
    kubernetes.io/change-cause: kubectl apply --filename=sample-deployment.yaml --record=true
  creationTimestamp: "2019-01-13T13:41:31Z"
  generation: 4
  labels:
    app: sample-app
    pod-template-hash: 6c5948bf66
  name: sample-deployment-6c5948bf66
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: Deployment
    name: sample-deployment
    uid: efb53a12-1738-11e9-94ad-525400bc2a02
  resourceVersion: "1027856"
  selfLink: /apis/extensions/v1beta1/namespaces/default/replicasets/sample-deployment-6c5948bf66
  uid: efb83911-1738-11e9-94ad-525400bc2a02
spec:
  replicas: 0
  selector:
    matchLabels:
      app: sample-app
      pod-template-hash: 6c5948bf66
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: sample-app
        pod-template-hash: 6c5948bf66
    spec:
      containers:
      - image: nginx:1.12
        imagePullPolicy: IfNotPresent
        name: nginx-container
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  observedGeneration: 4
  replicas: 0
[root@kube-master sample-deployment]# 

Master サーバーから新しい ReplicaSet( sample-deployment-7b4f67c7bc )の ReplicaSet 情報を確認します。ここでは、ReplicaSet の Revision 番号が2 となり、コンテナイメージも nginx:1.13 にアップデートされていることが確認できます。

[root@kube-master sample-deployment]# kubectl get replicasets sample-deployment-7b4f67c7bc -o yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  annotations:
    deployment.kubernetes.io/desired-replicas: "3"
    deployment.kubernetes.io/max-replicas: "4"
    deployment.kubernetes.io/revision: "2"
    kubernetes.io/change-cause: kubectl apply --filename=sample-deployment.yaml --record=true
  creationTimestamp: "2019-01-13T13:46:32Z"
  generation: 3
  labels:
    app: sample-app
    pod-template-hash: 7b4f67c7bc
  name: sample-deployment-7b4f67c7bc
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: Deployment
    name: sample-deployment
    uid: efb53a12-1738-11e9-94ad-525400bc2a02
  resourceVersion: "1027849"
  selfLink: /apis/extensions/v1beta1/namespaces/default/replicasets/sample-deployment-7b4f67c7bc
  uid: a2ab17f7-1739-11e9-94ad-525400bc2a02
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
      pod-template-hash: 7b4f67c7bc
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: sample-app
        pod-template-hash: 7b4f67c7bc
    spec:
      containers:
      - image: nginx:1.13
        imagePullPolicy: IfNotPresent
        name: nginx-container
        ports:
        - containerPort: 80
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  fullyLabeledReplicas: 3
  observedGeneration: 3
  readyReplicas: 3
  replicas: 3
[root@kube-master sample-deployment]#