cilium에서 제공하는 bgp 테스트 환경 구성이 있는데 이게 잘 동작을 안해서 엄청 고생을 하다. 도전과제겸 정리해봅니다.
공식 문서에서는 아래와 같이 간단하게 구성하고있는데 mac이라 그런지 바로 동작을 잘 안하네요.
2025.08.15 - [K8S/cilium] - containerlab을 사용하여 cilium + BGP 테스트 환경 만들기
사전 준비
테스트 환경은 mac arm64 이며 orbstack을 사용할 예정입니다.
vm 생성하기
mac에서는 바로 containerlab을 사용할 수 없어 orbstack으로 vm을 생성해줍니다. orbstack을 실행 후 명령어를 입력하세요
orb create ubuntu linux
이렇게 vm을 생성하면 쉽게 서버에 접근이 가능합니다.
ssh orb
kind로 클러스터 만들기
클러스터의 AS-number는 6500이고 노드에 라벨 키가 bgp인 경우 bgp 인스턴스를 활성화 할 에정이기 때문에 다음과 같이 클러스터를 생성합니다.
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
name: bgp-dev
networking:
ipFamily: dual
disableDefaultCNI: true
podSubnet: "10.1.0.0/16"
serviceSubnet: "10.2.0.0/16"
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-ip: "10.0.1.2"
node-labels: "bgp=65001"
- role: worker
kubeadmConfigPatches:
- |
kind: JoinConfiguration
nodeRegistration:
kubeletExtraArgs:
node-ip: "10.0.2.2"
node-labels: "bgp=65001"
이제 클러스터를 생성해줍니다.
kind create cluster --config cluster.yaml
containerlab으로 라우터 설정하기
이제 위의 컨테이너와 연결할 BGP 라우터를 구성합니다.
name: bgp-dev
topology:
nodes:
# A simple BGP router that peers with Cilium with eBGP.
router0:
kind: linux
image: frrouting/frr:v8.4.0
cmd: bash
exec:
- ip addr add 10.0.1.1/24 dev net0
- ip addr add 10.0.2.1/24 dev net1
- ip addr add 10.0.3.1/24 dev net2
- sysctl net.ipv4.ip_forward=1
- ip link add name loopback type dummy
- ip link set dev loopback up
- ip addr add 10.0.0.1/32 dev loopback
- ip route add blackhole 10.0.0.0/8
# Boiler plate to make FRR work
- touch /etc/frr/vtysh.conf
- touch /var/log/frr.log
- chown frr:frr /var/log/frr.log
- sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons
- /usr/lib/frr/frrinit.sh start
- >-
vtysh -c 'conf t'
-c 'log file /var/log/frr.log'
-c 'debug bgp neighbor-events'
-c 'debug bgp updates'
-c 'debug bgp zebra'
-c 'router bgp 65000'
-c ' bgp bestpath as-path multipath-relax'
-c ' no bgp ebgp-requires-policy'
-c ' bgp router-id 10.0.0.1'
-c ' neighbor CILIUM peer-group'
-c ' neighbor CILIUM remote-as external'
-c ' neighbor CILIUM password cilium123'
-c ' neighbor 10.0.1.2 peer-group CILIUM'
-c ' neighbor 10.0.2.2 peer-group CILIUM'
-c ' neighbor CILIUM ebgp-multihop 2'
-c ' neighbor CILIUM update-source 10.0.0.1'
-c ' address-family ipv4 unicast'
-c ' neighbor CILIUM activate'
-c ' maximum-paths 32'
-c ' exit'
-c '!'
# Server with Cilium. It shares netns with kind node.
server0:
kind: linux
image: nicolaka/netshoot:v0.11
network-mode: container:bgp-dev-control-plane
exec:
- ip addr add 10.0.1.2/24 dev net0
# These static routes are needed because Cilium cannot import routes currently.
- ip route add 10.0.0.0/8 via 10.0.1.1 dev net0
# Server with Cilium. It shares netns with kind node.
server1:
kind: linux
image: nicolaka/netshoot:v0.11
network-mode: container:bgp-dev-worker
exec:
- ip addr add 10.0.2.2/24 dev net0
# These static routes are needed because Cilium cannot import routes currently.
- ip route add 10.0.0.0/8 via 10.0.2.1 dev net0
# Server without Cilium. Useful for testing connectivity.
server2:
kind: linux
image: nicolaka/netshoot:v0.11
exec:
- ip addr add 10.0.3.2/24 dev net0
# These static routes are needed because this node doesn't have a BGP router.
- ip route add 10.0.0.0/8 via 10.0.3.1 dev net0
links:
- endpoints: ["router0:net0", "server0:net0"]
- endpoints: ["router0:net1", "server1:net0"]
- endpoints: ["router0:net2", "server2:net0"]
위의 설정 파일을 저장한뒤 conatienrlab으로 컨테이너를 띄워줍니다.
sudo containerlab -t topo.yaml deploy
cilium 설치하기
debug:
enabled: true
routingMode: native
ipv6:
enabled: false
bgpControlPlane:
enabled: true
statusReport:
enabled: false
securityContext:
capabilities:
ciliumAgent:
# cilium-agent에 179 포트를 바인딩 하기 위해 CAP_NET_BIND_SERVICE을 추가로 오픈합니다.
- CAP_NET_BIND_SERVICE
- CHOWN
- KILL
- NET_ADMIN
- NET_RAW
- IPC_LOCK
- SYS_MODULE
- SYS_ADMIN
- SYS_RESOURCE
- DAC_OVERRIDE
- FOWNER
- SETGID
- SETUID
ipv4NativeRoutingCIDR: 10.0.0.0/8
ipam:
mode: kubernetes
k8s:
requireIPv4PodCIDR: true
requireIPv6PodCIDR: false
operator:
enabled: true
replicas: 1
위의 설정으로 cilium도 구성을 완료합니다.
helm install cilium -n kube-system cilium/cilium --version 1.18.1 -f values.yaml
cilium이 상태가 정상이 될때까지 기다려줍니다.
cilium status --wait --namespace kube-system
BGP 설정하기
router 컨테이너의 루프백 인터페이스를 peer address로 설정하여 연결되도록 합니다.
사실 router 컨테이너로 먼저 연결이 될수있는 환경인데도 불구하고 연결이 잘 되지 않아 localPort를 오픈했습니다. localPort 오픈없이도 구성가능한 방법을 아시는 분은.. 알려주세요..
나중에확인을 해보니 TCP_MD5SIG를 orbstack에서 제공하는 vm의 커널에서 지원하지 않기 때문에 동작을 하지 않았던 것이었습니다. 비밀번호 설정을 라우터에서 제외하고 peer 설정에서도 제거 하면 동작합니다 ~
cat << EOF | kubectl apply -f -
apiVersion: cilium.io/v2
kind: CiliumBGPClusterConfig
metadata:
name: cilium-bgp
spec:
nodeSelector:
matchLabels:
bgp: "65001"
bgpInstances:
- name: "65001"
localASN: 65001
localPort: 179
peers:
- name: "65000"
peerASN: 65000
peerAddress: 10.0.0.1
peerConfigRef:
name: "cilium-peer"
EOF
그리고 peer 설정을 해줍니다. 라우터에 md5 비밀번호 설정이 되어있기 때문에 시크릿을 하나 추가합니다.
kubectl -n kube-system create secret generic --type=string bgp-auth-secret --from-literal=password=cilium123
그리고 다음과 같이 설정을 추가해줍니다. ebgpMultihop의 경우 TTL을 설정하는 기능인데
router의 loopback까지 가기 위해서는
Cilium 노드(10.0.1.2/10.0.2.2) → router0(10.0.1.1/10.0.2.1) → 루프백(10.0.0.1) 순서로 최소 1홉을 지나야하기 때문에
이 TTL 설정을 2로 변경했습니다.
cat << EOF | kubectl apply -f -
apiVersion: cilium.io/v2
kind: CiliumBGPPeerConfig
metadata:
name: cilium-peer
spec:
# 라우터에 password 미설정시 아래 설정 제거
authSecretRef: bgp-auth-secret
ebgpMultihop: 2
gracefulRestart:
enabled: true
restartTimeSeconds: 15
families:
- afi: ipv4
safi: unicast
advertisements:
matchLabels:
advertise: "bgp"
EOF
이제 마지막으로 광고 관련 설정을 해주면 됩니다.
cat << EOF | kubectl apply -f -
apiVersion: cilium.io/v2
kind: CiliumBGPAdvertisement
metadata:
name: blue-bgp-advertisements
labels:
advertise: bgp
spec:
advertisements:
- advertisementType: "Service"
service:
addresses:
- ClusterIP
- LoadBalancerIP
selector:
matchExpressions:
- { key: bgp, operator: In, values: [ blue ] }
EOF
Peer 연결은 established되었지만 아직 라우터에 광고가 되고 있는 것은 없습니다.
서비스 배포하기
lb ippol을 추가하여 lb가 설정될 수 있도록 합니다.
cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumLoadBalancerIPPool
metadata:
name: "ip-pool-blue"
labels:
bgp: blue
spec:
allowFirstLastIPs: "No"
blocks:
- cidr: "10.100.0.0/24"
serviceSelector:
matchExpressions:
- {key: bgp, operator: In, values: [blue]}
EOF
이제 위의 LB IP를 할당받을 서비스를 배포합니다.
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
name: lb-service-blue
labels:
bgp: blue
spec:
type: LoadBalancer
selector:
app: curl-blue
ports:
- protocol: TCP
port: 1234
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: curl-blue
labels:
app: curl-blue
spec:
replicas: 1
selector:
matchLabels:
app: curl-blue
template:
metadata:
labels:
app: curl-blue
spec:
containers:
- name: blue
image: traefik/whoami
EOF
이렇게 하면 이제 구성 완료입니다. 이제 라우터에 표시도 잘 됩니다.
실제로 테스트해보기
clab-bgp-dev-server2가 외부 환경처럼 구성된 컨테이너이기 때문에 여기서 테스트를 해보겠습니다.
테스트 시 통신이 잘 되는 것을 확인할 수 있습니다.
'K8S > 🔥 network study🔥' 카테고리의 다른 글
[cilium] L7 Traffic Shifting 테스트 (1) | 2025.08.22 |
---|---|
[cilium] Service Mesh 구성하기 (shared 모드) (0) | 2025.08.22 |
[cilium] cluster mesh 테스트 (0) | 2025.08.17 |
[cilium] BGP Control Plane (1) | 2025.08.15 |
[cilium] VxLAN, Geneve 오버레이 모드 (작성중) (1) | 2025.08.10 |