- 실습환경 설명

- k8s-ctr, k8s-w1, k8s-w1, router 총 4개의 노드(가상머신)으로 구성
- k8s-ctr 과 k8s-w1 은 같은 네트워크 대역 - 192.168.10.0/24
- k8s-w0 는 k8s-ctr, k8s-w1과 다른 네트워크 대역 - 192.168.20.0/24
- k8s-ctr, w1, w0 3개의 노드는 하나의 k8s 클러스터로 구성되어 있다.
- router 는 k8s 클러스터에 join 되지 않음.
192.168.10.0/24 ↔ 192.168.20.0/24 대역 라우팅 역할
네트워크 정보 확인

k8s-ctr podCIDR - 172.20.0.0/24
k8s-w0 podCIDR - 172.20.2.0/24
k8s-w1 podCIDR - 172.20.1.0/24
autoDirectNodeRoutes=true 이해하기
k8s-w1 에서 라우팅 정보

w1 노드에서 172.20.0.0/24 (컨트롤 플레인 podCIDR)로 가려면 192.168.10.100 (게이트웨이) 를 통과해야 한다.
172.20.2.0/24 대역에 대한 정보는 없다.
즉, k8s-w0노드의 podCIDR를 모르는 상황
k8s-w0 에서 라우팅 정보

w0 노드의 라우팅 테이블에서는 172.20.0.0/24 와 172.0.1.0/24 대역에 대한 정보다 둘다 없다.
즉, k8s-ctr, k8s-w1노드의 podCIDR를 k8s-w0노드는 모른다.
결론적으로 현재 k8s-ctr/k8s-w1 과 k8s-w0는 다른 네트워크 대역을 사용하고 있고, 각 노드들은 서로의 podCIDR를 모르는 상황.
pod들 끼리 통신이 되지 않는다.
이게 autoDirectNodeRoutes=true의 기능이다...???
솔직히 이해하지 못 했다.
ping Test

dummy interface 와 Node IP로의 ping 은 정상적으로 작동한다.
Pod간 통신이 되는지는 예제를 통해서 실습예정.
예제 어플리케이션 배포
# 샘플 애플리케이션 배포
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
예제 어플리케이션 배포 확인

webpod 를 3개 배포했는데, 각 노드에 하나씩 올라오는 것을 확인
실제로 ENDPOINTS 가 아래와 같은 것을 확인
172.20.2.24 (w0 podCIDR)
172.20.1.165 (w1 podCIDR)
172.20.0.64 (ctr podCIDR)
통신확인
kubectl exec -it curl-pod -- sh -c 'while true; do curl -s --connect-timeout 1 webpod | grep Hostname; echo "---" ; sleep 1; done'

k8s-ctr에서 curl 명령어를 webpod에 날려보면, 특정 시점에 응답이 오지 않는 것을 확인할 수 있다.
앞에서 예상했던, k8s-ctr 은 w0 노드의 podCIDR를 모르기 때문에 통신이 되지 않을 것이다 라는 가정이 맞았다.
정확한 원인을 파헤쳐보자
# k8s-w0 노드에 배포된 webpod 파드 IP 지정
export WEBPOD=$(kubectl get pod -l app=webpod --field-selector spec.nodeName=k8s-w0 -o jsonpath='{.items[0].status.podIP}')
echo $WEBPOD
# 신규 터미널 [router]
tcpdump -i any icmp -nn
# k8s-w0 노드에 있는 webpod에 curl 요청
kubectl exec -it curl-pod -- ping -c 2 -w 1 -W 1 $WEBPOD
문제가 되는 w0에 배포된 webpod의 IP를 변수 지정한 후에 curl 요청을 날린다.
동시에 router 에서 tcpdump를 통해서 무슨 일이 일어나는지 확인해본다.


curl 요청은 eth1 인터페이스를 통해서 들어왔다.
curlpod (172.20.0.193) 에서 w0 노드에 있는 webpod(172.20.2.24)로 가려면 eth2 인터페이스를 사용해야하는데, eth0 인터페이스를 통해서 나갔다.
k8s-ctr 노드의 라우팅 정보를 다시 확인해보면 172.20.2.0/24 대역에 해당하는 라우팅 정보가 없다.

어디에서 매칭이 안되기 때문에 default 인터페이스를 통해서 나간 것.
즉 다른 네트워크 대역을 사용하는 노드의 pod 들 사이에는 통신이 이루어 지지 않는다.
어떻게 해결할 것인가?
- 수동으로 라우팅 설정
- 가장 간단한 방법.
- 현재는 노드가 3개이지만, 만약 100대가 넘어가는 대규모의 노드에서는 수동으로 관리가 될까?
- 만약 노드의 podCIDR가 갑자기 변경이 되면? 이걸 수동으로 변경하나?
- 현실적으로 불가능
- 자동 BGP
- 자동으로 라우팅 설정
- 노드의 podCIDR가 변경되면 자동으로 적용
- Overlay Network
- 기존 물리 네트워크 위에 가상의 네트워크를 덧씌운 것.
- 현 예시에서는 podIP로 통신을 하지 않고, 가상의 네트워크 nodeIP를 씌워서 통신
- 여러가지가 있지만 VXLAN을 예시로 보면 pod1 -> pod2 로 통신할 때, podIP로 직접 통신을 하지 않고, VXLAN 이라는 NIC를 거쳐서 통신한다.
- pod1 -> VXLAN(node1) -> VXLAN (node 2) -> pod2 이런 식

'DevOps > cilium' 카테고리의 다른 글
| [Cilium Study] Pod간 통신 & k8s 외부 노출 3 (0) | 2025.08.10 |
|---|---|
| [Cilium Study] Pod간 통신 & k8s 외부 노출 2 (0) | 2025.08.09 |
| [Cilium Study] CoreDNS, LocalNodeDNS (3) | 2025.08.03 |
| [Cilium Study] Masquerading (4) | 2025.08.03 |
| [Cilium Study] Routing (6) | 2025.08.02 |