
4주차 실습 환경은 더욱 복잡한 네트워킹 시나리오를 다루기 위해 4노드 환경으로 확장되었습니다:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ k8s-ctr │ │ k8s-w1 │ │ k8s-w0 │ │ router │
│ (Control Plane) │ │ (Worker Node 1) │ │ (Worker Node 2) │ │ (외부 서버) │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ eth0: NAT │ │ eth0: NAT │ │ eth0: NAT │ │ eth0: NAT │
│ eth1:192.168.10.│ │ eth1:192.168.10.│ │ eth1:192.168.20.│ │ eth1:192.168.10.│
│ 100 │ │ 101 │ │ 100 │ │ 200 │
│ │ │ │ │ │ │ eth2:192.168.20.│
│ PodCIDR: │ │ PodCIDR: │ │ PodCIDR: │ │ 200 │
│ 172.20.0.0/24 │ │ 172.20.1.0/24 │ │ 172.20.2.0/24 │ │ │
│ │ │ │ │ │ │ loop1: 10.10.1. │
│ │ │ │ │ │ │ 200/24 │
│ │ │ │ │ │ │ loop2: 10.10.2. │
│ │ │ │ │ │ │ 200/24 │
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │ │
└───────────────────────┼───────────────────────┤ │
Host-Only Network │ │
(192.168.10.0/24) │ │
│ │
Host-Only Network │
(192.168.20.0/24) │
│ │
└───────────────────────┘
│
┌─────────────────┐
│ 사내망 시뮬레이션 │
│ 10.10.0.0/16 │
└─────────────────┘
핵심 구성 요소:
Vagrant를 통한 자동 배포:
# 실습 환경 배포
vagrant up
# 네트워크 인터페이스 정보 확인
# router 서버 네트워크 확인
sshpass -p 'vagrant' ssh vagrant@router ip -br -c -4 addr
# Expected output:
# lo UNKNOWN 127.0.0.1/8
# eth0 UP 10.0.2.15/24 metric 100
# eth1 UP 192.168.10.200/24
# eth2 UP 192.168.20.200/24
# loop1 UNKNOWN 10.10.1.200/24
# loop2 UNKNOWN 10.10.2.200/24
# k8s 노드들 네트워크 확인
ip -c -4 addr show dev eth1 # k8s-ctr
sshpass -p 'vagrant' ssh vagrant@k8s-w1 ip -c -4 addr show dev eth1 # k8s-w1
sshpass -p 'vagrant' ssh vagrant@k8s-w0 ip -c -4 addr show dev eth1 # k8s-w0
# 라우팅 정보 확인
ip -c route | grep static
sshpass -p 'vagrant' ssh vagrant@router ip -c route
네트워크 연결성 테스트:
# 기본 통신 확인
ping -c 1 10.10.1.200 # router loop1
ping -c 1 192.168.20.100 # k8s-w0 eth1
# 경로 추적 (Path MTU Discovery)
tracepath -n 192.168.20.100
# Expected output:
# 1?: [LOCALHOST] pmtu 1500
# 1: 192.168.10.200 1.222ms
# 1: 192.168.10.200 0.980ms
# 2: 192.168.20.100 1.620ms reached
# Resume: pmtu 1500 hops 2 back 2
기본 설정 확인:
# Cilium 버전 및 상태 확인
cilium version
cilium status
# 현재 설정된 라우팅 모드 확인
cilium config view | grep routing-mode
cilium config view | grep auto-direct-node-routes
# Expected: routing-mode: native, auto-direct-node-routes: true
Native Routing 모드의 핵심 설정:
--set routingMode=native--set autoDirectNodeRoutes=true이 설정은 Cilium이 각 노드의 PodCIDR에 대한 직접 경로를 자동으로 생성하도록 합니다.
# 현재 라우팅 테이블 확인
ip -c route
# 각 노드별 PodCIDR 확인
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'
# Expected output:
# k8s-ctr 172.20.0.0/24
# k8s-w1 172.20.1.0/24
# k8s-w0 172.20.2.0/24
# Worker 노드들의 라우팅 테이블 확인
sshpass -p 'vagrant' ssh vagrant@k8s-w1 ip -c route
sshpass -p 'vagrant' ssh vagrant@k8s-w0 ip -c route
애플리케이션 배포:
# 3개 노드에 분산 배포될 webpod 애플리케이션 생성
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:
- webpod
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
# 테스트 클라이언트 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
# Cilium 서비스 목록 확인
kubectl exec -n kube-system ds/cilium -- cilium-dbg service list
# eBPF 로드밸런서 맵 확인
kubectl exec -n kube-system ds/cilium -- cilium-dbg bpf lb list
kubectl exec -n kube-system ds/cilium -- cilium-dbg bpf lb list | grep 10.96.32.212
# NAT 테이블 확인
kubectl exec -n kube-system ds/cilium -- cilium-dbg bpf nat list
eBPF 맵 상세 분석:
# eBPF 맵 목록 (빈 엔트리 제외)
kubectl exec -n kube-system ds/cilium -- cilium-dbg map list | grep -v '0 0'
# 주요 eBPF 맵들:
# - cilium_lb4_services_v2: 서비스 정의
# - cilium_lb4_backends_v3: 백엔드 Pod 정보
# - cilium_lb4_reverse_nat: 역방향 NAT
# - cilium_ipcache_v2: IP 캐시
# 서비스 맵 상세 정보
kubectl exec -n kube-system ds/cilium -- cilium-dbg map get cilium_lb4_services_v2 | grep 10.96.32.212
# 백엔드 맵 정보
kubectl exec -n kube-system ds/cilium -- cilium-dbg map get cilium_lb4_backends_v3
# IP 캐시 맵 정보
kubectl exec -n kube-system ds/cilium -- cilium-dbg map get cilium_ipcache_v2
문제 상황:
k8s-w0 노드는 다른 네트워크 대역(192.168.20.0/24)에 위치하여 직접 통신이 불가능합니다.
# 기본 통신 테스트
kubectl exec -it curl-pod -- curl webpod | grep Hostname
# k8s-w0 노드의 Pod IP 확인
export WEBPOD=$(kubectl get pod -l app=webpod --field-selector spec.nodeName=k8s-w0 -o jsonpath='{.items[0].status.podIP}')
echo $WEBPOD
# 직접 통신 시도 (실패 예상)
kubectl exec -it curl-pod -- ping -c 2 -w 1 -W 1 $WEBPOD
패킷 추적 분석:
# router에서 ICMP 패킷 모니터링
# (router 서버에서 실행)
tcpdump -i any icmp -nn
# 예상 결과: k8s-ctr → router → 라우팅 실패
# 22:08:20.123415 eth1 In IP 172.20.0.89 > 172.20.2.36: ICMP echo request
# 22:08:20.123495 eth0 Out IP 172.20.0.89 > 172.20.2.36: ICMP echo request
# router의 라우팅 테이블 확인
ip route get 172.20.2.36
# Expected: 172.20.2.36 via 10.0.2.2 dev eth0 src 10.0.2.15 uid 0
해결 방안:
1. 방안 1: BGP를 통한 동적 라우팅 (5주차에서 다룸)
2. 방안 2: Overlay Network (Encapsulation) 사용
3. 방안 3: Static Route 수동 설정 (임시 해결책)

