반응형

 

🔍  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       │
            └─────────────────┘
  1. 서로 다른 CIDR 범위 사용
  2. Linux 라우팅 테이블을 통한 트래픽 분리
  3. 점진적 노드 마이그레이션

특정 노드의 포드는 하나의 네트워크에만 연결될 수 있지만, 마이그레이션이 진행되는 동안 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 기반 라우팅과는 호환되지 않음
  • 마이그레이션 중 정책 시행 비활성화 필요
반응형

+ Recent posts