Kubernetes Tools/Cilium

EP14. Cilium 운영 환경 구성 전략 | 롤아웃, 업데이트, 장애 복구

ygtoken 2025. 3. 23. 00:40
728x90

이 글에서는 Cilium을 프로덕션 환경에서 안정적으로 운영하기 위한 전략과 베스트 프랙티스를 알아봅니다. Helm을 이용한 체계적인 관리 방법부터 롤링 업데이트 전략, 그리고 장애 발생 시 신속한 복구 절차까지 실제 현업에서 필요한 실무 지식을 다룰 예정입니다. 특히 대규모 클러스터에서 CNI 업데이트와 같은 민감한 작업을 안전하게 수행하는 방법과 장애 상황에서의 문제 해결 프로세스를 중점적으로 살펴보겠습니다.


📌 Helm으로 관리하는 Cilium

Helm은 쿠버네티스 애플리케이션의 패키징과 배포를 간소화하는 도구로, Cilium과 같은 복잡한 CNI 컴포넌트를 효율적으로 관리하는 데 매우 적합합니다.

✅ Helm 기반 Cilium 설치 준비

먼저 Helm을 통한 Cilium 설치 및 관리를 위한 기본 환경을 준비합니다:

# Helm 저장소 추가
# Cilium의 공식 Helm 차트 저장소를 추가합니다
helm repo add cilium https://helm.cilium.io/

# 저장소 업데이트
# 최신 차트 정보를 가져옵니다
helm repo update

# 사용 가능한 Cilium 버전 확인
# 설치 가능한 Cilium 차트 버전을 확인합니다
helm search repo cilium/cilium --versions

✅ values.yaml 파일 구성

Helm 차트는 values.yaml 파일을 통해 커스터마이징할 수 있습니다. 프로덕션 환경에 적합한 Cilium 구성을 위한 values.yaml 파일을 작성해 봅시다:

# production-values.yaml
# Cilium의 주요 운영 파라미터 설정

# 클러스터 이름 (멀티 클러스터 환경에서 중요)
cluster:
  name: "prod-cluster-1"
  id: 1  # 클러스터 ID (Cluster Mesh에서 사용)

# eBPF 관련 설정
bpf:
  masquerade: true  # eBPF 기반 마스커레이딩 (성능 향상)
  hostRouting: false  # 호스트 네트워킹 최적화 (상황에 따라 설정)
  
# 노드 초기화 설정
nodeinit:
  enabled: true  # 노드 초기화 DaemonSet 활성화 (sysctl 설정 등)
  
# 쿠버네티스 리소스 제한 설정 (안정적 운영을 위해 중요)
resources:
  cilium:
    limits:
      cpu: "1000m"  # 1 CPU 코어까지 사용 가능
      memory: "1Gi"  # 1GB 메모리까지 사용 가능
    requests:
      cpu: "100m"   # 최소 0.1 CPU 코어 요청
      memory: "512Mi"  # 최소 512MB 메모리 요청
      
# 프로메테우스 메트릭 설정
prometheus:
  enabled: true  # 프로메테우스 메트릭 활성화
  serviceMonitor:
    enabled: true  # ServiceMonitor 리소스 생성 (Prometheus Operator와 통합)
    
# 운영자 (Operator) 설정
operator:
  replicas: 2  # 고가용성을 위한 Operator 복제본 수
  rollOutPods: true  # Pod 업데이트 시 순차적 롤아웃
  
# Hubble 설정 (네트워크 가시성)
hubble:
  enabled: true  # Hubble 활성화
  relay:
    enabled: true  # Hubble Relay 활성화
  ui:
    enabled: true  # Hubble UI 활성화
    
# 고급 네트워킹 설정
ipam:
  mode: "kubernetes"  # IPAM 모드 (IP 주소 할당 방식)
  
tunnel: "vxlan"  # 터널 모드 (vxlan, geneve, disabled)

# kubeProxyReplacement 설정
# "strict": kube-proxy 완전 대체
# "probe": 가능한 경우에만 대체
# "partial": 일부 기능만 대체
# "disabled": kube-proxy 대체 비활성화
kubeProxyReplacement: "probe"

# 보안 설정
encryption:
  enabled: false  # 노드 간 트래픽 암호화 (필요 시 활성화)
  
# 고가용성 설정
highAvailability:
  enabled: true  # HA 활성화

# 업그레이드 및 롤링 업데이트 설정
upgradeCompatibility: "1.12"  # 호환성 보장 버전
rollOutCiliumPods: true  # Cilium Pod 업데이트 시 순차적 롤아웃

✅ Helm으로 Cilium 설치 및 업그레이드

아래 명령어로 실제 Cilium을 설치하고 관리할 수 있습니다:

# 초기 설치
# 특정 네임스페이스에 Cilium을 설치합니다
# --create-namespace: 네임스페이스가 없을 경우 생성
# -f: 커스텀 values 파일 지정
# --version: 특정 Cilium 버전 지정
helm install cilium cilium/cilium \
  --namespace kube-system \
  --create-namespace \
  -f production-values.yaml \
  --version 1.14.1

# 구성 업데이트 (values.yaml 변경 후)
# 설정 파일이 변경되었을 때 업그레이드 수행
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f production-values.yaml \
  --version 1.14.1

# 현재 설치된 Cilium 상태 확인
# 설치 상태와 적용된 값 확인
helm status cilium -n kube-system

# 현재 사용 중인 values 값 확인
# 실제 적용된 구성 값 확인
helm get values cilium -n kube-system

✅ GitOps 방식의 Cilium 관리

프로덕션 환경에서는 GitOps 방식으로 Cilium을 관리하는 것이 좋습니다:

# GitOps 리포지토리 구조 예시
clusters/
  └── production/
      └── cilium/
          ├── kustomization.yaml  # Kustomize 설정
          ├── release.yaml        # Helm 차트 릴리스 정의
          └── values.yaml         # 환경별 Cilium 설정

release.yaml 예시 (Flux 또는 ArgoCD와 같은 GitOps 도구 사용):

# release.yaml
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: cilium
  namespace: kube-system
spec:
  interval: 1h  # 재조정 간격
  chart:
    spec:
      chart: cilium
      version: "1.14.1"  # 고정 버전 사용
      sourceRef:
        kind: HelmRepository
        name: cilium
        namespace: flux-system
  values:
    # 기본 값 설정 (필요시)
  valuesFrom:
    - kind: ConfigMap
      name: cilium-values
      valuesKey: values.yaml
  # 업그레이드 전략
  upgrade:
    remediation:
      retries: 3  # 실패 시 최대 재시도 횟수

📌 Cilium 롤링 업데이트 전략

CNI 컴포넌트 업데이트는 클러스터의 네트워크 연결에 영향을 줄 수 있어 신중하게 수행해야 합니다. 다음은 Cilium을 안전하게 업데이트하기 위한 전략입니다.

✅ 업데이트 전 준비사항

# 1. 현재 클러스터 상태 확인
# 모든 노드 상태 확인
kubectl get nodes

# 모든 Cilium Pod 상태 확인
kubectl get pods -n kube-system -l k8s-app=cilium

