콤퓨우터/필기: KodeKloud CKA 강의

122-127. OS Upgrades, Kubernetes Software Versions, Cluster Upgrade Process

파란화면 2024. 5. 17. 00:28
반응형

기본적으로 업데이트를 하기 전에, ReplicaSet (이나 Deployment)를 잘 짜서, 한 서버를 내려버리더라도 다른 노드에서 필요한 Pod들이 잘 돌도록 구성할 필요가 있다.

어떤 노드가 죽으면, 마스터노드가 죽은 노드에 있던 Pod들의 사망판정을 내리기까지 5분의 유예시간이 존재한다. 이것은 kube-controller-manager --pod-eviction-timeout=5m0s 명령어로 수정할 수 있다.

Drain하기

노드를 drain하면, 해당 노드에 대한 스케줄링은 멈추고 노드에 있던 모든 Pod들은 종료된다. ReplicaSet같은 게 제대로 설정되어 있다면, 꺼진 Pod들은 다른 노드로 옮겨 갈 것이다. Pod들이 옮겨간 뒤에, 업데이트를 하든 뭘 하든 지지고볶으면 된다.

kubectl drain node-name

하고 싶었던 일을 다 끝내고 Drain했던 노드를 다시 올렸다면, uncordon을 진행해서 스케줄러를 원래대로 돌려놓아야 한다.

  • drain: 노드에 새 Pod이 스케줄링되는 것을 차단하고, 모든 Pod들을 죽임
  • cordon: 노드에 새 Pod이 스케줄링되는 것만 차단함
  • uncordon: drain이나 cordon 상태를 해제함

Drain이 안 될 때

controlplane ~ ➜  kubectl drain node01 --ignore-daemonsets
node/node01 cordoned
error: unable to drain node "node01" due to error:cannot delete Pods declare no controller (use --force to override): default/hr-app, continuing command...
There are pending nodes to be drained:
 node01
cannot delete Pods declare no controller (use --force to override): default/hr-app

Pod이 ReplicaSet에 포함되어 있지 않은 경우 기본적으로 오류가 발생한다 (강제로 죽일 수는 있다)

버전

쿠버의 버전넘버는 여느 소프트웨어처럼 major-minor-patch 구성이다.
쿠버네티스는 여러 구성요소로 구성되지만, 이 모든 구성요소의 버전이 같아야 하는 것은 아니다.

아래는 Kubernetes 프로젝트에서 관리하여 같은 versoning scheme을 가지고 같이 배포되는 구성요소이다.

  • kube-apiserver
  • controller-manager
  • kube-scheduler
  • kubelet
  • kube-proxy

하지만 etcd, CoreDNS 등은 외부 프로젝트에서 관리하므로 쿠버 버전을 따라가지 않는다.

쿠버를 업데이트할 때에는 먼저 kube-apiserver부터 업데이트한다.

  • kubectl을 제외한 다른 모든 컴포넌트들의 버전은 kube-apiserver의 버전보다 낮거나 같아야 한다.
    • controller-manager와 scheduler는 kube-apiserver보다 1 마이너 버전만큼 낮을 수 있다. (예를 들어 kube-apiserver 버전이 1.10이라면, scheduler는 1.9로 사용가능)
    • kubelet와 kube-proxy는 kube-apiserver보다 2 마이너 버전만큼 낮을 수 있다. (예를 들어 kube-apiserver 버전이 1.10이라면, kubelet은 1.8까지 사용가능)
  • kube-apiserver 버전이 1.10이라면 kubectl은 1.9 ~ 1.11까지 사용 가능하다.

쿠버는 업데이트 시 마이너 버전을 1씩만 올릴 수 있도록 되어 있다. 예를 들어 1.10에서 1.13으로 바로 올라갈 수 없고, 1.10 -> 1.11 -> 1.12 -> 1.13 으로 순차적으로 업데이트해 주어야 한다.

업데이트하기

GCP의 GKE같은 Managed Kubernetes를 사용하고 있으면 딸깍 한번으로 알아서 해주겠지만, 쿠버를 직접 디플로이했다면?

Kubeadm으로 구성한 쿠버 클러스터를 업데이트하는 경우를 살펴보자.

마스터 노드 업데이트

마스터 노드에서는 기본적으로 (관리용을 제외한) Pod들이 구동되지 않으며, 마스터 노드가 내려가더라도 worker node에서 돌아가던 Pod들은 계속 일을 한다.

  • 물론 Kubectl과 쿠버 API는 먹통이 될 것이고 관리기능은 멈추겠지만, 아무튼 지금 돌아가고 있는 Pod 자체는 마스터노드가 내려가더라도 계속 돌아갈 것이다.

아무튼 마스터 노드를 내리고 쿠버를 업데이트한다.
kubeadm upgrade plan 명령어로 유용한 정보들을 볼 수 있다.

주의사항: kubeadm은 kubelet를 설치하지도 업데이트해주지도 않는다

  1. apt-get upgrade kubeadm=1.12.0-00 으로 kubeadm을 업데이트한다.
  2. kubeadm upgrade apply v1.12.0으로 kubeadm 업그레이드를 적용한다.

이러면 kube-apiserver, controller-manager, kube-scheduler, kubelet, kube-proxy가 몽땅 업데이트된다.

하지만 kubelet은 업데이트되지 않았다.

  • kubeadm 구성에서는 컨트롤 플레인 컴포넌트들을 Pod 형태로 구동시키기 위해, 마스터 노드에 kubelet을 설치하도록 되어 있다.
    • 쿠버를 수동 구성하는 경우 마스터 노드에는 kubelet이 없을 수 있다.

이제 kubelet을 업데이트한다.

  1. apt-get upgrade kubelet=1.12.0-00으로 kubelet을 업데이트한다.
  2. systemctl restart kubelet
  3. kubectl get nodes 의 결과, VERSION이 업데이트되어 보일 것이다.

워커 노드 업데이트

위에서도 언급되었듯이, 먼저 하나씩 노드를 Drain해서 그 노드에 있던 Pod들을 다른 노드로 배치한다.

그 다음 노드를 업데이트한다.

  • 클라우드 등의 가상화 환경인 경우, 신버전의 쿠버 노드 인스턴스를 생성하여 클러스터에 물린 뒤, 기존 인스턴스는 terminate할 수도 있다.

kubectl drain node-1
apt-get upgrade -y kubeadm=1.12.0-00
apt-get upgrade -y kubelet=1.12.0-00
kubeadm upgrade node config --kubelet-version v1.12.0
systemctl restart kubelet
kubelet uncordon node-1

반응형