4주차에 이어서 네트워크 대역이 다른 pod들 간의 통신장애를 해결하는 방법에 대해서 스터디를 진행했다.
그 중에 Cilium BGP Control plane 방식을 사용해서 통신을 가능하게 하는 실습을 진행했다.
1. BGP란?
BGP가 뭔지부터 알아야 될 것 같다.
BGP : Border Gateway Protocol, 인터넷과 대규모 네트워크에서 라우팅 정보를 교환하는 표준 프로토콜
정의
- 역할: 네트워크 간(IP Prefix 경로)의 도달 가능성 정보를 서로 교환하여, 어떤 경로로 패킷을 보내야 할지 결정.
- 위치: OSI 4계층(TCP) 위에서 동작 → 일반적으로 TCP 포트 179 사용.
- 성격: “경로 벡터 라우팅 프로토콜”
(단순히 최단 경로가 아니라, 경로의 속성·정책에 따라 경로 선택 가능)
동작원리
- BGP 피어링(Peering) 수립
- 두 장비(혹은 노드)가 TCP 연결을 맺고 서로 BGP 라우터로 인식.
- 라우트 광고(Route Advertisement)
- 자신이 도달 가능한 네트워크(예: 10.0.1.0/24)를 상대에게 알림.
- 라우팅 테이블 업데이트
- 받은 경로와 기존 경로를 비교, 정책에 따라 최적 경로 선택.
- 전파
- 선택한 경로를 다른 BGP 피어에게 다시 광고
특징
- 정책 기반 라우팅
→ 단순히 “가장 짧은 경로”가 아니라, AS Path(거친 네트워크 수), Local Preference, MED 값 등 다양한 속성으로 경로를 선택. - 확장성
→ 전 세계 인터넷의 경로 정보(90만+ 개의 IPv4 Prefix)를 처리 가능. - 안정성
→ 경로 변경 시에도 점진적으로 업데이트, 네트워크 전체 불안정 최소화.
K8s / CNI에서 BGP 활용
- 각 노드가 “BGP 라우터”처럼 동작 → 자신이 가진 Pod CIDR을 BGP로 광고.
- 네트워크 장비나 다른 노드들이 이 정보를 받아, Pod IP로 직접 라우팅 가능.
- 예: Calico, Cilium BGP Control Plane, MetalLB(BGP 모드)
2. 실습
실습환경 구성

네트워크 정보 확인
autoDirectNode?Routes=false
커널 라우트 테이블에 각 노드별 PodCIDR 라우팅이 없는 것을 확인
# router 네트워크 인터페이스 정보 확인
sshpass -p 'vagrant' ssh vagrant@router ip -br -c -4 addr
# k8s node 네트워크 인터페이스 정보 확인
ip -c -4 addr show dev eth1
for i in w1 w0 ; do echo ">> node : k8s-$i <<"; sshpass -p 'vagrant' ssh vagrant@k8s-$i ip -c -4 addr show dev eth1; echo; done
# 라우팅 정보 확인
sshpass -p 'vagrant' ssh vagrant@router ip -c route
ip -c route | grep static
## 노드별 PodCIDR 라우팅이 없다!
ip -c route
for i in w1 w0 ; do echo ">> node : k8s-$i <<"; sshpass -p 'vagrant' ssh vagrant@k8s-$i ip -c route; echo; done
# 통신 확인
ping -c 1 192.168.20.100 # k8s-w0 eth1

샘플 어플리케이션 배포
webpod 3개를 배포
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: webpod
spec:
replicas: 3
selector:
matchLabels:
app: webpod
template:
metadata:
labels:
app: webpod
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- sample-app
topologyKey: "kubernetes.io/hostname"
containers:
- name: webpod
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: webpod
labels:
app: webpod
spec:
selector:
app: webpod
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
EOF
k8s-ctr 노드에 curl-pod 파드 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: curl-pod
labels:
app: curl
spec:
nodeName: k8s-ctr
containers:
- name: curl
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF

통신문제 확인
위에서 배포한 샘플 파드가 제대로 배포됐는지 확인 후에, 파드들 간에 통신을 확인한다.
노드 내의 파드(같은 네트워크 대역)끼리만 통신이 되는 것을 확인 한다.
# 배포 확인
kubectl get deploy,svc,ep webpod -owide
kubectl get endpointslices -l app=webpod
kubectl get ciliumendpoints # IP 확인
# 통신 문제 확인 : 노드 내의 파드들 끼리만 통신되는 중!
kubectl exec -it curl-pod -- curl -s --connect-timeout 1 webpod | grep Hostname
kubectl exec -it curl-pod -- sh -c 'while true; do curl -s --connect-timeout 1 webpod | grep Hostname; echo "---" ; sleep 1; done'