# Cilium 진단 실행
cilium status --verbose

# 2. 백업 생성
# Cilium CRD 및 관련 리소스 백업
mkdir -p ./cilium-backup
kubectl get ciliumnetworkpolicies --all-namespaces -o yaml > ./cilium-backup/cilium-network-policies.yaml
kubectl get ciliumclusterwidenetworkpolicies -o yaml > ./cilium-backup/cilium-clusterwide-policies.yaml
kubectl get ciliumendpoints --all-namespaces -o yaml > ./cilium-backup/cilium-endpoints.yaml
kubectl get ciliumnodes -o yaml > ./cilium-backup/cilium-nodes.yaml

# 3. 테스트 및 모니터링 준비
# 지속적인 연결 테스트를 위한 스크립트 (별도 터미널에서 실행)
cat > connectivity-test.sh << 'EOF'
#!/bin/bash
while true; do
  echo "$(date): Checking cluster connectivity..."
  kubectl get pods --all-namespaces -o wide
  echo "Testing service connectivity..."
  kubectl run -it --rm debug --image=busybox --restart=Never -- \
    wget -qO- http://kubernetes.default.svc.cluster.local
  sleep 30
done
EOF
chmod +x connectivity-test.sh

✅ 단계적 롤아웃 전략

대규모 클러스터에서는 Cilium을 한 번에 모든 노드에 업데이트하는 것보다 단계적으로 롤아웃하는 것이 안전합니다.

# 단계적 롤아웃을 위한 values 설정
# canary-values.yaml
upgradeCompatibility: "1.14"  # 현재 버전과의 호환성 명시

# Operator 먼저 업데이트
operator:
  rollOutPods: true  # 순차적 Pod 롤아웃

# DaemonSet 업데이트 설정
rollOutCiliumPods: true  # 순차적 Cilium Pod 롤아웃

# 업데이트 전략 구성
updateStrategy:
  type: "RollingUpdate"
  rollingUpdate:
    maxUnavailable: 2  # 최대 2개 Pod까지 동시에 업데이트 허용

# PodDisruptionBudget 설정
podDisruptionBudget:
  enabled: true
  maxUnavailable: 1  # 동시에 최대 1개의 Pod만 중단 허용

✅ 카나리 배포 프로세스

카나리 배포 방식으로 일부 노드에서 먼저 새 버전을 테스트한 후 전체 클러스터로 확대하는 전략입니다:

# 1. 특정 노드에 레이블 지정 (카나리 노드)
kubectl label nodes worker-1 worker-2 cilium-canary=true

# 2. Cilium 카나리 배포 (테스트 노드에만)
# 카나리 노드에만 새 버전의 Cilium 적용
cat > cilium-canary.yaml << EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: cilium-canary
  namespace: kube-system
spec:
  selector:
    matchLabels:
      k8s-app: cilium-canary
  template:
    metadata:
      labels:
        k8s-app: cilium-canary
    spec:
      nodeSelector:
        cilium-canary: "true"  # 카나리 노드에만 배포
      # 나머지 Cilium Pod 스펙은 동일하게 구성
EOF

# 3. 카나리 노드 모니터링
# 카나리 노드의 Cilium Pod 로그 확인
kubectl logs -n kube-system -l k8s-app=cilium-canary -f

# 4. 테스트 성공 시 전체 롤아웃 진행
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f production-values.yaml \
  --version 1.14.2  # 새 버전으로 업그레이드

✅ 블루/그린 배포 전략

대규모 중요 클러스터에서는 블루/그린 배포 전략을 고려할 수 있습니다:

# 1. 새 버전용 클러스터 준비 (그린 환경)
# 현재 클러스터와 동일한 구성의 새 클러스터 생성

# 2. 새 클러스터에 최신 버전 Cilium 설치
helm install cilium cilium/cilium \
  --namespace kube-system \
  -f production-values.yaml \
  --version 1.14.2  # 새 버전

# 3. 새 클러스터 검증
# 필요한 모든 테스트 및 검증 수행

# 4. 워크로드 마이그레이션
# 점진적으로 워크로드를 새 클러스터로 이동

# 5. 트래픽 전환
# 모든 트래픽을 새 클러스터로 전환

# 6. 이전 클러스터 정리
# 검증 후 이전 클러스터 자원 정리

✅ 업데이트 중 문제 발생 시 롤백 절차

문제가 발생할 경우 신속하게 이전 버전으로 돌아갈 수 있는 롤백 절차가 필요합니다:

# 1. Helm을 통한 롤백
# 이전 릴리스로 롤백
helm rollback cilium 1 -n kube-system  # 1은 이전 릴리스 번호

# 2. 특정 버전으로 다운그레이드
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f production-values.yaml \
  --version 1.14.1  # 이전 안정 버전으로 롤백

# 3. 백업에서 복원 (필요한 경우)
kubectl apply -f ./cilium-backup/cilium-network-policies.yaml
kubectl apply -f ./cilium-backup/cilium-clusterwide-policies.yaml

📌 Cilium 장애 시 문제 해결 절차

네트워크 CNI 장애는 클러스터 전체에 영향을 미칠 수 있으므로, 신속하고 체계적인 대응이 중요합니다.

✅ 문제 감지 및 원인 파악

# 1. Cilium 상태 확인
# Cilium 에이전트 상태 확인
cilium status --verbose

# Cilium 컴포넌트 Pod 상태 확인
kubectl get pods -n kube-system -l k8s-app=cilium
kubectl get pods -n kube-system -l k8s-app=cilium-operator

# 2. Cilium 로그 분석
# Cilium 에이전트 로그 확인
kubectl logs -n kube-system -l k8s-app=cilium --tail=100

# Cilium 오퍼레이터 로그 확인
kubectl logs -n kube-system -l k8s-app=cilium-operator --tail=100

# 3. 노드 상태 확인
# 노드 네트워크 상태 확인
kubectl get nodes -o wide

# 노드별 Cilium 상태 확인
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
  echo "Checking node $node:"
  kubectl exec -n kube-system $(kubectl get pods -n kube-system -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$node'")].metadata.name}') -- cilium status
done

# 4. 엔드포인트 상태 확인
# Cilium 엔드포인트 상태 확인
cilium endpoint list

# 특정 Pod의 Cilium 엔드포인트 세부 정보
kubectl get pods -o wide | grep <pod-name>
PODIP=<pod-ip>
cilium endpoint list | grep $PODIP

# 5. 네트워크 정책 확인
# Cilium 네트워크 정책 확인
kubectl get ciliumnetworkpolicies --all-namespaces

# 정책 세부 정보 확인
kubectl describe ciliumnetworkpolicies <policy-name> -n <namespace>

✅ 공통 장애 시나리오 및 해결책

시나리오 1: Pod에 IP 할당 실패

# 증상: Pod가 "ContainerCreating" 상태에 멈춤

# 1. 진단
# Pod 상태 확인
kubectl describe pod <pod-name> -n <namespace>
# 일반적으로 "network plugin is not ready: cni config uninitialized" 같은 에러 표시됨