VXLAN(Virtual eXtensible Local Area Network)은 UDP 기반의 오버레이 터널링 프로토콜입니다:
VXLAN 헤더 구조:
VXLAN vs GENEVE 비교:
| 특징 | VXLAN | GENEVE |
|---|---|---|
| 헤더 크기 | 8 bytes (고정) | 8+ bytes (가변) |
| 메타데이터 | 제한적 | 확장 가능 |
| 성능 | 높음 | 보통 |
| 확장성 | 제한적 | 우수 |
| 사용 사례 | 일반적인 오버레이 | OpenStack, 복잡한 메타데이터 |

Calico Direct 모드:
Pod A (Node 1) → Node1 Route Table → Physical Network → Node2 Route Table → Pod B (Node 2)
Calico IPIP 모드:
Pod A → Node1 IPIP → Internet Protocol in IP → Node2 IPIP → Pod B
Cilium vs Calico 라우팅 비교:
| 특징 | Cilium Native | Cilium VXLAN | Calico Direct | Calico IPIP |
|---|---|---|---|---|
| 오버헤드 | 없음 | 50 bytes | 없음 | 20 bytes |
| 네트워크 요구사항 | 높음 | 낮음 | 높음 | 낮음 |
| 성능 | 최고 | 보통 | 최고 | 높음 |
| eBPF 활용 | 완전 | 완전 | 제한적 | 제한적 |
| L7 정책 | 지원 | 지원 | 제한적 | 제한적 |
커널 모듈 확인:
# VXLAN/GENEVE 커널 지원 확인
grep -E 'CONFIG_VXLAN=y|CONFIG_VXLAN=m|CONFIG_GENEVE=y|CONFIG_GENEVE=m|CONFIG_FIB_RULES=y' /boot/config-$(uname -r)
# Expected output:
# CONFIG_FIB_RULES=y # 커널에 내장됨
# CONFIG_VXLAN=m # 모듈로 컴파일됨 → 커널에 로드해서 사용
# CONFIG_GENEVE=m # 모듈로 컴파일됨 → 커널에 로드해서 사용
# 커널 모듈 로드
lsmod | grep -E 'vxlan|geneve'
modprobe vxlan
lsmod | grep -E 'vxlan|geneve'
# Worker 노드들에도 VXLAN 모듈 로드
for i in w1 w0 ; do
echo ">> node : k8s-$i <<"
sshpass -p 'vagrant' ssh vagrant@k8s-$i sudo modprobe vxlan
echo
done
Cilium VXLAN 모드 업그레이드:
# 기존 통신 상태 유지 (백그라운드)
kubectl exec -it curl-pod -- ping $WEBPOD1 &
# VXLAN 터널 모드로 업그레이드
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--version 1.18.0 \
--reuse-values \
--set routingMode=tunnel \
--set tunnelProtocol=vxlan \
--set autoDirectNodeRoutes=false \
--set installNoConntrackIptablesRules=false
# Cilium 재시작
kubectl rollout restart -n kube-system ds/cilium
VXLAN 인터페이스 및 설정 확인:
# Cilium 기능 상태 확인
cilium features status
cilium features status | grep datapath_network
# 라우팅 모드 확인
kubectl exec -it -n kube-system ds/cilium -- cilium status | grep ^Routing
cilium config view | grep tunnel
# VXLAN 인터페이스 확인
ip -c addr show dev cilium_vxlan
# 모든 노드의 VXLAN 인터페이스 확인
for i in w1 w0 ; do
echo ">> node : k8s-$i <<"
sshpass -p 'vagrant' ssh vagrant@k8s-$i ip -c addr show dev cilium_vxlan
echo
done
라우팅 테이블 변화:
# Control Plane 노드 라우팅
ip -c route | grep cilium_host
# Expected routes:
# 172.20.0.238 dev cilium_host proto kernel scope link
# 172.20.0.0/24 via 172.20.0.238 dev cilium_host proto kernel src 172.20.0.238
# 172.20.1.0/24 via 172.20.0.238 dev cilium_host proto kernel src 172.20.0.238 mtu 1450
# 172.20.2.0/24 via 172.20.0.238 dev cilium_host proto kernel src 172.20.0.238 mtu 1450
# 경로 확인
ip route get 172.20.1.10 # k8s-w1 Pod
ip route get 172.20.2.10 # k8s-w0 Pod
# Worker 노드들 라우팅 확인
for i in w1 w0 ; do
echo ">> node : k8s-$i <<"
sshpass -p 'vagrant' ssh vagrant@k8s-$i ip -c route | grep cilium_host
echo
done
각 노드의 Cilium Pod 이름 확인:
# 노드별 Cilium Pod 이름 지정
export CILIUMPOD0=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-ctr -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD1=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w1 -o jsonpath='{.items[0].metadata.name}')
export CILIUMPOD2=$(kubectl get -l k8s-app=cilium pods -n kube-system --field-selector spec.nodeName=k8s-w0 -o jsonpath='{.items[0].metadata.name}')
echo $CILIUMPOD0 $CILIUMPOD1 $CILIUMPOD2
# 각 노드의 router IP 확인
kubectl exec -it $CILIUMPOD0 -n kube-system -c cilium-agent -- cilium status --all-addresses | grep router
kubectl exec -it $CILIUMPOD1 -n kube-system -c cilium-agent -- cilium status --all-addresses | grep router
kubectl exec -it $CILIUMPOD2 -n kube-system -c cilium-agent -- cilium status --all-addresses | grep router
eBPF 맵 상태 확인:
# IP 캐시 맵 (노드별 터널 엔드포인트 정보)
kubectl exec -n kube-system $CILIUMPOD0 -- cilium-dbg bpf ipcache list
kubectl exec -n kube-system $CILIUMPOD1 -- cilium-dbg bpf ipcache list
kubectl exec -n kube-system $CILIUMPOD2 -- cilium-dbg bpf ipcache list
# Socket NAT 맵 (터널링 관련)
kubectl exec -n kube-system $CILIUMPOD0 -- cilium-dbg bpf socknat list
kubectl exec -n kube-system $CILIUMPOD1 -- cilium-dbg bpf socknat list
kubectl exec -n kube-system $CILIUMPOD2 -- cilium-dbg bpf socknat list
패킷 캡처 및 분석:
# k8s-w0 노드의 Pod IP 확인
export WEBPOD=$(kubectl get pod -l app=webpod --field-selector spec.nodeName=k8s-w0 -o jsonpath='{.items[0].status.podIP}')
echo $WEBPOD
# 터미널 1: router에서 VXLAN 패킷 모니터링
tcpdump -i any udp port 8472 -nn
# 터미널 2: ICMP 테스트
kubectl exec -it curl-pod -- ping -c 2 -w 1 -W 1 $WEBPOD
# 패킷 분석 예시:
# 08:49:29.969241 eth1 In IP 192.168.10.100.54386 > 192.168.20.100.8472:
# OTV, flags I 0x08, overlay 0, instance 23926
# IP 172.20.0.44 > 172.20.2.43: ICMP echo request
VXLAN 트래픽 상세 분석:
# 터미널 1: 패킷을 파일로 저장
tcpdump -i any udp port 8472 -w /tmp/vxlan.pcap
# 터미널 2: HTTP 트래픽 생성
kubectl exec -it curl-pod -- sh -c 'while true; do curl -s --connect-timeout 1 webpod | grep Hostname; echo "---" ; sleep 1; done'
# 패킷 분석 도구 사용
tshark -r /tmp/vxlan.pcap -d udp.port==8472,vxlan
termshark -r /tmp/vxlan.pcap
termshark -r /tmp/vxlan.pcap -d udp.port==8472,vxlan
# Hubble 플로우 모니터링
hubble observe -f --protocol tcp --pod curl-pod
# VXLAN 모드에서의 플로우 로그 예시:
# Aug 3 00:02:26.403: default/curl-pod:40332 ID:23926 -> default/webpod-697b545f57-76lt6:80 ID:12438 to-overlay FORWARDED TCP Flags: SYN
# Aug 3 00:02:26.405: default/curl-pod:40332 ID:23926 <- default/webpod-697b545f57-76lt6:80 ID:12438 to-endpoint FORWARDED TCP Flags: SYN, ACK
# Aug 3 00:02:26.405: default/curl-pod:40332 ID:23926 -> default/webpod-697b545f57-76lt6:80 ID:12438 to-overlay FORWARDED TCP Flags: ACK
# 주요 상태 설명:
# - to-overlay: 패킷이 오버레이 네트워크로 전송됨
# - to-endpoint: 패킷이 대상 엔드포인트로 전달됨
MTU 제한 확인:
# VXLAN 인터페이스 MTU 확인
ip -c addr show dev cilium_vxlan
# Expected: mtu 1450 (1500 - 50 bytes VXLAN overhead)
# MTU 테스트
kubectl exec -it curl-pod -- ping -M do -s 1500 $WEBPOD
# Expected error: ping: sendmsg: Message too long
# 적절한 크기로 테스트 (1450 - 28 = 1422 bytes payload)
kubectl exec -it curl-pod -- ping -M do -s 1422 $WEBPOD
MTU 관련 설명:
-M do 옵션으로 설정하여 조각화 방지-s 옵션으로 ICMP 데이터 크기 지정


