Ssoon
[3주차] Calico Mode : Direct 모드 / CrossSubnet 모드 본문
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기
✅ Direct 모드
[ k8s-m ]
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 172.16.0.0/16 true Always Never false false all()
[ k8s-m ]
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get ippool default-ipv4-ippool -o yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
creationTimestamp: "2024-09-13T01:29:35Z"
name: default-ipv4-ippool
resourceVersion: "4751"
uid: 39e31d54-8836-47e7-b5b1-9d2a90d91c26
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 24
cidr: 172.16.0.0/16
ipipMode: Always
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
[ k8s-m ]
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Always/ipipMode: Never/" | calicoctl apply -f -
Successfully applied 1 'IPPool' resource(s)
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get ippool default-ipv4-ippool -o yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
creationTimestamp: "2024-09-13T01:29:35Z"
name: default-ipv4-ippool
resourceVersion: "44677"
uid: 39e31d54-8836-47e7-b5b1-9d2a90d91c26
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 24
cidr: 172.16.0.0/16
ipipMode: Never
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
[ k8s-m ]
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 172.16.0.0/16 true Never Never false false all()
[ k8s-m ]
(⎈|SsoonLab:N/A) root@k8s-m:~# route -n | egrep '(Destination|UG)'
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.10.1 0.0.0.0 UG 100 0 0 ens5
172.16.34.0 192.168.10.1 255.255.255.0 UG 0 0 0 ens5
172.16.158.0 192.168.10.101 255.255.255.0 UG 0 0 0 ens5
172.16.184.0 192.168.10.102 255.255.255.0 UG 0 0 0 ens5
192.168.0.2 192.168.10.1 255.255.255.255 UGH 100 0 0 ens5
✅동작 확인
[ k8s-m ]
- 각 Node 에 Pod 생성합니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# cat node3-pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
nodeName: k8s-w1
containers:
- name: pod1
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
nodeName: k8s-w2
containers:
- name: pod2
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: pod3
spec:
nodeName: k8s-w0
containers:
- name: pod3
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl apply -f node3-pod3.yaml
pod/pod1 created
pod/pod2 created
pod/pod3 created
[ k8s-m ]
- pod1, pod2, pod3가 각각 k8s-w1, k8s-w2, k8s-w0 노드에서 실행 중이며, 각 파드는 정상적으로 Running 상태입니다.
- 각 파드는 Calico에 의해 네트워크 인터페이스를 통해 할당된 IP 주소를 가지고 있으며, 각 노드에서의 네트워크 인터페이스 이름도 확인할 수 있습니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 47s 172.16.158.8 k8s-w1 <none> <none>
pod2 1/1 Running 0 47s 172.16.184.2 k8s-w2 <none> <none>
pod3 1/1 Running 0 47s 172.16.34.1 k8s-w0 <none> <none>
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get wep
WORKLOAD NODE NETWORKS INTERFACE
pod1 k8s-w1 172.16.158.8/32 calice0906292e2
pod2 k8s-w2 172.16.184.2/32 calibd2348b4f67
pod3 k8s-w0 172.16.34.1/32 cali49778cadcf1
[ pod1 ]
🧿 pod1 Shell 접속하고 pod1 에서 pod2 로 핑 통신을 확인합니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl exec -it pod1 -- zsh
dP dP dP
88 88 88
88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P
88' `88 88ooood8 88 Y8ooooo. 88' `88 88' `88 88' `88 88
88 88 88. ... 88 88 88 88 88. .88 88. .88 88
dP dP `88888P' dP `88888P' dP dP `88888P' `88888P' dP
Welcome to Netshoot! (github.com/nicolaka/netshoot)
Version: 0.13
pod1 ~ ping -c 1 172.16.184.2
PING 172.16.184.2 (172.16.184.2) 56(84) bytes of data.
64 bytes from 172.16.184.2: icmp_seq=1 ttl=62 time=0.409 ms
--- 172.16.184.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.409/0.409/0.409/0.000 ms
[ k8s-w1 ]
🧿 ens5 네트워크 인터페이스에서 패킷을 캡처합니다.
- pod1 (172.16.158.8) ▶ pod2 (172.16.184.2) 로 패킷이 (ping 요청) 전송되었습니다.
- pod2 (172.16.184.2) ▶ pod1 (172.16.158.8) 로 패킷이 (ping 요청에 대한 응답) 전송되었습니다.
root@k8s-w1:~# tcpdump -i ens5 -nn icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens5, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:30:14.027539 IP 172.16.158.8 > 172.16.184.2: ICMP echo request, id 114, seq 1, length 64
17:30:14.028147 IP 172.16.184.2 > 172.16.158.8: ICMP echo reply, id 114, seq 1, length 64
[ k8s-w2 ]
🧿 ens5 네트워크 인터페이스에서 패킷을 캡처합니다.
- pod1 (172.16.158.8) ▶ pod2 (172.16.184.2) 로 패킷이 (ping 요청) 전송되었습니다.
- pod2 (172.16.184.2) ▶ pod1 (172.16.158.8) 로 패킷이 (ping 요청에 대한 응답) 전송되었습니다.
root@k8s-w2:~# tcpdump -i ens5 -nn icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens5, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:30:14.027603 IP 172.16.158.8 > 172.16.184.2: ICMP echo request, id 114, seq 1, length 64
17:30:14.027700 IP 172.16.184.2 > 172.16.158.8: ICMP echo reply, id 114, seq 1, length 64
[ pod1 ]
🧿 ens5 네트워크 인터페이스에서 패킷을 캡처합니다.
pod1 ~ ping -c 1 172.16.34.1
PING 172.16.34.1 (172.16.34.1) 56(84) bytes of data.
--- 172.16.34.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
[ k8s-w1 ] , [ k8s-w3 ]
🧿 모든 네트워크 인터페이스에서 IPv4 패킷을 캡처합니다.
- 정보가 표시되지 않습니다.
root@k8s-w1:~# tcpdump -i any proto 4 -nn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
root@k8s-w0:~# tcpdump -i any proto 4 -nn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
- k8s-w3 (192.168.20.0/24) 은 k8s-w1 (192.168.10.0/24) 과 다른 네트워크 대역으로 라우팅 되는데 라우팅 테이블에 pod (172.16.) 에 대한 라우팅정보가 없어 패킷을 전달하지 못합니다.
✅ CrossSubnet 모드
🧿 Node 간 같은 네트워크 대역 ▶ Direct 모드로 동작
🧿 Node 간 다른 네트워크 대역 ▶ IPIP 모드로 동작
[ k8s-m ]
- Calico의 설정 파일에서 ipipMode를 CrossSubnet으로 설정합니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl patch ippool default-ipv4-ippool -p '{"spec":{"ipipMode":"CrossSubnet"}}'
Successfully patched 1 'IPPool' resource
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get ippool default-ipv4-ippool -o yaml
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
creationTimestamp: "2024-09-13T01:29:35Z"
name: default-ipv4-ippool
resourceVersion: "54993"
uid: 39e31d54-8836-47e7-b5b1-9d2a90d91c26
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 24
cidr: 172.16.0.0/16
ipipMode: CrossSubnet
natOutgoing: true
nodeSelector: all()
vxlanMode: Never
(⎈|SsoonLab:N/A) root@k8s-m:~# calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 172.16.0.0/16 true CrossSubnet Never false false all()
🧿 라우팅 테이블에서 "UG" 플래그가 붙은 경로들만 필터링합니다.
[ k8s-m ]
- "UG"는 "Up"과 "Gateway"를 의미하며, 해당 경로가 활성화되어 있고 게이트웨이를 통해 라우팅된다는 것을 나타냅니다.
- 172.16.34.0 192.168.20.100 255.255.255.0 UG 0 0 0 tunl0:
- pod3 (172.16.34.0) 네트워크로 가는 트래픽은 192.168.20.100 게이트웨이를 통해 tunl0 인터페이스를 사용하여 전달됩니다. ▶ IPIP 모드
- 172.16.158.0 192.168.10.101 255.255.255.0 UG 0 0 0 ens5:
- pod1 (172.16.158.0) 네트워크로 가는 트래픽은 192.168.10.101 게이트웨이를 통해 ens5 인터페이스를 사용하여 전달됩니다. ▶ Direct 모드
- 172.16.184.0 192.168.10.102 255.255.255.0 UG 0 0 0 ens5:
- pod2 (172.16.184.0) 네트워크로 가는 트래픽은 192.168.10.102 게이트웨이를 통해 ens5 인터페이스를 사용하여 전달됩니다. ▶ Direct 모드
(⎈|SsoonLab:N/A) root@k8s-m:~# route -n | grep UG
0.0.0.0 192.168.10.1 0.0.0.0 UG 100 0 0 ens5
172.16.34.0 192.168.20.100 255.255.255.0 UG 0 0 0 tunl0
172.16.158.0 192.168.10.101 255.255.255.0 UG 0 0 0 ens5
172.16.184.0 192.168.10.102 255.255.255.0 UG 0 0 0 ens5
192.168.0.2 192.168.10.1 255.255.255.255 UGH 100 0 0 ens5
[ pod1 ]
- pod1 (172.16.158.8) ▶ pod3 (172.16.34.1) 로 ping 테스트를 합니다.
pod1 ~ ping -c 1 172.16.34.1
PING 172.16.34.1 (172.16.34.1) 56(84) bytes of data.
64 bytes from 172.16.34.1: icmp_seq=1 ttl=62 time=1.25 ms
--- 172.16.34.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.252/1.252/1.252/0.000 ms
[ k8s-w1 ]
🧿 IPIP 모드로 동작중
- 패킷 전송:
- k8s-w1 (192.168.10.101) 에서 k8s-w0 (192.168.10.100) 로 전송됨.
- 내부 데이터 전송:
- pod1 (172.16.158.8) 에서 pod3 (172.16.34.1) 로 이동.
- k8s-w1 (192.168.10.101) 에서 k8s-w0 (192.168.10.100) 로 가는 패킷 내부의 데이터가 pod1 (172.16.158.8) 과 pod3 (172.16.34.1) 사이에서 이동하고 있습니다.
root@k8s-w1:~# tcpdump -i any proto 4 -nn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
19:12:46.669779 ens5 Out IP 192.168.10.101 > 192.168.20.100: IP 172.16.158.8 > 172.16.34.1: ICMP echo request, id 218, seq 1, length 64
19:12:46.670934 ens5 In IP 192.168.20.100 > 192.168.10.101: IP 172.16.34.1 > 172.16.158.8: ICMP echo reply, id 218, seq 1, length 64
[ k8s-w0 ]
🧿 IPIP 모드로 동작중
root@k8s-w0:~# tcpdump -i any proto 4 -nn
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
19:12:46.670262 ens5 In IP 192.168.10.101 > 192.168.20.100: IP 172.16.158.8 > 172.16.34.1: ICMP echo request, id 218, seq 1, length 64
19:12:46.670477 ens5 Out IP 192.168.20.100 > 192.168.10.101: IP 172.16.34.1 > 172.16.158.8: ICMP echo reply, id 218, seq 1, length 64
'쿠버네티스 네트워크 스터디 3기' 카테고리의 다른 글
[4주차] ClusterIP (0) | 2024.09.23 |
---|---|
[4주차] 기본 구성 정보 (0) | 2024.09.23 |
[3주차] 다른 Node 에서 Pod ↔ Pod 간 통신 (0) | 2024.09.13 |
[3주차] Pod ↔ 외부(인터넷) 통신 (0) | 2024.09.13 |
[3주차] Pod ↔ Pod 통신 (0) | 2024.09.13 |
Comments