# Cilium 상태 확인
cilium status

# 2. 해결책
# Cilium Pod 재시작
kubectl delete pods -n kube-system -l k8s-app=cilium --field-selector spec.nodeName=<node-name>

# IPAM 상태 확인
cilium endpoint list
cilium bpf ipmasq list
cilium bpf ipmasq get

시나리오 2: Pod 간 통신 불가

# 증상: Pod 간 네트워크 통신이 동작하지 않음

# 1. 진단
# 두 Pod 사이의 연결 테스트
kubectl exec -it <source-pod> -- ping <destination-pod-ip>

# 네트워크 정책 확인
kubectl get ciliumnetworkpolicies --all-namespaces
kubectl get networkpolicies --all-namespaces

# Hubble을 통한 트래픽 관찰
hubble observe --pod-to <destination-pod> --pod-from <source-pod>

# 2. 해결책
# 네트워크 정책 확인 및 수정
kubectl describe ciliumnetworkpolicies -n <namespace>

# eBPF 맵 확인
cilium bpf policy get <endpoint-id>

# eBPF 프로그램 재생성
cilium endpoint regenerate <endpoint-id>

시나리오 3: DNS 해결 문제

# 증상: DNS 쿼리가 실패하거나 제대로 해결되지 않음

# 1. 진단
# CoreDNS 및 Cilium 상태 확인
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get pods -n kube-system -l k8s-app=cilium

# DNS 프록시 설정 확인
cilium config | grep dns-proxy

# DNS 쿼리 관찰
hubble observe --protocol dns

# 2. 해결책
# Cilium DNS 프록시 재설정
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --set "dnsProxy.enabled=true"

# CoreDNS와 Cilium 재시작
kubectl delete pods -n kube-system -l k8s-app=kube-dns
kubectl delete pods -n kube-system -l k8s-app=cilium

시나리오 4: Cilium 에이전트 충돌 또는 높은 CPU 사용률

# 증상: Cilium Pod가 지속적으로 재시작하거나 CPU 사용률이 비정상적으로 높음

# 1. 진단
# Cilium Pod 로그 및 상태 확인
kubectl logs -n kube-system <cilium-pod> -p  # 이전 인스턴스 로그
kubectl top pods -n kube-system <cilium-pod>  # 리소스 사용률 확인

# 커널 로그 확인 (노드에서)
journalctl -k | grep -i bpf

# 2. 해결책
# 리소스 제한 조정
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --set "resources.cilium.limits.cpu=2000m" \
  --set "resources.cilium.limits.memory=2Gi"

# eBPF 프로그램 최적화 설정
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  --reuse-values \
  --set "bpf.preallocateMaps=true" \
  --set "bpf.monitorAggregation=medium"

✅ 긴급 복구 절차

심각한 네트워크 장애 상황에서의 긴급 복구 절차:

# 1. Cilium CNI 임시 비활성화 (극단적 상황에서만 사용)
# 주의: 이 방법은 임시 조치이며 네트워크 정책이 적용되지 않음

# kubelet CNI 디렉토리 백업 (각 노드에서)
ssh <node> "sudo cp -r /etc/cni/net.d /etc/cni/net.d.backup"

# Cilium CNI 설정 임시 제거 (각 노드에서)
ssh <node> "sudo rm -f /etc/cni/net.d/05-cilium.conf"

# 기본 CNI로 대체 (kubenet 등)
ssh <node> "sudo cp /etc/cni/net.d.backup/10-kubenet.conf /etc/cni/net.d/"

# kubelet 재시작
ssh <node> "sudo systemctl restart kubelet"

# 2. 임시 연결성 확보 후 단계적 복구
# Cilium 완전 제거
helm uninstall cilium -n kube-system

# 모든 Cilium 리소스 정리
kubectl delete daemonset -n kube-system cilium
kubectl delete deployment -n kube-system cilium-operator
kubectl delete pods -n kube-system -l k8s-app=cilium
kubectl delete pods -n kube-system -l k8s-app=cilium-operator
kubectl delete cm -n kube-system cilium-config

# 노드 상태 초기화 (각 노드에서)
ssh <node> "sudo rm -rf /var/run/cilium /var/lib/cilium"

# Cilium 재설치 (안정 버전으로)
helm install cilium cilium/cilium \
  --namespace kube-system \
  -f production-values.yaml \
  --version 1.14.1

📌 클러스터 규모별 운영 전략

클러스터의 규모에 따라 Cilium 운영 전략이 달라질 수 있습니다.

✅ 소규모 클러스터 (10노드 이하)

소규모 클러스터에서는 간단한 설정으로 빠른 배포와 관리가 가능합니다.

# small-cluster-values.yaml
# 기본 설정에 몇 가지 최적화 적용

# 필수 컴포넌트만 활성화
hubble:
  enabled: true
  relay:
    enabled: true  # 네트워크 가시성 목적
  ui:
    enabled: false  # 필요 시 활성화

# 간소화된 리소스 설정
resources:
  cilium:
    limits:
      cpu: "500m"
      memory: "512Mi"
    requests:
      cpu: "100m"
      memory: "128Mi"

# 단일 오퍼레이터로 충분
operator:
  replicas: 1

# 기본 네트워킹 설정
tunnel: "vxlan"  # 간단하고 안정적인 옵션
kubeProxyReplacement: "probe"  # 호환성 유지

# 업데이트 전략
updateStrategy:
  type: "RollingUpdate"
  rollingUpdate:
    maxUnavailable: 1  # 작은 클러스터에서는 한 번에 하나씩

소규모 클러스터 관리 팁:

# 모든 컴포넌트 상태를 한 번에 확인
kubectl get pods -n kube-system -l k8s-app=cilium
kubectl get pods -n kube-system -l k8s-app=cilium-operator

# 전체 클러스터 네트워크 상태 점검
cilium status --verbose
cilium connectivity test

✅ 중규모 클러스터 (10-50 노드)

중규모 클러스터에서는 고가용성 구성과 효율적인 모니터링이 중요합니다.

# medium-cluster-values.yaml
# 고가용성과 모니터링 강화

# 고가용성 구성
operator:
  replicas: 2  # 오퍼레이터 HA 구성

# 향상된 모니터링
prometheus:
  enabled: true
  serviceMonitor:
    enabled: true

# 모니터링 대시보드
grafana:
  enabled: true

# 네트워크 가시성 완전 활성화
hubble:
  enabled: true
  metrics:
    enabled:
      - dns
      - drop
      - tcp
      - flow
      - icmp
      - http
  relay:
    enabled: true
  ui:
    enabled: true

# 적절한 리소스 할당
resources:
  cilium:
    limits:
      cpu: "1000m"
      memory: "1Gi"
    requests:
      cpu: "250m"
      memory: "512Mi"

# 롤링 업데이트 전략
updateStrategy:
  rollingUpdate:
    maxUnavailable: 3  # 최대 3개 노드 동시 업데이트

 

중규모 클러스터 운영 팁:

# 효율적인 모니터링 설정
# 1. AlertManager 규칙 설정
cat > cilium-alerts.yaml << EOF
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: cilium-alerts
  namespace: monitoring
