[Kubernetes]Kubernetesクラスタのアップグレード手順を確認する 

#はじめに
Kubernetsの検証をやってましたが、一区切りついたのでクラスタのバージョンアップをしてみたいと思います。
バージョンアップとなると壊れるかも知れない恐怖がありますので、「壊れてもいいや」と思える状態にならないと手が出せないです。

今回は以下の手順に沿ってv1.17からv1.18にバージョンアップします。

[Upgrading kubeadm clusters](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)

##バージョンアップの概要
今回はMasterノード 1台、Workerノード2台のクラスタ構成です。
全てオンプレ環境（PC上のVM）で、OSはCentOS 7です。

各ノード1台ずつアップグレードして、業務を停止せずにアップグレードを完了させます。（ローリングアップデート） 

バックアップは取っていませんが、必要に応じて事前に取っておいた方がいいと思います。

#Kubernetesのバージョンについて
Kubernetsの現時点での最新版はv1.18です。「1」がメジャーバージョン、「18」がマイナーバージョンです。
マイナーバージョンは約3カ月おきにリリースされて、3世代までがサポート対象となります。なので、現時点ではv1.18/v1.17/v1.16がサポートバージョンになります。
サポートが切れると脆弱性が見つかっても修正されませんので、Kubernetsをプロダクション環境で使う場合には、常にクラスタのバージョンアップをしなければなりません。

##参考
これを避けたいのであれば、Enterprise向けのKubernets製品を使うのも一つの手です。代表的なものとしては、Red HatのOpenShiftがあります。OpenShiftであれば、3年間サポートされるようです。

https://redhat.sios.jp/red-hat-openshift/lifecycle-red-hat-openshift-platform/


#Masterノードのアップグレード
Masterノードからアップグレードします。

##既存環境の確認
Kubeadmとkubeletのバージョンを確認します。

```
$ kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"06ad960bfd03b39c8310aaf92d1e7c12ce618213", GitTreeState:"clean", BuildDate:"2020-02-11T18:12:12Z", GoVersion:"go1.13.6", Compiler:"gc", Platform:"linux/amd64"}
$ kubectl get node
NAME           STATUS   ROLES    AGE    VERSION
k8s-master     Ready    master   138d   v1.17.3
k8s-worker01   Ready    <none>   138d   v1.17.3
k8s-worker02   Ready    <none>   138d   v1.17.3
```

また、各workerノードに一つずつPodがデプロイされています。

```
$ kubectl get pod -o wide
NAME                         READY   STATUS    RESTARTS   AGE   IP               NODE           NOMINATED NODE   READINESS GATES
nginx-dep-5589d85476-4t4zb   1/1     Running   0          18m   192.168.79.127   k8s-worker01   <none>           <none>
nginx-dep-5589d85476-p4zgk   1/1     Running   0          18m   192.168.69.227   k8s-worker02   <none>           <none>
```

##アップグレードバージョンの確認
利用可能なバージョンを確認します。

```
$ yum list --showduplicates kubeadm --disableexcludes=kubernetes
読み込んだプラグイン:fastestmirror, langpacks
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
Determining fastest mirrors
 * base: ftp-srv2.kddilabs.jp
 * extras: ftp-srv2.kddilabs.jp
 * updates: ftp.yz.yamagata-u.ac.jp
kubernetes                                                                                                                                                                                                                  505/505
インストール済みパッケージ
kubeadm.x86_64                                                                                                 1.17.3-0                                                                                                  @kubernetes
利用可能なパッケージ
kubeadm.x86_64                                                                                                 1.6.0-0                                                                                                   kubernetes
kubeadm.x86_64                                                                                                 1.6.1-0                                                                                                   kubernetes
kubeadm.x86_64                                                                                                 1.6.2-0                                                                                                   kubernetes
kubeadm.x86_64                                                                                                 1.6.3-0                                                                                                   kubernetes
・・・
kubeadm.x86_64                                                                                                 1.17.6-0                                                                                                  kubernetes
kubeadm.x86_64                                                                                                 1.18.0-0                                                                                                  kubernetes
kubeadm.x86_64                                                                                                 1.18.1-0                                                                                                  kubernetes
kubeadm.x86_64                                                                                                 1.18.2-0                                                                                                  kubernetes
kubeadm.x86_64                                                                                                 1.18.3-0                                                                                                  kubernetes
```
今回は最新の「v1.18.3」にします。

