LabHub
배우기 러닝패스 코스

CCA — Cilium Certified Associate

Declaring a Cluster Without kube-proxy

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

kube-proxy 를 대체하는 Cilium 설정을 값 파일로 정확히 선언하고, 실제 워크로드와 서비스로 백엔드가 잡히는 과정을 확인하며, "정말 kube-proxy 가 없는가"를 스스로 증명하는 스크립트를 만듭니다.

왜 중요한가

kubeProxyReplacement: true 한 줄이면 끝날 것 같지만 현장에서는 그렇지 않습니다. k8sServiceHost 를 빼면 Cilium 이 부팅 중 API 서버를 찾지 못해 클러스터 전체가 올라오지 않고, 기존 클러스터에서 kube-proxy 를 제거하며 전환하면 노드에 남은 KUBE- 체인이 eBPF 경로와 충돌합니다. 그래서 실무의 정석은 처음부터 설치하지 않는 것이고, 그것이 실제로 이뤄졌는지는 체인 개수를 세어 확인해야 합니다.

이 실습은 그 과정을 세 갈래로 나눠 익힙니다. 값 파일 작성은 "무엇을 켜는가"를, 실제 리소스 apply 는 "라벨과 셀렉터가 어떻게 백엔드를 만드는가"를, 검증 스크립트는 "어떻게 증명하는가"를 다룹니다. 세 번째가 특히 중요합니다. 문서에 적힌 기능과 이 노드에서 실제로 동작하는 것은 다른 명제입니다.

Cilium Helm values 와 스크립트는 /root/cca-config/ 아래에 작성하고, Kubernetes 기본 리소스는 실제로 apply 합니다.

단계

  1. 네임스페이스 cca-net 을 만드세요.
  2. /root/cca-config/cilium-values.yaml 을 만들고 최상위에 kubeProxyReplacement: true, k8sServiceHost: 10.0.0.120, k8sServicePort: 6443, 그리고 ipam.mode: kubernetes 를 쓰세요.
  3. 같은 파일에 이어서 routingMode: tunnel, tunnelProtocol: vxlan, bpf.masquerade: true, l7Proxy: true, encryption.enabled: true, encryption.type: wireguard 를 추가하세요.
  4. 노드 lab-node-0lab-node-1 에 라벨 cca.homelab/tier=gpu 를, 노드 lab-node-2 에 라벨 cca.homelab/tier=cpu 를 붙이세요.
  5. 네임스페이스 cca-net 에 디플로이먼트 web 을 3 레플리카로 배포하세요. 파드 라벨은 app=web, 이미지는 nginx:1.27-alpine, 파드 스펙의 nodeSelectorcca.homelab/tier: gpu 입니다.
  6. 같은 네임스페이스에 서비스 web 을 만드세요. 타입은 ClusterIP, port80, targetPort8080, selector 는 app=web 입니다.
  7. /root/cca-config/verify-kubeproxy-free.sh 를 작성하고 실행 권한을 주세요. 이 스크립트는 (1) kubectl 로 kube-system 의 kube-proxy 파드 개수를 세고, (2) iptables-save 출력에서 KUBE- 체인 개수를 세고, (3) cilium 상태에서 KubeProxyReplacement 값을 확인해야 합니다. 개수가 0 이 아니면 메시지를 출력하고 exit 1 로 끝내세요.

참고

실습 네임스페이스 만들기

네임스페이스 cca-net 을 만드세요.

가장 단순한 첫 단계입니다. 이름만 정확히 맞추세요.

kube-proxy 대체 핵심 값 쓰기

/root/cca-config/cilium-values.yaml 을 만들고 최상위에 kubeProxyReplacement: true, k8sServiceHost: 10.0.0.120, k8sServicePort: 6443, 그리고 ipam.mode: kubernetes 를 쓰세요.

kube-proxy 가 없으면 Cilium 자신이 API 서버 VIP 를 풀어 줄 주체인데, 부트스트랩 시점에는 아직 뜨지 않았습니다. 그래서 실제 주소를 따로 알려 줘야 합니다. IPAM 은 노드의 PodCIDR 을 그대로 쓰는 모드를 고르세요.

데이터패스 옵션 채우기

같은 파일에 이어서 routingMode: tunnel, tunnelProtocol: vxlan, bpf.masquerade: true, l7Proxy: true, encryption.enabled: true, encryption.type: wireguard 를 추가하세요.

같은 파일에 이어서 씁니다. 언더레이가 PodCIDR 경로를 모르는 홈랩이니 캡슐화가 필요하고, SNAT 도 iptables 가 아니라 eBPF 로 넘겨야 합니다. HTTP 메서드 단위 정책을 쓰려면 켜야 하는 스위치가 하나 더 있습니다.

노드에 체급 라벨 붙이기

노드 lab-node-0lab-node-1 에 라벨 cca.homelab/tier=gpu 를, 노드 lab-node-2 에 라벨 cca.homelab/tier=cpu 를 붙이세요.

쿠버네티스 입장에서는 모든 GPU 가 그냥 GPU 1개입니다. 의미 있는 배치를 하려면 사람이 라벨로 의미를 심어야 합니다. 라벨 키에 슬래시가 들어가는 것에 주의하세요.

배치 제약이 붙은 워크로드 배포

네임스페이스 cca-net 에 디플로이먼트 web 을 3 레플리카로 배포하세요. 파드 라벨은 app=web, 이미지는 nginx:1.27-alpine, 파드 스펙의 nodeSelectorcca.homelab/tier: gpu 입니다.

파드 템플릿에 nodeSelector 를 넣습니다. 앞 단계에서 붙인 라벨 키와 값이 정확히 같아야 하고, 어긋나면 파드가 Pending 에 머뭅니다.

서비스로 묶고 백엔드 확인하기

같은 네임스페이스에 서비스 web 을 만드세요. 타입은 ClusterIP, port80, targetPort8080, selector 는 app=web 입니다.

서비스 포트와 컨테이너 포트는 다를 수 있습니다. selector 가 파드 라벨과 어긋나면 서비스는 만들어지지만 백엔드가 0개가 됩니다. 이 상태가 kube-proxy 든 eBPF 든 트래픽이 안 가는 가장 흔한 원인입니다.

검증 스크립트 작성하기

/root/cca-config/verify-kubeproxy-free.sh 를 작성하고 실행 권한을 주세요. 이 스크립트는 (1) kubectl 로 kube-system 의 kube-proxy 파드 개수를 세고, (2) iptables-save 출력에서 KUBE- 체인 개수를 세고, (3) cilium 상태에서 KubeProxyReplacement 값을 확인해야 합니다. 개수가 0 이 아니면 메시지를 출력하고 exit 1 로 끝내세요.

주장이 아니라 측정이어야 합니다. kube-proxy 파드 개수와 노드의 KUBE- 체인 개수를 세어 0 인지 확인하고, Cilium 쪽 상태도 함께 봐야 합니다. 실패하면 0 이 아닌 종료 코드를 내고, 파일에 실행 권한도 주세요.