spec:
  groups:
  - name: cilium
    rules:
    - alert: CiliumAgentDown
      expr: up{job="cilium-agent"} == 0
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "Cilium agent down on {{ \$labels.instance }}"
        description: "Cilium agent has been down on {{ \$labels.instance }} for more than 5 minutes."
    
    - alert: CiliumHighCPUUsage
      expr: rate(process_cpu_seconds_total{job="cilium-agent"}[5m]) * 100 > 80
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "High CPU usage on Cilium agent"
        description: "Cilium agent {{ \$labels.instance }} has high CPU usage ({{ \$value }}%)."
EOF
kubectl apply -f cilium-alerts.yaml

# 2. 상태 점검 스크립트
cat > check-cilium-health.sh << 'EOF'
#!/bin/bash
echo "=== Cilium Health Status ==="
kubectl -n kube-system exec -it $(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[0].metadata.name}') -- cilium status --verbose

echo -e "\n=== Cilium Connectivity Status ==="
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
  echo "Node: $node"
  CILIUM_POD=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$node'")].metadata.name}')
  if [ -z "$CILIUM_POD" ]; then
    echo "  No Cilium pod found!"
    continue
  fi
  kubectl -n kube-system exec -it $CILIUM_POD -- cilium status --brief
  echo ""
done

echo -e "\n=== Cilium Operator Status ==="
kubectl -n kube-system get pods -l k8s-app=cilium-operator
kubectl -n kube-system logs -l k8s-app=cilium-operator --tail=20

echo -e "\n=== Endpoint Status ==="
kubectl -n kube-system exec -it $(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[0].metadata.name}') -- cilium endpoint list
EOF
chmod +x check-cilium-health.sh

✅ 대규모 클러스터 (50노드 이상)

대규모 클러스터에서는 성능 최적화와 세분화된 운영 정책이 중요합니다.

# large-cluster-values.yaml
# 성능 최적화 및 고급 기능 활성화

# 고가용성 및 확장성 구성
operator:
  replicas: 3  # 높은 가용성을 위한 복제본 수 증가
  
# 성능 최적화
bpf:
  masquerade: true       # eBPF 기반 마스커레이딩으로 성능 향상
  hostRouting: true      # 호스트 라우팅 최적화
  preallocateMaps: true  # eBPF 맵 사전 할당으로 메모리 사용 최적화
  monitorAggregation: "maximum"  # 모니터링 데이터 집계 최대화

# 네트워크 성능 최적화
loadBalancer:
  algorithm: "maglev"    # 로드 밸런싱 알고리즘 최적화
  mode: "dsr"            # 직접 서버 반환 모드로 트래픽 효율 향상
  acceleration: "native" # 네이티브 로드 밸런싱 가속

# 완전한 kube-proxy 대체
kubeProxyReplacement: "strict"

# 큰 클러스터를 위한 IPAM 최적화
ipam:
  mode: "cluster-pool"
  operator:
    clusterPoolIPv4PodCIDRList: ["10.0.0.0/8"]
    clusterPoolIPv4MaskSize: 24   # /24 서브넷으로 노드당 할당

# 업데이트 전략 세분화
updateStrategy:
  rollingUpdate:
    maxUnavailable: "10%"  # 비율 기반 업데이트

# 리소스 할당 증가
resources:
  cilium:
    limits:
      cpu: "2000m"
      memory: "2Gi"
    requests:
      cpu: "500m"
      memory: "1Gi"
  operator:
    limits:
      cpu: "1000m"
      memory: "1Gi"
    requests:
      cpu: "250m"
      memory: "512Mi"

# 노드 초기화 최적화
nodeinit:
  enabled: true
  resources:
    limits:
      cpu: "100m"
      memory: "100Mi"
    requests:
      cpu: "100m"
      memory: "100Mi"

# hubble 확장성 설정
hubble:
  enabled: true
  relay:
    enabled: true
    replicas: 3  # 복제본 증가
  ui:
    enabled: true
  metrics:
    enabled:
      - drop
      - tcp
      - flow
      - icmp
      - http

대규모 클러스터 운영 팁:

# 1. 전용 모니터링 솔루션 통합
# Prometheus 리소스 증가
cat > prometheus-values.yaml << EOF
server:
  resources:
    limits:
      cpu: 2000m
      memory: 8Gi
    requests:
      cpu: 500m
      memory: 4Gi
  retention: 15d
  
# Cilium 데이터 수집 최적화
serviceMonitors:
  - name: cilium-agent
    interval: 30s
    scrapeTimeout: 15s
  - name: cilium-operator
    interval: 30s
    scrapeTimeout: 15s
EOF

# 2. 자동화된 유지보수 스크립트
cat > cilium-maintenance.sh << 'EOF'
#!/bin/bash
# 클러스터 내 노드를 그룹으로 나누어 순차적으로 유지보수

# 구성
MAX_UNAVAILABLE=5  # 동시에 유지보수할 최대 노드 수
MAINTENANCE_TIMEOUT=600  # 각 노드 유지보수 최대 시간(초)

