K8s 1.14->1.15 업그레이드 가이드
1. 원활한 마이너 버전 판올림의 필요성
빅데이터 플랫폼과 마이크로서비스 아키텍처는 대부분 사내(On-premise) 혹은 폐쇄망 환경의 베어메탈 서버 위에 구축된 쿠버네티스(K8s) 클러스터에서 동작했습니다. 퍼블릭 클라우드(EKS, GKE)처럼 마우스 클릭 한 번으로 컨트롤 플레인이 업그레이드되는 환경이 아니었기 때문에, K8s 마이너 버전이 릴리즈될 때마다 우리가 직접 수동으로 호스트 OS(Ubuntu) 패키지 단위부터 노드별 무중단 롤링 업그레이드를 수행해야만 했습니다. 1.14.x 버전에서 1.15.x 버전으로 올라가면서 팀 내 스탠다드로 정립했던 업그레이드 절차를 기록합니다.
2. Drain과 Cordon의 차이
kubeadm을 이용한 업그레이드의 핵심 사상은 다음과 같습니다.
- Control Plane (Master Node) 먼저: 뇌에 해당하는 마스터 컴포넌트를 먼저 신버전으로 올립니다.
- Worker Node 나중에: 워커 노드들은 순차적으로
cordon(스케줄링 중지) 및drain(파드 대피) 등의 과정을 섞어가며 진행할 수도 있고, 개발계라면 단순히 패키지를 올려 반영할 수 있습니다. - 버전 고정 (hold): OS 패키지 매니저(apt)가 임의로 쿠버네티스 컴포넌트를 단독 업데이트하지 못하도록 반드시
apt-mark hold로 버전을 고정해두어야 의존성 깨짐(Crash)을 막을 수 있습니다.
3. Control Plane 및 Worker 노드 업그레이드 및 구현
1. 마스터 노드 (Control Plane) 업그레이드
마스터 노드에 접속하여 가장 먼저 클러스터 관리 도구인 kubeadm 자체를 1.15.4로 업그레이드합니다.
# 1. Kubeadm 패키지의 잠금을 풀고 업데이트
$ sudo apt-cache policy kubeadm
$ sudo apt-mark unhold kubeadm
$ sudo apt-get update
$ sudo apt-get install -y kubeadm=1.15.4-00
$ sudo apt-mark hold kubeadm
# 버전 확인
$ kubeadm versionkubeadm이 신버전이 되었다면, 실제 클러스터 컴포넌트(apiserver, controller-manager, scheduler 등)를 어떻게 올릴지 플랜을 점검하고 적용합니다.
# 2. 업그레이드 플랜 검증 및 실제 적용
$ sudo kubeadm upgrade plan
$ sudo kubeadm upgrade apply v1.15.4
# 3. Kubelet 및 Kubectl 런타임 업그레이드 후 데몬 재시작
$ sudo apt-mark unhold kubelet kubectl
$ sudo apt-get update
$ sudo apt-get install -y kubelet=1.15.4-00 kubectl=1.15.4-00
$ sudo apt-mark hold kubelet kubectl
$ sudo systemctl restart kubelet2. 워커 노드 (Worker Node) 업그레이드
마스터가 정상적으로 1.15 버전으로 올라왔다면, 데이터를 서빙하는 실제 워커 노드들을 하나씩 작업합니다.
# 1. 워커 노드의 kubeadm 업그레이드
$ sudo apt-mark unhold kubeadm
$ sudo apt-get update
$ sudo apt-get install -y kubeadm=1.15.4-00
$ sudo apt-mark hold kubeadm
# 2. 노드 스펙 업그레이드 명령
$ sudo kubeadm upgrade node
# 3. Kubelet 및 Kubectl 업그레이드 후 데몬 재시작
$ sudo apt-mark unhold kubelet kubectl
$ sudo apt-get update
$ sudo apt-get install -y kubelet=1.15.4-00 kubectl=1.15.4-00
$ sudo apt-mark hold kubelet kubectl
$ sudo systemctl restart kubelet4. 무중단 롤아웃 결과
1.14에서 1.15로 넘어가는 과정은 비교적 큰 장애나 호환성 문제 없이 스무스하게 넘어갈 수 있었습니다. 하지만 이와 같은 수동 작업의 반복은 “이걸 과연 프로덕션 환경에서 수십 개의 노드를 상대로 무장애 롤링 업데이트로 해낼 수 있을까?”에 대한 깊은 고민을 안겨주었습니다. 이후 Ansible을 적극 도입해 위 명령어 세트 전체를 플레이북(Playbook)화하여 자동화를 이룩해나갔던 기억이 납니다.