본문 바로가기
DevOps/cilium

[Cilium Study] Pod간 통신 & k8s 외부 노출 4

by 서어켜엉 2025. 8. 10.

 

Service LB IPAM

  • LB IPAM은 Cilium이 IP 주소를 LoadBalancer 유형의 서비스에 할당할 수 있게 해주는 기능이다.
  • LB IPAM은 Cilium BGP Control Plane 및 L2 Announcements / L2 Aware LB(베타)와 같은 기능과 함께 작동한다.
  • Cilium BGP Control Plane을 사용하여 LB IPAM이 할당한 IP 주소를 BGP를 통해 광고하고
    L2 Announcements / L2 Aware LB를 통해 로컬로 광고한다.
  • LB IPAM은 항상 활성화되어 있지만 휴면 상태이다. 

 

LB IPAM Pool 설정

# 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

# CiliumLoadBalancerIPPool 축약어 : ippools,ippool,lbippool,lbippools
kubectl api-resources | grep -i CiliumLoadBalancerIPPool
#ciliumloadbalancerippools           ippools,ippool,lbippool,lbippools   cilium.io/v2               false        CiliumLoadBalancerIPPool

kubectl get ippools
#NAME               DISABLED   CONFLICTING   IPS AVAILABLE   AGE
#cilium-lb-ippool   false      False         5               20s

 

앞서 pod간 통신 실험을 했던 webpod Service를 LoadBalancer Type으로 변경

# webpod 서비스를 LoadBalancer Type 변경 설정
kubectl patch svc webpod -p '{"spec":{"type":"LoadBalancer"}}'

# 확인
kubectl get svc webpod

 

LBIP 로 curl 요청 테스트를 진행

# 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

3개의 pod name이 모두 출력된다.

 

내부에서는 잘 통신이 된다.

 

외부 통신 확인

실습환경에서 router 노드만 클러스터 외부 노드이다.

router node 에서 LBIP 로 통신이 되는지 실습해보자

LBIP=192.168.10.211
curl --connect-timeout 1 $LBIP
arping -i eth1 $LBIP -c 1
arping -i eth1 $LBIP -c 100000
...

계속 timeout 이 발생하는 상황

 

webpod 서비스를 L2 Announcements로 LoadBalancer ExternalIP로 호출

설정 변경

# 설정 업그레이드
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
cilium config view | grep enable-l2

 

추가적으로 정책 설정을 변경한다.

# 정책 설정 : arp 광고하게 될 service 와 node 지정(controlplane 제외) -> 설정 직후 arping 확인!
## 제약사항 : L2 ARP 모드에서 LB IPPool 은 같은 네트워크 대역에서만 유효. -> k8s-w0 을 제외한 이유. 포함 시 리더 노드 선정 시 동작 실패 상황 발생!
cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2alpha1"  # not v2
kind: CiliumL2AnnouncementPolicy
metadata:
  name: policy1
spec:
  serviceSelector:
    matchLabels:
      app: webpod
  nodeSelector:
    matchExpressions:
      - key: kubernetes.io/hostname
        operator: NotIn
        values:
          - k8s-w0
  interfaces:
  - ^eth[1-9]+
  externalIPs: true
  loadBalancerIPs: true
EOF


# 확인
kubectl -n kube-system get lease
kubectl -n kube-system get lease | grep "cilium-l2announce"

정책 setting 후 바로 arp 통신이 된다.

 

리더 역할을 하는 노드가 어디인지 확인해본다

kubectl -n kube-system get lease/cilium-l2announce-default-webpod -o yaml | yq

 

arp 응답이 오니까 실제로 pod간 통신이 되는지 확인해보자

arping -i eth1 $LBIP -c 1000
curl --connect-timeout 1 $LBIP

arp -a

 

 

리더 노드에 장애 주입 후 failover 확인

# 현재 리더 노드 확인
kubectl -n kube-system get lease | grep "cilium-l2announce"

# 리더 노드 강제 reboot
sshpass -p 'vagrant' ssh vagrant@k8s-w1  sudo reboot
# 혹은
sshpass -p 'vagrant' ssh vagrant@k8s-ctr sudo reboot

# 신규 터미널 (router) : arp 변경(갱신) 확인
arp -a

 

두번 째 줄 mac address가 갱신된 것 확인

 

실제로 리더노드도 변경된 것을 확인

w1 -> ctr 노드로 변경됐다.