LoginSignup
50
33

More than 5 years have passed since last update.

Kubernetes: Deployment のローリングアップデートの条件と設定

Last updated at Posted at 2017-10-19

Kubernetes の Deployment のローリングアップデートが起こる条件と設定についてのメモです。Deployment のローリングアップデート自体の仕組みについては Kubernetes: Deployment の仕組み にまとめています。

Deployment のローリングアップデートが起きる条件

Deployment のローリングアップデートは Deployment の Pod Template (.spec.template) という Pod のテンプレート情報に変更があったときにのみ行われます。例えば Deployment のアノテーション(.metadata.annotations) を変更してもローリングアップデートは起きませんが、Pod Template のアノテーション(.spec.template.metadata.annotations) を更新するとローリングアップデートが実行されます。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    run: myapp
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      run: myapp
  # この部分が PodTemlate。ここに変更があったときローリングアップデートが起こる
  template:
    metadata:
      labels:
        run: myapp
    spec:
      containers:
      - image: nginx:1.13
        name: myapp

手動のローリングアップデート

Deployment の PodTemlate の値を書き換えることで Pod のイメージの変更なしにローリングアップデートを手動で行うことができます。Pod を再起動させたいときに便利です。変更は Pod Template のどの値でも良いですが、アノテーション(.spec.template.metadata.annotations)が一番影響が少ないと思われます。下記のように kubectl patch コマンドで書き換えることができます。

# dummy-for-update というアノテーションに現在時刻を書き込んでローリングアップデートさせる
$ kubectl patch deployment $DEPLOYMENT_NAME \
  -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"dummy-for-update\":\"$(date +%s)\"}}}}}"

自分の所属している Z Lab ではforce-update-deploymentというスクリプトにして利用しています。

# kube-dns の kube-dns を再起動する
$ force-update-deployment kube-dns -n kube-system
deployment "kube-dns" patched

ローリングアップデート時の Pod 数の増減の設定

Deployment では下記の 2つのフィールドによってローリングアップデート時の Pod 数の増減を制御できます。manifest で指定した Deployment の apiVersion によってデフォルト値が異なるため注意が必要です。extensions/v1beta1 のデフォルトの挙動ではレプリカ数 (.spec.replicas) が 1 の場合 ready 状態の Pod が 0 になるタイミングがありえます。

apiVersion に関わらずレプリカ数の値を 2 以上にしておけば多くの場合問題ないでしょう。

  • .spec.strategy.rollingUpdate.maxUnavailable ローリングアップデート時に許容できる最大の unavailable になる Pod 数 (削除できる Pod 数)
    • apiVersion が extensions/v1beta1 の場合デフォルトは 1
    • apiVersion が apps/v1beta1, apps/v1beta2 の場合デフォルトは 25%。端数は切り捨て
  • .spec.strategy.rollingUpdate.maxSurge ローリングアップデート時に許容できる超過して作られる Pod の最大数
    • apiVersion が extensions/v1beta1 の場合デフォルトは 1
    • apiVersion が apps/v1beta1, apps/v1beta2 の場合デフォルトは 25%。端数は切り上げ

apps/v1beta2 は kubernetes v1.8 からの apiVersion になります。

apiVersion が extensions/v1beta1 の場合

maxUnavailable, maxSurge ともに 1 がデフォルトのため、Pod を新しく作って そのready を待たず、すぐにPod を削除する挙動になります。レプリカ数が 1 の場合は一時的にどれも ready になっていない状態がありえます。 maxUnavailable を 0 に設定することで最低 1 pod は ready な状態を保つことができます。

$ kubectl get deploy mydep-ext -w
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
mydep-ext   1         1         1         1         3m # rolling-update 前
mydep-ext   1         1         0         1         3m # 今の Pod が up-to-date でなくなる
mydep-ext   1         2         1         1         3m # 新しいバージョンの Pod が作られる
mydep-ext   1         1         1         0         3m # ready を待たず古い Pod を削除
mydep-ext   1         1         1         1         3m # 新しいバージョンが ready になる

apiVersion が apps/v1beta1 の場合

maxUnavailable, maxSurge ともに 25% がデフォルトになっており、maxUnavailable の方は端数は切り捨てられるので、レプリカ数が 1の場合、unavailable として許容する Pod数は 0 となります。Pod を新しく作り ready になるのを待ってから Pod を削除するため、レプリカ数が 1 であっても最低 1 Pod は ready な状態になります。

$ kubectl get deploy mydep-app -w
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
mydep-app   1         1         1         1         37s # rolling-update 前
mydep-app   1         1         0         1         37s # 今の Pod が up-to-date でなくなる
mydep-app   1         2         1         1         37s # 新しいバージョンの Pod が作られる
mydep-app   1         2         1         2         41s # ready を待つ
mydep-app   1         1         1         1         41s # 古い Pod を削除
50
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
33