##kubeadmのアップグレード
kubeadmをアップグレードします。

```
$ sudo yum install -y kubeadm-1.18.3-0 --disableexcludes=kubernetes
読み込んだプラグイン:fastestmirror, langpacks
Determining fastest mirrors
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
base                                                                                                                                                                                                         | 3.6 kB  00:00:00
docker-ce-stable                                                                                                                                                                                             | 3.5 kB  00:00:00
extras                                                                                                                                                                                                       | 2.9 kB  00:00:00
kubernetes/signature                                                                                                                                                                                         |  454 B  00:00:00
kubernetes/signature                                                                                                                                                                                         | 1.4 kB  00:00:00 !!!
updates                                                                                                                                                                                                      | 2.9 kB  00:00:00
(1/4): extras/7/x86_64/primary_db                                                                                                                                                                            | 205 kB  00:00:00
(2/4): docker-ce-stable/x86_64/primary_db                                                                                                                                                                    |  45 kB  00:00:00
(3/4): kubernetes/primary                                                                                                                                                                                    |  73 kB  00:00:01
(4/4): updates/7/x86_64/primary_db                                                                                                                                                                           | 3.0 MB  00:00:01
kubernetes                                                                                                                                                                                                                  533/533
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ kubeadm.x86_64 0:1.17.3-0 を 更新
---> パッケージ kubeadm.x86_64 0:1.18.3-0 を アップデート
--> 依存性解決を終了しました。

依存性を解決しました

====================================================================================================================================================================================================================================
 Package                                               アーキテクチャー                                     バージョン                                               リポジトリー                                              容量
====================================================================================================================================================================================================================================
更新します:
 kubeadm                                               x86_64                                               1.18.3-0                                                 kubernetes                                               8.8 M

トランザクションの要約
====================================================================================================================================================================================================================================
更新  1 パッケージ

総ダウンロード容量: 8.8 M
Downloading packages:
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
a23839a743e789babb0ce912fa440f6e6ceb15bc5db42dd91aa0838c994b3452-kubeadm-1.18.3-0.x86_64.rpm                                                                                                                 | 8.8 MB  00:00:02
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  更新します              : kubeadm-1.18.3-0.x86_64                                                                                                                                                                             1/2
  整理中                  : kubeadm-1.17.3-0.x86_64                                                                                                                                                                             2/2
  検証中                  : kubeadm-1.18.3-0.x86_64                                                                                                                                                                             1/2
  検証中                  : kubeadm-1.17.3-0.x86_64                                                                                                                                                                             2/2

更新:
  kubeadm.x86_64 0:1.18.3-0

完了しました!
```

バージョンが上がっていることを確認します。

```
$ kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.3", GitCommit:"2e7996e3e2712684bc73f0dec0200d64eec7fe40", GitTreeState:"clean", BuildDate:"2020-05-20T12:49:29Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
```
指定したバージョン（v1.18.3）になってますね。

##drain（Podの退避）
MasterノードからPodをdrainし、スケジューリング対象から外します。その際、「--ignore-daemonsets」オプションを指定して、DaemonSetもdrainします。

```
$ kubectl drain k8s-master --ignore-daemonsets
node/k8s-master cordoned
evicting pod "calico-kube-controllers-77c4b7448-6prr9"
evicting pod "coredns-6955765f44-55wbn"
evicting pod "coredns-6955765f44-bhdvr"
pod/calico-kube-controllers-77c4b7448-6prr9 evicted
pod/coredns-6955765f44-55wbn evicted
pod/coredns-6955765f44-bhdvr evicted
node/k8s-master evicted
```

##Upgrade plan の確認
クラスタがアップグレードできることを確認します。

