개요

 

쿠버네티스는 몇 달에 한 번씩 소규모 릴리스를 통해 새로운 피처와 기능을 발표한다.

 

kubectl get nodes 명령어로 현재 사용중인 kubernetes 버전이 확인 가능하며 만약 새로운 버전으로 업그레이드 하고 싶다면 공식문서를 참조해야 한다. 

CKA 시험 도중에도 공식문서 참조가 가능하니 공식문서를 따라가면서 하는 것이 공부에도 용이하다. 

 

https://kubernetes.io/ko/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/

 

위 공식문서를 토대로 kubernetes 버전 1.30 -> 1.31로의 버전 업그레이드를 시도한다. 

 

버전 호환성 규칙

쿠버네티스 버전은 주 버전(major), 부 버전(minor), 패치 버전(patch)으로 구성된다. 예를 들어 v1.30.0에서는 

주가 1이고 부가 30이고 패치가 0이다. 

 

이러한 버전들 사이에는 호환성이 중요하기 떄문에 버전을 업데이트 하는 것에 있어서 제한을 가진다. 

 

가장 핵심적으로 봐야할 것은 kube-apiserver 버전이다. kube-apiserver가 쿠버네티스의 핵심 컴포넌트로, 클러스터의 상태를 관리하고 클러스터 내 모든 구성 요소가 상호작용하는 API 엔드포인트 역할을 하기 때문에 다른 구성요소들보다 높은 버전을 유지할 필요가 있다. 

 

이외에도 지켜야 할 규칙이 있다.

 

 

1. 부 버전(minor) 업그레이드는 한 단계씩만 가능하다.

 

ControlPlane 그리고 WorkerNode의 부 버전(minor version) 차이는 한 단계까지만 허용된다.

예를 들어, v1.29에서 v1.30으로는 업그레이드가 가능하지만, v1.29에서 바로 v1.31로는 업그레이드할 수 없다.

따라서 중간 버전을 건너뛰는 업그레이드는 불가능하므로, 반드시 순차적으로 한 단계씩 업그레이드해야 한다.

 

실제로 AWS EKS 또한 순차적으로 부 버전(minor)를 업그레이드하게끔 구성되어 있다.  

 

 

2. kubeadm이 가장 먼저 업그레이드되어야 한다.

 

kubeadm을 가장 먼저 업그레이드 해야 하며, 이후에 kubeletkubectl을 업그레이드 해야 한다.

앞서 얘기한 kube-apiserver나 controller-manager와 같은 핵심 컴포넌트들이 kubeadm을 업그레이드하면서 종속적으로 같이 업그레이드되기 때문에  kubeadm을 가장 먼저 업그레이드 해야 한다.

 

kubelet은 kubeadm과 같은 버전이거나 한 단계 낮은 버전만 지원한다.

예를 들어, kubeadm v1.30을 사용한다면 kubelet v1.30 또는 v1.29을 사용할 수 있다.

 

3. kubelet과 kubeadm의 버전 차이는 한 단계까지 허용한다.

 

kubeadm이 먼저 업그레이드되기 때문에, kubelet은 한 단계 이전 버전이어도 동작하지만, 반드시 이후에 kubelet도 업그레이드하여 버전을 같게 해줘야 한다.

 

4. kubectl 버전은 클러스터 버전과 일치해야 한다.

 

kubectl은 반드시 kube-apiserver 버전과 호환되어야 하며, API 서버의 버전과 동일하거나, 한 단계 상위/하위 마이너 버전일 때만 안정적으로 동작합니다.

예를 들어, API 서버가 v1.26이라면, kubectl은 v1.25, v1.26, 또는 v1.27을 사용할 수 있다.

 

 

업그레이드 전략

 

먼저 kubernetes를 업그레이드 하는 방법은 어느 환경에서 kubernetes를 사용하느냐에 따라 다르다 

 

1. CSP 

GKE (Google Kubernetes Engine), EKS (Elastic Kubernetes Service), AKS (Azure Kubernetes Service) 와 같은 CSP에서 제공하는 쿠버네티스 서비스는 자체 제공되는 관리 도구를 사용해 클러스터 업그레이드를 진행할 수 있다. 

 

2. Kubeadm

kubernetes 커뮤니티에서 직접 제공하고 관리되는 도구로 기본적으로 오픈소스이기 때문에 개인이 가장 많이 사용한다. 

따라서 Kubeadm을 이용한 업그레이드를 진행하였다.

 

