kubeadmにて作成したKubernetes Clusterをアップグレードしてみます。下記は参考の公式ドキュメント。
環境
- 構成
- マスターノード
- 1台
- ワーカーノード
- 1台
- マスターノード
- バージョン
- OS
- Ubuntu 20.04.1 LTS
- kubernetes
- 現行
- 1.19.0
- アップグレード先
- 1.20.2-00
- 現行
- CNI
- calico/cni:v3.17.1
- コンテナランタイム
- Docker version 19.03.11
- OS
etcdはKubernetes内に作っています。
アップグレード中の影響
ざっと確認ですが、マスターノードをアップグレード中は、KubernetesのControl Planeで提供される機能を利用できなくなります。現在起動中のPodには影響を与えませんが、kube-apiへのアクセス、SchedulerやControlerでの管理動作、etcdへのアクセスは不可能となります。そのため、新規でのオブジェクト作成やDaemonSetにたいする管理動作等には影響が発生します。
事前確認
アップグレード先のKubernetesバージョンに対して、現在利用しているCNIやコンテナランタイムが動作可能であるか、事前に確認する必要があります。それら以外にも、管理用のPodやControllerを起動させている場合、それらを動作対応も確認しておく必要があります。
CNI(Calico)
Calicoをバージョンしたところ、Kubernetes 1.20がサポートに入っていなかったのですが、動くことを知っているので、無視してアップグレードしてしまいます。
Kubernetes requirements
Supported versions
We test Calico v3.17 against the following Kubernetes versions.
1.17
1.18
1.19
コンテナラインタイム(Docker CE)
公式ドキュメントには下記とあるのですが、リリースノート見に行っても、Dockerがdeprecatedされた情報のみで、サポートバージョンについては記載ありませんでした。
The Kubernetes release notes list which versions of Docker are compatible with that version of Kubernetes.
Stack overflowに、以下の投稿ありましたが、結局確かなことは分かりませんでした。
I have confirmed the information on the changelog for version 1.16. On the changelog for version 1.17, 1.18 and 1.19, there is no change about the Dependecies section about docker version. It seems that k8s 1.17, 1.18 and 1.19 support the same version. (1.13.1, 17.03, 17.06, 17.09, 18.06, 18.09)
Which docker versions are supported on kubernetes 1.18 and 1.19?
まあ、動くこと知っているので、無視してアップグレードしてしまいます。
マスターノードのアップグレード
マスターノード側から作業します。マスターノードにssh接続します。
kubeadmのアップグレード
アップグレード可能なkubeadmバージョンを確認します。1.20バージョンの最新である、 1.20.2-00
へアップグレードする方針とします。
$ sudo apt update $ sudo apt-cache madison kubeadm
実際にアップグレードする前に、ノードをdrainして、evict可能なPodを退避させてあげます。
$ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubeadm-upgrade-master Ready master 30h v1.19.0 10.146.0.5 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11 kubeadm-upgrade-worker Ready <none> 29h v1.19.0 10.146.0.6 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11 $ $ kubectl drain kubeadm-upgrade-master --ignore-daemonsets node/kubeadm-upgrade-master already cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-rdsjh, kube-system/kube-proxy-xfg67 evicting pod kube-system/calico-kube-controllers-744cfdf676-qnfl4 evicting pod kube-system/coredns-f9fd979d6-fg92v evicting pod kube-system/coredns-f9fd979d6-hsr4v pod/calico-kube-controllers-744cfdf676-qnfl4 evicted pod/coredns-f9fd979d6-hsr4v evicted pod/coredns-f9fd979d6-fg92v evicted node/kubeadm-upgrade-master evicted $ $ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubeadm-upgrade-master Ready,SchedulingDisabled master 30h v1.19.0 10.146.0.5 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11 kubeadm-upgrade-worker Ready <none> 29h v1.19.0 10.146.0.6 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11
モジュールをアップグレードします。
# replace x in 1.20.x-00 with the latest patch version $ sudo apt-mark unhold kubeadm $ sudo apt-get install -y kubeadm=1.20.2-00 $ sudo apt-mark hold kubeadm
バージョンの確認。
$ kubeadm version kubeadm version: &version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.2", GitCommit:"faecb196815e248d3ecfb03c680a4507229c2a56", GitTreeState:"clean", BuildDate:"2021-01-13T13:25:59Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
Kubernetes Clusterのアップグレード
アップグレード可否を確認できるコマンドが用意されているため、事前に確認を行います。
$ sudo kubeadm upgrade plan v1.20.2 [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 -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.19.7 [upgrade/versions] kubeadm version: v1.20.2 [upgrade/versions] Latest stable version: v1.20.2 [upgrade/versions] Latest version in the v1.19 series: v1.20.2 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE kubelet 2 x v1.19.0 v1.20.2 Upgrade to the latest version in the v1.19 series: COMPONENT CURRENT AVAILABLE kube-apiserver v1.19.7 v1.20.2 kube-controller-manager v1.19.7 v1.20.2 kube-scheduler v1.19.7 v1.20.2 kube-proxy v1.19.7 v1.20.2 CoreDNS 1.7.0 1.7.0 etcd 3.4.9-1 3.4.13-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.20.2 _____________________________________________________________________ The table below shows the current state of component configs as understood by this version of kubeadm. Configs that have a "yes" mark in the "MANUAL UPGRADE REQUIRED" column require manual config upgrade or resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually upgrade to is denoted in the "PREFERRED VERSION" column. API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED kubeproxy.config.k8s.io v1alpha1 v1alpha1 no kubelet.config.k8s.io v1beta1 v1beta1 no _____________________________________________________________________
実行。
$ sudo kubeadm upgrade apply v1.20.2 [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 -o yaml' [preflight] Running pre-flight checks. [upgrade] Running cluster health checks [upgrade/version] You have chosen to change the cluster version to "v1.20.2" [upgrade/versions] Cluster version: v1.19.7 [upgrade/versions] kubeadm version: v1.20.2 [upgrade/confirm] Are you sure you want to proceed with the upgrade? [y/N]: y [upgrade/prepull] Pulling images required for setting up a Kubernetes cluster ... [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.20.2". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
アップグレードされました。尚、本アップグレード処理では、Cluster内で利用されている証明書の更新もされるそうです。そのため、独自に証明書を作成している場合、考慮が必要となります。
Note: kubeadm upgrade also automatically renews the certificates that it manages on this node. To opt-out of certificate renewal the flag --certificate-renewal=false can be used.
CNIのアップグレード
CNIのアップグレードが必要な場合、このタイミングでアップグレード(実行されているPod)の更新を行います。本構成のCalicoでは、アップグレード不要のため、スキップします。
その他マスターノードのアップグレード
今回はシングル構成のため実施しないですが、マスターノードが冗長構成の場合、以下のコマンドにて同様にアップグレード処理を行います。
$ sudo kubeadm upgrade node
kubeletとkubectlをアップグレード
kubeletとkubectlのモジュールを、kubeadmのバージョンに合わせてアップグレードします。
$ sudo apt-mark unhold kubelet kubectl $ sudo apt-get install -y kubelet=1.20.2-00 kubectl=1.20.2-00 $ sudo apt-mark hold kubelet kubectl
kubeletプロセスの再起動。
$ sudo systemctl daemon-reload $ sudo systemctl restart kubelet $ sudo systemctl status kubelet ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled) Drop-In: /etc/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since Tue 2021-01-19 08:50:23 UTC; 9s ago Docs: https://kubernetes.io/docs/home/ Main PID: 23941 (kubelet) Tasks: 13 (limit: 9544) Memory: 34.7M CGroup: /system.slice/kubelet.service └─23941 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml > Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910708 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "lib-mod> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910737 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "xtables> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910769 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "usr-loc> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910800 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "usr-sha> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910829 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "cni-bin> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910857 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "etc-pki> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910884 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "lib-mod> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910913 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "kube-pr> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910948 23941 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "ca-cert> Jan 19 08:50:24 kubeadm-upgrade-master kubelet[23941]: I0119 08:50:24.910962 23941 reconciler.go:157] Reconciler: start to sync state
マスター側での処理完了のため、nodeをuncordonしておきます。
$ kubectl uncordon kubeadm-upgrade-master node/kubeadm-upgrade-master uncordoned $ $ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubeadm-upgrade-master Ready control-plane,master 30h v1.20.2 10.146.0.5 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11 kubeadm-upgrade-worker Ready <none> 30h v1.19.0 10.146.0.6 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11
ワーカーノードのアップグレード
ワーカーノードにssh接続します。
kubeadmのアップグレード
マスターノードと同様に、kubeadmのモジュールをアップグレードします。
その前に、対象ノードをdrainしておきます。
$ kubectl drain kubeadm-upgrade-worker --ignore-daemonsets node/kubeadm-upgrade-worker already cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/calico-node-tj78s, kube-system/kube-proxy-s9b6j evicting pod kube-system/coredns-74ff55c5b-xcjfq evicting pod kube-system/calico-kube-controllers-744cfdf676-556b4 evicting pod default/sample-54dd9cdb5d-xkgnw evicting pod kube-system/coredns-74ff55c5b-gz4kj pod/sample-54dd9cdb5d-xkgnw evicted pod/calico-kube-controllers-744cfdf676-556b4 evicted pod/coredns-74ff55c5b-gz4kj evicted pod/coredns-74ff55c5b-xcjfq evicted node/kubeadm-upgrade-worker evicted $ $ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubeadm-upgrade-master Ready control-plane,master 30h v1.20.2 10.146.0.5 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11 kubeadm-upgrade-worker Ready,SchedulingDisabled <none> 30h v1.19.0 10.146.0.6 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11
アップグレードします。
$ sudo apt-mark unhold kubeadm $ sudo apt-get update $ sudo apt-get install -y kubeadm=1.20.2-00 $ sudo apt-mark hold kubeadm
確認。
$ sudo kubeadm version kubeadm version: &version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.2", GitCommit:"faecb196815e248d3ecfb03c680a4507229c2a56", GitTreeState:"clean", BuildDate:"2021-01-13T13:25:59Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
Kubernetes Clusterのアップグレード
Clusterのアップグレード処理を実施します。
$ 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 -o yaml' [preflight] Running pre-flight checks [preflight] Skipping prepull. Not a control plane node. [upgrade] Skipping phase. Not a control plane node. [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のアップグレード
kubeletとkubectlのモジュールをアップグレードします。
$ sudo apt-mark unhold kubelet kubectl $ sudo apt-get install -y kubelet=1.20.2-00 kubectl=1.20.2-00 $ sudo apt-mark hold kubelet kubectl
kubeletプロセスの再起動。
$ sudo systemctl daemon-reload $ sudo systemctl restart kubelet $ sudo systemctl status kubelet ● kubelet.service - kubelet: The Kubernetes Node Agent Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled) Drop-In: /etc/systemd/system/kubelet.service.d └─10-kubeadm.conf Active: active (running) since Tue 2021-01-19 09:14:03 UTC; 4s ago Docs: https://kubernetes.io/docs/home/ Main PID: 43766 (kubelet) Tasks: 13 (limit: 9544) Memory: 30.3M CGroup: /system.slice/kubelet.service └─43766 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml > Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.038554 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "policys> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.038614 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "kube-pr> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.038694 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "xtables> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.038789 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "lib-mod> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.038826 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "kube-pr> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.038976 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "var-lib> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.039004 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "xtables> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.039033 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "cni-net> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.039057 43766 reconciler.go:224] operationExecutor.VerifyControllerAttachedVolume started for volume "calico-> Jan 19 09:14:05 kubeadm-upgrade-worker kubelet[43766]: I0119 09:14:05.039071 43766 reconciler.go:157] Reconciler: start to sync state
ワーカーノード側での処理完了のため、nodeをuncordonしておきます。
$ kubectl uncordon kubeadm-upgrade-worker node/kubeadm-upgrade-worker uncordoned $ $ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME kubeadm-upgrade-master Ready control-plane,master 30h v1.20.2 10.146.0.5 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11 kubeadm-upgrade-worker Ready <none> 30h v1.20.2 10.146.0.6 <none> Ubuntu 20.04.1 LTS 5.4.0-1034-gcp docker://19.3.11
Clusterのアップグレードが完了しました。
その他メモ
kubeadm upgrade apply
や kubeadm upgrade node
時に、何をしているかの説明。
kubectl cordon
や kubectl uncordon
を実行するわけで、Cluster上でPodが偏ってしまうじゃないかと思ったのですが、 descheduler
というものがあるみたいです。
Descheduler, based on its policy, finds pods that can be moved and evicts them.
Cluster上でCronJobとして動くものらしいです。