```
$ sudo kubeadm upgrade plan
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade] Fetching available versions to upgrade to
[upgrade/versions] Cluster version: v1.17.3
[upgrade/versions] kubeadm version: v1.18.3
[upgrade/versions] Latest stable version: v1.18.5
[upgrade/versions] Latest stable version: v1.18.5
[upgrade/versions] Latest version in the v1.17 series: v1.17.8
[upgrade/versions] Latest version in the v1.17 series: v1.17.8

Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT   CURRENT       AVAILABLE
Kubelet     3 x v1.17.3   v1.17.8

Upgrade to the latest version in the v1.17 series:

COMPONENT            CURRENT   AVAILABLE
API Server           v1.17.3   v1.17.8
Controller Manager   v1.17.3   v1.17.8
Scheduler            v1.17.3   v1.17.8
Kube Proxy           v1.17.3   v1.17.8
CoreDNS              1.6.5     1.6.7
Etcd                 3.4.3     3.4.3-0

You can now apply the upgrade by executing the following command:

        kubeadm upgrade apply v1.17.8

_____________________________________________________________________

Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT   CURRENT       AVAILABLE
Kubelet     3 x v1.17.3   v1.18.5

Upgrade to the latest stable version:

COMPONENT            CURRENT   AVAILABLE
API Server           v1.17.3   v1.18.5
Controller Manager   v1.17.3   v1.18.5
Scheduler            v1.17.3   v1.18.5
Kube Proxy           v1.17.3   v1.18.5
CoreDNS              1.6.5     1.6.7
Etcd                 3.4.3     3.4.3-0

You can now apply the upgrade by executing the following command:

        kubeadm upgrade apply v1.18.5

Note: Before you can perform this upgrade, you have to update kubeadm to v1.18.5.

_____________________________________________________________________
```

最後にアップグレードのコマンドが表示されます。ここではなぜか「v1.18.5」と表示されています。

##アップグレード
アップグレードプランで表示された「v1.18.5」でアップグレードしてみます。

```
$ sudo kubeadm upgrade apply v1.18.5
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade/version] You have chosen to change the cluster version to "v1.18.5"
[upgrade/versions] Cluster version: v1.17.3
[upgrade/versions] kubeadm version: v1.18.3
[upgrade/version] FATAL: the --version argument is invalid due to these errors:

        - Specified version to upgrade to "v1.18.5" is higher than the kubeadm version "v1.18.3". Upgrade kubeadm first using the tool you used to install kubeadm

Can be bypassed if you pass the --force flag
To see the stack trace of this error execute with --v=5 or higher
```

失敗しました。やはりyumでインストールしたkubeadmのバージョン（v1.18.3）と合わないので失敗しています。
Upgrade planでv1.18.5が表示されたのは謎ですが、v1.18.3を指定してアップグレードします。


```
$ sudo kubeadm upgrade apply v1.18.3
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade/version] You have chosen to change the cluster version to "v1.18.3"
[upgrade/versions] Cluster version: v1.17.3
[upgrade/versions] kubeadm version: v1.18.3
[upgrade/confirm] Are you sure you want to proceed with the upgrade? [y/N]: y
[upgrade/prepull] Will prepull images for components [kube-apiserver kube-controller-manager kube-scheduler etcd]
[upgrade/prepull] Prepulling image for component etcd.
[upgrade/prepull] Prepulling image for component kube-apiserver.
[upgrade/prepull] Prepulling image for component kube-controller-manager.
[upgrade/prepull] Prepulling image for component kube-scheduler.
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-kube-scheduler
[apiclient] Found 0 Pods for label selector k8s-app=upgrade-prepull-etcd
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-kube-controller-manager
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-kube-apiserver
[apiclient] Found 1 Pods for label selector k8s-app=upgrade-prepull-etcd
[upgrade/prepull] Prepulled image for component etcd.
[upgrade/prepull] Prepulled image for component kube-controller-manager.
[upgrade/prepull] Prepulled image for component kube-apiserver.
[upgrade/prepull] Prepulled image for component kube-scheduler.
[upgrade/prepull] Successfully prepulled the images for all the control plane components
[upgrade/apply] Upgrading your Static Pod-hosted control plane to version "v1.18.3"...
Static pod: kube-apiserver-k8s-master hash: 6b6a0a73255ee4281de8dca07998054a
Static pod: kube-controller-manager-k8s-master hash: 4d17d776eb5d9c61bbec5d1e95adacfb
Static pod: kube-scheduler-k8s-master hash: e3025acd90e7465e66fa19c71b916366
[upgrade/etcd] Upgrading to TLS for etcd
{"level":"warn","ts":"2020-07-13T22:08:19.236+0900","caller":"clientv3/retry_interceptor.go:61","msg":"retrying of unary invoker failed","target":"passthrough:///https://10.20.30.10:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = context deadline exceeded"}
[upgrade/etcd] Non fatal issue encountered during upgrade: the desired etcd version for this Kubernetes version "v1.18.3" is "3.4.3-0", but the current etcd version is "3.4.3". Won't downgrade etcd, instead just continue
[upgrade/staticpods] Writing new Static Pod manifests to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests623514539"
W0713 22:08:20.478236   29486 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[upgrade/staticpods] Preparing for "kube-apiserver" upgrade
[upgrade/staticpods] Renewing apiserver certificate
[upgrade/staticpods] Renewing apiserver-kubelet-client certificate
[upgrade/staticpods] Renewing front-proxy-client certificate
[upgrade/staticpods] Renewing apiserver-etcd-client certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-apiserver.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2020-07-13-22-08-04/kube-apiserver.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
Static pod: kube-apiserver-k8s-master hash: 6b6a0a73255ee4281de8dca07998054a
Static pod: kube-apiserver-k8s-master hash: 83c4ef266c3b5fae801e94624406195e
[apiclient] Found 1 Pods for label selector component=kube-apiserver
[upgrade/staticpods] Component "kube-apiserver" upgraded successfully!
[upgrade/staticpods] Preparing for "kube-controller-manager" upgrade
[upgrade/staticpods] Renewing controller-manager.conf certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-controller-manager.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2020-07-13-22-08-04/kube-controller-manager.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
Static pod: kube-controller-manager-k8s-master hash: 4d17d776eb5d9c61bbec5d1e95adacfb
Static pod: kube-controller-manager-k8s-master hash: c019bf493518b70e6417f6d40acb391a
[apiclient] Found 1 Pods for label selector component=kube-controller-manager
[upgrade/staticpods] Component "kube-controller-manager" upgraded successfully!
[upgrade/staticpods] Preparing for "kube-scheduler" upgrade
[upgrade/staticpods] Renewing scheduler.conf certificate
[upgrade/staticpods] Moved new manifest to "/etc/kubernetes/manifests/kube-scheduler.yaml" and backed up old manifest to "/etc/kubernetes/tmp/kubeadm-backup-manifests-2020-07-13-22-08-04/kube-scheduler.yaml"
[upgrade/staticpods] Waiting for the kubelet to restart the component
[upgrade/staticpods] This might take a minute or longer depending on the component/version gap (timeout 5m0s)
Static pod: kube-scheduler-k8s-master hash: e3025acd90e7465e66fa19c71b916366
Static pod: kube-scheduler-k8s-master hash: e3025acd90e7465e66fa19c71b916366
Static pod: kube-scheduler-k8s-master hash: e3025acd90e7465e66fa19c71b916366
Static pod: kube-scheduler-k8s-master hash: fcdf74fa577cf14b27fe39d482d17a2b
[apiclient] Found 1 Pods for label selector component=kube-scheduler
[upgrade/staticpods] Component "kube-scheduler" upgraded successfully!
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.18" in namespace kube-system with the configuration for the kubelets in the cluster
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.18.3". Enjoy!

[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
```
今度は成功しました！

##uncordon
`kubectl uncordon`を実行して、Masterノードをスケジューリング対象に戻します。

```
$ kubectl uncordon k8s-master
node/k8s-master uncordoned
```

##kubeletとkubectlのアップグレード
kubeletとkubectlをv1.18.3にアップグレードします。

