Kubernetes Cluster Upgrade, 제대로 이해하기
본 포스팅에서는 Kubernetes 클러스터를 업그레이드하는 방법에 대해 이해하는 목표를 가집니다.
🔗 Kubernetes Series
모든 Kubernetes 시리즈를 확인하시려면 위를 참고해 주세요.
Versioning
쿠버네티스는 표준 소프트웨어 릴리스 버전 관리 절차를 따릅니다.
쿠버네티스의 첫 번째 Major 버전인 1.0
은 2015년에 발표되었고, 최근 버전은 1.30
(2024-04-17) 입니다.
Semantic Versioning
: MAJOR.MINOR.PATCH
MAJOR version
: when you make incompatible API changes
MINOR version
: when you add functionality in a backward compatible manner. features / functionalities 단위
PATCH version
: when you make backward compatible bug fixes
MINOR
버전은 몇 달마다 새로운 feature 와 functionality 출시하며
PATCH
버전은 버그를 수정하며 더 자주 업데이트합니다.
쿠버네티스는 몇 달에 한 번씩 소규모 릴리스를 통해 새로운 피처와 기능을 발표합니다.
kubectl get nodes
명령을 실행하면 설치한 쿠버네티스 클러스터를 특정 버전을 확인할 수 있습니다.
❯ kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 58d v1.29.2
node01 Ready <none> 58d v1.29.2
위에서는 1.29.2 버전을 사용하고 있다는 것을 알 수 있습니다.
위 버전 말고도, Alpha와 Beta가 릴리즈 됩니다.
|
* v1.10.0 (March 2018)
|\
| * v1.10.0-beta
| |
| |
| * v1.10.0-alpha
|/
|
모든 버그를 고치고 개선하면 먼저 alpha
태그를 부착한 Alpha를 릴리즈 합니다.
기본적으로 Alpha는 기능이 비활성화되어 있으며 버그가 존재할 수 있습니다.
그 다음 코드를 잘 테스트하면 Beta 릴리스로 넘어가고, 새 기능이 디폴트로 활성화됩니다.
그리고 마지막으로, 최종적으로 안정적인 상태를 릴리즈합니다.
페이지를 확인해보면 쿠버네티스를 tar 파일로 다운로드할 수도 있습니다.
추출해보면 해당 쿠버네티스 버전에 해당하는 컴포넌트가 존재하는데, 모든 컴포넌트가 모두 같은 버전으로 포함되어 있습니다.
Upgrade Process
쿠버네티스 Control Plane (이하 컨트롤 플레인) 컴포넌트는 각각의 버전을 갖습니다.
또한, 컴포넌트 중엔 Etcd 클러스터나 CoreDNS 같이 외부 컴포넌트 종속성을 가진 컴포넌트도 존재하며,
이 경우 자체 프로젝트의 버전을 가집니다.
이 외 컨트롤 플레인의 주요 컴포넌트 대부분 동일한 버전이겠지만,
모두 동일한 버전을 갖는 게 의무는 아니며, 개별 업그레이드를 할 수도 있습니다.
Supported versions
하지만 각 컨트롤 플레인 컴포넌트는 서로 의존하기 때문에,
개별 업데이트 시 제한을 가집니다.
먼저, kube-apiserver는 컨트롤 플레인의 주요 구성요소이면서,
다른 구성요소들과 통신하는 구성요소이기 때문에,
어떤 다른 구성요소도 kube-apiserver보다 높은 버전으로 되어 있어서는 안됩니다.
controller-manager와 kube-scheduler는 kube-apiserver 보다 한 버전까지 더 낮출 수 있습니다.
즉, kube-apiserver 버전이 X
라면
controller-manager나 kube-scheduler는 X-1
버전까지 호환 가능하며,
kubelet과 kube-proxy 는 X-2
버전까지 호환 가능합니다.
가령, kube-apiserver 버전이 v1.10
라면
controller-manager 나 kube-scheduler는 v1.9
혹은 v1.10
버전이어야 하고,
kubelet과 kube-proxy 는 v1.8
, v1.9
, v1.10
중 한 버전이어야 함
이때, kube-apiserver 는 kubectl 에 의존하기 때문에
kubectl 는kube-apiserver 보다 높은 버전인 v1.11
이나 v1.12
, v1.13
중 하나여야 합니다.
기본적으로, 쿠버네티스는 업그레이드 시 최근 세 개의 minor
버전까지만 지원합니다.
쿠버네티스가 v1.13
을 출시하면서 v1.12
, v1.11
및 v1.10
까지만 지원한다는 의미입니다.
반대로 생각해보면, 현재 버전이 v1.10
이라면, 쿠버네티스는 버전 v1.13
까지 업그레이드 할 수 있다는 말이죠.
권장하는 업데이트 방식은, 한 번에 마이너 버전 하나씩 업그레이드하는 것입니다.
❌ v1.10 → v1.13
✅️ v1.10 → v1.11 → v1.12 → v1.13
실제 AWS 에서는 단 하나의 마이너 버전만을 업그레이드하게끔 제한합니다.
Upgrade Strategy
쿠버네티스를 업그레이드 하는 방법은 어떻게 설치되어 있느냐에 따라 달라집니다.
✔️ Cloud Service: Provider
GKE (Google Kubernetes Engine), EKS (Elastic Kubernetes Service), AKS (Azure Kubernetes Service) 와 같은 클라우드 서비스는 업그레이드를 지원합니다. 따라서 아주 간편하게 버튼 클릭 만으로 업그레이드를 실행할 수 있습니다.
✔️ kubeadm
쿠버네티스 커뮤니티에서 직접 관리되는 툴로, 간편하게 클러스터를 설치하고 업그레이드를 할 수 있습니다.
아래에서 자세히 다뤄볼 예정입니다.
✔️ Manual Installation
직접 하나씩 설치해서 업그레이드 하는 방식입니다.
kubeadm
간략히 말해보자면, kubeadm을 통한 업그레이드는
kubeadm upgrade plan
와 kubeadm upgrade apply
명령어를 통해 간편하게 업그레이드 할 수 있습니다.
지금부터 한 클러스터를 업그레이드 한다고 가정해봅시다.
production 환경에 클러스터가 있고, 클러스터의 major 버전을 두 번 업그레이드 해야 합니다.
이 클러스터는 master node(이하 마스터 노드) 와 worker node(이하 워커 노드)를 가지고 있습니다.
Master 🟠🔴 🟠🟡 🟡🟢
Node Node 1 Node 2 Node 3
v1.10 v1.10 v1.10 v1.10
클러스터 업그레이드는 크게 두 가지 단계로 이루어집니다.
1. 마스터 노드 업그레이드
2. 워커 노드 업그레이드
#1. Upgrading Master Node
먼저, 마스터 노드를 업그레이드 합니다.
Master 🟠🔴 🟠🟡 🟡🟢
Node Node 1 Node 2 Node 3
v1.10 🔃 v1.10 v1.10 v1.10
마스터 노드가 업그레이드되는 동안 컨트롤 플레인의 컴포넌트가 잠시 다운됩니다.
kube-apiserver, kube-scheduler, kube-controller-manager 등
하지만, 마스터 노드가 다운된다고 해서 클러스터 내의 워커 노드와 앱이 영향을 받는 건 아닙니다.
워커 노드에 호스트된 모든 작업은 평소처럼 사용자들에게 제공됩니다.
다만, 마스터가 다운됐으니 관리 기능도 다운됩니다.
kube-controller-manager
도 작동 하지 않기 때문에,
kubectl이나 다른 쿠버네티스 API를 통해 클러스터에 액세스할 수 없습니다.
즉, 새 앱을 배포하거나 기존 앱을 삭제, 수정할 수 없습니다.
결론적으로, Pod가 고장 나면 새 포드가 자동으로 생성되지 않겠지만,
노드와 포드가 작동하는한 앱은 실행되고 사용자는 영향을 받지 않습니다.
업그레이드가 완료되면 클러스터가 백업되고 이후 정상 작동합니다.
Master 🟠🔴 🟠🟡 🟡🟢
Node Node 1 Node 2 Node 3
v1.11 v1.10 v1.10 v1.10
마스터 노드의 버전이 v1.11
로 업데이트 되었습니다.
이제, 워커 노드를 업그레이드할 차례입니다.
#2. Upgrade Worker Node
워커 노드는 세 가지의 다양한 업그레이트 방식이 있습니다.
✔️ Strategy 1. Upgrade All of Them At Once
첫 번째는 한번에 모두 업그레이드합니다.
Master 🟠🔴 🟠🟡 🟡🟢
Node Node 1 Node 2 Node 3
v1.11 v1.10 🔃 v1.10 🔃 v1.10 🔃
업그레이드가 완료되면 노드가 백업되고, 새 Pod가 스케줄링 된 후 사용자가 다시 접근할 수 있습니다.
하지만 Pod가 한번에 모두 다운되는 다운타임을 발생시키는 전략입니다.
잠시동안 사용자가 앱에 접속할 수 없습니다.
✔️ Strategy 2. Upgrade One Node At a Time
두 번째 전략은, 한 번에 노드 하나씩 업그레이드합니다.
Master 🟠🟡 + 🔴 🟡🟢 + 🟠
Node Node 1 Node 2 Node 3
v1.11 v1.10 🔃 v1.10 v1.10
첫 번째 노드를 업그레이드 할 때, Pod가 두 번째와 세 번째 노드로 이동합니다.
첫 번째 노드가 업그레이드 된 후, 두 번째 노드를 업데이트합니다.
Master 🟠🟡🟢 🟡🔴🟠
Node Node 1 Node 2 Node 3
v1.11 v1.11 v1.10 v1.10
첫 번째와 세 번째 노드로 Pod가 이동합니다.
마지막으로, 세 번째 노드가 업데이트 될 때, 이전과 마찬가지로 다른 노드로 Pod가 이동합니다.
✔️ Strategy 3. Add New Nodes to the Cluster
세 번째 전략은 클러스터에 새로운 소프트웨어 버전을 가진 노드를 추가합니다.
Master 🟠🔴 🟠🟡 🟡🟢
Node Node 1 Node 2 Node 3 Node 4
v1.11 v1.10 v1.10 v1.10 v1.11
Pod을 새 노드로 옮기고 옛 노드를 제거합니다.
Master 🟠🟡 🟡🟢 🟠🔴
NodeNode 1Node 2 Node 3 Node 4
v1.11v1.10v1.10 v1.10 v1.11
해당 방식은 클라우드 환경에서 특히 편리합니다.
새 노드를 프로비전하고 오래된 걸 해체할 수 있기 때문입니다.
새 소프트웨어 버전의 노드로 모두 교체될 때까지 진행합니다.
Hands-on Upgrade
kubeadm
에는 클러스터 업그레이드를 돕는 명령이 있습니다.
kubeadm upgrade plan
명령을 실행하면 많은 정보를 얻을 수 있습니다.
❯ kubeadm upgrade plan
...
[upgrade/versions] Cluster version: v1.28.0
[upgrade/versions] kubeadm version: v1.28.0
...
COMPONENT CURRENT TARGET
kubelet 2 x v1.28.0 v1.28.9
Upgrade to the latest version in the v1.28 series:
COMPONENT CURRENT TARGET
kube-apiserver v1.28.0 v1.28.9
kube-controller-manager v1.28.0 v1.28.9
kube-scheduler v1.28.0 v1.28.9
kube-proxy v1.28.0 v1.28.9
CoreDNS v1.10.1 v1.10.1
etcd 3.5.9-0 3.5.9-0
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.28.9
Note: Before you can perform this upgrade, you have to update kubeadm to v1.28.9.
...
현재 클러스터 버전, kubeadm 버전, 모든 컨트롤 플레인 컴포넌트의 각 버전,
또 Target Version (업데이트 가능한 어떤 버전) 보여줍니다.
⚠️ 단, kubeadm은 kubelet을 업데이트 시키지 않습니다.
1. upgrade kubeadm
먼저, 클러스터를 업데이트하려면 kubeadm 툴 자체를 업그레이드 해야합니다.
kubeadm 업데이트를 진행합니다.
❯ apt-get upgrade -y kubeadm=1.12.0-00
...
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.12.0". Enjoy!
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
-y
option: Automatic yes to prompts; assume "yes" as answer to all prompts and run non-interactively.
kubeadm 버전을 v1.11.0
에서 v1.12.0
으로 업그레이드합니다.
이후 클러스터를 해당 커맨드를 통해 업그레이드합니다.
❯ kubeadm upgrade apply v1.12.0
명령이 완료되면 컨트롤 플레인의 구성요소는 1.12로 변경됩니다.
하지만, kubectl get nodes
명령어로 확인해보면, 아직 버전이 1.11이 것을 볼 수 있습니다.
이유는 API 서버 자체의 버전이 아니라 API 서버에 등록된 각 노드들의 kubelet 버전을 보여주기 때문입니다.
2. upgrade kubelet
다음 단계는 마스터 노드에 있는 kubelet 업그레이드합니다.
여러분의 setup에 따라 마스터 노드에서 kubelet이 실행될 수도 아닐 수도 있습니다.
이 경우 kubeadm과 함께 배포된 클러스터는 마스터 노드에 kubelet가 있는데, 컨트롤 플레인 컴포넌트를 실행하는 데 사용됩니다.
apt-get 업그레이드 kubelet 명령을 실행합니다.
❯ apt-get upgrade -y kubelet=1.12.0-00
패키지가 업그레이드 되고 난 후, kubelet 서비스를 다시 시작합니다.
❯ systemctl restart kubelet
kubectl get nodes
명령을 실행하면 마스터가 v1.12.0
로 업그레이드 됩니다.
❯ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready master 1d
node-1 Ready <none> 1d v1.11.3
node-2 Ready <none> 1d v1.11.3
3. upgrade worker nodes
다음 단계는 워커 노드 업그레이드합니다.
한 노드 씩 작업을 위해 Pod를 이동시켜야 합니다.
kubectl drain
명령어로 노드에서 모든 Pod를 안전하게 종료하 다른 노드의 일정을 재조정할 수 있습니다.
❯ kubectl drain node-1
그 다음, 워커 노드에서 kubeadm
과 kubelet
패키지 업그레이드합니다.
❯ apt-get upgrade -y kubeadm=1.12.0-00
❯ apt-get upgrade -y kubealet=1.12.0-00
❯ kubeadm upgrade node config --kubelet-version v1.12.0
❯ systemctl restart kubelet
그런 다음 kubeadm 도구 업그레이드 명령을 이용해 새 kubelet 버전을 위해 노드 구성을 업데이트합니다.
이후 kubelet 서비스 다시 시작합니다.
이제 노드는 새 소프트웨어 버전(v1.12)과 함께 재생성 됩니다.
하지만 노드에 Pod를 없앨 때 Unscheduleable
표시를 했는데요.
kubectl uncordon
명령어를 통해 다시 스케줄링 가능한 상태로 변경해야합니다.
❯ kubectl uncordon node-1
하지만 이는 단지 Schedule 가능하다는 표시를 한 거지,
Pod가 이 노드로 바로 돌아온다는 걸 의미하진 않습니다.
이렇게 모든 노드를 업그레이드 하면 업그레이드가 끝납니다.
그럼 여기까지, 쿠버네티스 업그레이드 방법에 대해 알아보았습니다.
| Reference |
🔗 Kubernetes.io - Official Docs
🔗 Udemy: certified-kubernetes-administrator-with-practice-tests