初心者
kubernetes

Kubernetes Deploymentを理解する

More than 1 year has passed since last update.

Kubernetes Deploymentを理解する

kubernetes初心者です。違和感があればコメントください。

Kubernetes Deploymentは"デプロイする"という作業に対応する概念です。

DeploymentはReplicasetを管理し、ReplicasetはPodを管理するという関係性があります。StatefulSetなどのデプロイにDeploymentは利用できません。

1. 簡単な方法でDeploymentを作成してみる

非常に簡単な方法でDeploymentを作成してみます。

例えば、 kubectl run で適当なContainerを起動した時の状態を確認してみます。

# deploymentを作成
$ kubectl run ubuntu -i -t /bin/bash --image=ubuntu

# deployment,replicaset,podを表示
$ kubectl get deployment,replicaset,pod -o wide
NAME            DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINER(S)   IMAGE(S)   SELECTOR
deploy/ubuntu   1         1         1            1           22m       ubuntu         ubuntu     run=ubuntu

NAME                   DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)   SELECTOR
rs/ubuntu-1756523028   1         1         1         22m       ubuntu         ubuntu     pod-template-hash=1756523028,run=ubuntu

NAME                         READY     STATUS    RESTARTS   AGE       IP           NODE
po/ubuntu-1756523028-th3z6   1/1       Running   1          22m       172.17.0.4   minikube

kubectl runしか行っていないので紐付きが分かりにくいですが、DeploymentとReplicasetが同じSelectorを持っていることが分かるので、Deployment→ReplicaSet→Podという紐付きが分かります。

2. DeploymentでRolling UpdateとRollback

前回はkubectl runで簡易的にDeploymentを作成したが、今回は本番稼働を想定しymlファイルを作成してDeploymentをデプロイ、さらにRolling Updateも試してみます。

本章で確かめることがこちら。

  • nginx(v1.12)を作成するDeploymentをデプロイする
  • nginx(v1.13)にRolling Updateする
  • nginx(v1.12)にRollbackする
  • 削除する

2.1. Deploymentの準備

さて、今回 kubectl create で利用するYAMLファイルはこちら。

nginx-deployment-blue.yml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.12.1
        ports:
        - containerPort: 10080

nginx-deployment-green.yml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.5
        ports:
        - containerPort: 10080

image: nginx:xxxxx で指定しているバージョンが異なるだけ。

概要としては、Nginxコンテナを2つ起動する。blueがnginx v1.12.1で、greenがnginx v1.13.5としており、まずはblueを起動し、greenにRolling Update方式で切り替えることを試してみる。

ここで指定するapiVersion はKubernetesのバージョンに依存するため、APIリファレンスを参照してください。今回使う kind はDeploymentなので、以下のURLでDeploymentがどの apiVersion で操作できるかを確認します。

Nginxコンテナは公式のリポジトリを使いました。

https://hub.docker.com/_/nginx/

2.2. Deploymentをデプロイする

kubectl applyを使ってDeploymentをデプロイする。ここで指定するのはblueの方。「--record」を利用することで、ReplicaSetのAnnotationにコマンドやRevision(後述)を履歴として保存しておける。

$ kubectl apply -f nginx-deployment-blue.yml --record
deployment "nginx-deployment" created

※ Kubernetes v1.6までは kubectl create だったが、v1.7からは初回作成の時でも kubectl apply だけで良くなった。もしv1.7以降で、 kubectl create を利用してデプロイするDeploymentを更新する場合は、最初にcreateする時に --save-config を付ける必要がある。

次に、Deployment, ReplicaSet, Podを表示する。

ここで、Selectorに「app=nginx」を指定することで、今回作成したDeploymentに関連するものだけを表示することが出来る。
(YAMLファイルの中で「spec.selector.matchLabels」に「app: nginx」を指定しているため)

$ kubectl get deployment,replicaset,pod -o wide --selector app=nginx
NAME                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
deploy/nginx-deployment   2         2         2            2           2m        nginx          nginx:1.12.1   app=nginx

NAME                             DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
rs/nginx-deployment-3028074442   2         2         2         2m        nginx          nginx:1.12.1   app=nginx,pod-template-hash=3028074442

NAME                                   READY     STATUS    RESTARTS   AGE       IP           NODE
po/nginx-deployment-3028074442-78cwt   1/1       Running   0          2m        172.17.0.5   minikube
po/nginx-deployment-3028074442-8k4cv   1/1       Running   0          2m        172.17.0.6   minikube

2.3. DeploymentをRolling Updateする