# 노드 목록 가져오기
NODES=($(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'))
TOTAL_NODES=${#NODES[@]}
echo "클러스터 내 총 ${TOTAL_NODES}개 노드에 대해 유지보수를 시작합니다."

# 노드 그룹으로 나누기
NODE_GROUPS=()
for ((i=0; i<${TOTAL_NODES}; i+=${MAX_UNAVAILABLE})); do
  group="${NODES[@]:$i:${MAX_UNAVAILABLE}}"
  NODE_GROUPS+=("$group")
done

# 그룹별로 유지보수 수행
for ((group_idx=0; group_idx<${#NODE_GROUPS[@]}; group_idx++)); do
  group=${NODE_GROUPS[$group_idx]}
  echo -e "\n=== 그룹 $((group_idx+1))/${#NODE_GROUPS[@]} 유지보수 시작 ==="
  echo "대상 노드: $group"
  
  # 이 그룹의 노드들에 대해 유지보수 모드 활성화
  for node in $group; do
    echo "[$node] 유지보수 모드 활성화..."
    kubectl cordon $node
    
    # 노드의 Cilium Pod 찾기
    CILIUM_POD=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$node'")].metadata.name}')
    if [ -z "$CILIUM_POD" ]; then
      echo "[$node] Cilium Pod를 찾을 수 없습니다."
      continue
    fi
    
    # Cilium Pod 재시작
    echo "[$node] Cilium Pod 재시작: $CILIUM_POD"
    kubectl -n kube-system delete pod $CILIUM_POD
    
    # Cilium Pod가 Ready 상태가 될 때까지 대기
    echo "[$node] Cilium Pod가 준비될 때까지 대기 중..."
    start_time=$(date +%s)
    while true; do
      current_time=$(date +%s)
      elapsed=$((current_time - start_time))
      
      if [ $elapsed -gt $MAINTENANCE_TIMEOUT ]; then
        echo "[$node] 타임아웃: Cilium Pod가 준비 상태가 되지 않았습니다."
        break
      fi
      
      NEW_CILIUM_POD=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$node'")].metadata.name}')
      if [ -z "$NEW_CILIUM_POD" ]; then
        sleep 5
        continue
      fi
      
      POD_STATUS=$(kubectl -n kube-system get pod $NEW_CILIUM_POD -o jsonpath='{.status.phase}')
      READY_STATUS=$(kubectl -n kube-system get pod $NEW_CILIUM_POD -o jsonpath='{.status.containerStatuses[0].ready}')
      
      if [[ "$POD_STATUS" == "Running" && "$READY_STATUS" == "true" ]]; then
        echo "[$node] Cilium Pod가 준비되었습니다: $NEW_CILIUM_POD"
        break
      fi
      
      sleep 5
    done
    
    # 유지보수 모드 비활성화
    echo "[$node] 유지보수 모드 비활성화..."
    kubectl uncordon $node
  done
  
  echo "=== 그룹 $((group_idx+1))/${#NODE_GROUPS[@]} 유지보수 완료 ==="
done

echo -e "\n모든 노드 유지보수가 완료되었습니다."
EOF
chmod +x cilium-maintenance.sh

# 3. 노드별 eBPF 리소스 모니터링
cat > monitor-ebpf-resources.sh << 'EOF'
#!/bin/bash
# 각 노드의 eBPF 리소스 사용량 모니터링

echo "=== eBPF 리소스 사용량 모니터링 ==="
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
  echo -e "\nNode: $node"
  CILIUM_POD=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$node'")].metadata.name}')
  
  if [ -z "$CILIUM_POD" ]; then
    echo "  No Cilium pod found!"
    continue
  fi
  
  echo "--- eBPF Map 사용량 ---"
  kubectl -n kube-system exec $CILIUM_POD -- cilium bpf map list
  
  echo "--- 프로그램 상태 ---"
  kubectl -n kube-system exec $CILIUM_POD -- cilium status --verbose | grep -A 10 "Kernel"
  
  echo "--- 메모리 상태 ---"
  kubectl -n kube-system exec $CILIUM_POD -- cilium status --verbose | grep -A 5 "Memory"
done
EOF
chmod +x monitor-ebpf-resources.sh

📌 운영 환경에서의 Cilium 튜닝 포인트

프로덕션 환경에서 Cilium을 최적화하기 위한 주요 튜닝 포인트를 살펴보겠습니다.

✅ 성능 최적화 설정

# performance-tuning-values.yaml
# 성능 최적화를 위한 주요 설정

# eBPF 튜닝
bpf:
  # 마스커레이딩을 eBPF로 수행하여 성능 향상
  masquerade: true
  
  # 호스트 라우팅 최적화
  hostRouting: true
  
  # eBPF 맵 사전 할당으로 메모리 관리 최적화
  preallocateMaps: true
  
  # 최대 엔드포인트 수 설정
  mapValues:
    # 최대 엔드포인트 수 (클러스터 크기에 맞게 조정)
    # 10k = 약 10,000개 Pod 지원
    endpoints: 65535
  
  # 모니터링 이벤트 집계 수준
  # none, low, medium, maximum
  monitorAggregation: "medium"
  
  # 모니터링 큐 크기
  monitorQueueSize: 32768
  
  # CT(Connection Tracking) 이벤트 수집 마스크
  # - succ: 성공한 연결
  # - timewait: TIME_WAIT 상태의 연결 
  # - close: 종료된 연결
  # 프로덕션에서는 최소한의 이벤트만 수집하도록 설정
  ctTcpMax: 524288
  ctAnyMax: 262144
  
# Hubble 최적화
hubble:
  enabled: true
  # 플로우 버퍼 크기
  flowBufferSize: 65535
  
  # 메트릭 최적화
  metrics:
    enabled:
      - drop # 드롭된 패킷만 메트릭으로 수집 (최소화)
  
  # Relay 설정
  relay:
    enabled: true
    replicas: 2
    resources:
      limits:
        cpu: 1000m
        memory: 1Gi
      requests:
        cpu: 100m
        memory: 512Mi

# 프록시 최적화
proxy:
  # 프록시 리소스 제한
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 1000m
      memory: 512Mi

# 노드 초기화 설정
nodeinit:
  enabled: true
  # 커널 파라미터 최적화
  extraEnv:
    - name: SYSCTL_CONNTRACK_MAX
      value: "1000000" # 최대 커넥션 트래킹 수
    - name: SYSCTL_CONNTRACK_TCP_TIMEOUT_ESTABLISHED
      value: "86400" # 24시간 (초 단위)

# 리소스 설정
resources:
  cilium:
    requests:
      cpu: 500m
      memory: 512Mi
    limits:
      cpu: 2000m
      memory: 2Gi

✅ 시스템 수준 최적화

Cilium 성능을 최대화하기 위한 시스템 수준 설정:

# 노드 커널 파라미터 최적화 스크립트
cat > optimize-node-kernel.sh << 'EOF'
#!/bin/bash
# Cilium 성능을 위한 커널 파라미터 최적화

# 커넥션 트래킹 설정
echo "net.netfilter.nf_conntrack_max=1000000" >> /etc/sysctl.conf
echo "net.netfilter.nf_conntrack_tcp_timeout_established=86400" >> /etc/sysctl.conf

# 네트워크 성능 설정
echo "net.core.somaxconn=32768" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog=8192" >> /etc/sysctl.conf
echo "net.ipv4.tcp_fin_timeout=30" >> /etc/sysctl.conf
echo "net.ipv4.tcp_keepalive_time=600" >> /etc/sysctl.conf
echo "net.core.netdev_max_backlog=5000" >> /etc/sysctl.conf
echo "net.ipv4.tcp_rmem=4096 87380 16777216" >> /etc/sysctl.conf
echo "net.ipv4.tcp_wmem=4096 65536 16777216" >> /etc/sysctl.conf
echo "net.core.rmem_max=16777216" >> /etc/sysctl.conf
echo "net.core.wmem_max=16777216" >> /etc/sysctl.conf

# eBPF 관련 설정
echo "kernel.perf_event_paranoid=0" >> /etc/sysctl.conf
echo "kernel.kptr_restrict=0" >> /etc/sysctl.conf

# 변경사항 적용
sysctl -p
EOF
chmod +x optimize-node-kernel.sh

# 노드 대상으로 자동화 적용 (예: kubeadm 클러스터)
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
  echo "Optimizing node: $node"
  ssh $node "sudo bash -c '$(cat optimize-node-kernel.sh)'"
done

✅ 대규모 환경을 위한 고급 설정

대규모 프로덕션 환경에서의 추가 최적화:

# large-scale-values.yaml

# kube-proxy 완전 대체
kubeProxyReplacement: "strict"

# XDP 가속 활성화 (지원 가능한 NIC에서만)
loadBalancer:
  acceleration: "native"
  mode: "dsr"  # 직접 서버 반환 모드
  algorithm: "maglev"  # 일관된 해시 알고리즘

# eBPF 기반 서비스 처리
bpfLBSockHostNSOnly: false  # 모든 네임스페이스에서 eBPF 로드 밸런싱 활성화

# 클러스터 메시 (멀티 클러스터 연결)
cluster:
  name: "cluster1"
  id: 1

clustermesh:
  enabled: true
  apiserver:
    replicas: 2
    service:
      type: LoadBalancer

# IPv6 지원
ipv6:
  enabled: true

# 네이티브 라우팅 모드 (터널 없음)
tunnel: "disabled"
autoDirectNodeRoutes: true
ipam:
  mode: "kubernetes"

# 엔드포인트 상태 GC 최적화
endpointGC:
  interval: "5m"
  timeoutSec: 86400

# 인증서 자동 교체
certgen:
  enabled: true
  image:
    pullPolicy: IfNotPresent

✅ 업그레이드 및 유지보수 자동화

업그레이드 및 유지보수 작업을 자동화하기 위한 스크립트:

# cilium-rolling-upgrade.sh
#!/bin/bash
# Cilium 롤링 업그레이드 자동화 스크립트

# 설정
TARGET_VERSION="1.14.2"
VALUES_FILE="production-values.yaml"
NAMESPACE="kube-system"
BACKUP_DIR="cilium-backup-$(date +%Y%m%d-%H%M%S)"
HEALTH_CHECK_RETRIES=10
HEALTH_CHECK_INTERVAL=30

# 백업 디렉토리 생성
mkdir -p $BACKUP_DIR

echo "=== Cilium 업그레이드 시작: 버전 $TARGET_VERSION ==="

# 1. 현재 상태 백업
echo "현재 상태 백업 중..."
kubectl get ciliumnetworkpolicies --all-namespaces -o yaml > $BACKUP_DIR/cilium-network-policies.yaml
kubectl get ciliumclusterwidenetworkpolicies -o yaml > $BACKUP_DIR/cilium-clusterwide-policies.yaml
helm get values cilium -n $NAMESPACE -o yaml > $BACKUP_DIR/previous-values.yaml

# 2. 사전 점검
echo "사전 점검 수행 중..."
cilium status
if [ $? -ne 0 ]; then
  echo "Cilium이 정상 상태가 아닙니다. 업그레이드를 중단합니다."
  exit 1
fi

# 노드 상태 확인
NODE_COUNT=$(kubectl get nodes -o name | wc -l)
READY_NODES=$(kubectl get nodes | grep -c "Ready")
if [ $READY_NODES -ne $NODE_COUNT ]; then
  echo "모든 노드가 Ready 상태가 아닙니다. 업그레이드를 중단합니다."
  exit 1
fi

# 3. Helm 업그레이드 수행
echo "Cilium 업그레이드 중... 버전: $TARGET_VERSION"
helm upgrade cilium cilium/cilium \
  --namespace $NAMESPACE \
  -f $VALUES_FILE \
  --version $TARGET_VERSION

if [ $? -ne 0 ]; then
  echo "Helm 업그레이드가 실패했습니다. 이전 상태로 복원합니다."
  # 자동 롤백 시도
  helm rollback cilium 1 -n $NAMESPACE
  exit 1
fi

# 4. 업그레이드 완료 대기
echo "업그레이드 완료 대기 중..."
for ((i=1; i<=$HEALTH_CHECK_RETRIES; i++)); do
  echo "상태 확인 중... ($i/$HEALTH_CHECK_RETRIES)"
  
  # Cilium Pod 준비 상태 확인
  CILIUM_PODS=$(kubectl get pods -n $NAMESPACE -l k8s-app=cilium -o name | wc -l)
  CILIUM_READY=$(kubectl get pods -n $NAMESPACE -l k8s-app=cilium | grep -c "Running")
  
  # Cilium Operator 준비 상태 확인
  OPERATOR_PODS=$(kubectl get pods -n $NAMESPACE -l k8s-app=cilium-operator -o name | wc -l)
  OPERATOR_READY=$(kubectl get pods -n $NAMESPACE -l k8s-app=cilium-operator | grep -c "Running")
  
  if [ $CILIUM_PODS -eq $CILIUM_READY ] && [ $OPERATOR_PODS -eq $OPERATOR_READY ]; then
    echo "모든 Cilium 컴포넌트가 준비되었습니다."
    
    # Cilium 상태 확인
    cilium status
    if [ $? -eq 0 ]; then
      echo "Cilium 상태 정상: 업그레이드 성공!"
      exit 0
    fi
  fi
  
  # 아직 준비되지 않음, 대기 후 재시도
  echo "Cilium 준비 대기 중... $HEALTH_CHECK_INTERVAL초 후 재확인"
  sleep $HEALTH_CHECK_INTERVAL
done

# 시간 초과, 롤백 고려
echo "업그레이드 후 상태 확인 시간이 초과되었습니다. 상황을 확인하세요."
echo "필요한 경우 다음 명령으로 롤백할 수 있습니다:"
echo "  helm rollback cilium 1 -n $NAMESPACE"
exit 1

📌 실제 장애 사례 및 대응 방안

실제 현장에서 발생할 수 있는 Cilium 관련 장애 사례와 그 대응 방안을 살펴보겠습니다.

✅ 사례 1: IPAM 소진으로 인한 Pod 할당 실패

증상: 새로운 Pod가 "ContainerCreating" 상태에서 멈추고 kubectl describe pod에서 IP 할당 관련 오류가 표시됩니다.

원인: Cilium IPAM(IP Address Management)에서 할당 가능한 IP 풀이 소진되었습니다.

해결 방안:

# 1. 현재 IPAM 상태 확인
cilium status --verbose | grep -A 10 IPAM

# 2. 오류 로그 확인
kubectl logs -n kube-system -l k8s-app=cilium-operator | grep -i "ipam\|allocation\|pool"

# 3. 해결책 적용: IPAM 풀 확장
# values.yaml 파일 수정
cat > ipam-update.yaml << EOF
ipam:
  mode: "cluster-pool"  # 클러스터 풀 모드
  operator:
    clusterPoolIPv4PodCIDRList: 
      - "10.0.0.0/8"    # 더 넓은 CIDR 범위
    clusterPoolIPv4MaskSize: 24  # /24 서브넷 마스크 (노드당 할당)
EOF

# Helm을 통한 설정 업데이트
helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f ipam-update.yaml \
  --reuse-values

# 4. 기존 IP 할당 정리 (필요한 경우)
# 종료된/실패한 Pod의 IP 정리
for ns in $(kubectl get namespaces -o jsonpath='{.items[*].metadata.name}'); do
  # Failed 또는 Unknown 상태의 Pod 정리
  for pod in $(kubectl get pods -n $ns -o jsonpath='{range .items[?(@.status.phase=="Failed" || @.status.phase=="Unknown")]}{.metadata.name}{"\n"}{end}'); do
    echo "Deleting failed pod: $ns/$pod"
    kubectl delete pod -n $ns $pod --force
  done
done

✅ 사례 2: Cilium 에이전트 충돌 및 메모리 누수

증상: Cilium Pod가 주기적으로 재시작하거나 OOM(Out of Memory) 오류로 종료됩니다.

원인: eBPF 맵 과다 사용 또는 메모리 누수로 인한 리소스 소진.

해결 방안:

# 1. 문제 진단
# 메모리 사용량 확인
kubectl top pods -n kube-system -l k8s-app=cilium

# OOM 관련 로그 확인
kubectl logs -n kube-system -l k8s-app=cilium --previous | grep -i "OOM\|memory\|killed"

# 노드의 시스템 로그 확인 (SSH 접속 필요)
ssh <node> "sudo journalctl -k | grep -i 'oom\|memory\|cilium'"

# 2. 단기 해결: 리소스 제한 증가
cat > memory-fix.yaml << EOF
resources:
  cilium:
    limits:
      memory: "4Gi"  # 메모리 한도 증가
      cpu: "2000m"   # CPU 한도 증가
    requests:
      memory: "512Mi"
      cpu: "250m"
EOF

helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f memory-fix.yaml \
  --reuse-values

# 3. 장기 해결: 메모리 최적화 설정
cat > memory-optimization.yaml << EOF
bpf:
  # eBPF 맵 사전 할당으로 메모리 최적화
  preallocateMaps: true
  
  # 모니터링 최적화
  monitorAggregation: "medium"
  monitorInterval: "5s"
  monitorFlags: "syn"  # 최소 패킷만 모니터링
  
  # TCP 연결 추적 최적화
  ctTcpMax: 262144     # 최대 TCP 연결 수 조정
  ctAnyMax: 131072     # 최대 non-TCP 연결 수 조정
  
  # 맵 값 최적화 (클러스터 크기에 맞게 조정)
  mapValues:
    # 동시 연결 수 기반 설정
    conntrack: 262144  # 최대 연결 추적 항목
    lbmap: 16384       # 최대 로드밸런싱 항목
    nat: 16384         # 최대 NAT 항목
    endpoints: 16384   # 최대 엔드포인트 수
    
hubble:
  # Hubble 최적화
  enabled: true
  metrics:
    enabled: []        # 필요한 메트릭만 활성화
  relay:
    enabled: false     # 필요한 경우에만 활성화
  ui:
    enabled: false     # 필요한 경우에만 활성화
EOF

helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f memory-optimization.yaml \
  --reuse-values

✅ 사례 3: 네트워크 정책 문제로 인한 서비스 통신 실패

증상: 특정 Pod 간 통신이 예상치 않게 차단됩니다.

원인: 잘못 구성된 CiliumNetworkPolicy 또는 정책 충돌.

해결 방안:

# 1. 현재 적용된 정책 확인
kubectl get ciliumnetworkpolicies --all-namespaces
kubectl get ciliumclusterwidenetworkpolicies

# 2. 문제 진단
# 특정 Pod 간 트래픽 확인
hubble observe --pod-from <source-pod> --pod-to <destination-pod> --verdict DROPPED

# 특정 네임스페이스의 드롭된 모든 트래픽 확인
hubble observe --namespace <namespace> --verdict DROPPED

# 정책에 의해 드롭된 트래픽 확인
hubble observe --verdict DROPPED -o json | jq 'select(.drop_reason == "Policy denied")'

# 3. 정책 디버깅
# 문제가 되는 정책 상세 조회
kubectl describe ciliumnetworkpolicies <policy-name> -n <namespace>

# 4. 임시 해결: 문제가 되는 정책 비활성화
kubectl delete ciliumnetworkpolicies <policy-name> -n <namespace>

# 5. 정책 테스트 및 수정
# 테스트 정책 생성
cat > test-policy.yaml << EOF
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "test-allow-policy"
  namespace: <namespace>
spec:
  description: "Test policy to allow specific traffic"
  endpointSelector:
    matchLabels:
      app: <destination-app>
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: <source-app>
    toPorts:
    - ports:
      - port: "<port>"
        protocol: TCP
EOF

# 정책 적용 및 검증
kubectl apply -f test-policy.yaml
hubble observe --pod-from <source-pod> --pod-to <destination-pod>

# 6. 디버깅 도구: 실시간 정책 테스트
# 실시간으로 정책 허용/거부 상태 모니터링하는 스크립트
cat > policy-debug.sh << 'EOF'
#!/bin/bash
SOURCE_POD="$1"
DEST_POD="$2"
PORT="${3:-80}"

if [ -z "$SOURCE_POD" ] || [ -z "$DEST_POD" ]; then
  echo "Usage: $0 <source-pod> <dest-pod> [port]"
  exit 1
fi

echo "Starting policy debug between $SOURCE_POD and $DEST_POD on port $PORT..."
echo "Press Ctrl+C to stop."

# 정책 상태 모니터링 시작
hubble observe --pod-from $SOURCE_POD --pod-to $DEST_POD --follow &
HUBBLE_PID=$!

# 실제 트래픽 생성
kubectl exec -it $SOURCE_POD -- bash -c "while true; do curl -m 1 -s $DEST_POD:$PORT >/dev/null; sleep 2; done" &
TRAFFIC_PID=$!

# 종료 핸들러
trap 'kill $HUBBLE_PID $TRAFFIC_PID 2>/dev/null' EXIT

# 대기
read -p "Press Enter to stop debugging..."
EOF
chmod +x policy-debug.sh

# 스크립트 실행
./policy-debug.sh <source-pod> <destination-pod> <port>

✅ 사례 4: 노드 간 통신 장애로 인한 클러스터 분할

증상: 특정 노드의 Pod들이 다른 노드의 Pod들과 통신할 수 없습니다.

원인: 노드 간 네트워크 연결 문제 또는 Cilium 터널 인터페이스 장애.

해결 방안:

# 1. 노드 간 연결성 확인
# 각 노드의 Cilium 상태 확인
for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
  echo "Checking node $node:"
  cilium_pod=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$node'")].metadata.name}')
  if [ -z "$cilium_pod" ]; then
    echo "  No Cilium pod found on node $node!"
    continue
  fi
  
  echo "  Cilium status:"
  kubectl -n kube-system exec $cilium_pod -- cilium status --verbose | grep -A 5 "Cluster health"
  
  echo "  Tunnel interface:"
  kubectl -n kube-system exec $cilium_pod -- ip addr show cilium_vxlan
done

# 2. 연결 테스트
# 모든 노드 간 핑 테스트
for source_node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
  source_pod=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$source_node'")].metadata.name}')
  if [ -z "$source_pod" ]; then
    continue
  fi
  
  echo "Testing connectivity from node $source_node:"
  
  for dest_node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
    if [ "$source_node" = "$dest_node" ]; then
      continue
    fi
    
    dest_pod=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$dest_node'")].metadata.name}')
    if [ -z "$dest_pod" ]; then
      continue
    fi
    
    dest_ip=$(kubectl -n kube-system get pod $dest_pod -o jsonpath='{.status.podIP}')
    echo "  Pinging $dest_node ($dest_pod - $dest_ip):"
    kubectl -n kube-system exec $source_pod -- ping -c 3 $dest_ip
  done
done

# 3. 문제 해결

# 3.1 터널 인터페이스 재생성
# 문제가 있는 노드의 Cilium Pod 재시작
kubectl delete pod -n kube-system <problematic-cilium-pod>

# 3.2 네트워크 정책 확인
kubectl get ciliumnetworkpolicies --all-namespaces
kubectl get ciliumclusterwidenetworkpolicies

# 3.3 노드 네트워크 디버깅
cat > node-network-debug.sh << 'EOF'
#!/bin/bash
NODE="$1"
if [ -z "$NODE" ]; then
  echo "Usage: $0 <node-name>"
  exit 1
fi

CILIUM_POD=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$NODE'")].metadata.name}')
if [ -z "$CILIUM_POD" ]; then
  echo "No Cilium pod found on node $NODE!"
  exit 1
fi

echo "=== Node Network Debug: $NODE ==="

echo -e "\n--- Cilium Status ---"
kubectl -n kube-system exec $CILIUM_POD -- cilium status --verbose

echo -e "\n--- Network Interfaces ---"
kubectl -n kube-system exec $CILIUM_POD -- ip addr

echo -e "\n--- Routing Table ---"
kubectl -n kube-system exec $CILIUM_POD -- ip route

echo -e "\n--- eBPF Maps ---"
kubectl -n kube-system exec $CILIUM_POD -- cilium bpf tunnel list