```
$ sudo yum install -y kubelet-1.18.3-0 kubectl-1.18.3-0 --disableexcludes=kubernetes
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ kubectl.x86_64 0:1.17.3-0 を 更新
---> パッケージ kubectl.x86_64 0:1.18.3-0 を アップデート
---> パッケージ kubelet.x86_64 0:1.17.3-0 を 更新
---> パッケージ kubelet.x86_64 0:1.18.3-0 を アップデート
--> 依存性解決を終了しました。

依存性を解決しました

====================================================================================================================================================================================================================================
 Package                                               アーキテクチャー                                     バージョン                                               リポジトリー                                              容量
====================================================================================================================================================================================================================================
更新します:
 kubectl                                               x86_64                                               1.18.3-0                                                 kubernetes                                               9.5 M
 kubelet                                               x86_64                                               1.18.3-0                                                 kubernetes                                                21 M

トランザクションの要約
====================================================================================================================================================================================================================================
更新  2 パッケージ

総ダウンロード容量: 30 M
Downloading packages:
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
(1/2): cd5d6980c3e1b15de222db08729eff40f7031b7fa56c71ae3e28e420ba9678cd-kubectl-1.18.3-0.x86_64.rpm                                                                                                          | 9.5 MB  00:00:05
(2/2): d1a0216cfab2fb28e82be531327ebde9a554bb6d33e3c8313acc9bc728ba59d1-kubelet-1.18.3-0.x86_64.rpm                                                                                                          |  21 MB  00:00:09
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
合計                                                                                                                                                                                                3.3 MB/s |  30 MB  00:00:09
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  更新します              : kubectl-1.18.3-0.x86_64                                                                                                                                                                             1/4
  更新します              : kubelet-1.18.3-0.x86_64                                                                                                                                                                             2/4
  整理中                  : kubectl-1.17.3-0.x86_64                                                                                                                                                                             3/4
  整理中                  : kubelet-1.17.3-0.x86_64                                                                                                                                                                             4/4
  検証中                  : kubelet-1.18.3-0.x86_64                                                                                                                                                                             1/4
  検証中                  : kubectl-1.18.3-0.x86_64                                                                                                                                                                             2/4
  検証中                  : kubectl-1.17.3-0.x86_64                                                                                                                                                                             3/4
  検証中                  : kubelet-1.17.3-0.x86_64                                                                                                                                                                             4/4

更新:
  kubectl.x86_64 0:1.18.3-0                                                                                        kubelet.x86_64 0:1.18.3-0

完了しました!
```

###kubeletの再起動
kubeletをrestartして、バージョンを確認します。

```
$ sudo systemctl daemon-reload
$ sudo systemctl restart kubelet
$ kubectl get node
NAME           STATUS   ROLES    AGE    VERSION
k8s-master     Ready    master   138d   v1.18.3
k8s-worker01   Ready    <none>   138d   v1.17.3
k8s-worker02   Ready    <none>   138d   v1.17.3
```

Masterノードのみ、「v1.18.3」になってますね。

#Workerノードのアップグレード（1台目）
続いて、Workerノードをアップグレードします。WorkerノードとMasterノードの作業がありますので、プロンプトを変えて区別しています。

##kubeadmのアップグレード
Workerノードのkubeadmをアップグレードします。

```
[k8s-worker01]$ sudo yum install -y kubeadm-1.18.3-0 --disableexcludes=kubernetes
読み込んだプラグイン:fastestmirror, langpacks
Determining fastest mirrors
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
base                                                                                                                                                                                        | 3.6 kB  00:00:00
docker-ce-stable                                                                                                                                                                            | 3.5 kB  00:00:00
extras                                                                                                                                                                                      | 2.9 kB  00:00:00
kubernetes/signature                                                                                                                                                                        |  454 B  00:00:00
kubernetes/signature                                                                                                                                                                        | 1.4 kB  00:00:00 !!!
updates                                                                                                                                                                                     | 2.9 kB  00:00:00
(1/6): base/7/x86_64/group_gz                                                                                                                                                               | 153 kB  00:00:00
(2/6): docker-ce-stable/x86_64/primary_db                                                                                                                                                   |  45 kB  00:00:00
(3/6): extras/7/x86_64/primary_db                                                                                                                                                           | 205 kB  00:00:00
(4/6): kubernetes/primary                                                                                                                                                                   |  73 kB  00:00:01
(5/6): updates/7/x86_64/primary_db                                                                                                                                                          | 3.0 MB  00:00:01
(6/6): base/7/x86_64/primary_db                                                                                                                                                             | 6.1 MB  00:00:04
kubernetes                                                                                                                                                                                                 533/533
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ kubeadm.x86_64 0:1.17.3-0 を 更新
---> パッケージ kubeadm.x86_64 0:1.18.3-0 を アップデート
--> 依存性解決を終了しました。

依存性を解決しました

===================================================================================================================================================================================================================
 Package                                           アーキテクチャー                                 バージョン                                          リポジトリー                                          容量
===================================================================================================================================================================================================================
更新します:
 kubeadm                                           x86_64                                           1.18.3-0                                            kubernetes                                           8.8 M

トランザクションの要約
===================================================================================================================================================================================================================
更新  1 パッケージ

総ダウンロード容量: 8.8 M
Downloading packages:
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
a23839a743e789babb0ce912fa440f6e6ceb15bc5db42dd91aa0838c994b3452-kubeadm-1.18.3-0.x86_64.rpm                                                                                                | 8.8 MB  00:00:02
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  更新します              : kubeadm-1.18.3-0.x86_64                                                                                                                                                            1/2
  整理中                  : kubeadm-1.17.3-0.x86_64                                                                                                                                                            2/2
  検証中                  : kubeadm-1.18.3-0.x86_64                                                                                                                                                            1/2
  検証中                  : kubeadm-1.17.3-0.x86_64                                                                                                                                                            2/2

更新:
  kubeadm.x86_64 0:1.18.3-0

完了しました!
```

