Service LB _ IPAM
- LB IPAM은 Cilium이 IP 주소를 LoadBalancer 유형의 서비스에 할당할 수 있게 해주는 기능입니다. 이 기능은 일반적으로 클라우드 제공업체에 맡겨지지만, 프라이빗 클라우드 환경에 배포할 때 이러한 기능을 항상 사용할 수 있는 것은 아닙니다.
- 프라이빗 클라우드에서 LoadBalancer 서비스를 배포할 때 가장 흔한 고민 중 하나는 IP 할당입니다. 퍼블릭 클라우드에서는 클라우드 제공업체가 이를 자동으로 처리해주지만, 프라이빗 클라우드에서는 IP를 어떻게 할당하고 광고할지 사용자가 직접 고민해야 하죠.
👉 Cilium을 사용 계획 중이라면 LB IPAM + BGP Control Plane 조합이 MetalLB보다 자연스럽고 강력한 선택일 수 있습니다.
🔍 LB IPAM이란?
LB IPAM (LoadBalancer IP Address Management) 은 Cilium이 LoadBalancer 타입의 서비스 객체에 External IP를 자동으로 할당할 수 있게 해주는 기능입니다.
- 일반적으로 클라우드 제공업체가 담당하는 기능을 대체
- 프라이빗 클라우드 환경에서 유용
- 외부 트래픽 진입을 위한 IP 할당 및 관리 자동화

주요 기능
🧩 주요 기능: Cilium LB IPAM이 제공하는 유연한 IP 관리 기능
- Service Selectors: 라벨로 특정 서비스만 IPAM 대상으로 지정
- Pool 비활성화: IP 풀을 동적으로 활성화/비활성화
- 서비스 확인: 어떤 서비스가 LB IPAM을 사용하는지 조회
- LoadBalancerClass 지정: 광고 방식을 BGP 또는 L2로 설정
- IP 직접 요청: 특정 서비스에 IP를 수동으로 지정
- Sharing Keys: 하나의 EX-IP를 여러 서비스가 포트로 공유
🚀 실습 : Cilium LB IPAM 테스트하기
- [k8s 클러스터 내부] webpod 서비스를 LoadBalancer Type 설정 with Cilium LB IPAM
# cilium ip pool 생성
kubectl get CiliumLoadBalancerIPPool -A
# 충돌나지 않는지 대역 확인 할 것!
cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2" # v1.17 : cilium.io/v2alpha1
kind: CiliumLoadBalancerIPPool
metadata:
name: "cilium-lb-ippool"
spec:
blocks:
- start: "192.168.10.211"
stop: "192.168.10.215"
EOF

service Type 변경
kubectl patch svc webpod -p '{"spec":{"type":"LoadBalancer"}}'