BGP 설정 후 통신 확인
터미널 3개로 하면 좋음. -> router , k8s-ctr 접속 후 2개는 모니터링. k8s-ctr 하나는 명령어 입력
- router 노드 접속 : sshpass -p 'vagrant' ssh vagrant@router
# router node 에서
# Cilium node 연동 설정 방안 1
cat << EOF >> /etc/frr/frr.conf
neighbor CILIUM peer-group
neighbor CILIUM remote-as external
neighbor 192.168.10.100 peer-group CILIUM
neighbor 192.168.10.101 peer-group CILIUM
neighbor 192.168.20.100 peer-group CILIUM
EOF
cat /etc/frr/frr.conf
systemctl daemon-reexec && systemctl restart frr
systemctl status frr --no-pager --full
# 모니터링 걸어두기!
journalctl -u frr -f

- cilium에 bgp 설정
# BGP 동작할 노드를 위한 label 설정
kubectl label nodes k8s-ctr k8s-w0 k8s-w1 enable-bgp=true
kubectl get node -l enable-bgp=true
# Config Cilium BGP
cat << EOF | kubectl apply -f -
apiVersion: cilium.io/v2
kind: CiliumBGPAdvertisement
metadata:
name: bgp-advertisements
labels:
advertise: bgp
spec:
advertisements:
- advertisementType: "PodCIDR"
---
apiVersion: cilium.io/v2
kind: CiliumBGPPeerConfig
metadata:
name: cilium-peer
spec:
timers:
holdTimeSeconds: 9
keepAliveTimeSeconds: 3
ebgpMultihop: 2
gracefulRestart:
enabled: true
restartTimeSeconds: 15
families:
- afi: ipv4
safi: unicast
advertisements:
matchLabels:
advertise: "bgp"
---
apiVersion: cilium.io/v2
kind: CiliumBGPClusterConfig
metadata:
name: cilium-bgp
spec:
nodeSelector:
matchLabels:
"enable-bgp": "true"
bgpInstances:
- name: "instance-65001"
localASN: 65001
peers:
- name: "tor-switch"
peerASN: 65000
peerAddress: 192.168.10.200 # router ip address
peerConfigRef:
name: "cilium-peer"
EOF
- 통신확인
# BGP 연결 확인
ss -tnlp | grep 179
ss -tnp | grep 179
# cilium bgp 정보 확인
cilium bgp peers
cilium bgp routes available ipv4 unicast
kubectl get ciliumbgpadvertisements,ciliumbgppeerconfigs,ciliumbgpclusterconfigs
kubectl get ciliumbgpnodeconfigs -o yaml | yq

- router node frr 재시작
systemctl restart frr && journalctl -u frr -f

Cilium BGP는 기본적으로 외부 경로를 커널 라우팅 테이블에 주입하지 않음.
- 커널 라우팅 테이블 (FIB, Forwarding Information Base)
- 리눅스 커널이 직접 참조하는 "실제 패킷 포워딩용" 라우팅 테이블
- 목적지 IP → 인터페이스/게이트웨이 결정
- ip route로 확인 가능
- BGP 데몬 라우팅 테이블 (RIB, Routing Information Base)
- BGP 프로토콜을 통해 학습·교환된 경로를 저장하는 "논리적 테이블"
- 실제 패킷 포워딩에 쓰이지 않고, BGP 피어들과 라우팅 정보를 교환하기 위한 데이터베이스
- FRR, GoBGP, Bird 같은 데몬이 관리
- Cilium BGP도 기본적으로는 이 레벨에서 경로를 관리
왜 BGP 설정을 다 했는데도 같은 노드에 있는 pod만 통신이 되는가?
Cilium 으로 BGP 사용 시, 2개 이상의 NIC 사용할 경우에는 Node에 직접 라우팅 설정 및 관리가 필요함.
- 현재 실습 환경은 2개의 NIC(eth0, eth1)을 사용하고 있는 상황으로, default GW가 eth0 경로로 설정 되어 있음.
- eth1은 k8s 통신 용도로 사용 중. 즉, 현재 k8s 파드 사용 대역 통신 전체는 eth1을 통해서 라우팅 설정하면됨.
- 해당 라우팅을 상단에 네트워크 장비가 받게 되고, 해당 장비는 Cilium Node를 통해 모든 PodCIDR 정보를 알고 있기에, 목적지로 전달 가능함.
- 결론은 Cilium 으로 BGP 사용 시, 2개 이상의 NIC 사용할 경우에는 Node에 직접 라우팅 설정 및 관리가 필요함.
# k8s-ctr node에서
ip route add 172.20.0.0/16 via 192.168.10.200
sshpass -p 'vagrant' ssh vagrant@k8s-w1 sudo ip route add 172.20.0.0/16 via 192.168.10.200
sshpass -p 'vagrant' ssh vagrant@k8s-w0 sudo ip route add 172.20.0.0/16 via 192.168.20.200

'DevOps > cilium' 카테고리의 다른 글
| [Cilium Study] BGP / Cluster mesh 비교 (4) | 2025.08.17 |
|---|---|
| [Cilium Study] Cluster mesh (3) | 2025.08.17 |
| [Cilium Study] Pod간 통신 & k8s 외부 노출 4 (4) | 2025.08.10 |
| [Cilium Study] Pod간 통신 & k8s 외부 노출 3 (0) | 2025.08.10 |
| [Cilium Study] Pod간 통신 & k8s 외부 노출 2 (0) | 2025.08.09 |