echo -e "\n--- Endpoint Information ---"
kubectl -n kube-system exec $CILIUM_POD -- cilium endpoint list -o json | jq '.[] | {id, status, identity, labels, networking}'

echo -e "\n--- Nodes Information ---"
kubectl -n kube-system exec $CILIUM_POD -- cilium node list

echo -e "\n--- Connectivity Tests ---"
echo "Testing 8.8.8.8:"
kubectl -n kube-system exec $CILIUM_POD -- ping -c 3 8.8.8.8 || echo "Failed to ping 8.8.8.8"

echo "Testing kubernetes.default:"
kubectl -n kube-system exec $CILIUM_POD -- curl -k https://kubernetes.default || echo "Failed to connect to kubernetes.default"

echo -e "\n=== Debug Complete ==="
EOF
chmod +x node-network-debug.sh

# 노드 디버깅 실행
./node-network-debug.sh <problematic-node>

# 3.4 터널 모드 변경 (심각한 경우)
cat > tunnel-fix.yaml << EOF
# vxlan에서 geneve로 변경
tunnel: "geneve"

# 또는 터널 비활성화하고 직접 라우팅으로 전환
# tunnel: "disabled"
# autoDirectNodeRoutes: true
EOF

helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f tunnel-fix.yaml \
  --reuse-values