1단계: Pod 생성
2단계: Service (ClusterIP 타입)
3단계: Service (NodePort 타입)
4단계: Service (LoadBalancer 타입)
Service 타입별 특성 비교:
| 특징 | ClusterIP | NodePort | LoadBalancer | ExternalName |
|---|---|---|---|---|
| 외부 접근 | ❌ | ✅ | ✅ | N/A |
| 로드밸런싱 | ✅ | ✅ | ✅ | ❌ |
| 포트 제한 | ❌ | ✅ | ❌ | N/A |
| 클라우드 의존성 | ❌ | ❌ | ✅ | ❌ |
| 운영 복잡성 | 낮음 | 보통 | 낮음 | 낮음 |
주요 용어:
kube-proxy는 각 노드에서 실행되는 네트워크 프록시로 Kubernetes Service 개념의 일부를 구현합니다:

kube-proxy 모드별 성능 비교:
| 특징 | User Space | iptables | IPVS | nftables | eBPF (Cilium) |
|---|---|---|---|---|---|
| 성능 | 낮음 | 보통 | 높음 | 높음 | 최고 |
| 확장성 | 나쁨 | 제한적 | 우수 | 우수 | 우수 |
| 커널 의존성 | 낮음 | 보통 | 높음 | 높음 | 높음 |
| 메모리 사용량 | 높음 | 보통 | 낮음 | 낮음 | 낮음 |
| CPU 사용량 | 높음 | 보통 | 낮음 | 낮음 | 낮음 |
1. User Space 프록시 모드 (미사용)
클라이언트 → iptables REDIRECT → kube-proxy → Pod
2. iptables 프록시 모드
클라이언트 → iptables DNAT → Pod (직접)
3. IPVS 프록시 모드
클라이언트 → IPVS (kernel space) → Pod
4. nftables 프록시 모드
클라이언트 → nftables API → Pod
5. eBPF 모드 + XDP
클라이언트 → eBPF (XDP) → Pod
LoadBalancer IP Address Management는 LoadBalancer 타입의 서비스에 External IP를 할당할 수 있게 해주는 기능입니다:
주요 특징:
동작 방식:
1. IP 풀 생성: CiliumLoadBalancerIPPool CRD로 IP 범위 정의
2. 자동 할당: LoadBalancer 서비스 생성 시 IP 자동 할당
3. 광고 메커니즘: BGP 또는 L2 Announcements를 통한 IP 광고
핵심 기능들:
# 기존 IP Pool 확인
kubectl get CiliumLoadBalancerIPPool -A
# IP Pool 생성 (충돌하지 않는 대역 사용)
cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2"
kind: CiliumLoadBalancerIPPool
metadata:
name: "cilium-lb-ippool"
spec:
blocks:
- start: "192.168.10.211"
stop: "192.168.10.215"
EOF
# CiliumLoadBalancerIPPool 축약어 확인
kubectl api-resources | grep -i CiliumLoadBalancerIPPool
# 축약어: ippools, ippool, lbippool, lbippools
# IP Pool 상태 확인
kubectl get ippools
# Expected output:
# NAME DISABLED CONFLICTING IPS AVAILABLE AGE
# cilium-lb-ippool false False 5 5 20s
# webpod 서비스를 LoadBalancer 타입으로 변경
kubectl patch svc webpod -p '{"spec":{"type":"LoadBalancer"}}'
# 서비스 상태 확인
kubectl get svc webpod
# Expected output:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORTS AGE
# webpod LoadBalancer 10.96.32.212 192.168.10.211 80:32039/TCP 150m
# External IP 확인
LBIP=$(kubectl get svc webpod -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "LoadBalancer IP: $LBIP"
클러스터 내부에서 테스트:
# 클러스터 내부에서 LB IP로 접근
curl -s $LBIP
kubectl exec -it curl-pod -- curl -s $LBIP
kubectl exec -it curl-pod -- curl -s $LBIP | grep Hostname
# 소스 IP 확인 (Pod 관점)
kubectl exec -it curl-pod -- curl -s $LBIP | grep RemoteAddr
# 로드밸런싱 확인
for i in {1..100}; do
kubectl exec -it curl-pod -- curl -s $LBIP | grep Hostname
done | sort | uniq -c | sort -nr
IP 할당 상태 확인:
# IP Pool 상태 상세 확인
kubectl get ippools
kubectl get ippools -o jsonpath='{.items[*].status.conditions[?(@.type!="cilium.io/PoolConflict")]}' | jq
# 서비스 상태 JSON 확인
kubectl get svc webpod -o json | jq
kubectl get svc webpod -o jsonpath='{.status}' | jq
클러스터 외부에서 접근 시도:
# router에서 LB IP 접근 시도 (실패 예상)
# (router 서버에서 실행)
LBIP=192.168.10.211
curl --connect-timeout 1 $LBIP
# ARP 테이블 확인
arping -i eth1 $LBIP -c 1
# 지속적인 ARP 요청 (응답 없음)
arping -i eth1 $LBIP -c 100000
문제 원인:

MetalLB Layer2 모드 동작:
1. Speaker Pod가 LoadBalancer IP에 대한 ARP 응답
2. 특정 노드에서만 IP 소유권 주장 (리더 선출)
3. MAC 주소 학습을 통한 트래픽 전달
4. 장애 시 다른 노드로 IP 이동
Cilium L2 Announcements 장점:
Cilium L2 Announcements 설정:
# L2 Announcements 활성화
helm upgrade cilium cilium/cilium \
--namespace kube-system \
--reuse-values \
--set l2announcements.enabled=true
# 설정 확인
cilium config view | grep l2-announcements
# Expected: l2-announcements-enabled: true
# L2 Announcements 정책 생성
cat << EOF | kubectl apply -f -
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
name: default-l2-announcement-policy
spec:
serviceSelector:
matchLabels:
app: webpod
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: DoesNotExist
interfaces:
- eth1
externalIPs: true
loadBalancerIPs: true
EOF
# 정책 확인
kubectl get CiliumL2AnnouncementPolicy
kubectl describe CiliumL2AnnouncementPolicy default-l2-announcement-policy
# LoadBalancer IP 재확인
LBIP=$(kubectl get svc webpod -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "LoadBalancer IP: $LBIP"
# k8s 노드들에서 ARP 테이블 확인
ip -c neigh | grep $LBIP
sshpass -p 'vagrant' ssh vagrant@k8s-w1 ip -c neigh | grep $LBIP
sshpass -p 'vagrant' ssh vagrant@k8s-w0 ip -c neigh | grep $LBIP
# router에서 ARP 요청 및 응답 확인
# (router 서버에서 실행)
arping -i eth1 $LBIP -c 3
# ARP 테이블에서 응답 확인
arp -a | grep $LBIP
# router에서 HTTP 접근 (성공 예상)
# (router 서버에서 실행)
curl -s $LBIP
curl -s $LBIP | grep Hostname
# 지속적인 접근 테스트
while true; do
curl -s --connect-timeout 1 $LBIP | grep Hostname
sleep 1
done
# Cilium L2 Announcements 관련 로그 확인
kubectl logs -n kube-system -l k8s-app=cilium -c cilium-agent | grep -i l2
# L2 Announcements 상태 확인
cilium status | grep -i l2
# LoadBalancer 서비스에 대한 L2 광고 확인
kubectl exec -n kube-system ds/cilium -c cilium-agent -- cilium service list | grep LoadBalancer
문제 1: ARP 응답 없음
# L2 정책 확인
kubectl get CiliumL2AnnouncementPolicy -o yaml
# 노드 셀렉터 확인
kubectl get nodes --show-labels
# 인터페이스 설정 확인
ip -c addr show dev eth1
문제 2: 특정 노드에서만 응답
# 리더 선출 상태 확인
kubectl logs -n kube-system -l k8s-app=cilium -c cilium-agent | grep leader
# 모든 노드의 L2 상태 확인
for node in k8s-ctr k8s-w1 k8s-w0; do
echo "=== Node: $node ==="
kubectl get pods -n kube-system -l k8s-app=cilium --field-selector spec.nodeName=$node
done
# L2 Announcements 메트릭 확인
kubectl exec -n kube-system ds/cilium -c cilium-agent -- curl -s localhost:9962/metrics | grep l2
# 네트워크 인터페이스 통계
ip -s link show dev eth1
# ARP 캐시 만료 시간 확인
cat /proc/sys/net/ipv4/neigh/eth1/base_reachable_time_ms
핵심 컴포넌트:
Cilium 관련 메트릭:
# Cilium Agent 메트릭 확인
kubectl exec -n kube-system ds/cilium -c cilium-agent -- curl -s localhost:9962/metrics | head -20
# Cilium Operator 메트릭 확인
kubectl exec -n kube-system deploy/cilium-operator -- curl -s localhost:9963/metrics | head -20
# Hubble 메트릭 확인
kubectl exec -n kube-system deploy/hubble-relay -- curl -s localhost:9965/metrics | head -20
성능 지표:
# eBPF 맵 사용률
cilium_datapath_conntrack_gc_entries
cilium_bpf_map_pressure
# 엔드포인트 재생성
cilium_endpoint_regenerations_total
# 패킷 드롭
cilium_drop_count_total
cilium_drop_bytes_total
서비스 지표:
# 로드밸런서 백엔드
cilium_services_events_total
cilium_k8s_client_api_calls_total
# L2 Announcements
cilium_l2_announcements_total
# L2 광고 성공/실패
kubectl exec -n kube-system ds/cilium -c cilium-agent -- curl -s localhost:9962/metrics | grep l2_announcement
권장 시청 영상:
핵심 문서:
Native Routing vs Overlay:
권장 시나리오:
L2 Announcements 적합 환경:
BGP 권장 환경:
Native Routing 문제:
# 라우팅 테이블 확인
ip route show table main
# BGP 피어 상태 확인 (BGP 사용 시)
cilium bgp peers
# 노드 간 연결성 확인
ping <other-node-ip>
L2 Announcements 문제:
# L2 정책 상태 확인
kubectl get CiliumL2AnnouncementPolicy -o yaml
# ARP 테이블 확인
ip neigh show
# 인터페이스 상태 확인
ip link show
네트워크 성능 측정:
# iperf3를 통한 대역폭 측정
kubectl run iperf3-server --image=networkstatic/iperf3 --port=5201
kubectl run iperf3-client --image=networkstatic/iperf3 --rm -it -- -c <server-ip>
# 지연시간 측정
kubectl exec -it curl-pod -- ping -c 100 <target-ip> | tail -1
네트워킹 모드 이해:
Service 외부 노출:
아키텍처 선택 기준:
스케일링 고려사항:
5주차 예상 내용:
추가 실습 권장:
이로써 Cilium의 핵심 네트워킹 기능과 서비스 외부 노출 메커니즘에 대한 포괄적인 이해를 완성하였습니다. 다음 주차에서는 이러한 기반 위에 더욱 고급화된 BGP 라우팅과 멀티클러스터 네트워킹을 학습하게 될 것입니다.