'Kubernetes Upgrade'에 해당되는 글 2건

  1. 2020.07.31 Kubernetes v1.16.3 에서 v1.17.7로 업그레이드 시 문제 해결 1
  2. 2020.01.09 Kubernetes Upgrade (Kubespray 활용) 1
반응형

며칠 전 Kubernetes Cluster 를 v1.16.3 에서 v1.18.5 로 업그레이드 하다가 발견된 이슈를 해결한 내용을 공유합니다.

 

제가 관리하고 있는 Kubernetes 는 Kubespray 로 설치했었고 업그레이드 역시 Kubespray 를 활용했습니다.

Kubespray 는 Kubernetes 설치에 kubeadm 을 사용하는데 kubeadm 은 마이너 버전 차이가 1 을 초과하면 업그레이드를 지원하지 않습니다.

그렇기 때문에 v1.16.x 에서 v1.18.x 로 업그레이드를 하려며 v1.16.x -> v1.17.x -> v1.18.x 로 단계적으로 업그레이드를 해야 합니다.

 

 

기존 설치된 버전은 kubespray 의 release-2.12 브랜치로 v1.16.3 이었고,  kubespray tags/v2.13.2 을 활용하면 v1.17.7 로 업그레이들 할 수 있습니다.

 

 

## deploy 디렉토리로 변경

$ cd ~/deploy/kubespray

 

 

## kubespray 다운로드 (tag 로 할 때)

$ git checkout master

$ git pull

$ git checkout -b tag_v2.13.2 tags/v2.13.2

$ sudo pip install -r requirements.txt

 

 

## inventory 복사 (업그레이드 할 때)