blue -> greenにRolling Updateをしてみる。

更新の際も kubectl apply を利用する。

$ kubectl apply -f nginx-deployment-green.yml --record
deployment "nginx-deployment" configured

ちなみに、YAMLファイルを作成せずとも、以下のように kubectl set コマンドで動的に値を渡すことも可能。

kubectl set image deployment/nginx-deployment nginx=nginx:1.13.5

適用したらどう見えるのかを確認する。

$ kubectl get deployment,replicaset,pod -o wide --selector app=nginx
NAME                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
deploy/nginx-deployment   2         2         2            2           3m        nginx          nginx:1.13.5   app=nginx

NAME                             DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
rs/nginx-deployment-3028074442   0         0         0         3m        nginx          nginx:1.12.1   app=nginx,pod-template-hash=3028074442 # 前のReplicaSet
rs/nginx-deployment-3520727465   2         2         2         18s       nginx          nginx:1.13.5   app=nginx,pod-template-hash=3520727465 # 今のReplicaSet

NAME                                   READY     STATUS    RESTARTS   AGE       IP           NODE
po/nginx-deployment-3520727465-39zbt   1/1       Running   0          17s       172.17.0.5   minikube
po/nginx-deployment-3520727465-q77ct   1/1       Running   0          18s       172.17.0.7   minikube

古いReplicaSetが残っているものの、Podは新しいものに切り替わっているのが分かる(NAMEに割り当たるランダム文字列が違うことから)。

applyした履歴は以下のコマンドで参照することが出来る。

$  kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1       kubectl apply --filename=nginx-deployment-blue.yml --record=true
2       kubectl apply --filename=nginx-deployment-green.yml --record=true

REVISION毎にどのような内容だったのかを参照するには「--revision」で番号を指定する。

$ kubectl rollout history deployment nginx-deployment --revision=1
deployments "nginx-deployment" with revision #1
Pod Template:
  Labels:   app=nginx
    pod-template-hash=3028074442
  Annotations:  kubernetes.io/change-cause=kubectl apply --filename=nginx-deployment-blue.yml --record=true
  Containers:
   nginx:
    Image:  nginx:1.12.1
    Port:   10080/TCP
    Environment:    <none>
    Mounts: <none>
  Volumes:  <none>

2.4. DeploymentをRollbackする

前項で見た履歴の通り、Revision 1が古いバージョン(blue)、Revision 2が今のバージョン(green)なので、Revision 1に戻してみる。

$ kubectl rollout undo deployment nginx-deployment --to-revision=1
deployment "nginx-deployment" rolled back

状態を確認する。

$ kubectl get deployment,replicaset,pod -o wide --selector app=nginx
NAME                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
deploy/nginx-deployment   2         2         2            2           57m       nginx          nginx:1.12.1   app=nginx

NAME                             DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR
rs/nginx-deployment-3028074442   2         2         2         57m       nginx          nginx:1.12.1   app=nginx,pod-template-hash=3028074442
rs/nginx-deployment-3520727465   0         0         0         54m       nginx          nginx:1.13.5   app=nginx,pod-template-hash=3520727465

NAME                                   READY     STATUS    RESTARTS   AGE       IP           NODE
po/nginx-deployment-3028074442-4s8xv   1/1       Running   0          42m       172.17.0.5   minikube
po/nginx-deployment-3028074442-73fgz   1/1       Running   0          42m       172.17.0.6   minikube

古い方のReplicaSetに対してContainerがいて、またPodも新しく作り直されていることが分かる。

更にRevisionを確認する。

$ kubectl rollout history deployment nginx-deployment
deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
2       kubectl apply --filename=nginx-deployment-green.yml --record=true
3       kubectl apply --filename=nginx-deployment-blue.yml --record=true

#$

新しいRevision 3が生成されていることが分かる。また、Revision 2から1へとRolling backしたため、Revision 1がなくなっていることも分かる。

2.5. Deploymentを削除する

ここまでやってきたDeploymentを削除する。

DeploymentはReplicasetを管理し、ReplicasetはPodを管理するという関連性があるため、Deploymentを削除することでPodまで削除することが出来る。

$ kubectl delete deployment nginx-deployment
deployment "nginx-deployment" deleted

消えたことを確認する。

$ kubectl get deployment,replicaset,pod -o wide --selector app=nginx
No resources found.

まとめ

  • DeploymentはReplicasetを管理し、ReplicasetはPodを管理している
  • DeploymentはRecisionを管理することで、Rolling UpdateやRolling Backをサポートする

参考:

参照: