[기술검증] 물리 서버는 그대로, Kubernetes는 새 버전으로: Cluster API In-place Upgrade

Tech Story/DevOps & Container

[기술검증] 물리 서버는 그대로, Kubernetes는 새 버전으로: Cluster API In-place Upgrade

 
Tech-Frontier.md kt cloud
$ whoami --team
kt cloud Cloud플랫폼팀 정성훈
📋 요약 TL;DR
이 글에서는 물리 서버 기반 Kubernetes 클러스터에서
Cluster API와 BYOH Provider를 활용한 In-place Upgrade 구현과 검증 과정을 다룹니다.

제한된 인프라 환경에서 업그레이드 전략을 선택하고 운영 안정성을 높이는 방향을 정리합니다.

#Kubernetes #ClusterAPI #InPlaceUpgrade #BYOHProvider #BareMetalKubernetes

Kubernetes 클러스터는 한 번 설치하고 끝나는 시스템이 아닙니다. 운영을 시작하면 노드 증설, 버전 업그레이드, 장애 복구, 설정 표준화 같은 작업이 반복됩니다. 클러스터가 여러 개로 늘어나면 문제의 중심도 “어떻게 설치할 것인가”에서 “생성부터 변경, 업그레이드, 삭제까지 어떻게 같은 방식으로 관리할 것인가”로 이동합니다.

 

특히 이미 준비된 물리 서버를 장기간 사용하는 환경에서는 클라우드 VM과 다른 제약을 고려해야 합니다. 새 인스턴스를 필요할 때마다 만들고 없앨 수 없고, 업그레이드를 위해 여분의 Host를 상시 확보하기도 어렵습니다. 이번 글에서는 이러한 환경에서 Cluster API와 BYOH Provider를 선택한 배경, 실제 운영 과정에서 발견한 두 가지 기술적 과제, 그리고 Rolling Upgrade와 공존하면서 Control Plane과 Worker Node 모두에 적용할 수 있는 In-place Upgrade를 구현하고 검증한 과정을 소개합니다.


1. 설치 자동화보다 클러스터 생명주기 관리가 필요했다

물리 서버 위에서 용도별 Kubernetes 클러스터를 여러 개 운영하려면 세 가지 조건이 필요했습니다. 첫째, 클러스터마다 설치 방식이 달라지지 않아야 했습니다. 둘째, 변경 이력과 목표 상태를 코드로 관리할 수 있어야 했습니다. 셋째, 생성·확장·업그레이드·삭제를 반복 가능한 절차로 자동화해야 했습니다.

 

Kubernetes를 구성하는 대표적인 방법을 이 관점에서 비교하면 차이가 분명해집니다.

구분 kubeadm Kubespray Cluster API
중심 역할 Kubernetes 기본 구성 Ansible 기반 반복 설치 클러스터 생명주기 관리
운영 방식 명령 중심 Playbook 중심 선언형 리소스와 Controller 중심
강점 단순하고 표준적 온프레미스 설치 자동화에 유리 생성·확장·업그레이드·삭제를 일관되게 관리
적합한 상황 테스트, 기본 구성 동일 구성의 반복 설치 여러 클러스터의 장기 운영과 GitOps 연계

 

kubeadm과 Kubespray도 충분히 유용한 도구입니다. 다만 우리가 해결하려던 문제는 “클러스터를 한 번 잘 설치하는 것”이 아니라, 시간이 지나도 여러 클러스터의 원하는 상태를 지속적으로 맞추는 것이었습니다. 이 때문에 Kubernetes 리소스를 다루듯 Cluster, Machine, Control Plane, Bootstrap, Infrastructure 리소스를 선언하고 Controller가 실제 상태를 조정하는 Cluster API를 선택했습니다.

 

Cluster API의 장점은 운영자가 명령을 정해진 순서로 실행하는 대신 “원하는 클러스터 상태”를 선언할 수 있다는 점입니다. 버전 변경도 YAML의 목표 상태로 남고, 변경 이력은 GitOps 흐름에서 추적할 수 있습니다. 운영 절차가 개인의 숙련도보다 코드와 Controller의 조정 로직에 가까워지는 것입니다.


2. 이미 준비된 물리 서버에는 BYOH가 더 적합했다