LB IP 로 통신 테스트
# LBIP로 curl 요청 확인 : k8s 노드들에서 LB EXIP로 통신 가능!
kubectl get svc webpod -o jsonpath='{.status.loadBalancer.ingress[0].ip}'
LBIP=$(kubectl get svc webpod -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -s $LBIP
kubectl exec -it curl-pod -- curl -s $LBIP
kubectl exec -it curl-pod -- curl -s $LBIP | grep Hostname # 대상 파드 이름 출력
kubectl exec -it curl-pod -- curl -s $LBIP | grep RemoteAddr # 대상 파드 입장에서 소스 IP 출력(Layer3)
# 반복 접속 :
while true; do kubectl exec -it curl-pod -- curl -s $LBIP | grep Hostname; sleep 0.1; done
for i in {1..100}; do kubectl exec -it curl-pod -- curl -s $LBIP | grep Hostname; done | sort | uniq -c | sort -nr
# IP 할당 확인
kubectl get ippools
kubectl get ippools -o jsonpath='{.items[*].status.conditions[?(@.type!="cilium.io/PoolConflict")]}' | jq
kubectl get svc webpod -o json | jq
kubectl get svc webpod -o jsonpath='{.status}' | jq

k8s 클러스터 외부 - 통신 안됨
[k8s 클러스터 외부] webpod 서비스를 LoadBalancer External IP로 호출 확인 → 실패
# router : K8S 외부에서 통신 불가!
LBIP=192.168.10.211
curl --connect-timeout 1 $LBIP
///
# curl: (28) Failed to connect to 192.168.10.211 port 80 after 1001 ms: Timeout was reached
arping -i eth1 $LBIP -c 1
arping -i eth1 $LBIP -c 100000
...

- L2 Announcements은 로컬 영역 네트워크에서 서비스를 가시화하고 도달할 수 있도록 하는 기능입니다. 이 기능은 주로 사무실이나 캠퍼스 네트워크와 같은 BGP 기반 라우팅 없이 네트워크 내에서 온프레미스 배포를 목적으로 합니다.
- 이 기능을 사용하면 ExternalIPs 또는 LoadBalancer IP에 대한 ARP 쿼리에 응답합니다. 이러한 IP는 여러 노드에 있는 가상 IP(네트워크 장치에 설치되지 않음)이므로 각 서비스에 대해 한 번에 하나의 노드가 ARP 쿼리에 응답하고 MAC 주소로 응답합니다. 이 노드는 서비스 로드 밸런싱 기능으로 로드 밸런싱을 수행하여 north/south 로드 밸런서 역할을 합니다.
- 이 기능의 장점은 각 서비스가 고유한 IP를 사용할 수 있어 여러 서비스가 동일한 포트 번호를 사용할 수 있다는 점입니다. NodePort를 사용할 때 트래픽을 보낼 호스트를 결정하는 것은 클라이언트의 몫이며, 노드가 다운되면 IP+Port 콤보를 사용할 수 없게 됩니다. L2 Announcements를 통해 서비스 VIP는 다른 노드로 마이그레이션하기만 하면 계속 작동하게 됩니다.
👉 Cilium_ L2 Announcements는 ARP 쿼리를 기반으로 L2 Layer에서 동작합니다.
⚠️ 제약사항 (Limitations)
Cilium의 LB IPAM 및 L2 Announcements 기능을 사용할 때 고려해야 할 몇 가지 제약이 있습니다:
- ❌ IPv6/NDP 미지원
현재 이 기능은 IPv6 및 NDP를 지원하지 않습니다.
NDP (Neighbor Discovery Protocol)는 IPv6 환경에서 매우 중요한 역할을 하는 L2 계층 프로토콜입니다.
🛠️ NDP가 왜 중요한가?
- IPv6 환경에서는 ARP가 아예 존재하지 않기 때문에,
NDP 없이는 통신 자체가 불가능합니다. - L2 네트워크에서의 자동화된 주소 탐색/갱신 기능을 제공하므로
로드밸런서, 클러스터 네트워크, 서비스 디스커버리 등에 필수 요소입니다.
- 📡 ARP 요청 단일 노드 수신
L3 → L2 변환 방식 때문에, 특정 IP에 대한 모든 ARP 요청이 한 노드에 집중됩니다.
→ 이로 인해 클러스터 진입 전에는 로드밸런싱이 불가능합니다. - ⚖️ 트래픽 불균형 가능성
내부적으로 트래픽 분산 메커니즘이 없어, 동일한 정책 그룹 내 노드들이 비대칭적으로 로드될 수 있습니다.
👉 자세한 내용은 Leader Election 문서를 참고하세요. - 🚫 externalTrafficPolicy: Local 비호환
해당 설정은 L2 광고 기능과 호환되지 않습니다.
→ Pod가 없는 노드에서 서비스 IP가 광고될 수 있어, 트래픽 손실이 발생할 수 있습니다.
⚠️ 왜 L2 Announcements와 충돌할까?
**L2 광고 방식 (예: ARP, NDP)**은 클러스터 외부에 서비스 IP를 “모든 노드에서 사용 가능”하다고 브로드캐스트합니다.
즉, Pod가 없는 노드에서도 서비스 IP를 광고해버립니다.
이렇게 되면:
- 외부 클라이언트가 Pod가 없는 노드로 요청을 보냄
- 해당 노드는 트래픽을 처리할 수 없음 (Pod 없음)
- 결과적으로 트래픽 드롭(유실) 발생
k8s 클러스터 외부 - 통신 안됨 - cilium l2 announcements = true
# 모니터링 : router VM
arping -i eth1 $LBIP -c 100000
Timeout
Timeout
60 bytes from 08:00:27:01:19:f3 (192.168.10.211): index=0 time=769.167 usec
60 bytes from 08:00:27:01:19:f3 (192.168.10.211): index=1 time=417.917 usec
...
# 설정 업그레이드
helm upgrade cilium cilium/cilium --namespace kube-system --version 1.18.0 --reuse-values \
--set l2announcements.enabled=true && watch -d kubectl get pod -A
kubectl rollout restart -n kube-system ds/cilium
# 확인
kubectl -n kube-system exec ds/cilium -c cilium-agent -- cilium-dbg config --all | grep EnableL2Announcements
EnableL2Announcements : true
cilium config view | grep enable-l2
enable-l2-announcements true
enable-l2-neigh-discovery true
'컨테이너 > 쿠버네티스 네트워크' 카테고리의 다른 글
| [Cilium] (14) 실리움 네트워킹 _ Service LB IPAM (BGP) (1) | 2025.08.12 |
|---|---|
| [Cilium] (13) 실리움 네트워킹 _ BGP Control Plane (8) | 2025.08.12 |
| [Cilium] (11) 실리움 네트워킹 _ VXLAN Encapsulation (3) | 2025.08.06 |
| [Cilium] (10) 실리움 네트워킹 _ Native Routing (0) | 2025.08.05 |
| [Cilium] (9) 실리움 네트워킹_ NodeLocalDNS, Cilium LRP (4) | 2025.07.29 |