Kubernetes Upgrade 는 고려해야 할 사항이 많지만 Kubespray 를 활용하면 의외로 간단할 수 도 있다.
Kubespray 는 Kubernetes 설치에 kubeadm 을 활용하기 때문에 업그레이드는 Kubernetes 의 바로 윗단계 마이너버전까지만 가능하다. 예를 들어 지금 Kubernetes 버전이 v1.14.x 이면 v1.16.x 로는 업그레이드를 못한다. v1.16.x 로 업그레이드를 하기 위해서는 v1.15.x 로 업그레이드를 하고, v1.16.x 로 다시 업그레이드를 해야 한다.
마침 업그레이드가 필요했고 현재 설치된 Kubernetes 버전이 v1.14.3 이므로 v1.15.6 으로 업그레이드를 먼저 진행하였다.
$ cd kubespray
$ git branch
master
* release-2.11
release-2.12
tag_v2.10.4
tag_v2.9.0
Kubespray 의 release-2.11 branch 는 Kubernetes Kubernetes v1.15.6 이다. 아래 명령어로 확인할 수 버전을 확인할 수 있다.
kube_version: v1.15.6
$ grep -nr kube_version: .
./docs/upgrades.md:30:And then repeat with v1.4.6 as kube_version:
./inventory/sample/group_vars/k8s-cluster/k8s-cluster.yml:23:kube_version: v1.15.6
./inventory/k1-seungkyua/group_vars/k8s-cluster/k8s-cluster.yml:23:kube_version: v1.15.6
./roles/download/defaults/main.yml:52:kube_version: v1.15.6
./roles/kubespray-defaults/defaults/main.yaml:15:kube_version: v1.15.6
./RELEASE.md:37: is bound to ``kube_version: 1.4.x``, ``calico_version: 0.22.0``, ``etcd_version: v3.0.6``,
./RELEASE.md:40: And Kubespray v3.x.x shall be bound to ``kube_version: 2.x.x`` respectively.
먼저 Master 3대를 업그레이드 하여 업그레이드를 순차적으로 하는 것이 좋다. Kubernetes Master 와 Work Node 는 minor 차이가 나더
라도 큰 문제가 생기지 않기 때문에 순차적 검증을 할 수 있다. 물론 kube-apiserver 에서 활성화한 특정 feature 와 resource version 은 사전에 반드시 테스트하여 안전성을 확보한 후 진행해야 한다.
$ ansible-playbook -e @inventory/k1-seungkyua/extra-vars.yml -b -f 30 -i inventory/k1-seungkyua/inventory.ini upgrade-cluster.yml --limit k1-master01,k1-master02,k1-master03
중요한 것은 --limit 옵션으로 Master 만 업그레이드를 진행한다는 것이다.
Every 2.0s: kubectl get nodes Thu Jan 9 16:15:35 2020
NAME STATUS ROLES AGE VERSION
k1-master01 Ready master 323d v1.15.6
k1-master02 Ready master 323d v1.15.6
k1-master03 Ready master 323d v1.15.6
k1-node01 Ready ingress,node 323d v1.14.3
k1-node02 Ready node 323d v1.14.3
k1-node03 Ready node 322d v1.14.3
k1-node04 Ready node 323d v1.14.3
k1-node05 Ready node 323d v1.14.3
이제 Worker 를 업그레이드 할 차례인데, Worker 를 업그레이드는 고려해야 할 사항이 있다. 노드를 업그레이드 하기 위해서는 drain 을 하여 Pod 를 eviction 하는데 Kubespray 는 evction 이 완료될 때 까지 기다린다. DaemonSet 은 무시하는 옵션이 있지만 PodDisruptionBudget 은 policy 에 걸리면 pod 가 terminating 상태에서 완료되지 않기 때문에 timeout 으로 업그레이드에 실패하게 된다. 여기서는 elasticsearch 가 문제가 있어 timeout 나서 실패하였다.
# kubectl get PodDisruptionBudget -A
NAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
istio-system istio-egressgateway 1 N/A 0 76d
istio-system istio-galley 1 N/A 0 76d
istio-system istio-ingressgateway 1 N/A 0 76d
istio-system istio-pilot 1 N/A 0 76d
istio-system istio-policy 1 N/A 0 76d
istio-system istio-telemetry 1 N/A 0 76d
logging elasticsearch-k1-master-pdb N/A 1 0 71d
elasticsearch 문제를 해결하고 다시 k1-node01 이라는 Worker 노드 1대만 업그레이드를 진행한다.
$ ansible-playbook -e @inventory/k1-seungkyua/extra-vars.yml -b -f 30 -i inventory/k1-seungkyua/inventory.ini upgrade-cluster.yml --limit k1-node01
문제없이 업그레이드가 완료되었다.
Every 2.0s: kubectl get nodes Thu Jan 9 16:27:17 2020
NAME STATUS ROLES AGE VERSION
k1-master01 Ready master 323d v1.15.6
k1-master02 Ready master 323d v1.15.6
k1-master03 Ready master 323d v1.15.6
k1-node01 Ready ingress,node 323d v1.15.6
k1-node02 Ready node 323d v1.14.3
k1-node03 Ready node 322d v1.14.3
k1-node04 Ready node 323d v1.14.3
k1-node05 Ready node 323d v1.14.3
이제 나머지 노드를 모드 업그레이드를 하면 된다. Kubespray 는 한대씩 순차적으로 업그레이드를 하기 때문에 전체 서비스에는 영향이 없다. (서비스를 여러 pod 로 load balancing 했을 경우에)