업그레이드 가이드
업그레이드 가이드 (Upgrade Guide)
이 가이드는 Kubernetes에서 실행 중인 Cilium을 업그레이드하는 방법을 안내해요. 업그레이드 전에 전체 가이드를 읽고 필요한 단계를 이해하는 것이 중요합니다. Cilium은 일반적으로 연속된 마이너 릴리스 사이의 업그레이드·롤백만 지원해요.
출처: Upgrade Guide
본문
이 업그레이드 가이드는 Kubernetes에서 실행 중인 Cilium을 대상으로 해요. 질문이 있다면 Cilium Slack에서 편하게 문의하세요.
경고
실제 수행 전에 필요한 모든 단계를 이해하기 위해 업그레이드 가이드 전체를 읽으세요.
1.20 업그레이드 노트 섹션을 읽고 필요한 단계를 완료하기 전에는 1.21로 업그레이드하지 마세요. 이 단계를 건너뛰면 업그레이드가 제대로 동작하지 않을 수 있어요.
테스트된 롤백·업그레이드 경로는 연속된 마이너 릴리스 사이뿐이에요. 롤백과 업그레이드는 항상 한 번에 한 마이너 릴리스씩 수행하세요. 즉, (가상의) 1.1에서 1.2로 갔다가 되돌아오는 것은 지원되지만 1.1에서 1.3으로 갔다가 되돌아오는 것은 지원되지 않아요.
업그레이드를 시도하기 전에 항상 현재 버전의 최신 패치 릴리스로 업데이트하세요.
사전 점검 실행 (필수)
Kubernetes로 업그레이드를 배포할 때, Kubernetes는 먼저 파드를 종료하고 새 이미지 버전을 가져온 다음 새 이미지를 띄워요. 업그레이드 중 에이전트의 다운타임을 줄이고 ErrImagePull 오류를 방지하기 위해 사전 점검(pre-flight check)이 새 이미지 버전을 미리 가져와요.
Kubernetes Without kube-proxy 모드로 실행 중이라면 cilium-preflight.yaml 파일을 생성할 때 Kubernetes API 서버 IP 및/또는 포트도 함께 전달해야 해요.
Helm 저장소:
helm template cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set preflight.enabled=true \
--set agent=false \
--set operator.enabled=false \
> cilium-preflight.yaml
kubectl create -f cilium-preflight.yaml
OCI 레지스트리:
helm template oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set preflight.enabled=true \
--set agent=false \
--set operator.enabled=false \
> cilium-preflight.yaml
kubectl create -f cilium-preflight.yaml
복잡한 설치:
helm template cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set preflight.enabled=true \
--set agent=false \
--set operator.enabled=false \
--set k8sServiceHost=API_SERVER_IP \
--set k8sServicePort=API_SERVER_PORT \
> cilium-preflight.yaml
kubectl create -f cilium-preflight.yaml
OCI 레지스트리 (kubeproxy-free):
helm template oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set preflight.enabled=true \
--set agent=false \
--set operator.enabled=false \
--set k8sServiceHost=API_SERVER_IP \
--set k8sServicePort=API_SERVER_PORT \
> cilium-preflight.yaml
kubectl create -f cilium-preflight.yaml
Helm install 직접 사용 (Helm 저장소):
helm install cilium-preflight cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set preflight.enabled=true \
--set agent=false \
--set operator.enabled=false
Helm install 직접 사용 (OCI 레지스트리):
helm install cilium-preflight oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set preflight.enabled=true \
--set agent=false \
--set operator.enabled=false \
--set k8sServiceHost=API_SERVER_IP \
--set k8sServicePort=API_SERVER_PORT
cilium-preflight.yaml을 적용한 뒤, READY 상태인 파드 수가 실행 중인 Cilium 파드 수와 동일한지 확인하세요.
$ kubectl get daemonset -n kube-system | sed -n '1p;/cilium/p'
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
cilium 2 2 2 2 2 <none> 1h20m
cilium-pre-flight-check 2 2 2 2 2 <none> 7m15s
READY 파드 수가 같아지면, Cilium pre-flight deployment가 READY 1/1로 표시되는지도 확인하세요. READY 0/1로 표시되면 CNP 검증 섹션을 참고해 문제를 해결한 후 업그레이드를 계속하세요.
$ kubectl get deployment -n kube-system cilium-pre-flight-check -w
NAME READY UP-TO-DATE AVAILABLE AGE
cilium-pre-flight-check 1/1 1 0 12s
사전 점검 정리하기
preflight DaemonSet의 READY 수가 실행 중인 cilium 파드 수와 같고 preflight Deployment가 READY 1/1로 표시되면, cilium-preflight를 삭제하고 업그레이드를 진행할 수 있어요.
kubectl delete -f cilium-preflight.yaml
helm delete cilium-preflight --namespace=kube-system
Cilium 업그레이드
정상적인 클러스터 운영 중에는 모든 Cilium 컴포넌트가 같은 버전을 실행해야 해요. 그중 하나만 업그레이드하면(예: operator를 업그레이드하지 않고 agent만 업그레이드) 예상치 못한 클러스터 동작이 발생할 수 있어요. 아래 단계는 모든 컴포넌트를 하나의 안정 릴리스에서 이후 안정 릴리스로 업그레이드하는 방법을 설명해요.
경고
수행 전에 전체 가이드를 읽어 필요한 모든 단계를 이해하세요.
1.20 업그레이드 노트를 읽고 필요한 단계를 완료하기 전에는 1.21로 업그레이드하지 마세요. 이 단계를 건너뛰면 업그레이드가 제대로 동작하지 않을 수 있어요.
1단계: 최신 패치 버전으로 업그레이드
한 마이너 릴리스에서 다른 마이너 릴리스(예: 1.x → 1.y)로 업그레이드할 때는 먼저 Cilium 릴리스 시리즈의 최신 패치 릴리스로 업그레이드하는 것이 좋아요. 최신 패치 릴리스로 업그레이드하면 마이너 릴리스 업그레이드 후 롤백이 필요할 때 가장 매끄럽게 진행돼요. 이전 버전의 업그레이드 가이드는 왼쪽 아래 모서리에서 각 마이너 버전별로 찾을 수 있어요.
2단계: Helm으로 Cilium 배포 업그레이드
Helm을 사용해 Cilium을 직접 업그레이드하거나, 기존 배포를 kubectl로 업그레이드할 때 사용할 새 YAML 파일 세트를 생성할 수 있어요. 기본적으로 Helm은 각 새 릴리스에 포함된 기본 values 파일로 새 템플릿을 생성해요. 초기 배포 시 사용했던 것과 동일한 옵션을 지정하는지(명령줄로 지정하거나 values를 YAML 파일에 저장) 계속 확인해야 해요.
Helm 저장소를 설정하세요:
helm repo add cilium https://helm.cilium.io/
Cilium 차트는 OCI 레지스트리(Quay.io 및 Docker Hub)에서도 사용할 수 있어요. 추가 설정 없이 oci:// URL로 바로 설치할 수 있어요. 차트 서명 검증·digest 기반 설치 등 자세한 내용은 OCI 레지스트리 섹션을 참고하세요.
업그레이드 중 데이터패스 중단을 최소화하려면 upgradeCompatibility 옵션을 이 클러스터에 처음 설치한 Cilium 버전으로 설정해야 해요.
필요한 YAML 파일을 생성하고 배포하세요:
helm template cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set upgradeCompatibility=1.X \
> cilium.yaml
kubectl apply -f cilium.yaml
helm template oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set upgradeCompatibility=1.X \
> cilium.yaml
kubectl apply -f cilium.yaml
Helm으로 Cilium 릴리스를 배포하려면:
helm upgrade cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set upgradeCompatibility=1.X
helm upgrade cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set upgradeCompatibility=1.X
참고
--set대신 배포에 맞는 values를 YAML 파일로 저장하고, 그 파일로 최신 Cilium 버전의 YAML을 재생성할 수도 있어요. 위 명령을 실행하면 기존 클러스터의 ConfigMap을 덮어쓰므로, 기존 옵션을 명령줄에 지정하거나 아래처럼 YAML 파일에 저장해 보존하는 것이 중요해요:
agent: true
upgradeCompatibility: "1.8"
ipam:
mode: "kubernetes"
k8sServiceHost: "API_SERVER_IP"
k8sServicePort: "API_SERVER_PORT"
kubeProxyReplacement: "true"
그런 다음 이 values 파일로 업그레이드할 수 있어요:
helm upgrade cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
-f my-values.yaml
helm upgrade로 한 마이너 릴리스에서 다른 마이너 릴리스로 업그레이드할 때는 Helm의 --reuse-values 플래그를 사용하지 마세요. --reuse-values 플래그는 새 릴리스에 새로 도입된 values를 무시해서 Helm 템플릿이 잘못 렌더링될 수 있어요. 기존 설치의 values를 재사용하려면 이전 values를 파일로 저장하고, 이름이 바뀌거나 더 이상 사용되지 않는 값이 있는지 확인한 뒤 위에서 설명한 대로 helm upgrade 명령에 전달하세요. 기존 설치의 values를 다음 명령으로 가져와 저장할 수 있어요:
helm get values cilium --namespace=kube-system -o yaml > old-values.yaml
--reuse-values 플래그는 Cilium 차트 버전이 변경되지 않은 경우(예: Cilium을 업그레이드하지 않고 구성 변경만 적용할 때 helm upgrade 사용)에만 안전하게 쓸 수 있어요.
3단계: 롤백
때로는 단계를 놓치거나 업그레이드 중 문제가 생겨 롤아웃을 되돌려야 할 수 있어요. 롤아웃을 되돌리려면:
kubectl rollout undo daemonset/cilium -n kube-system
helm history cilium --namespace=kube-system
helm rollback cilium [REVISION] --namespace=kube-system
이렇게 하면 Cilium DaemonSet의 최신 변경이 되돌아가고 Cilium이 업그레이드 이전 상태로 복원돼요.
참고
새 마이너 버전의 새 기능을 이미 사용한 후 롤백할 때는 버전별 참고 사항을 확인해 하위 호환이 되지 않는 기능 사용이 있는지 확인하고 준비한 뒤 다운그레이드/롤백하세요. 이 단계는 새 마이너 버전에서 도입된 새 기능을 새 리소스를 만들거나 ConfigMap으로 새 기능을 명시적으로 선택한 경우에만 필요해요.
버전별 참고 사항
이 섹션은 1.20에 특화된 업그레이드 노트를 다뤄요. Cilium을 1.20으로 업그레이드하기 전에 주의 깊게 읽고 제안된 조치를 취하세요. 이전 릴리스로의 업그레이드는 이전 버전으로의 업그레이드 노트를 참고하세요.
테스트된 업그레이드·롤백 경로는 연속된 마이너 릴리스 사이뿐이에요. 항상 한 번에 한 마이너 릴리스씩 업그레이드·롤백하세요. 또한 업그레이드를 시도하기 전에 항상 현재 버전의 최신 패치 릴리스로 업데이트하세요.
테스트된 업그레이드는 네트워크 정책이 없거나 L3/L4 네트워크 정책만 있는 새 연결·기존 연결에 거의 영향을 주지 않을 것으로 예상돼요. 사용자 공간 프록시를 통하는 트래픽(예: L7 정책이 있거나 Ingress/Gateway API 사용)은 업그레이드 중 중단되며, 프록시를 통해 통신하는 엔드포인트는 연결을 다시 설정해야 해요.
1.20 업그레이드 노트
필수 조치 (Action Required)
환경에서 다음 기능을 사용한다면, 이 기능들의 동작 변경 때문에 조치가 필요할 수 있어요. 업그레이드 중 무엇을 해야 하는지 아래 노트를 주의 깊게 읽으세요.
- Mutual Authentication (Beta) 지원이 더 이상 권장되지 않으며(deprecated) 향후 버전에서 제거될 예정이에요. 대신 Ztunnel Transparent Encryption (Beta)을 고려하고, 이 대안 기능이 사용 사례에 맞는지 피드백을 주세요.
- Envoy Go Extensions(proxylib)는 Cilium 1.18에서 deprecated된 후 제거되었어요.
.spec.ingress[].toPorts[].rules또는.spec.egress[].toPorts[].rules항목에kafka,l7,l7proto하위 필드가 있는CiliumNetworkPolicy또는CiliumClusterwideNetworkPolicy네트워크 정책이 있다면, 업그레이드 전에 해당rules항목을 정책에서 제거하세요. - 여전히
CiliumNodeConfig의v2alpha1API 버전을 사용한다면,cilium.io/v2alpha1을 참조하는 기존 매니페스트·툴링을cilium.io/v2를 사용하도록 업데이트하세요. - Cilium은 기본적으로 CNI 표준
v1.0.0을 사용하도록 업데이트됐어요. 커스텀 CNI 구성을 쓴다면 CNI 구성에서 요청하는 버전을1.0.0으로 업데이트하는 것을 고려하세요. - Cilium의 Gateway API 지원은 이제 제대로 동작하려면 최소 Gateway API v1.6.1을 요구해요.
TLSRoute리소스가 Gateway API v1.6.1에서v1alpha2에서v1지원으로 승격됐고, 클러스터가 항상v1버전을 지원해야 하기 때문이에요. 이전에TLSRoute를 사용했다면 Gateway API v1.6.1의 Experimental 버전TLSRoute리소스를 반드시 설치해야 해요. 이 버전에는 아직 CRD의v1alpha2버전도 포함되어 있어요. v1.6 Standard 버전의TLSRoute리소스를 설치하면 기존TLSRoute오브젝트를 apiserver가 etcd에서 읽을 수 없게 되어 클러스터에서 사실상 사라지게 됩니다.TLSRoute리소스를 백업하고, Cilium을 v1.20으로 업그레이드하기 전에 Gateway API를 v1.6.1로 업그레이드하세요. 설치 방법은 Gateway API 지원을 참고하세요.
정보 노트 (Informational Notes)
spec도specs도 지정하지 않은CiliumNetworkPolicy와CiliumClusterwideNetworkPolicy리소스는 이제 Kubernetes API 서버가 CEL 검증 규칙으로 승인(admission) 시 거부해요. 이전에는 이런 빈 정책이 수용됐고 Cilium 에이전트가 나중에 경고 로그만 남겼어요. 클러스터에 이미 존재하는 빈 정책에는 영향이 없지만, 결과가 빈 정책이 되는 create·update는 거부됩니다.CiliumNode의 Azure IPAM 상태가 이제 인터페이스 수준에서 서브넷을 추적하며, AWS·AlibabaCloud IPAM 표현과 일치해요. Azure NIC의 모든 IP 구성은 서브넷을 공유해야 하므로, 새status.azure.interfaces[].subnet오브젝트(id와cidr)가 서브넷 정보의 권위 있는 소스예요. 이전에 중복되던status.azure.interfaces[].addresses[].subnet과 평면status.azure.interfaces[].cidr필드는 deprecated되며, 운영자와 에이전트의 순서 무관 롤링 업그레이드를 지원하고 CRD를 파싱하는 외부 소비자가status.azure.interfaces[].subnet으로 읽기를 전환할 시간을 주기 위해 한 릴리스 동안 mirror로 계속 채워져요. 향후 릴리스에서 두 deprecated 필드는 모두 제거돼요.- Cilium MCS-API 구현이 이제 MCS-API CRD의
v1beta1버전을 사용해요.v1alpha1은 계속 완전히 지원되며 이 업그레이드는 완전히 투명해야 해요. 향후 개선과v1alpha1의 eventual deprecation에 대비하려면ServiceExport리소스를v1beta1로 업데이트하는 것이 좋아요. - 로컬 REST API와
cilium-dbg bgp명령으로 BGP 피어·라우트·라우트 정책을 나열하는 것은 deprecated예요. 대신 BGP hive 셸 명령cilium shell -- bgp/*을 사용하세요. - 자동 생성된 Cluster Mesh 인증서의 기본 유효 기간이 1년으로 줄었고, Hubble 인증서의 기본 유효 기간과 일치해요.
helm방식(기본)으로 생성된 인증서는 Helm 차트가 다시 렌더링될 때(보통 Cilium 업그레이드 시)에만 갱신돼요. 인증서 만료를 막으려면 최소 1년에 한 번 Cilium을 업그레이드하거나,clustermesh.apiserver.tls.auto.certValidityDuration옵션으로 더 긴 유효 기간을 명시적으로 설정하세요. 다른 생성 방식(cronJob,certmanager)은 자동 인증서 갱신을 지원하므로 같은 제약이 적용되지 않아요. cronJob모드에서 Hubble과 Cluster Mesh 인증서를 자동 생성하는 데 쓰는 certgen 도구가 이제, 생성할 리프 인증서의 전체 기간 동안 CA 체인이 유효한 상태로 유지되도록 기본적으로 강제하며, 그렇지 않으면 하드 오류로 실패해요. 이렇게 하면 CA 인증서가 실제로 만료되기 전에 수동으로 재생성해야 하는 상황을 조기에 알 수 있어요. 이 검증은certgen.enforceCAValidityThroughoutLeavesDuration=false로 끌 수 있어요.
기능 변경 (Changes to Features)
- Service Loadbalancing에
KubeProxyReplacement을 사용하면서SocketLB를 비활성화하거나socketLB.hostNamespaceOnly=true로 설정한 경우, 일반 파드에서 NodePort 서비스로의 클러스터 내 연결은 이제 네트워크 트래픽이 클라이언트 파드를 떠날 때 즉시 로드밸런싱돼요(대상 노드에서가 아니라). 이는 SocketLB가 활성화된 경우의 동작과 일치해요. 따라서 클라이언트 파드의 NetworkPolicy가 서비스 백엔드 방향 egress 트래픽을 허용하고, 백엔드의 NetworkPolicy는 클라이언트 파드의 ingress 트래픽을 허용해야 해요.
새 옵션 (New Options)
이 Cilium 버전에서 도입된 옵션:
configDriftDetectionHelm 값 그룹이 ConfigMap 드리프트 감지를 제어하도록 도입됐고, 기본적으로 활성화돼요. Cilium은 이 검사를 보고하는 Prometheus 메트릭을 노출해요.bpf.datapathMode=auto구성 옵션이 도입됐어요. 설정하면 Cilium이 호스트에서 netkit 지원을 프로브하고, 발견되면 netkit 모드를 런타임에 선택해요. 그렇지 않으면 표준 veth 모드로 되돌아가요. 이는 상태 출력에서 데이터패스 모드를 "configured mode"와 "operational mode"로 나누는 부작용이 있어요. 기본값은 여전히bpf.datapathMode=veth이지만 향후 릴리스에서 바뀔 수 있어요.
변경된 옵션 (Changed Options)
이 Cilium 버전에서 이전 릴리스와 다르게 동작하도록 수정된 옵션:
bpf.tproxy=true는 netkit 데이터패스 모드와 호환되지 않아요. netkit도 활성화되면 Cilium이 시작하지 못해요. 자동 감지 데이터패스 모드를 사용하면 netkit 지원이 있어도 Cilium이 veth 모드로 되돌아가요.clustermesh.apiserver.tls.server.{extraDnsNames,extraIpAddresses}옵션이clustermesh.apiserver.tls.auto.server.{extraDnsNames,extraIpAddresses}로 대체됐어요. 설정된 이전 값은 하위 호환을 위해 여전히 fallback으로 사용돼요.clustermesh-apiserver.cilium.ioDNS 이름도 기본적으로 더 이상 포함되지 않아요.- Cluster Mesh 인증서는
cronJob생성 모드를 선택하면 4개월마다 자동으로 재생성되도록 구성됐어요.
사용하지 않게 된 옵션 (Deprecated Options)
이 Cilium 버전에서 사용하지 않게 된(deprecated) 옵션. 향후 버전에서 제거되므로 사용 중이라면 대안으로 마이그레이션해야 해요.
hubble.preferIpv6Helm 값과--hubble-prefer-ipv6에이전트 플래그가 deprecated됐고 Cilium 1.20에서 제거될 예정이에요. 대신 health probe와 Hubble 피어 통신에 모두 적용되는 최상위preferIpv6Helm 값과--prefer-ipv6에이전트 플래그를 사용하세요.--tofqdns-pre-cache에이전트 플래그와 해당 Helm 값dnsProxy.preCache가 deprecated됐고 v1.21에서 제거될 예정이에요.
제거된 옵션 (Removed Options)
이전에 deprecated됐다가 이제 Cilium에서 제거된 옵션들:
- 이전에 deprecated된 Helm 값
clustermesh.enableMCSAPISupport가clustermesh.mcsapi.enabledHelm 값으로 대체되어 제거됐어요. encryption.ipsec.interfaceHelm 플래그(--encrypt-interface에이전트 플래그)는 Cilium 1.18 이후 no-op이었고 이제 제거됐어요.- Envoy Go Extensions(proxylib)와 Kafka 인식 네트워크 정책 지원이 제거됐어요. 이 기능들은 v1.18에서 deprecated됐어요.
CiliumNodeConfig의v2alpha1API 버전이 제거됐어요.CiliumNodeConfig리소스는 이제apiVersion: cilium.io/v2를 사용해야 해요. 이 버전은 Cilium 1.16부터 사용 가능했어요.cilium.io/v2alpha1을 참조하는 기존CiliumNodeConfig매니페스트·툴링을cilium.io/v2를 사용하도록 업데이트하세요.- Helm 값
hubble.redact.kafka.apiKey와 해당hubble-redact-kafka-apikey에이전트 플래그가 Kafka 지원 제거의 일부로 제거됐어요. - 이전에 deprecated되고 무시되던
--ces-slice-modeoperator 플래그가 제거됐어요. - 이전에 deprecated된
--node-port-algorithm에이전트 플래그가--bpf-lb-algorithm(loadBalancer.algorithmHelm 값)으로 대체되어 제거됐어요. - 이전에 deprecated된
--node-port-mode에이전트 플래그가--bpf-lb-mode(loadBalancer.modeHelm 값)로 대체되어 제거됐어요. - 이전에 deprecated되고 무시되던
--enable-ipsec-encrypted-overlay에이전트 플래그(Helmencryption.ipsec.encryptedOverlay)가 제거됐어요. - 이전에 deprecated된
--enable-encryption-strict-mode에이전트 플래그(Helmencryption.strictMode.enabled)가--enable-encryption-strict-mode-egress(Helmencryption.strictMode.egress.enabled)로 대체되어 제거됐어요. - 이전에 deprecated된
--encryption-strict-mode-cidr에이전트 플래그(Helmencryption.strictMode.cidrs)가--encryption-strict-egress-cidr(Helmencryption.strictMode.egress.cidrs)로 대체되어 제거됐어요. - 이전에 deprecated된
--encryption-strict-mode-allow-remote-node-identities에이전트 플래그(Helmencryption.strictMode.allowRemoteNodeIdentities)가--encryption-strict-egress-allow-remote-node-identities(Helmencryption.strictMode.egress.allowRemoteNodeIdentities)로 대체되어 제거됐어요. - 이전에 deprecated된
--k8s-api-server에이전트 플래그가--k8s-api-server-urls(Helmk8s.apiServerURLs값)로 대체되어 제거됐어요. cilium-dbg preflight fqdn-poller하위 명령과preflight.tofqdnsPreCacheHelm 값이 제거됐어요. 원래 v1.3~v1.4 업그레이드 경로를 위해 도입됐고 더 이상 필요하지 않아요.- 이전에 deprecated된
cilium-docker-plugin이 제거됐어요. - Cluster Mesh TLS 인증서·키를 Helm 값으로 제공하던 이전 방식이 제거됐어요.
clustermesh.apiserver.tls.auto.enabled=false로 설정할 때는 이제 Cilium Helm 차트 밖에서 이런 시크릿을 미리 만들어야 해요.
메트릭 변경 (Changes to Metrics)
추가된 메트릭 (Added Metrics)
cilium_policy_missing_proxy_redirects: 엔드포인트 정책 계산 중 누락된 프록시 리다이렉트의 총 수를 보고해요.cilium_endpoint_component_status: 각 컴포넌트(BPF,Policy)의 상태(OK,Warning,Failure)로 태그된 엔드포인트 수를 보고해요.cilium_kubernetes_resource_sync_duration: 특정 Kubernetes 리소스 동기화의 시간(초)을 보고해요.cilium_hive_start_duration: hive.Start 메서드의 시간을 보고해요.cilium_hive_stop_duration: hive.Stop 메서드의 시간을 보고해요. 메트릭이 hive로 처리될 때는 보고되지 않아요(cilium-agent, cilium-operator에서 흔함). 기본적으로 비활성화.cilium_hive_populate_duration: hive.Populate 메서드의 시간을 보고해요.
변경된 메트릭 (Changed Metrics)
- Cilium Operator REST API 엔드포인트
/v1/metrics(DumpMetrics)가 이제 원시 샘플 합계 대신 히스토그램·요약 메트릭의 quantile별 값을 반환해요. 히스토그램 메트릭은 이제 quantile 라벨0.5,0.9,0.99로 세 개 항목을 내보내요. 요약 메트릭은 선언된 quantile마다 항목 하나를 내보내요. 이는 operator 메트릭 API 출력을cilium-dbg metrics list동작과 일치시켜요. cilium_feature_np_other_l7_policies_total메트릭이 더 이상 Kafka 정책을 세지 않아요. Kafka 인식 네트워크 정책 지원이 제거됐기 때문이에요.policy_change_total메트릭이 이제source(directory, k8s, custom, generated)와operation(update, delete) 차원을 추가로 보고해요.endpoint_regeneration_total메트릭이 이제reason과error차원을 추가로 보고해요.session_state,advertised_routes,received_routes,reconcile_errors_total,reconcile_run_duration_seconds메트릭이 이제instance_name라벨을 포함해요.vrouter라벨은 제거됐으니instance_name을 사용하세요.session_state,advertised_routes,received_routes메트릭이 이제local_asn라벨을 포함해요.
제거된 메트릭 (Removed Metrics)
cilium_agent_bootstrap_seconds가 제거됐어요. 대신 각 job의cilium_hive_jobs_oneshot_last_run_duration_seconds를 사용하세요.cilium_operator_ipam_ips가 제거됐어요. 대신 노드별cilium_operator_ipam_available_ips,cilium_operator_ipam_used_ips,cilium_operator_ipam_needed_ips를 사용하세요.cilium_operator_ipam_available_interfaces가 제거됐어요. 대신cilium_operator_ipam_interface_candidates와cilium_operator_ipam_empty_interface_slots를 사용하세요.
제거된 CRD 필드 (Removed CRD Fields)
CiliumNode CRD에서 다음 폐기된 필드가 제거됐어요:
spec.eni.instance-id: 대신spec.instance-id를 사용하세요. v1.8부터 deprecated.spec.eni.min-allocate: 대신spec.ipam.min-allocate를 사용하세요. v1.8부터 deprecated.spec.eni.pre-allocate: 대신spec.ipam.pre-allocate를 사용하세요. v1.8부터 deprecated.spec.eni.max-above-watermark: 대신spec.ipam.max-above-watermark를 사용하세요. v1.8부터 deprecated.status.azure.interfaces[].GatewayIP: 대신status.azure.interfaces[].gateway를 사용하세요. v1.10부터 deprecated.
고급 (Advanced)
업그레이드 영향 (Upgrade Impact)
업그레이드는 실행 중인 배포에 영향이 최소화되도록 설계됐어요. 네트워킹 연결, 정책 적용, 로드밸런싱은 일반적으로 계속 동작해요. 업그레이드 중 사용할 수 없는 작업 목록은 다음과 같아요:
- API 인식 정책 규칙은 사용자 공간 프록시에서 적용되며 Cilium 파드의 일부로 실행돼요. Cilium을 업그레이드하면 프록시가 재시작되어 연결이 끊기고 재설정돼요.
- 기존 정책은 계속 적용되지만, 새 정책 규칙의 구현은 특정 노드에서 업그레이드가 완료된 후로 연기돼요.
cilium-dbg monitor같은 모니터링 컴포넌트는 Cilium 파드가 재시작되는 동안 잠깐 중단돼요. 이벤트는 큐에 쌓였다가 업그레이드 후 읽혀요. 이벤트 수가 이벤트 버퍼 크기를 초과하면 이벤트가 유실될 수 있어요.
kvstore 기반 identity에서 Kubernetes CRD 기반 identity로 마이그레이션
Cilium 1.6부터 작은 클러스터에서 Kubernetes CRD 기반 보안 identity를 사용할 수 있어요. 1.6의 다른 변경과 함께 원하면 kvstore 없이 운영할 수 있게 해줘요. 기존 kvstore 배포의 identity를 CRD 기반 identity로 마이그레이션할 수 있어요. 이는 업데이트가 클러스터 전체로 배포될 때 트래픽 중단을 최소화해요.
마이그레이션
identity가 바뀌면 Cilium이 공유 identity 저장소와 초기화·동기화하는 동안 기존 연결이 중단될 수 있어요. 이 중단은 일부 인스턴스에서 기존 파드에 새 숫자 identity가 사용되고 다른 곳에서는 다른 값이 사용될 때 발생해요. CRD 기반 identity로 전환할 때 CRD identity를 미리 할당해 숫자 identity가 kvstore의 것과 일치하도록 할 수 있어요. 이렇게 하면 롤아웃의 새·이전 Cilium 인스턴스가 서로 일치할 수 있어요.
이를 달성하는 방법은 두 가지예요: kvstore의 모든 identity를 CRD로 특정 시점 복사하는 일회성 cilium preflight migrate-identity 스크립트(Cilium 1.6에서 추가)를 실행하거나, Cilium이 kvstore와 CRD 양쪽에서 동시에 identity를 관리해 매끄럽게 마이그레이션하는 "Double Write" identity 할당 모드(Cilium 1.17에서 추가)를 사용하는 거예요.
cilium preflight migrate-identity 스크립트로 마이그레이션
cilium preflight migrate-identity 스크립트는 kvstore의 identity를 CRD로 복사하는 데 쓸 수 있는 일회성 도구예요. 몇 가지 제한 사항이 있어요:
- 일회성 마이그레이션이 완료된 후 kvstore에서 identity가 새로 생성되면 CRD로 복사되지 않아요. 즉 identity 변동이 없는 클러스터에서 마이그레이션을 수행해야 해요.
- Cilium이
--identity-allocation-mode=crd로 마이그레이션된 후 문제가 생겨도--identity-allocation-mode=kvstore로 쉽게 되돌릴 방법이 없어요. 이 제한이 받아들여지기 어렵다면 대신 "Double Write" identity 할당 모드를 권장해요.
다음 단계는 cilium preflight migrate-identity 스크립트로 마이그레이션을 수행하는 예시예요. 원하면 명령을 다시 실행해도 안전해요. 이미 할당된 identity나 마이그레이션할 수 없는 identity를 식별해줘요. identity 34815는 마이그레이션되고, 17003은 이미 마이그레이션됐으며, 11730은 충돌이 있어 그 라벨에 새 ID가 할당됐음을 볼 수 있어요.
아래 단계는 롤아웃 중 새 identity가 생성되지 않는 안정적인 클러스터를 가정해요. CRD 기반 identity를 사용하는 Cilium이 실행되기 시작하면 kvstore의 기존 identity와 충돌하는 방식으로 identity를 할당하기 시작할 수 있어요.
cilium preflight 매니페스트는 etcd 지원이 필요하며 다음으로 빌드할 수 있어요:
helm template cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set preflight.enabled=true \
--set agent=false \
--set config.enabled=false \
--set operator.enabled=false \
--set etcd.enabled=true \
--set etcd.ssl=true \
> cilium-preflight.yaml
kubectl create -f cilium-preflight.yaml
마이그레이션 예시
$ kubectl exec -n kube-system cilium-pre-flight-check-1234 -- cilium-dbg preflight migrate-identity
INFO[0000] Setting up kvstore client
INFO[0000] Connecting to etcd server... config=/var/lib/cilium/etcd-config.yml endpoints="[https://192.168.60.11:2379]" subsys=kvstore
INFO[0000] Setting up kubernetes client
INFO[0000] Establishing connection to apiserver host="https://192.168.60.11:6443" subsys=k8s
INFO[0000] Connected to apiserver subsys=k8s
INFO[0000] Got lease ID 29c66c67db8870c8 subsys=kvstore
INFO[0000] Got lock lease ID 29c66c67db8870ca subsys=kvstore
INFO[0000] Successfully verified version of etcd endpoint config=/var/lib/cilium/etcd-config.yml endpoints="[https://192.168.60.11:2379]" etcdEndpoint="https://192.168.60.11:2379" subsys=kvstore version=3.3.13
INFO[0000] CRD (CustomResourceDefinition) is installed and up-to-date name=CiliumNetworkPolicy/v2 subsys=k8s
INFO[0000] Updating CRD (CustomResourceDefinition)... name=v2.CiliumEndpoint subsys=k8s
INFO[0001] CRD (CustomResourceDefinition) is installed and up-to-date name=v2.CiliumEndpoint subsys=k8s
INFO[0001] Updating CRD (CustomResourceDefinition)... name=v2.CiliumNode subsys=k8s
INFO[0002] CRD (CustomResourceDefinition) is installed and up-to-date name=v2.CiliumNode subsys=k8s
INFO[0002] Updating CRD (CustomResourceDefinition)... name=v2.CiliumIdentity subsys=k8s
INFO[0003] CRD (CustomResourceDefinition) is installed and up-to-date name=v2.CiliumIdentity subsys=k8s
INFO[0003] Listing identities in kvstore
INFO[0003] Migrating identities to CRD
INFO[0003] Skipped non-kubernetes labels when labelling ciliumidentity. All labels will still be used in identity determination labels="map[]" subsys=crd-allocator
INFO[0003] Migrated identity identity=34815 identityLabels="k8s:class=tiefighter;k8s:io.cilium.k8s.policy.cluster=default;k8s:io.cilium.k8s.policy.serviceaccount=default;k8s:io.kubernetes.pod.namespace=default;k8s:org=empire;"
WARN[0003] ID is allocated to a different key in CRD. A new ID will be allocated for the this key identityLabels="k8s:class=deathstar;k8s:io.cilium.k8s.policy.cluster=default;k8s:io.cilium.k8s.policy.serviceaccount=default;k8s:io.kubernetes.pod.namespace=default;k8s:org=empire;" oldIdentity=11730
INFO[0003] Reusing existing global key key="k8s:class=deathstar;k8s:io.cilium.k8s.policy.cluster=default;k8s:io.cilium.k8s.policy.serviceaccount=default;k8s:io.kubernetes.pod.namespace=default;k8s:org=empire;" subsys=allocator
INFO[0003] New ID allocated for key in CRD identity=17281 identityLabels="k8s:class=deathstar;k8s:io.cilium.k8s.policy.cluster=default;k8s:io.cilium.k8s.policy.serviceaccount=default;k8s:io.kubernetes.pod.namespace=default;k8s:org=empire;" oldIdentity=11730
INFO[0003] ID was already allocated to this key. It is already migrated identity=17003 identityLabels="k8s:class=xwing;k8s:io.cilium.k8s.policy.cluster=default;k8s:io.cilium.k8s.policy.serviceaccount=default;k8s:io.kubernetes.pod.namespace=default;k8s:org=alliance;"
참고
preflight 명령에
ciliumCLI 옵션--k8s-kubeconfig-path와--kvstore-opt를 함께 쓰는 것도 가능해요. 기본값은 cilium-agent가 구성하는 방식을 따르는 거예요.
cilium preflight migrate-identity --k8s-kubeconfig-path /var/lib/cilium/cilium.kubeconfig --kvstore etcd --kvstore-opt etcd.config=/var/lib/cilium/etcd-config.yml
마이그레이션이 완료되면 CRD와 etcd에 저장된 엔드포인트를 나열해 엔드포인트 identity가 일치하는지 확인하세요:
$ kubectl get ciliumendpoints -A # 새 CRD 기반 엔드포인트
$ kubectl exec -n kube-system cilium-1234 -- cilium-dbg endpoint list # 기존 etcd 기반 엔드포인트
CRD identity 정리
마이그레이션이 잘못된 경우 초기 상태부터 다시 시작할 수 있어요. --identity-allocation-mode=crd로 실행 중인 Cilium 인스턴스가 없는지 확인하고 다음을 실행하세요:
$ kubectl delete ciliumid --all
"Double Write" identity 할당 모드로 마이그레이션
참고
이는 베타 기능이에요. 문제가 있으면 피드백을 주고 GitHub 이슈를 올려주세요.
"Double Write" Identity 할당 모드는 Cilium이 identity를 KVStore 값 과 CRD로 동시에 할당하게 해줘요. 이 모드에는 두 버전이 있어요: kvstore에서 진실의 원천(source of truth)이 나오는 버전(--identity-allocation-mode=doublewrite-readkvstore)과 CRD에서 진실의 원천이 나오는 버전(--identity-allocation-mode=doublewrite-readcrd)이에요.
높은 수준의 마이그레이션 계획은 다음과 같아요:
- 시작 상태: Cilium이 KVStore 모드로 실행 중.
- Cilium을 모든 읽기가 KVStore에서 일어나는 "Double Write" 모드로 전환. 모든 identity가 CRD로도 복제되지만 사용되지 않는다는 점만 제외하면 순수 KVStore 모드와 거의 동일해요.
- Cilium을 모든 읽기가 CRD에서 일어나는 "Double Write" 모드로 전환. 순수 CRD 모드로 실행되는 것과 동일하지만, 빠른 롤백 가능성을 위해 identity가 여전히 KVStore에도 업데이트돼요.
- Cilium을 CRD 모드로 전환. KVStore는 더 이상 사용되지 않으며 폐기 준비가 돼요. 이렇게 하면 2·3단계에서 빠른 롤백 가능성과 함께 점진적·매끄러운 마이그레이션을 수행할 수 있어요.
또한 "Double Write" 모드가 활성화되면 Operator가 마이그레이션 진행 상황을 모니터링하는 추가 메트릭을 내보내요. 이 메트릭을 사용해 KVStore와 CRD 간 identity 불일치에 대해 알림을 받을 수 있어요.
이걸로 CRD에서 KVStore 모드로 마이그레이션할 수도 있다는 점에 주의하세요. 모든 작업을 역순으로 반복하기만 하면 돼요.
롤아웃 지침
- 먼저 Operator, 그다음 Agents를
--identity-allocation-mode=doublewrite-readkvstore로 재배포하세요. - Operator 메트릭과 로그를 모니터링해 모든 identity가 KVStore와 CRD 간에 수렴했는지 확인하세요. Operator가 내보내는 관련 메트릭:
cilium_operator_identity_crd_total_count와cilium_operator_identity_kvstore_total_count는 각각 CRD와 KVStore의 전체 identity 수를 보고해요.cilium_operator_identity_crd_only_count와cilium_operator_identity_kvstore_only_count는 각각 CRD에만 또는 KVStore에만 있는 identity 수를 보고해 불일치를 감지하는 데 도움을 줘요. 추가 조사가 필요하면 Operator 로그에 KVStore와 CRD identity 간 차이에 대한 상세 정보가 들어 있어요. KVStore identity와 CRD identity의 Garbage Collection은 약간 다른 시점에 발생하므로,--identity-gc-interval과--identity-heartbeat-timeout설정에 따라 일정 기간 메트릭에 차이가 보일 수 있다는 점에 유의하세요.
- 모든 identity가 수렴하면 Operator와 Agents를
--identity-allocation-mode=doublewrite-readcrd로 재배포하세요. 이러면 Cilium이 CRD에서만 identity를 읽지만 KVStore에는 계속 기록해요. - KVStore를 폐기할 준비가 되면 먼저 Agents, 그다음 Operator를
--identity-allocation-mode=crd로 재배포하세요. 이러면 Cilium이 identity를 CRD에만 읽고 쓰게 돼요. - 이제 KVStore를 폐기할 수 있어요.
policy-default-local-cluster 변경 준비하기
Cilium 네트워크 정책은 예전에 모든 클러스터의 엔드포인트를 암묵적으로 선택했어요. Cilium 1.18이 policy-default-local-cluster라는 새 옵션을 도입했고, 이는 Cilium 1.19에서 기본으로 설정될 예정이에요. 이 옵션은 기본적으로 엔드포인트 선택을 로컬 클러스터로 제한해요. ClusterMesh와 네트워크 정책을 사용한다면 이는 Breaking Change이며 Cilium 1.19로 업그레이드하기 전에 조치를 취해야 해요.
이 새 옵션은 ConfigMap이나 Helm 값 clustermesh.policyDefaultLocalCluster로 설정할 수 있어요. Cilium 1.19에서 policy-default-local-cluster를 false로 설정해 기존 동작을 유지할 수 있지만, 이 옵션은 deprecated되어 향후 릴리스에서 제거될 예정이므로 policy-default-local-cluster를 true로 설정하도록 마이그레이션을 계획해야 해요.
실제로 네트워크 정책 마이그레이션하기
cilium clustermesh inspect-policy-default-local-cluster --all-namespaces 명령은 policy-default-local-cluster 변경으로 달라질 모든 정책을 발견하는 데 도움을 줘요. 특정 네임스페이스만 조사하려면 --all-namespaces 대신 -n my-namespace를 쓰면 돼요.
업데이트가 필요한 네트워크 정책이 하나 있는 예시:
$ cilium clustermesh inspect-policy-default-local-cluster --all-namespaces
⚠️ CiliumNetworkPolicy 0/1
⚠️ default/allow-from-bar
✅ CiliumClusterWideNetworkPolicy 0/0
✅ NetworkPolicy 0/0
이 상황에서는 policy-default-local-cluster 변경의 영향을 받는 CiliumNetworkPolicy가 하나뿐이에요. 정책을 살펴보죠:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: allow-from-bar
namespace: default
spec:
description: "Allow ingress traffic from bar"
endpointSelector:
matchLabels:
name: foo
ingress:
- fromEndpoints:
- matchLabels:
name: bar
이 네트워크 정책은 클러스터를 명시적으로 선택하지 않아요. 즉 policy-default-local-cluster가 false로 설정되면 ClusterMesh에 연결된 모든 클러스터의 bar에서 오는 트래픽을 허용해요. policy-default-local-cluster가 true로 설정되면 이 정책은 로컬 클러스터의 bar에서 오는 트래픽만 허용해요.
foo와 bar가 항상 같은 클러스터에 있다면 추가 조치는 필요 없어요.
이 조치를 전역 수준이 아니라 개별 정책에 적용하고 싶거나, bar가 원격 클러스터에 있다면 정책을 이렇게 업데이트할 수 있어요:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: allow-from-bar
namespace: default
spec:
description: "Allow ingress traffic from bar"
endpointSelector:
matchLabels:
name: foo
ingress:
- fromEndpoints:
- matchLabels:
name: bar
io.cilium.k8s.policy.cluster: fixme-cluster-name
bar가 여러 클러스터에 있다면 여러 클러스터를 선택하는 matchExpressions를 이렇게 사용할 수도 있어요:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: allow-from-bar
namespace: default
spec:
description: "Allow ingress traffic from bar"
endpointSelector:
matchLabels:
name: foo
ingress:
- fromEndpoints:
- matchLabels:
name: bar
matchExpressions:
- key: io.cilium.k8s.policy.cluster
operator: In
values:
- fixme-cluster-name-1
- fixme-cluster-name-2
대신 policy-default-local-cluster를 false로 설정하는 것과 같은 동작을 이 개별 정책에 복원하고 싶다면, 모든 클러스터에 있는 bar의 트래픽을 허용할 수도 있어요:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: allow-from-bar
namespace: default
spec:
description: "Allow ingress traffic from bar"
endpointSelector:
matchLabels:
name: foo
ingress:
- fromEndpoints:
- matchLabels:
name: bar
matchExpressions:
- key: io.cilium.k8s.policy.cluster
operator: Exists
CNP 검증
CNP Validator를 실행하면 클러스터에 배포된 정책이 유효한지 확인할 수 있어요. 업그레이드 전에 이 검증을 실행하는 것이 중요해요. 그래야 업그레이드 후 Cilium이 올바르게 동작하는지 확인할 수 있기 때문이에요. 이 검증을 건너뛰면 Cilium이 잘못된 Network Policy의 NodeStatus를 업데이트하지 못할 수 있고, 최악의 경우 정책이 잘못된 형식인데 Cilium이 검증 스키마 문제로 그 정책을 적용하지 않아 사용자에게 안전하다는 잘못된 인상을 줄 수 있어요. 이 CNP Validator는 사전 점검 사전 점검 실행 (필수)의 일부로 자동 실행돼요.
cilium-pre-flight-check를 배포하고 Deployment가 READY 1/1을 표시하는지 확인하세요. 그렇지 않으면 파드 로그를 확인하세요.
$ kubectl get deployment -n kube-system cilium-pre-flight-check -w
NAME READY UP-TO-DATE AVAILABLE AGE
cilium-pre-flight-check 0/1 1 0 12s
$ kubectl logs -n kube-system deployment/cilium-pre-flight-check -c cnp-validator --previous
level=info msg="Setting up kubernetes client"
level=info msg="Establishing connection to apiserver" host="https://172.20.0.1:443" subsys=k8s
level=info msg="Connected to apiserver" subsys=k8s
level=info msg="Validating CiliumNetworkPolicy 'default/cidr-rule': OK!
level=error msg="Validating CiliumNetworkPolicy 'default/cnp-update': unexpected validation error: spec.labels: Invalid value: \"string\": spec.labels in body must be of type object: \"string\""
level=error msg="Found invalid CiliumNetworkPolicy"
이 예시에서 default 네임스페이스의 cnp-update라는 CiliumNetworkPolicy가 업그레이드하려는 Cilium 버전에 대해 유효하지 않음을 볼 수 있어요. 이 정책을 고치려면 정책을 로컬에 저장하고 수정해야 해요. 이 예시에서 .spec.labels가 공식 스키마에 맞지 않는 문자열 배열로 설정되어 있어요.
$ kubectl get cnp -n default cnp-update -o yaml > cnp-bad.yaml
$ cat cnp-bad.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
[...]
spec:
endpointSelector:
matchLabels:
id: app1
ingress:
- fromEndpoints:
- matchLabels:
id: app2
toPorts:
- ports:
- port: "80"
protocol: TCP
labels:
- custom=true
[...]
이 정책을 고치려면 .spec.labels를 올바른 형식으로 설정하고 이 변경을 Kubernetes에 커밋해야 해요.
$ cat cnp-bad.yaml
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
[...]
spec:
endpointSelector:
matchLabels:
id: app1
ingress:
- fromEndpoints:
- matchLabels:
id: app2
toPorts:
- ports:
- port: "80"
protocol: TCP
labels:
- key: "custom"
value: "true"
[...]
$
$ kubectl apply -f ./cnp-bad.yaml
수정된 정책을 적용한 뒤, 정책을 검증하던 파드를 삭제하면 Kubernetes가 즉시 새 파드를 만들어 수정된 정책이 이제 유효한지 확인해요.
$ kubectl delete pod -n kube-system -l k8s-app=cilium-pre-flight-check-deployment
pod "cilium-pre-flight-check-86dfb69668-ngbql" deleted
$ kubectl get deployment -n kube-system cilium-pre-flight-check
NAME READY UP-TO-DATE AVAILABLE AGE
cilium-pre-flight-check 1/1 1 1 55m
$ kubectl logs -n kube-system deployment/cilium-pre-flight-check -c cnp-validator
level=info msg="Setting up kubernetes client"
level=info msg="Establishing connection to apiserver" host="https://172.20.0.1:443" subsys=k8s
level=info msg="Connected to apiserver" subsys=k8s
level=info msg="Validating CiliumNetworkPolicy 'default/cidr-rule': OK!
level=info msg="Validating CiliumNetworkPolicy 'default/cnp-update': OK!
level=info msg="All CCNPs and CNPs valid!"
정책이 유효해지면 업그레이드 과정을 계속할 수 있어요. 사전 점검 정리