LoginSignup
1
1

More than 3 years have passed since last update.

AKS で Node 再起動の影響を最小限にするための仕組みを理解する

Posted at

Kubernetes の運用をしていると避けて通れないのは、サーバー/Kubernetes コンポーネントのアップデート、アップグレードの作業です。それを実行する際には、Node 再起動が必要となります。ここまで Pod が動いている Node を指定する仕組みなどを触れてきましたが、再起動する際にアプリケーションへの影響を最小限にする仕組みを見ていきたいと思います。

環境準備

過去の記事にしたがって、AKS の検証環境を準備します。
Azure Kubernetes Services 環境を構築する

その上で今回は以下のマニフェストファイルで、3つの Node を持つクラスターに対して Nignx の Deployment を作成します。

nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

作成が完了したら、Pod と Node の関係性を以下オプションを付けたコマンドで確認します。

$ kubectl get pod -o custom-columns=Pod:metadata.name,Node:spec.nodeName
Pod                    Node
nginx-5c7588df-77kvs   aks-nodepool1-38358128-vmss000001
nginx-5c7588df-rpdbl   aks-nodepool1-38358128-vmss000000
nginx-5c7588df-z64g6   aks-nodepool1-38358128-vmss000002

作成したそれぞれの Pod が 3つの Node に分散されて配置していることが分かります。ここまでで準備は完了です。

Cordon/Uncordon

Cordon は「閉鎖する」という意味です。Cordon を実行することで、特定の Node をスケジュールの対象から除外することが可能です。Uncordon はその逆で、Node をスケジュール対象に戻すコマンドです。実際に上記で確認した aks-nodepool1-38358128-vmss000001 という名前の Node に対して Cordon を実行してみます。

$ kubectl cordon aks-nodepool1-38358128-vmss000001
node/aks-nodepool1-38358128-vmss000001 cordoned

これで特定の Node が Cordon の対象になりました。kubectl get node コマンドで詳細を確認してみます。

$ kubectl get node
NAME                                STATUS                     ROLES   AGE   VERSION
aks-nodepool1-38358128-vmss000000   Ready                      agent   11m   v1.13.12
aks-nodepool1-38358128-vmss000001   Ready,SchedulingDisabled   agent   10m   v1.13.12
aks-nodepool1-38358128-vmss000002   Ready                      agent   11m   v1.13.12

指定した Node が SchedulingDisabled となっているのが分かります。これはスケジューリングから除外されたことを意味していて、Pod のスケールアップ等から除外されていることを表します。試しにレプリカ数を増やしてみます。

$ kubectl scale deployment nginx --replicas=6
deployment.extensions/nginx scaled

先ほどの Pod と Node の関係性を表示するコマンドで確認してみます。

$ kubectl get pod -o custom-columns=Pod:metadata.name,Node:spec.nodeName
Pod                    Node
nginx-5c7588df-77kvs   aks-nodepool1-38358128-vmss000001
nginx-5c7588df-9nwdd   aks-nodepool1-38358128-vmss000000
nginx-5c7588df-jbwjg   aks-nodepool1-38358128-vmss000002
nginx-5c7588df-jkwck   aks-nodepool1-38358128-vmss000000
nginx-5c7588df-rpdbl   aks-nodepool1-38358128-vmss000000
nginx-5c7588df-z64g6   aks-nodepool1-38358128-vmss000002

Cordon した Node には変更が加わっていないことが分かります。これが Cordon の効果です。Cordon されている Node は Uncordon コマンドでスケジュール対象に戻すことが可能です。

$ kubectl uncordon aks-nodepool1-38358128-vmss000001
node/aks-nodepool1-38358128-vmss000001 uncordoned

$ kubectl get node
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-38358128-vmss000000   Ready    agent   15m   v1.13.12
aks-nodepool1-38358128-vmss000001   Ready    agent   15m   v1.13.12
aks-nodepool1-38358128-vmss000002   Ready    agent   15m   v1.13.12

Drain

Drain では、先ほどの Cordon の動きに加えて、Pod の削除と再作成を行います。Cordon の様に CLI で実行できます。

$ kubectl drain aks-nodepool1-38358128-vmss000001
node/aks-nodepool1-38358128-vmss000001 cordoned
error: unable to drain node "aks-nodepool1-38358128-vmss000001", aborting command...

There are pending nodes to be drained:
 aks-nodepool1-38358128-vmss000001
error: cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/kube-proxy-d5pqv

この際エラーメッセージが出ています。デーモンセットがあるため、オプションを指定して実行してくださいと言わているため、その通りに実行してみます。

$ kubectl drain aks-nodepool1-38358128-vmss000001 --ignore-daemonsets
node/aks-nodepool1-38358128-vmss000001 already cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/kube-proxy-d5pqv
evicting pod "nginx-5c7588df-77kvs"
pod/nginx-5c7588df-77kvs evicted
node/aks-nodepool1-38358128-vmss000001 evicted

この Drain では、aks-nodepool1-38358128-vmss000001 に配置されている Pod を削除し、他の Node に再作成を行っています。先ほどの Pod と Node の関係性を確認するコマンドを実行して確認してます。

$ kubectl get pod -o custom-columns=Pod:metadata.name,Node:spec.nodeName
Pod                    Node
nginx-5c7588df-9nwdd   aks-nodepool1-38358128-vmss000000
nginx-5c7588df-jbwjg   aks-nodepool1-38358128-vmss000002
nginx-5c7588df-jkwck   aks-nodepool1-38358128-vmss000000
nginx-5c7588df-nhzfv   aks-nodepool1-38358128-vmss000002
nginx-5c7588df-rpdbl   aks-nodepool1-38358128-vmss000000
nginx-5c7588df-z64g6   aks-nodepool1-38358128-vmss000002

Drain で指定した aks-nodepool1-38358128-vmss000001 には Pod が配置されていないことが確認できました。Node の状態も確認してみると、Cordon したときと同じように ScheduleDisable の状態になっていることが分かります。何も配置されていない Node なので正常にアップデートできる準備が整った、という事になります。

$ kubectl get node
NAME                                STATUS                     ROLES   AGE   VERSION
aks-nodepool1-38358128-vmss000000   Ready                      agent   22m   v1.13.12
aks-nodepool1-38358128-vmss000001   Ready,SchedulingDisabled   agent   22m   v1.13.12
aks-nodepool1-38358128-vmss000002   Ready                      agent   22m   v1.13.12

ここまでできればあとは Node をアップデートしたり、再起動することが出来ます。Azure CLI でできるので非常に簡単ですね!

参考

Cluster Management
https://kubernetes.io/docs/tasks/administer-cluster/cluster-management/

Safely Drain a Node while Respecting the PodDisruptionBudget
https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/

1
1
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
1
1