$ rm -rf inventory/k1-seungkyua/group_vars/*

$ cp -r inventory/sample/group_vars inventory/k1-seungkyua

 

 

 

## hosts.ini 수정

$ vi inventory/k1-seungkyua/inventory.ini

[all]

k1-master01 ansible_host=k1-master01 ip=192.168.30.13 iface=eno49

k1-master02 ansible_host=k1-master02 ip=192.168.30.14 iface=ens2f0

k1-master03 ansible_host=k1-master03 ip=192.168.30.15 iface=eno49

k1-node01 ansible_host=k1-node01 ip=192.168.30.12 iface=ens2f0

k1-node02 ansible_host=k1-node02 ip=192.168.30.17 iface=ens2f0

k1-node03 ansible_host=k1-node03 ip=192.168.30.18 iface=ens2f0

k1-node04 ansible_host=k1-node04 ip=192.168.30.21 iface=ens2f0

k1-node05 ansible_host=k1-node05 ip=192.168.30.20 iface=ens2f0

 

[etcd]

k1-master01

k1-master02

k1-master03

 

[kube-master]

k1-master01

k1-master02

k1-master03

 

[kube-node]

k1-node01

k1-node02

k1-node03

k1-node04

k1-node05

 

[calico-rr]

 

[k8s-cluster:children]

kube-master

kube-node

calico-rr

 

 

## k8s-cluster.yml 수정

$ vi inventory/k1-seungkyua/extra-vars.yml

 

enable_nodelocaldns: false

 

# 신규 설치시에만 세팅

# skydns_server: "{{ kube_service_addresses|ipaddr('net')|ipaddr(10)|ipaddr('address') }}"

 

kube_proxy_mode: ipvs

 

# hostname and hosts file

populate_inventory_to_hosts_file: false

override_system_hostname: false

 

# Helm deployment

helm_enabled: true

 

## copy admin.conf

kubeconfig_localhost: true

kubectl_localhost: true

 

## calico setting

ipip_mode: Never

peer_with_router: true

nat_outgoing: true

global_as_num: "65000"

peers:

  - router_id: "192.168.30.1"

    as: "65000"

 

# calico_ip_auto_method: "interface=eth.*"

# calico_ip_auto_method: "interface=ens6"

calico_ip_auto_method: "can-reach=8.8.8.8"

 

kubeadm_enabled: true

 

docker_insecure_registries:

  - tacorepo:5000

 

dashboard_enabled: true

 

# Local volume provisioner deployment

local_volume_provisioner_enabled: true

 

metrics_server_enabled: true

 

## rbd provisioner deployment

rbd_provisioner_enabled: true

rbd_provisioner_monitors: 192.168.30.23:6789,192.168.30.24:6789,192.168.30.25:6789

rbd_provisioner_pool: kubes

rbd_provisioner_secret: QVFBTmRVVlh5UmZoTlJBQTMyZTh6Qk5uajV1VElrMDJEbWFwWmc9PQ==

rbd_provisioner_user_secret: QVFDdC9CcFlpZ0o3TVJBQTV2eStjbDM5RXNLcFkzQyt0WEVHckE9PQ==

 

 

저의 경우에는 calico 를 활용하여 switch 와 bgp 로 통신하므로 bgp 설정을 넣었습니다.

 

 

 

## k8s 업그레이드 수행

$ ansible-playbook -e @inventory/k1-seungkyua/extra-vars.yml -b -f 30 -i inventory/k1-seungkyua/inventory.ini upgrade-cluster.yml

 

 

 

업그레이드를 돌리면 순차적으로 drain 과 uncordon 을 수행하는데 중간에 에러가 날 경우에는 kubelet 을 업그레이드 이전 버전으로 돌려놓아야 합니다.

 

예를 들어, master02 를 업그레이드 하다가 에러가 나면 아래의 작업을 수행해 줘야 합니다.

 

1. 에러가 나도 kubelet 의 버전은 올라가므로 kubelet 버전을 업그레이드 이전으로 다운그레이드 해야 합니다. 쉬운 방법은 다른 노드에 있는 kubelet 을 복사해서 kubelet 을 restart 해야 합니다.

systemctl restart kubelet

 

 

2. schedule 이 disabled 되어 있을 수 있으니 uncordon 해줘야 합니다.

kubectl uncordon k1-master02

  

 

 

 

 

## 업그레이드 시 에러 날 경우

PodDisruptionBudget 을 확인해야 함

istio 의 MIN AVAILABLE 은 전부 0 으로 세팅

elasticsearch 는 삭제

 

# 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

 

Master의 root 디렉토리 확인

 

/root/.kube/http-cache 디렉토리 삭제

/root/.docker/config 파일 삭제 (도커 로그인정보를 가지고 있어서 docker pull 이 안될 수 있음)

 

coreDNS 가 10.233.0.3 이면 kubeadm 에서 coreDNS 는 10.233.0.10 이어야 한다는 업그레이드 에러 발생

 

kubeadm 명령어에 --print-config 옵션을 붙혀서 미리 한 번 실행하여 이상이 없는지 확인

 

kubeadm upgrade apply -y v1.17.7 --config=/etc/kubernetes/kubeadm-config.yaml --ignore-preflight-errors=all --allow-experimental-upgrades --allow-release-candidate-upgrades --etcd-upgrade=false --certificate-renewal=true --force --v=9 --print-config

 

실행에 이상이 없으면 kubespray 의 roles/kubernetes/master/tasks/kubeadm-upgrade.yml 에 해당 옵션을 추가

 

 

 

 

kubelet upgrade 시에 에러가 발생하였음.

kubelet 버전은 v1.16.3 에서 v1.17.7 로 업그레이드가 되었으나 기존 옵션으로 kubelet 이 start 시에 에러가 남

kubelet --version 으로 v1.17.7 이면 v1.16.3 으로 kubelet 을 다시 복사하고 Kubelet restart

 

 

 

 

 

 

반응형
Posted by seungkyua@gmail.com
,
반응형

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 했을 경우에)

 

반응형
Posted by seungkyua@gmail.com
,