Kubeadm

앞에서 얘기한 규칙대로 업그레이드를 진행한다. 

 

1. MasterNode 업그레이드

 

MasterNode가 업그레이드되는 동안 MasterNode에 떠있는 kubernetes 핵심 컴포넌트(kube-apiserver, kube-scheduler, controller-manger 등)들이 잠시 다운되게 된다. 

 

하지만 WorkerNode들에 떠있는 Service Pod들은 이에 영향을 받지 않고 정상 작동을 한다.

하지만 핵심 컴포넌트들이 죽었기에 새로운 pod들을 배포, 삭제, 수정 하는 것은 불가하고 kubectl을 통한 kubeapi-server 상호작용 또한 불가능하다. 

 

2. WorkerNode 업그레이드

 

MasterNode와 달리 WorkerNode 업그레이드에는 세 가지의 방식이 존재한다. 

 

1. 모든 WorkerNode 한번에 업그레이드

 

모든 worker node가 다운되며 업그레이드가 완료되면 node가 복원되는 동시에 deployment나 replicaset으로 배포가 되었던 pod들이 복원되기 시작한다. 

 

가장 간단하지만 client가 service에 접근하지 못한다는 단점을 가지고 있으며 node의 다운타임이 5분을 넘어간다면 모든 pod의 정보가 소실되며 그 후에는 복원되지 않는다. 

 

2. WorkerNode 한 개씩 업그레이드

 

drain 명령어를 이용하여 진행하며 업그레이드하려는 node에 존재하는 pod를 다른 WorkerNode들에게 분배해 service를 다운되지 않게끔 한다. 

 

3. 새로운 node를 생성한다. 

 

주로 클라우드에서 제공하는 kubernetes service를 쓸 떄 용이한 방법이다. 새로운 버전의 WorkerNode를 프로비저닝하고 pod를 옮긴 후 오래된 버전의 WorkerNode를 삭제한다. 

 

모든 WorkerNode에 위 방법을 적용한다. 

 

 

위의 경우들은 여러 개의 WorkerNode들이 있을 경우의 시나리오이므로 만약 WorkerNode가 한 개일 경우 MasterNode의 taint를 해제하여 WorkerNode에 있는 pod들을 일시적으로 옮겨줄 필요가 있다. 

 

업그레이드 실습 

 

1. Master Node 업그레이드

 

1) Master Node drain

 

해당 실습환경에서는 WorkerNode가 한 개이기 때문에 MasterNode의 taint가 해제되어있다. 

따라서 service pod를 계속 유지하기 위해 drain을 적용한다.

 

kubectl drain controlplane --ignore-daemonsets

 

 

2) kubeadm 패키지 버전 업그레이드

 

vim /etc/apt/sources.list.d/kubernetes.list

deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /

apt-cache madison kubeadm

apt-get install kubeadm=1.31.0-1.1

 

3) kubeadm 업그레이드 준비

 

업그레이드를 시작하기 전에 클러스터의 상태를 확인한다.

업그레이드 가능한 버전을 확인할 수 있고 또 호환성을 확인할 수 있다.

kubeadm upgrade plan v1.31.0

 

4) kubeadm 업그레이드 

 

kubeadm upgrade apply v1.31.0

 

 

5) kubelet 업그레이드 후 서비스 재시작

 

apt-get install kubelet=1.31.0-1.1

systemctl daemon-reload

systemctl restart kubelet

 

6) drain 해제

 

kubectl uncordon controlplane

 

2. Worker Node 업그레이드

0) worker node ssh 접속

 

ssh node01

 

 

1) Worker Node drain

 

service pod를 계속 유지하기 위해 drain을 적용한다.

 

kubectl drain node01 --ignore-daemonsets

 

 

2) kubeadm 패키지 버전 업그레이드

 

vim /etc/apt/sources.list.d/kubernetes.list

deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /

apt-cache madison kubeadm

apt-get install kubeadm=1.31.0-1.1

 

3) kubeadm 업그레이드 

 

kubeadm upgrade node

 

 

4) kubelet 업그레이드 후 서비스 재시작

 

apt-get install kubelet=1.31.0-1.1

systemctl daemon-reload

systemctl restart kubelet

 

5)  drain 해제

 

kubectl uncordon node01

 

 

6) 결과 확인

 

사진을 uncordon을 적용하지 않고 캡처해 SchedulingDisabled이지만 정상 작동한다.