はじめに
Kubernetesは1つのバージョンがサポートされる期間が約1年(v1.19以降)です。これはマネージドなKubernetesも同様なので、定期的なアップグレードが必要になります。
そこで、Container Engine for Kubernetes (OKE) のアップグレード手順を確認します。
アップグレード可否の確認
アップグレードが可能になると、OCIコンソールのバージョンの横に !マーク がつきます。
コントロールプレーンのアップグレード
コントロールプレーン → ワーカーノードの順にアップグレードします。
クラスタ詳細の場面で アップグレード可能 が青くなっていますので、クリックします。
アップグレードするバージョンを選択して、アップグレードをクリックします。
以下の画面になるのでしばらく待ちます。
アップグレードが完了すると、以下のようにアイコンがグリーンに変わります。
なお、アップグレード時間は5分くらいでした。マネージドではないKubernetesだとコントロールプレーンのアップグレードをする際には、kubeadmコマンドを使ったりしますが、マネージドなKubernetesだとアップグレードをキックするだけなので楽でいいですね。
また、アップグレード中に以下のようにデプロイしているPodに対してアクセスし続けてましたが、止まることはなかったです。
$ while true; do echo -n "$(date +%T) " ; curl -s http://xxx.xxx.xxx.xxx ; sleep 1 ; done
01:10:52 hello
01:10:54 hello
01:10:55 hello
01:10:56 hello
・・・
ワーカーノードのアップグレード
ワーカーノードのアップグレード方式
ワーカーノードのアップグレードには「インプレースワーカーノードアップグレード」「アウトオブプレースワーカーノードアップグレード」の2つの方式があります。
今回は「インプレースワーカーノードアップグレード」でやってみたいと思います。
OKEのワーカーノードは、複数のノードをまとめたノードプールという単位でクラスタに組み込まれます。
インプレースワーカーノードアップグレードは、既存のノードプール内で順次ワーカーノードをアップグレード(入れ替え)します。
アウトオブプレースワーカーノードアップグレードは、新しいバージョンのノードプールをクラスタに追加して、ノードプールごと新しいバージョンに入れ替えます。
インプレースワーカーノードアップグレード
ノードプールのアップグレード
OCIコンソールの「クラスタ詳細」から「ノード・プール」を確認します。
コントロールプレーンと同様にKubernetesバージョンに !マーク がついています。
プール名(ここではpool1)をクリックして、ノードプール詳細画面の「編集」クリックし、アップグレードするバージョンを選択します。(通常はアップグレードしたコントロールプレーンと同じバージョン)
上の画面で「変更の保存」をクリックすると、以下のような画面になります。
ノードプールはv1.22になっていますが、ノードはまだv1.21です。
ワーカーノードのアップグレード
通常、ワーカーノードは複数台で構成しますので、この後にkubectl drain
をしてノードを入れ替えていきますが、今回は1台のみの構成なのでまずはワーカーノードを2ノードにスケールさせます。
「スケール」をクリックして、ノード数を2にします。
しばらく待つと、新しいインスタンスが立ち上がります。
新しく追加されたインスタンスはノードプールと同じバージョン(v1.22)で上がってきます。
Podの移動
ここからはkubectl
コマンドでの操作になります。
旧バージョンのワーカーノード上で起動しているPodを新バージョンのワーカーノードに移動させます。
ノードの状態を確認します。v1.21と1.22が混在していますね。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.0.10.44 Ready node 49s v1.22.5
10.0.10.69 Ready node 20d v1.21.5
Podを確認します。2つのPod(Deployment)がv1.21のノード上にあります。
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-dep-598b589c46-cwzm6 1/1 Running 0 35m 10.244.0.12 10.0.10.69 <none> <none>
nginx-dep-598b589c46-pmg6q 1/1 Running 0 35m 10.244.0.13 10.0.10.69 <none> <none>
DaemonSetも確認しておきます。
$ kubectl get daemonset -A
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system csi-oci-node 2 2 2 2 2 <none> 20d
kube-system kube-flannel-ds 2 2 2 2 2 <none> 20d
kube-system kube-proxy 2 2 2 2 2 beta.kubernetes.io/os=linux 20d
kube-system nvidia-gpu-device-plugin 0 0 0 0 0 <none> 20d
kube-system proxymux-client 2 2 2 2 2 node.info.ds_proxymux_client=true 20
kubectl drain
を実行して、Podを移動させます。その際、--ignore-daemonsets
オプションもつけておきます。--ignore-daemonsets
オプションはDaemonSetが管理するPodを無視するオプションです。
$ kubectl drain 10.0.10.69 --ignore-daemonsets
node/10.0.10.69 cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/csi-oci-node-g28xk, kube-system/kube-flannel-ds-fb64p, kube-system/kube-proxy-hf49w, kube-system/proxymux-client-mkxn5
evicting pod kube-system/kube-dns-autoscaler-5cd75c9b4c-bhnhh
evicting pod default/nginx-dep-598b589c46-pmg6q
evicting pod default/nginx-dep-598b589c46-cwzm6
evicting pod kube-system/coredns-7bb8797d57-d992t
evicting pod kube-system/coredns-7bb8797d57-lfgfh
pod/nginx-dep-598b589c46-cwzm6 evicted
pod/coredns-7bb8797d57-lfgfh evicted
pod/kube-dns-autoscaler-5cd75c9b4c-bhnhh evicted
pod/nginx-dep-598b589c46-pmg6q evicted
pod/coredns-7bb8797d57-d992t evicted
node/10.0.10.69 evicted
確認します。v1.21のノードは、スケジューリング対象から外されています。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.0.10.44 Ready node 10m v1.22.5
10.0.10.69 Ready,SchedulingDisabled node 20d v1.21.5
Podはv1.22のノードに移動していますね。
移動と書きましたが、正確にはPodを停止して新しいPodを立ち上げています。よく見るとPodの名前が変わっています。
業務を無停止で移動させるためには、DeploymentのReplica数やRollingUpdateのパラメータを適切に設定する必要があります。
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-dep-598b589c46-4nkn5 1/1 Running 0 83s 10.244.0.130 10.0.10.44 <none> <none>
nginx-dep-598b589c46-6hbrc 1/1 Running 0 83s 10.244.0.131 10.0.10.44 <none> <none>
ワーカーノードの入れ替え
旧バージョンのワーカーノードの「インスタンスの詳細」画面に行き、「他のアクション」から「終了」を選択し、インスタンスを終了させます。
インスタンスを終了させると、ノードプールで指定しているノード数に合わせるために、新しいインスタンスがノードプールに組み込まれます。
kubectl
コマンドでもノードが入れ替わったことを確認します。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.0.10.169 Ready node 11m v1.22.5
10.0.10.218 Ready node 2m32s v1.22.5
なお、ワーカーノード数を1に戻したい場合は、ノードプールの「スケール」からノード数を1に設定します。
まとめ
マネージドなKubernetesだとバージョンアップ作業が楽でよいですね。
今回はノード数が少なかったのでインプレースワーカーノードアップグレードでもよいですが、ノード数が増えるとアウトオブプレースワーカーノードアップグレードの方がよさそうな気がします。
ただ、アウトオブプレースワーカーノードアップグレードの場合は、一時的にノード数が2倍になりますので、その分のコストが必要になるのがデメリットですね。