##drain（Podの退避）
WorkerノードにデプロイされているPodをdrainし、スケジューリング対象から外します。その際、DaemonSetもdrainします。


```
[k8s-master]$ kubectl drain k8s-worker01 --ignore-daemonsets
node/k8s-worker01 cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-cgdgk, kube-system/kube-proxy-m76p2, metallb-system/speaker-89wjx
evicting pod default/nginx-dep-5589d85476-4t4zb
evicting pod kube-system/calico-kube-controllers-77c4b7448-b55bl
evicting pod kube-system/coredns-66bff467f8-pmq95
pod/calico-kube-controllers-77c4b7448-b55bl evicted
pod/nginx-dep-5589d85476-4t4zb evicted
pod/coredns-66bff467f8-pmq95 evicted
node/k8s-worker01 evicted
```

##kubelet構成のアップグレード
Masterノードで以下のコマンドを実行します。

```
[k8s-master]$ sudo kubeadm upgrade node
[upgrade] Reading configuration from the cluster...
[upgrade] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
[upgrade] Upgrading your Static Pod-hosted control plane instance to version "v1.18.3"...
Static pod: kube-apiserver-k8s-master hash: 00f5c9af581644d88b6a6824cf93ee01
Static pod: kube-controller-manager-k8s-master hash: b05610bba851d38ee8c93e1d8d8451fc
Static pod: kube-scheduler-k8s-master hash: a8caea92c80c24c844216eb1d68fe417
[upgrade/etcd] Upgrading to TLS for etcd
[upgrade/etcd] Non fatal issue encountered during upgrade: the desired etcd version for this Kubernetes version "v1.18.3" is "3.4.3-0", but the current etcd version is "3.4.3". Won't downgrade etcd, instead just continue
[upgrade/staticpods] Writing new Static Pod manifests to "/etc/kubernetes/tmp/kubeadm-upgraded-manifests174442946"
W0713 22:22:45.680253   21786 manifests.go:225] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC"
[upgrade/staticpods] Preparing for "kube-apiserver" upgrade
[upgrade/staticpods] Current and new manifests of kube-apiserver are equal, skipping upgrade
[upgrade/staticpods] Preparing for "kube-controller-manager" upgrade
[upgrade/staticpods] Current and new manifests of kube-controller-manager are equal, skipping upgrade
[upgrade/staticpods] Preparing for "kube-scheduler" upgrade
[upgrade/staticpods] Current and new manifests of kube-scheduler are equal, skipping upgrade
[upgrade] The control plane instance for this node was successfully updated!
[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.18" ConfigMap in the kube-system namespace
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[upgrade] The configuration for this node was successfully updated!
[upgrade] Now you should go ahead and upgrade the kubelet package using your package manager.
```

##kubeletとkubectlのアップグレード
Workerノードでkubeletとkubectlをアップグレードします。

