🔍 Cilium 의 무중단 마이그레이션
회사의 요구사항에 따라 Kubernetes 클러스터에서 CNI(Container Network Interface)를 변경할 수도 있습니다.
전통적으로 모든 노드의 CNI 를 새로운 CNI 로 재구성한 후, 각 노드를 재시작하여 CNI 를 교체하는 방법을 생각할 수 있습니다.
하지만 롤아웃 중 마이그레이션 된 노드와 마이그레이션 되지 않는 노드가 통신이 되지 않는 현상이 있을 수 있습니다.
Cilium 은 듀얼 오버레이(Dual Overlay) 방식을 통해 이러한 문제를 해결합니다.
┌─────────────────┐ ┌─────────────────┐
│ Flannel Pod │ │ Cilium Pod │
│ (10.244.x.x) │ │ (10.245.x.x) │
└─────────────────┘ └─────────────────┘
│ │
└───────────┬───────────┘
│
┌─────────────────┐
│ Linux Routing │
│ Table │
└─────────────────┘
- 서로 다른 CIDR 범위 사용
- Linux 라우팅 테이블을 통한 트래픽 분리
- 점진적 노드 마이그레이션
특정 노드의 포드는 하나의 네트워크에만 연결될 수 있지만, 마이그레이션이 진행되는 동안 Cilium 포드와 Cilium이 아닌 포드 모두에 접근할 수 있습니다.
🛠️ 실습 환경 구성
1. flannel 설치되어 있는 환경 구축
먼저 Kind를 사용하여 flannel 을 설치할 테스트 클러스터를 생성합니다.
# kind-config.yaml
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
- role: control-plane
- role: worker
- role: worker
networking:
disableDefaultCNI: true
# 클러스터 생성
kind create cluster --config=kind-config.yaml
2. Flannel 설치
# 참조용 CNI 플러그인 설치
kubectl apply -n kube-system --server-side -f https://raw.githubusercontent.com/cilium/cilium/1.17.6/examples/misc/migration/install-reference-cni-plugins.yaml
# Flannel 설치
kubectl apply --server-side -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
# 노드 준비 상태 확인
kubectl wait --for=condition=Ready nodes --all
3. 연결성 모니터링 도구 설치 (선택사항)
# Goldpinger로 연결성 모니터링
kubectl apply -f https://raw.githubusercontent.com/bloomberg/goldpinger/master/extras/example-goldpinger-rbac.yaml
📋 마이그레이션 사전 준비
1. CIDR 및 포트 선택
기존에 사용 중인 다른 모든 CIDR과 달라야 하며, 캡슐할 프로토콜/포트를 다르게 지정해야 합니다.
기존에 사용하고 있던 프로토콜을 그대로 사용하고 싶은 경우, 포트 번호를 다르게 선정해야 합니다.
| 항목 | 기존 (Flannel) | 새로운 (Cilium) |
| Pod CIDR | 10.244.0.0/16 | 10.245.0.0/16 |
| 프로토콜 | VXLAN | VXLAN |
| 포트 | 8472 (기본) | 8473 |
2. Helm Values 파일 생성
cilium helm 차트에서 사용하려고 하는 values 파일을 생성하여 마이그레이션 설정을 세팅합니다.
# values-migration.yaml
operator:
unmanagedPodWatcher:
restart: false # 마이그레이션 중 기존 Pod 재시작 금지
routingMode: tunnel
tunnelProtocol: vxlan
tunnelPort: 8473 # 기존 Flannel과 다른 포트 사용
cni:
customConf: true # CNI 구성 파일 설치 금지
uninstall: false # 종료 시 CNI 구성 제거 금지
ipam:
mode: "cluster-pool"
operator:
clusterPoolIPv4PodCIDRList: ["10.245.0.0/16"] # 새로운 CIDR
policyEnforcementMode: "never" # 정책 시행 비활성화
bpf:
hostLegacyRouting: true # 레거시 라우팅 허용
🔧 마이그레이션 프로세스
Step 1: Cilium 설치 (보조 모드)
# Cilium CLI를 통한 값 자동 감지
cilium install --version 1.17.6 --values values-migration.yaml --dry-run-helm-values > values-initial.yaml
# Helm을 통한 Cilium 설치
helm repo add cilium https://helm.cilium.io/
helm install cilium cilium/cilium --namespace kube-system --values values-initial.yaml
Step 2: 설치 확인
# Cilium 상태 확인
cilium status --wait
# 출력 예시:
# Cluster Pods: 0/3 managed by Cilium
# (아직 어떤 Pod도 Cilium에 의해 관리되지 않음)
Step 3: CiliumNodeConfig 생성
# cilium-node-config.yaml
apiVersion: cilium.io/v2
kind: CiliumNodeConfig
metadata:
namespace: kube-system
name: cilium-default
spec:
nodeSelector:
matchLabels:
io.cilium.migration/cilium-default: "true"
defaults:
write-cni-conf-when-ready: /host/etc/cni/net.d/05-cilium.conflist
custom-cni-conf: "false"
cni-chaining-mode: "none"
cni-exclusive: "true"
# CiliumNodeConfig 적용
kubectl apply --server-side -f cilium-node-config.yaml
Step 4: 노드 선택 및 준비
# 워커 노드부터 시작 (컨트롤 플레인 노드는 마지막)
NODE="kind-worker"
# 노드 스케줄링 금지
kubectl cordon $NODE
# 노드 드레인 (권장)
kubectl drain --ignore-daemonsets $NODE
⚠️ 주의사항
- 컨트롤 플레인 노드는 마지막에 마이그레이션
- 드레인은 선택사항이지만 권장됨
Step 5: 노드 라벨링
# 마이그레이션 라벨 적용
kubectl label node $NODE --overwrite "io.cilium.migration/cilium-default=true"
이 라벨을 적용하면 CiliumNodeConfig 가 해당 노드에 적용됩니다.
Step 6: Cilium DaemonSet 재시작
# 해당 노드의 Cilium Pod 삭제
kubectl -n kube-system delete pod --field-selector spec.nodeName=$NODE -l k8s-app=cilium
# DaemonSet 롤아웃 상태 확인
kubectl -n kube-system rollout status ds/cilium -w
Step 7: 노드 재부팅
# Kind 환경에서 노드 재시작
docker restart $NODE
Step 8: 마이그레이션 검증
# Cilium 상태 확인
cilium status --wait
# 노드 상태 확인
kubectl get -o wide node $NODE
# 네트워크 연결성 테스트
kubectl -n kube-system run --attach --rm --restart=Never verify-network \
--overrides='{"spec": {"nodeName": "'$NODE'", "tolerations": [{"operator": "Exists"}]}}' \
--image ghcr.io/nicolaka/netshoot:v0.8 -- /bin/bash -c 'ip -br addr && curl -s -k https://$KUBERNETES_SERVICE_HOST/healthz && echo'
Step 9: 노드 활성화
# 노드 스케줄링 재개
kubectl uncordon $NODE
🏁 마이그레이션 완료 후 작업
1. 전체 마이그레이션 완료 확인
# 모든 Pod이 Cilium에 의해 관리되는지 확인
cilium status
# 출력 예시:
# Cluster Pods: 15/15 managed by Cilium
2. Cilium 설정 업데이트
# 최종 설정 생성
cilium install --version 1.17.6 --values values-initial.yaml --dry-run-helm-values \
--set operator.unmanagedPodWatcher.restart=true \
--set cni.customConf=false \
--set policyEnforcementMode=default \
--set bpf.hostLegacyRouting=false > values-final.yaml
# 설정 변경 사항 확인
diff values-initial.yaml values-final.yaml
3. 최종 업그레이드 적용
# Helm 업그레이드
helm upgrade --namespace kube-system cilium cilium/cilium --values values-final.yaml
# DaemonSet 재시작
kubectl -n kube-system rollout restart daemonset cilium
# 최종 상태 확인
cilium status --wait
4. 정리 작업
# CiliumNodeConfig 삭제
kubectl delete -n kube-system ciliumnodeconfig cilium-default
# 기존 Flannel 삭제
kubectl delete -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
⚠️ 주의사항
- 테스트 환경에서 먼저 실습 필수
- NetworkPolicy 사용 시 임시 삭제 필요
- BGP 기반 라우팅과는 호환되지 않음
- 마이그레이션 중 정책 시행 비활성화 필요
'인프라 > 쿠버네티스' 카테고리의 다른 글
| [cilium] Hubble 개념과 설치 (5) | 2025.07.21 |
|---|---|
| [cilium] Cilium Network Policy (0) | 2025.07.21 |
| [cilium] flannel -> cilium 마이그레이션 (without kube-proxy) (0) | 2025.07.15 |
| [cilium] cilium 네트워크 패킷 흐름 (with ebpf) (1) | 2025.07.15 |
| /etc/kubernetes/pki/ vs /var/lib/kubelet/pki/ 차이점 (0) | 2025.07.02 |