Container Engine for Kubernetes (OKE) のクラスタアップグレード手順を確認する

# はじめに
Kubernetesは1つのバージョンがサポートされる期間が約1年（v1.19以降）です。これはマネージドなKubernetesも同様なので、定期的なアップグレードが必要になります。
そこで、Container Engine for Kubernetes (OKE) のアップグレード手順を確認します。

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Concepts/contengaboutupgradingclusters.htm#Upgrading_Clusters_to_Newer_Kubernetes_Versions

# アップグレード可否の確認
アップグレードが可能になると、OCIコンソールのバージョンの横に __！マーク__ がつきます。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_15-42-31vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/4ec7e411-ad0a-ed98-95e5-4d7932972021.png)

# コントロールプレーンのアップグレード
コントロールプレーン → ワーカーノードの順にアップグレードします。

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengupgradingk8smasternode.htm

クラスタ詳細の場面で __アップグレード可能__ が青くなっていますので、クリックします。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_15-42-55vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/ed54667e-5dd0-5019-4f5a-dd2f41a51586.png)

アップグレードするバージョンを選択して、アップグレードをクリックします。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_15-43-53vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/f89f9ba3-59d7-8711-8207-7dc250f6e970.png)

以下の画面になるのでしばらく待ちます。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_15-44-6vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/7a2f3287-0ed9-ac56-ed51-e97ee90006b3.png)

アップグレードが完了すると、以下のようにアイコンがグリーンに変わります。
なお、アップグレード時間は5分くらいでした。マネージドではないKubernetesだとコントロールプレーンのアップグレードをする際には、kubeadmコマンドを使ったりしますが、マネージドなKubernetesだとアップグレードをキックするだけなので楽でいいですね。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_15-55-36vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/6303e6b8-3694-55c8-4eec-2f4245f85690.png)

また、アップグレード中に以下のようにデプロイしている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
・・・
```

# ワーカーノードのアップグレード

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengupgradingk8sworkernode.htm

## ワーカーノードのアップグレード方式
ワーカーノードのアップグレードには「インプレースワーカーノードアップグレード」「アウトオブプレースワーカーノードアップグレード」の2つの方式があります。
今回は「インプレースワーカーノードアップグレード」でやってみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/5a1deb93-dfd0-54b3-a408-1b8778b62f2e.png)

OKEのワーカーノードは、複数のノードをまとめたノードプールという単位でクラスタに組み込まれます。
インプレースワーカーノードアップグレードは、既存のノードプール内で順次ワーカーノードをアップグレード（入れ替え）します。
アウトオブプレースワーカーノードアップグレードは、新しいバージョンのノードプールをクラスタに追加して、ノードプールごと新しいバージョンに入れ替えます。

## インプレースワーカーノードアップグレード
### ノードプールのアップグレード

OCIコンソールの「クラスタ詳細」から「ノード・プール」を確認します。
コントロールプレーンと同様にKubernetesバージョンに __!マーク__ がついています。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_16-33-54vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/9c6f3130-8040-5525-b398-d594f7de42aa.png)

プール名（ここではpool1）をクリックして、ノードプール詳細画面の「編集」クリックし、アップグレードするバージョンを選択します。（通常はアップグレードしたコントロールプレーンと同じバージョン）

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_16-34-46vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/4c4df122-5515-4803-2744-424d94321771.png)

上の画面で「変更の保存」をクリックすると、以下のような画面になります。
ノードプールはv1.22になっていますが、ノードはまだv1.21です。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_16-36-8vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/b0d54b99-aef8-3266-2335-6bacac2fb4d0.png)

### ワーカーノードのアップグレード

通常、ワーカーノードは複数台で構成しますので、この後に`kubectl drain`をしてノードを入れ替えていきますが、今回は1台のみの構成なのでまずはワーカーノードを2ノードにスケールさせます。
「スケール」をクリックして、ノード数を2にします。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_16-42-44vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/3fb14107-8115-773e-ad8e-e67d119ebe23.png)

しばらく待つと、新しいインスタンスが立ち上がります。
新しく追加されたインスタンスはノードプールと同じバージョン（v1.22）で上がってきます。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_16-48-16vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/5e810a77-7d6f-e8e4-eb2c-997828636517.png)

#### 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>
```

#### ワーカーノードの入れ替え
旧バージョンのワーカーノードの「インスタンスの詳細」画面に行き、「他のアクション」から「終了」を選択し、インスタンスを終了させます。

![ホーム  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_17-14-46vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/7a5ee449-3a9c-0706-99c6-71805ea0d505.png)

インスタンスを終了させると、ノードプールで指定しているノード数に合わせるために、新しいインスタンスがノードプールに組み込まれます。

![Kubernetesクラスタ(OKE)  Oracle Cloud Infrastructure - Google Chrome_2022-3-24_17-22-15vv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492530/9792e1f0-9ee3-3651-f79c-4a18332acb19.png)

`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倍になりますので、その分のコストが必要になるのがデメリットですね。