```
[k8s-worker01]$ sudo yum install -y kubelet-1.18.3-0 kubectl-1.18.3-0 --disableexcludes=kubernetes
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: ftp.riken.jp
 * extras: ftp.riken.jp
 * updates: ftp.riken.jp
依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ kubectl.x86_64 0:1.17.3-0 を 更新
---> パッケージ kubectl.x86_64 0:1.18.3-0 を アップデート
---> パッケージ kubelet.x86_64 0:1.17.3-0 を 更新
---> パッケージ kubelet.x86_64 0:1.18.3-0 を アップデート
--> 依存性解決を終了しました。

依存性を解決しました

===================================================================================================================================================================================================================
 Package                                           アーキテクチャー                                 バージョン                                          リポジトリー                                          容量
===================================================================================================================================================================================================================
更新します:
 kubectl                                           x86_64                                           1.18.3-0                                            kubernetes                                           9.5 M
 kubelet                                           x86_64                                           1.18.3-0                                            kubernetes                                            21 M

トランザクションの要約
===================================================================================================================================================================================================================
更新  2 パッケージ

総ダウンロード容量: 30 M
Downloading packages:
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
(1/2): cd5d6980c3e1b15de222db08729eff40f7031b7fa56c71ae3e28e420ba9678cd-kubectl-1.18.3-0.x86_64.rpm                                                                                         | 9.5 MB  00:00:03
(2/2): d1a0216cfab2fb28e82be531327ebde9a554bb6d33e3c8313acc9bc728ba59d1-kubelet-1.18.3-0.x86_64.rpm                                                                                         |  21 MB  00:00:06
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
合計                                                                                                                                                                               4.4 MB/s |  30 MB  00:00:06
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  更新します              : kubectl-1.18.3-0.x86_64                                                                                                                                                            1/4
  更新します              : kubelet-1.18.3-0.x86_64                                                                                                                                                            2/4
  整理中                  : kubectl-1.17.3-0.x86_64                                                                                                                                                            3/4
  整理中                  : kubelet-1.17.3-0.x86_64                                                                                                                                                            4/4
  検証中                  : kubelet-1.18.3-0.x86_64                                                                                                                                                            1/4
  検証中                  : kubectl-1.18.3-0.x86_64                                                                                                                                                            2/4
  検証中                  : kubectl-1.17.3-0.x86_64                                                                                                                                                            3/4
  検証中                  : kubelet-1.17.3-0.x86_64                                                                                                                                                            4/4

更新:
  kubectl.x86_64 0:1.18.3-0                                                                                kubelet.x86_64 0:1.18.3-0

完了しました!
```

###kubeletの再起動
kubeletをrestartします。

```
[k8s-worker01]$ sudo systemctl daemon-reload
[k8s-worker01]$ sudo systemctl restart kubelet
```

Workerノードをuncordonして、スケジューリング対象に戻します。

```
[k8s-master]$ kubectl uncordon k8s-worker01
node/k8s-worker01 uncordoned
```
バージョンを確認します。

```
[k8s-master]$ kubectl get node
NAME           STATUS   ROLES    AGE    VERSION
k8s-master     Ready    master   138d   v1.18.3
k8s-worker01   Ready    <none>   138d   v1.18.3
k8s-worker02   Ready    <none>   138d   v1.17.3
```

#Workerノードのアップグレード（2台目）
1台目と同様の手順でアップグレードします。手順は同じなので、詳細は割愛します。

```
[k8s-master]$ kubectl get node
NAME           STATUS   ROLES    AGE    VERSION
k8s-master     Ready    master   138d   v1.18.3
k8s-worker01   Ready    <none>   138d   v1.18.3
k8s-worker02   Ready    <none>   138d   v1.18.3
```
これでKubernetesクラスタのアップグレードは完了です。


#（参考1）業務継続の確認
今回は業務を止めずに3つのノードをローリングアップデートしました。
実際に業務が止まっていないかを以下のように、外部サーバからLoadBalancerを介して10秒間隔でコンテナに対してリクエストを送り続けて確認しました。

```
[client]$ while true; do echo -n "$(date +%T) " ; curl -s http://10.20.30.150:8080 ; sleep 10 ;done
22:01:42 Hello!
22:01:52 Hello!
22:02:02 Hello!
22:02:12 Hello!
22:02:23 Hello!
22:02:33 Hello!
・・・
```

全てのログは載せられませんが、確認したところ全てリクエストは返ってきていました。
もしかすると、10秒の間に切れてたタイミングがあるかも知れませんが、業務無停止でアップグレードできたのかなと思います。

#（参考2）トラブル
k8s-worker02をdrainするところで、失敗しました。原因はk8s-worker02にデプロイされていたメトリクスサーバがローカルストレージを持っていたためにdrainができませんでした。
今回はメトリクスサーバを一旦削除して対処しています。以下が詳細になります。

##事象

