Kekeの日記

エンジニア、読書なんでも

Kubernetesで安全にマシンタイプを変更するDrainとPodDisruptBudget

f:id:bobchan1915:20181002232922p:plain

動機

プロジェクト開始のときは、machine typeはn1-standard-1でした。

しかし、いろんなデプロイメントをするとクラスタのスペックが足りなくなりました。

今回はそのようなときに使える、安全にNodeのマシンタイプを移行するソリューションを記事にしました。

手順

最初の状態

以下のようなコマンドを叩いて、自分のNode Poolを確認します。

$ gcloud container node-pools list --cluster $(gcloud config get-value container/cluster) --region $(gcloud config get-value compute/region)

NAME          MACHINE_TYPE   DISK_SIZE_GB  NODE_VERSION
default-pool  n1-standard-1  100           1.9.7-gke.6

やはり、デフォルトのNode Poolであるdefault-poolが設定されていあります。

Nodeを取得すると以下のような結果になります。

$ kubectl get node

NAME                                            STATUS    ROLES     AGE       VERSION
gke-hoge-cluster-default-pool-8eb6b5df-9hjh   Ready     <none>    2d        v1.9.7-gke.6
gke-hoge-cluster-default-pool-8eb6b5df-ctb5   Ready     <none>    2d        v1.9.7-gke.6

実際はこのような状態です。

f:id:bobchan1915:20181002231107p:plain

Node Poolを追加

以下のコマンドよりNode Poolを追加します。

今回は--machine-type=n1-highmem-22つのNodeを追加します。

gcloud container node-pools create larger-pool --cluster migration-tutorial --machine-type=n1-highmem-2 --num-nodes=2

すると以下のようになります。

$ kubectl get node

NAME                                            STATUS    ROLES     AGE       VERSION
gke-hoge-cluster-larger-pool-8eb6b5df-ie24   Ready     <none>    10s        v1.9.7-gke.6
gke-hoge-cluster-larger-pool-8eb6b5df-eoa4   Ready     <none>    10s        v1.9.7-gke.6
gke-hoge-cluster-default-pool-8eb6b5df-9hjh   Ready     <none>    2d        v1.9.7-gke.6
gke-hoge-cluster-default-pool-8eb6b5df-ctb5   Ready     <none>    2d        v1.9.7-gke.6

つまり、gke-xxx-xxx-larger-pool-xxx-xxxのようなNode Poolが作成されたことが分かります。

図にすると以下のような感じです。

f:id:bobchan1915:20181002231817p:plain

default-poolのDrain

kubectl drain NODE_NAMEというコマンドがあり、以下のような役割をします。

  • PodをスケジューリングできないようにUnschedulableにする(kubectl cordon)
  • Podを退避(evict)する(kubectl evict)

これをdefault poolのノードでやっていきます。

kubectl drain gke-hoge-cluster-default-pool-8eb6b5df-9hjh --force --ignore-daemonsets
kubectl drain gke-hoge-cluster-default-pool-8eb6b5df-ctb5 --force --ignore-daemonsets

またオプションは以下の通りです。

  • force: Podを強制的に消す
  • ignore-daemonsets: DaemonSetはevictせず、削除する

このようにすると以下のようになります。

f:id:bobchan1915:20181002232922p:plain

古いNode Poolを削除する

以下のコマンドで削除することができます。

gcloud container node-pools delete default-pool --cluster $(gcloud config get-value container/cluster)

すると以下のようになっているはずです。

f:id:bobchan1915:20181002232931p:plain

これで目的とするマシンタイプを変更することができました。

安全なDrainのためのPodDisruptionBudget

名前の通り、どのようにPod削除するかの予算を立てます。

いきなり

kubectl drain gke-hoge-cluster-default-pool-8eb6b5df-9hjh --force --ignore-daemonsets
kubectl drain gke-hoge-cluster-default-pool-8eb6b5df-ctb5 --force --ignore-daemonsets

を同時にすると、Podが一つもReadyの状態ではなくなる可能性があり、これによってダウンタイムが発生してしまいます。

それを避けるために以下のように指定します。

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: myapp
spec:
  maxUnavailable: 1
  selector:
    matchLabels:
      run: myapp

ここでspec.maxUnavailableとしたのは、停止してよりPodの最大数です。

これによって、どんなに同時にdrainをしても一気にPodがevictされることがなくなり、ダウンタイムは発生しなくなります。

参考文献

異なるマシンタイプへのワークロードの移行  |  Kubernetes Engine のチュートリアル  |  Google Cloud

qiita.com