Cluster API를 사용하려면 실제 인프라를 다루는 Infrastructure Provider를 선택해야 합니다. Bare Metal 환경에서는 Metal3처럼 전원 제어, PXE 부팅, OS 배포까지 자동화하는 방식이 강력합니다. 하지만 대상 서버의 OS와 네트워크가 이미 준비되어 있고, 목표가 서버 프로비저닝이 아니라 기존 Host를 Kubernetes 노드로 편입하는 것이라면 BMC·PXE·Ironic 계층을 추가로 운영하는 비용이 커질 수 있습니다.

 

BYOH(Bring Your Own Host) Provider는 준비된 Linux Host에 Agent를 설치하고 해당 Host를 Cluster API 관리 대상으로 연결합니다. Management Cluster에는 Cluster API와 BYOH Provider의 Controller가 동작하고, 운영자는 클러스터 상태를 YAML로 선언합니다. 각 Host의 Agent는 Controller의 요청을 받아 필요한 작업을 수행합니다. 이 구조는 물리 서버 준비 절차와 Kubernetes 클러스터 생명주기 관리를 분리하면서도, 기존 자산을 그대로 활용할 수 있다는 점에서 목적에 잘 맞았습니다.


3. 운영 과정에서 드러난 두 가지 한계

Cluster API와 BYOH 조합은 기본 방향에 적합했지만, 장기 운영을 위해서는 두 가지 과제를 해결해야 했습니다.

3-1. API Version 전환은 문자열 변경이 아니었다

사용 중인 BYOH Provider는 기존 Cluster API의 v1beta1 계약을 기준으로 구현되어 있었습니다. 이를 v1beta2 흐름에 맞추려면 매니페스트의 apiVersion만 바꾸는 것으로는 충분하지 않았습니다. CRD 스키마와 API Type, Condition 표현, Controller 로직, Webhook 변환, 테스트 구조까지 Provider 전반을 함께 정비해야 했습니다.

 

동시에 기존 리소스를 사용하는 클러스터가 중단되지 않아야 했습니다. 그래서 신규 리소스는 v1beta2 기반으로 처리하면서도 기존 v1beta1 리소스를 읽고 유지할 수 있도록 호환성을 함께 고려했습니다. Provider와 BYOH Agent를 업그레이드한 뒤에도 기존 Host·Machine 리소스가 유지되는지 확인했고, API Version별 조회와 변환 흐름도 점검했습니다.

 

이 작업의 의미는 단순한 버전 추종에 있지 않습니다. Provider가 최신 Cluster API 계약 위에서 계속 확장될 수 있는 기반을 마련해야 이후의 업그레이드 기능도 안정적으로 구현할 수 있기 때문입니다.

3-2. Rolling Upgrade는 안전하지만, 고정된 물리 자원에서는 비쌌다

Cluster API의 일반적인 업그레이드는 새 Machine을 만든 뒤 기존 Machine을 제거하는 Rolling Upgrade 방식입니다. 새 노드를 먼저 구성하고 검증한 후 기존 노드를 내릴 수 있어 절차가 예측 가능하고, 문제가 생기면 기존 노드를 유지하는 전략도 세우기 쉽습니다. 새 VM을 빠르게 생성할 수 있는 클라우드 환경에서는 자연스러운 선택입니다.

 

반면 물리 서버 수가 고정된 환경에서는 같은 방식이 다른 비용을 만듭니다. 새 노드를 만들 여분의 Host가 필요하고, 기존 서버를 다시 편입하는 절차가 복잡해지며, 전체 업그레이드 시간도 길어집니다. 운영자가 실제로 원하는 것은 “서버와 노드 정체성은 유지하고 Kubernetes 버전만 올리는 것”인 경우가 많았습니다.

 

여기서 중요한 점은 Rolling Upgrade가 잘못된 방식이라는 뜻이 아니라는 것입니다. 안정성과 복구 용이성이 중요한 환경에서는 여전히 좋은 기본값입니다. 다만 인프라의 교체 가능성과 여유 자원에 따라 다른 실행 전략도 선택할 수 있어야 했습니다.


4. Rolling을 없애지 않고 In-place를 선택지로 추가하다

In-place Upgrade는 기존 노드를 삭제하고 새로 만드는 대신, 현재 사용 중인 Host와 Machine 위에서 Kubernetes 구성요소를 직접 업그레이드하는 방식입니다. Host, Machine, Node 이름을 유지할 수 있고 추가 Host를 요구하지 않는다는 점이 BYOH와 Bare Metal 환경에 적합합니다.

 