```
[k8s-master]$ kubectl drain k8s-worker02 --ignore-daemonsets
node/k8s-worker02 cordoned
error: unable to drain node "k8s-worker02", aborting command...

There are pending nodes to be drained:
 k8s-worker02
error: cannot delete Pods with local storage (use --delete-local-data to override): kube-system/metrics-server-fbc46dc5f-nlhvs
```
Workerノードはスケジューリング対象から外れましたが、メトリクスサーバ（metrics-server-fbc46dc5f-nlhvs）がローカルストレージを持っているため、drainに失敗しています。

##対処
###メトリクスサーバの詳細確認

```
[k8s-master]$ kubectl -n kube-system describe pod metrics-server-fbc46dc5f-nlhvs
Name:         metrics-server-fbc46dc5f-nlhvs
Namespace:    kube-system
Priority:     0
Node:         k8s-worker02/10.20.30.30
・・・
Containers:
  metrics-server:
・・・
    Mounts:
      /tmp from tmp-dir (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from metrics-server-token-5s57t (ro)
・・・
Volumes:
  tmp-dir:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
・・・
```
EmptyDirがアサインされています。
以下のように--forceオプションを付与しても結果は同じだったので、メトリクスサーバ自体は業務には影響ないとして一旦削除することとしました。

`kubectl drain k8s-worker02 --ignore-daemonsets --force` 

###メトリクスサーバの削除
削除する前に、再構成できるようマニフェストファイルを保存してから削除します。

```
[k8s-master]$ kubectl -n kube-system get pod metrics-server-fbc46dc5f-nlhvs -o yaml > metrics.yaml
[k8s-master]$ kubectl -n kube-system delete pod metrics-server-fbc46dc5f-nlhvs
pod "metrics-server-fbc46dc5f-nlhvs" deleted
```

###drain
再度drainします。

```
[k8s-master]$ kubectl drain k8s-worker02 --ignore-daemonsets
node/k8s-worker02 already cordoned
WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tkcz5, kube-system/kube-proxy-6x2wd, metallb-system/speaker-vdh69
evicting pod default/nginx-dep-5589d85476-qkj8p
evicting pod default/nginx-dep-5589d85476-p4zgk
evicting pod kube-system/calico-kube-controllers-77c4b7448-xqqhv
evicting pod kube-system/coredns-66bff467f8-f4s5z
evicting pod metallb-system/controller-5c9894b5cd-4hnzc
pod/controller-5c9894b5cd-4hnzc evicted
error when evicting pod "nginx-dep-5589d85476-qkj8p" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/nginx-dep-5589d85476-qkj8p
error when evicting pod "nginx-dep-5589d85476-qkj8p" (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
pod/calico-kube-controllers-77c4b7448-xqqhv evicted
pod/nginx-dep-5589d85476-p4zgk evicted
pod/coredns-66bff467f8-f4s5z evicted
evicting pod default/nginx-dep-5589d85476-qkj8p
pod/nginx-dep-5589d85476-qkj8p evicted
node/k8s-worker02 evicted
```
PodDisruptionBudgetの影響でerrorと表示されていますが、ここでは問題ありません。
[参考：[Kubernetes]ノードメンテナンスについて確認する](https://qiita.com/dingtianhongjie/items/b6c2f7e3c940eb3142f2#poddisruptionbudget)

drainが成功しましたので、以降は確認した手順でアップグレードします。

##メトリクスサーバの再作成
アップグレードが終わったら、バックアップしておいたマニフェストファイルをapplyして、メトリクスサーバを再作成します。

```
[k8s-master]$ kubectl apply -f metrics.yaml
pod/metrics-server-fbc46dc5f-nlhvs created
[k8s-master]$ kubectl top node
NAME           CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
k8s-master     226m         11%    1659Mi          60%
k8s-worker01   174m         8%     791Mi           28%
k8s-worker02   150m         7%     754Mi           27%
```

#まとめ
Kubernetesは同じバージョンを9ヶ月ほどしかサポートできませんので、余裕をみて半年に一回くらいのペースでアップグレードする感じですね。
今回は3台のクラスタ構成ですので一台ずつ手でアップグレードしましたが、もっと大規模なクラスタだと手でやるのは難しいですね。Ansibleとか使って自動化しないと継続するのは難しそうです。