Kubernetes v1.36: 혼합 버전 프록시, 베타 단계로 진입
Source: Kubernetes Blog
Kubernetes 1.28에서 우리는 Mixed Version Proxy (MVP)를 알파 기능(Feature Gate UnknownVersionInteroperabilityProxy 아래)으로 소개했습니다. 목표는 간단하지만 중요했습니다: 오래된 API 서버가 아직 알지 못하는 리소스에 대한 요청을 잘못된 404 Not Found 대신 새로운 피어 API 서버로 올바르게 라우팅하여 클러스터 업그레이드를 보다 안전하게 만드는 것이었습니다.
우리는 Mixed Version Proxy가 Kubernetes 1.36에서 베타로 전환되고 기본적으로 활성화된다는 소식을 전하게 되어 기쁩니다! 초기 릴리스 이후 기능이 크게 발전했으며, 주요 결함을 보완하고 아키텍처를 현대화했습니다.
아래에서는 기능이 어떻게 진화했는지, 그리고 클러스터에서 이를 활용하기 위해 알아야 할 사항을 정리했습니다.
어떤 문제를 해결하고 있나요?
업그레이드 중인 고가용성 컨트롤 플레인에서는 서로 다른 버전의 API 서버가 동시에 실행됩니다. 각 서버는 서로 다른 API 그룹·버전·리소스를 제공할 수 있습니다.
MVP가 없으면, 클라이언트 요청이 해당 리소스를 제공하지 못하는 API 서버에 도달했을 때(예: 업그레이드 중에 새로 도입된 API 버전) 그 서버는 404 Not Found를 반환합니다. 이는 클러스터에 해당 리소스가 존재하지만 현재 서버에서는 제공하지 못한다는 점에서 기술적으로 잘못된 응답이며, 잘못된 가비지 컬렉션이나 네임스페이스 삭제 차단과 같은 심각한 부작용을 초래할 수 있습니다.
MVP는 이러한 요청을 해당 리소스를 제공할 수 있는 피어 API 서버로 프록시함으로써 문제를 해결합니다.
sequenceDiagram
participant Client
participant API_Server_A
participant API_Server_B
Client->>API_Server_A: 1. Resource 요청 (예: v2)
Note over API_Server_A: 로컬에서 제공 불가 판단
API_Server_A->>API_Server_A: 2. Discovery Cache에서 가능한 피어 조회
API_Server_A->>API_Server_B: 3. 요청 프록시 (x-kubernetes-peer-proxied 헤더 추가)
API_Server_B->>API_Server_B: 4. 로컬에서 요청 처리
API_Server_B-->>API_Server_A: 5. 응답 반환
API_Server_A-->>Client: 6. 응답 전달
JavaScript가 활성화되어 있어야 이 내용을 볼 수 있습니다.
1.28 이후 어떻게 진화했나요?
알파 구현은 훌륭한 개념 증명이었지만 몇 가지 제한점이 있었고 오래된 메커니즘에 의존했습니다. 베타를 위해 다음과 같이 현대화했습니다.
StorageVersion API에서 Aggregated Discovery로 전환
알파 버전에서는 API 서버가 어떤 피어가 어떤 리소스를 제공하는지 파악하기 위해 StorageVersion API에 의존했습니다. 이 방식은 기능적으로는 동작했지만 CRD와 Aggregated API에 아직 지원되지 않는다는 큰 한계가 있었습니다.
베타에서는 StorageVersion API 호출 대신 Aggregated Discovery를 사용합니다. 이제 API 서버는 집계된 discovery 데이터를 통해 피어의 역량을 동적으로 파악합니다.
빠진 조각: Peer‑Aggregated Discovery
1.28 블로그에서는 리소스 요청은 프록시할 수 있었지만, discovery 요청은 여전히 로컬 API 서버가 알고 있는 내용만 보여준다는 큰 격차가 있었습니다.
1.36에서는 Peer‑Aggregated Discovery를 추가했습니다! 클라이언트가 discovery(예: 사용 가능한 API 목록 조회)를 수행하면, API 서버는 로컬 뷰와 모든 활성 피어의 discovery 데이터를 병합합니다. 이를 통해 클라이언트는 어느 API 서버에 연결했든 전체 클러스터에서 사용 가능한 모든 API를 하나의 통합된 뷰로 얻을 수 있습니다.
sequenceDiagram
participant Client
participant API_Server_A
participant API_Server_B
Client->>API_Server_A: 1. Discovery Document 요청
API_Server_A->>API_Server_A: 2. 로컬 API 획득
API_Server_A->>API_Server_B: 3. 피어 API 획득 (캐시 또는 직접)
API_Server_A->>API_Server_A: 4. 리스트를 결정적으로 병합·정렬
API_Server_A-->>Client: 5. 통합 Discovery Document 반환
JavaScript가 활성화되어 있어야 이 내용을 볼 수 있습니다.
Peer‑Aggregated Discovery는 기본 동작이 됩니다(--peer-ca-file 플래그가 설정된 경우에만 활성화되며, 설정되지 않으면 서버는 로컬 API만 표시합니다). 그러나 특정 API 서버가 제공하는 리소스만 확인하고 싶을 때도 있습니다. 이 경우 요청의 Accept 헤더에 profile=nopeer 파라미터를 포함하면 비집계 뷰를 얻을 수 있습니다. 예시:
Accept: application/json;g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList;profile=nopeer
필수 설정
Feature Gate는 기본적으로 활성화되지만, 피어 API 서버 간의 안전한 통신을 위해 몇 가지 플래그를 반드시 설정해야 합니다. 올바르게 동작하려면 API 서버에 다음 플래그를 지정하십시오:
-
--feature-gates=UnknownVersionInteroperabilityProxy=true
1.36에서는 기본값이지만, 확인 차원에서 명시해 두는 것이 좋습니다. -
--peer-ca-file=[중요]
피어 API 서버의 서빙 인증서를 검증하기 위한 CA 번들을 지정합니다. 이 플래그가 없으면 TLS 검증 오류로 프록시가 실패합니다. -
--peer-advertise-ip와--peer-advertise-port
피어가 이 API 서버에 접근할 때 사용할 네트워크 주소를 설정합니다. 지정하지 않으면--advertise-address혹은--bind-address값이 사용됩니다. 내부 인터페이스를 통해 통신하는 복잡한 네트워크 토폴로지가 있다면 명시적으로 설정하는 것을 강력히 권장합니다.
kubeadm으로 설정하기
클러스터를 kubeadm으로 관리한다면 ClusterConfiguration 파일에 다음과 같이 플래그를 추가할 수 있습니다:
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
apiServer:
extraArgs:
peer-ca-file: "/etc/kubernetes/pki/ca.crt"
# 필요 시 peer-advertise-ip 와 peer-advertise-port 도 추가
행동 권고
멀티‑마스터 클러스터를 운영하고 정기적으로 업그레이드한다면 Mixed Version Proxy는 큰 안전성 향상을 제공합니다. 1.36에서 기본값이 되므로 다음을 권장합니다:
--peer-ca-file플래그가 올바르게 설정되었는지 확인하세요.- 1.36 업그레이드를 준비하면서 스테이징 환경에서 기능을 테스트하세요.
- 사용 경험을 SIG API Machinery에 피드백하세요(슬랙, 메일링 리스트, SIG API Machinery 회의 참석 등).