다만 자원을 아끼는 대신 제어 로직의 책임은 커집니다. 어떤 변경을 In-place로 처리할 수 있는지 판단해야 하고, 실행 전 상태를 점검해야 하며, 실패했을 때 중단·재시도·수동 개입 중 어떤 정책을 적용할지 정해야 합니다. 진행 상태도 Condition, Event, Log로 충분히 관찰할 수 있어야 합니다.

 

이번 고도화에서는 모든 업그레이드를 In-place로 강제하지 않았습니다. 버전 변경이 In-place 적용 범위에 들어오면 Controller와 BYOH Agent가 기존 Machine에서 역할별 업그레이드 흐름을 실행하고, Condition·Event·Log로 진행 상태를 반영합니다. Worker Node는 노드 구성요소 갱신 흐름을 따르고, Control Plane은 API Server와 etcd 상태, 노드별 업그레이드 순서를 고려한 별도 조정 흐름을 사용합니다. 반대로 Host 교체가 필요하거나 안전하게 직접 변경하기 어려운 항목은 기존 Rolling 흐름을 유지합니다. 핵심은 Rolling을 대체하는 것이 아니라, 변경 유형과 인프라 제약에 맞춰 실행 전략을 선택할 수 있도록 확장하는 것입니다.

[기술검증] 물리 서버는 그대로, Kubernetes는 새 버전으로: Cluster API In-place Upgrade
그림 1. Rolling 또는 In-place 전략


5. Control Plane·Worker Node In-place Upgrade 구현·검증

In-place Upgrade는 기존 노드를 직접 변경하기 때문에 기능 구현만큼 안전장치와 관찰 가능성이 중요했습니다. 먼저 In-place로 처리할 수 있는 변경 범위와 판단 기준, 실패 처리 정책, Machine·ByoMachine의 상태 표현 방식을 공통으로 정의했습니다. 그 위에 Worker Node의 구성요소 갱신 흐름과 Control Plane의 API Server·etcd 상태 확인 및 노드별 순서 제어 흐름을 역할별로 구현했습니다. BYOH Agent가 각 노드에서 필요한 kubeadm 기반 작업을 실행하고, Controller가 전체 진행 상태를 조정·관찰하도록 구성했습니다.

 

구현 후에는 Rolling과 In-place 동작 비교, 실패 시나리오, 다중 노드 환경, 역할별 kubeadm 기반 버전 전환을 포함한 검증을 수행했습니다. 검증 결과 기존 Host·Machine·Node를 유지한 상태에서 Control Plane과 Worker Node의 버전을 갱신할 수 있었고, 추가 Host 없이 업그레이드가 진행되며, 성공·실패 상태가 관리 리소스와 로그를 통해 추적되는 것을 확인했습니다. Control Plane은 노드별 진행 순서와 API Server·etcd 상태를 확인하면서 전환하고, Worker Node는 정의한 정책에 따라 순차적으로 갱신되는 흐름도 점검했습니다. 또한 In-place 대상이 아닌 변경은 기존 Rolling 방식으로 처리할 수 있도록 두 전략의 공존 구조를 확인했습니다.

 

현재 API Version 대응은 v1beta2 지원과 기존 v1beta1 호환성 확보까지 완료했고, Control Plane과 Worker Node In-place Upgrade도 구현과 검증을 마쳤습니다. 따라서 이 기능은 더 이상 PoC나 일부 노드만을 대상으로 한 검증 과제가 아니라, 클러스터의 주요 역할 전체에서 동작을 확인한 업그레이드 선택지입니다. 현재의 초점은 기능 가능성 확인이 아니라 운영 환경별 적용 범위, 유지보수 절차, 실패 대응 정책을 표준화하는 단계로 이동했습니다.


6. 이번 과정에서 얻은 세 가지 인사이트

첫째, Provider 호환성은 기능 개발보다 먼저 해결해야 하는 기반 작업입니다. API 계약, 상태 표현, 변환 Webhook이 정리되지 않으면 그 위에 추가한 기능도 다음 버전 변화에서 다시 흔들릴 수 있습니다.

 

둘째, In-place Upgrade는 역할별 안전 정책이 핵심입니다. Worker Node와 달리 Control Plane은 API Server 가용성, etcd 상태, 업그레이드 순서를 함께 고려해야 합니다. 실제 구현과 검증에서도 하나의 공통 명령으로 처리하기보다 역할별 실행 흐름을 분리하고, Condition·Event·Log로 진행 상태와 실패 지점을 확인할 수 있게 만드는 일이 기능의 안정성을 좌우했습니다.

 

셋째, 업그레이드 전략은 오케스트레이션 도구만이 아니라 인프라의 성격에 맞춰 선택해야 합니다. 교체가 쉬운 VM 환경과 고정된 물리 서버 환경에 동일한 전략만 적용하면 어느 한쪽에서는 불필요한 비용이 발생합니다. 선언형 관리 모델은 유지하되, 실제 실행 방식은 인프라 특성에 맞게 확장하는 것이 중요합니다.


마무리

Cluster API의 가치는 클러스터를 만드는 데서 끝나지 않습니다. 생성, 변경, 업그레이드, 삭제를 하나의 선언형 운영 모델로 연결할 때 비로소 여러 클러스터를 일관되게 관리할 수 있습니다.

 

이번 고도화로 v1beta2 기반의 Provider 확장 기반을 정비하고, Control Plane과 Worker Node In-place Upgrade의 구현과 검증을 완료했습니다. 기존 Host·Machine·Node를 유지하면서 추가 Host 없이 클러스터 주요 구성요소의 버전을 갱신하는 흐름과 상태 추적 구조를 확인했으며, Rolling Upgrade도 그대로 남겨 환경과 변경 위험도에 따라 전략을 선택할 수 있게 했습니다. 앞으로의 과제는 기능 자체의 구현·검증이 아니라 운영 적용 체계를 정교화하는 것입니다. 파일럿 적용, 운영 절차 문서화, GitOps 정책과 장애 대응 가이드 정비를 통해 적용 범위를 단계적으로 넓혀갈 계획입니다.

 

 

kt cloud 클라우드 플랫폼 서비스 바로가기 배너

?› 자주 묻는 질문 FAQ

Q. In-place Upgrade가 Rolling Upgrade보다 항상 더 좋은가요?
A. 아닙니다. 새 VM이나 Host를 쉽게 확보할 수 있고 교체를 통한 격리가 중요한 환경에서는 Rolling Upgrade가 더 단순하고 안전한 선택일 수 있습니다. In-place Upgrade는 추가 자원이 제한적이거나 Host와 Node 정체성을 유지해야 하는 환경에서 장점이 큽니다. 변경 범위, 실패 복구 방식, 서비스 가용성 요구사항을 기준으로 두 전략을 선택해야 합니다.
Q. In-place Upgrade가 실패하면 자동으로 이전 버전으로 돌아가나요?
A. 직접 업그레이드는 모든 변경을 자동으로 이전 버전으로 되돌리는 구조는 아닙니다. 이번 구현에서는 Condition·Event·Log로 단계별 상태를 기록하고 실패 시나리오 검증을 완료해, 실패 지점과 후속 조치를 식별할 수 있도록 했습니다. 실제 운영에서는 재시도 가능 조건과 수동 복구 절차를 함께 준비해야 합니다.
Q. Control Plane도 같은 방식으로 업그레이드할 수 있나요?
A. 가능합니다. 이번 고도화에서는 Worker Node뿐 아니라 Control Plane도 기존 Host·Machine·Node를 유지한 채 In-place 방식으로 업그레이드하도록 구현하고 검증했습니다. 다만 두 역할의 실행 절차는 동일하지 않습니다. Control Plane은 API Server와 etcd 상태, 노드별 업그레이드 순서를 고려한 별도 조정 로직을 사용하고, Worker Node는 노드 구성요소 갱신 정책에 따라 진행합니다. 공통점은 추가 Host 없이 업그레이드하며 상태를 Condition·Event·Log로 추적한다는 점입니다.
Q. 기존 v1beta1 리소스는 v1beta2 전환 과정에서 다시 만들어야 하나요?
A. 기존 리소스를 일괄 재생성하지 않는 것을 목표로 호환 구조를 설계했습니다. CRD와 API Type을 정비하고 변환 Webhook과 Controller 로직을 함께 수정해, 신규 v1beta2 리소스를 지원하면서 기존 v1beta1 리소스도 유지·조회할 수 있도록 검증했습니다. 실제 적용 전에는 각 환경의 CRD 백업, 변환 테스트, 롤백 절차를 별도로 준비하는 것이 안전합니다.