✅ 사례 5: 커널 호환성 문제

증상: Cilium Pod가 시작되지만 계속 충돌하거나 특정 eBPF 기능이 작동하지 않습니다.

원인: 호스트 커널 버전이 Cilium의 eBPF 기능을 완전히 지원하지 않습니다.

해결 방안:

# 1. 커널 버전 확인
kubectl get nodes -o custom-columns=NAME:.metadata.name,KERNEL:.status.nodeInfo.kernelVersion

# 2. Cilium 진단 로그 확인
for pod in $(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[*].metadata.name}'); do
  echo "Checking pod $pod:"
  kubectl -n kube-system logs $pod | grep -i "kernel\|bpf\|feature\|unsupported"
done

# 3. 이슈가 있는 노드의 Cilium 에이전트 로그 분석
kubectl -n kube-system logs <problematic-cilium-pod> | grep -i "error\|fail\|warning"

# 4. 호환성 모드로 전환
cat > compatibility-mode.yaml << EOF
# eBPF 호환성 설정
bpf:
  # 특정 기능 비활성화
  hostRouting: false
  masquerade: false
  
# kube-proxy 대체 비활성화하고 kube-proxy 사용
kubeProxyReplacement: "disabled"

# 기본 터널 모드 사용
tunnel: "vxlan"

# 기타 고급 기능 비활성화
loadBalancer:
  acceleration: "disabled"
  mode: "snat"

# 특정 호스트 환경 감지 비활성화
enableRuntimeDeviceDetection: false
EOF

helm upgrade cilium cilium/cilium \
  --namespace kube-system \
  -f compatibility-mode.yaml \
  --reuse-values

# 5. 노드별 eBPF 기능 감지 도구
cat > ebpf-feature-detect.sh << 'EOF'
#!/bin/bash
# 각 노드의 eBPF 기능 지원 여부 확인

for node in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
  echo "Node: $node"
  cilium_pod=$(kubectl -n kube-system get pods -l k8s-app=cilium -o jsonpath='{.items[?(@.spec.nodeName=="'$node'")].metadata.name}')
  
  if [ -z "$cilium_pod" ]; then
    echo "  No Cilium pod found!"
    continue
  fi
  
  echo "  Checking eBPF features:"
  kubectl -n kube-system exec $cilium_pod -- cilium-dbg kernel-check || echo "  Failed to run kernel check"
done
EOF
chmod +x ebpf-feature-detect.sh

# 스크립트 실행
./ebpf-feature-detect.sh

📌 Summary

이 글에서는 프로덕션 환경에서 Cilium을 안정적으로 운영하기 위한 전략과 방법론을 살펴보았습니다. 주요 내용을 요약하면 다음과 같습니다:

  • Helm 기반 관리: Cilium을 Helm 차트로 관리하여 배포, 업그레이드, 롤백을 체계적으로 수행할 수 있습니다. values.yaml 파일을 통해 다양한 환경에 맞게 구성을 최적화할 수 있습니다.
  • 롤링 업데이트 전략: 카나리 배포, 블루/그린 배포 등의 방법으로 안전하게 Cilium을 업데이트할 수 있습니다. 특히 대규모 클러스터에서는 점진적인 롤아웃 전략이 중요합니다.
  • 장애 복구 절차: 네트워크 정책 문제, IP 할당 실패, 에이전트 충돌 등 다양한 장애 상황에 대한 체계적인 대응 방안을 마련해야 합니다. 문제 식별부터 해결까지의 프로세스를 명확히 정립하는 것이 중요합니다.
  • 규모별 운영 전략: 소규모, 중규모, 대규모 클러스터에 따라 Cilium 구성과 운영 방식을 차별화하여 최적의 성능과 안정성을 확보할 수 있습니다.
  • 성능 최적화: eBPF 설정, 시스템 커널 파라미터, 리소스 할당 등 다양한 측면에서 Cilium 성능을 최적화할 수 있는 방법이 있습니다. 특히 대규모 환경에서는 세밀한 튜닝이 필요합니다.
  • 자동화 및 모니터링: 운영 작업을 자동화하고 모니터링 시스템을 구축하여 문제를 사전에 감지하고 신속하게 대응할 수 있는 체계를 갖추는 것이 중요합니다.

프로덕션 환경에서 Cilium을 운영할 때는 단순히 기능적인 측면뿐만 아니라, 안정성, 성능, 확장성, 유지보수성 등 다양한 운영 요소를 고려해야 합니다. 또한 지속적인 모니터링과 주기적인 유지보수를 통해 클러스터 네트워크 인프라를 건강하게 유지하는 것이 중요합니다.

728x90