Sep 23, 2019
Jan 1, 1970
N/A Views
MD
warning
この記事は2年以上前に更新されたものです。情報が古くなっている可能性があります。

アプリケーションのアップデートはDeploymentによって行われます。

image

アプリケーションのアップデートを行う場合は、Dockerイメージのタグを新しいバージョンに変更し、kubectl applyすれば良いです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - image: making/hello-pks:0.0.2 # <-- 0.0.1からアップデート

ただし、ダウンタイムなしにアプリケーションをアップデートしたい場合は、コンテナのヘルスチェックとDeploymentのアップデートストラテジーに気をつける必要があります。

目次

コンテナのヘルスチェック

Deplotmentでアプリケーションを更新する場合は、更新したコンテナが正常に動作しているかどうかを
Deploymentのコントローラーは知る必要があります。このヘルスチェックがないと、次のPodを更新して良いか正しく判断することができません。

コンテナのヘルスチェックにはReadiness ProbeとLiveness Probeの2種類があります。
Readiness Probeはコンテナがトラフィックを受けられるかどうかをチェックし、Liveness Probeはコンテナが生存しているかどうかをチェックします。
アプリケーションの更新の際はReadiness Probeを正しく設定する必要があります。

Readiness Probe

Deploymentのspec.template.spec.containers[]readinessProbeの設定を行います。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - image: making/hello-pks:0.0.1
        name: hello-pks
        ports:
        - containerPort: 8080
        env:
        - # ...
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
          periodSeconds: 5

Readinss ProbeおよびLiveness ProbeはHTTP、TCP、コマンド実行結果によるヘルスチェックをサポートしています。
ここではHTTPヘルスチェック(httpGet)のみ扱います。その他の方法はドキュメントを参照してください。
making/hello-pksSpring Boot Actuatorを使っており、ヘルスチェックエンドポイントとして/actuator/healthpathに設定できます。

initialDelaySecondsはコンテナが起動を開始してから初めのチェックを行うまでの待ち時間(秒)です。
timeoutSecondsは1回のチェックで失敗とみなすまでのタイムアウト(秒)です。failureThresholdはヘルスチェックを失敗とみなすまでのリトライ回数です。
periodSecondsはリトライの間隔(秒)です。

Liveness Probe

Liveness Probeはアプリケーションの更新には直接関係しませんが、ヘルスチェックの1種としてここで説明します。
Liveness Probeはコンテナの生存確認に使われ、Liveness Probeが失敗した場合はコンテナが再起動します。
アプリが終了せずに動かなくなったり、デッドロックしてstuckしたアプリを再起動するために使用します。

Deploymentspec.template.spec.containers[]livenessProbeの設定を行います。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - image: making/hello-pks:0.0.1
        name: hello-pks
        ports:
        - containerPort: 8080
        env:
        - # ...
        readinessProbe:
          # ...
        livenessProbe:
          httpGet:
            path: /actuator/info
            port: 8080
          initialDelaySeconds: 20
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 1

設定項目はReadiness Probeと同じです。

Readinss ProbeおよびLiveness Probeに同じ内容を設定するのは良くありません。Liveness Probeではデータベースの接続チェック等は行わない方が良いです。

Readiness ProbeとLiveness Probeの違いはこの記事が詳しいです。

Deploymentのアップデートストラテジー

Deploymentでアプリケーションを更新する場合にアップデートストラテジーとしてRollingUpdateRecreateが選べます。
デフォルトはRollingUpdateです。

Rolling Update

Rolling UpdateではPodを少しずつ新しいバージョンに移行し、ダウンタイムなく切り替えることができます。
Rolling Updateの挙動はmaxUnavailablemaxSurgeによって調節できます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    # ...

maxUnavailableはアップデート中に許容できる最大の使用不可Podの数または割合です。
maxSurgeはアップデート中にreplicas数を超えて増やして良いPodの数または割合です。
maxUnavailablemaxSurgereplicasに依存しないように%で指定した方が良いです。

maxUnavailablemaxSurgeともにデフォルト値は25%です。

例えばreplicas4の場合でmaxUnavailable2maxSurge0だとします。
その場合はPod数は次の表のように推移します。(実行タイミングやコンテナの起動速度により異なる場合があります)

旧バージョンのPod数(Ready/Desired) 新バージョンのPod数(Ready/Desired)
4/4 0/0
2/2 0/2
0/0 2/4
0/0 4/4

移行の途中にReadyなPod数の合計が2 (4 - 2)な状態を経由していることがわかります。

🎥 asciinemaで見る(ReplicaSetのDESIREDREADYの数字の推移に注目してください)

replicas4の場合でmaxUnavailable0maxSurge2だとします。
その場合はReady状態なPod数は次の表のように推移します。(実行タイミングやコンテナの起動速度により異なる場合があります)

旧バージョンのPod数(Ready/Desired) 新バージョンのPod数(Ready/Desired)
4/4 0/0
4/4 0/2
3/3 1/3
2/2 2/4
1/1 3/4
0/0 4/4

移行中もReadyなPod数の合計が4であることがわかります。

🎥 asciinemaで見る(ReplicaSetのDESIREDREADYの数字の推移に注目してください)

例えばreplicas4の場合でmaxUnavailable2maxSurge2だとします。
その場合はPod数は次の表のように推移します。(実行タイミングやコンテナの起動速度により異なる場合があります)

旧バージョンのPod数(Ready/Desired) 新バージョンのPod数(Ready/Desired)
4/4 0/0
2/2 0/4
1/1 1/4
0/0 2/4
0/0 4/4

🎥 asciinemaで見る(ReplicaSetのDESIREDREADYの数字の推移に注目してください)

Recreate

Recreateの場合、全てのPodを停止してから再作成します。
バージョンアップに要する時間は短く余分なリソースも不要ですが、ダウンタイムが発生します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  strategy:
    type: Recreate
  # ...

replicas4の場合、Pod数は次の表のように推移します。(実行タイミングやコンテナの起動速度により異なる場合があります)

旧バージョンのPod数(Ready/Desired) 新バージョンのPod数(Ready/Desired)
4/4 0/0
0/0 0/0
0/0 0/4
0/0 2/4
0/0 4/4

🎥 asciinemaで見る(ReplicaSetのDESIREDREADYの数字の推移に注目してください)


以上の内容をまとめ、hello-pks.ymlを次のように編集してください。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-pks
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  selector:
    matchLabels:
      app: hello-pks
  template:
    metadata:
      labels:
        app: hello-pks
    spec:
      containers:
      - image: making/hello-pks:0.0.2
        name: hello-pks
        ports:
        - containerPort: 8080
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: NODE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        readinessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
          periodSeconds: 5
        livenessProbe:
          httpGet:
            path: /actuator/info
            port: 8080
          initialDelaySeconds: 20
          timeoutSeconds: 1
          periodSeconds: 10
          failureThreshold: 1
---
kind: Service
apiVersion: v1
metadata:
  name: hello-pks
spec:
  type: LoadBalancer
  selector:
    app: hello-pks
  ports:
  - protocol: TCP
    port: 8080

kubectl applyで変更を適用してください。

kubectl apply -f hello-pks.yml

出力結果

deployment "hello-pks" configured
Found a mistake? Update the entry.
Share this article: