Ssoon

[3주차] Pod ↔ 외부(인터넷) 통신 본문

쿠버네티스 네트워크 스터디 3기

[3주차] Pod ↔ 외부(인터넷) 통신

구구달스 2024. 9. 13. 14:35
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기

Pod 배포 전 기본 상태 확인

🧿 Calico 네트워크 플러그인에서 사용 중인 IP 풀의 세부 정보

  • default-ipv4-ippool 는 172.16.0.0/16 범위의 IP 주소를 포함하는 IP 풀입니다.
  • NAT는 활성화되어 있으며, 모든 트래픽에 대해 IP-in-IP 터널링이 사용됩니다. VXLAN 터널링은 사용하지 않으며, IP 풀은 활성 상태로 BGP를 통해 광고될 수 있습니다.
  •  IP 풀은 클러스터 내 모든 노드에 적용됩니다.
(⎈|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()
  • cali-nat-outgoing 체인은 NAT를 사용하여 패킷의 출발지 IP 주소를 변환하는 규칙을 포함합니다.
  • 이 규칙은 모든 프로토콜에 대해 적용되며, 출발지 IP 주소가 특정 IP 집합에 포함되고, 목적지 IP 주소가 다른 IP 집합에 포함되지 않을 때 NAT 변환을 수행합니다.
  • MASQUERADE 동작을 사용하여 소스 IP 주소를 변환합니다. 내부 네트워크의 IP 주소를 외부 IP 주소로 변환하여 인터넷과의 통신을 가능하게 합니다.
root@k8s-w1:~# iptables -n -t nat --list cali-nat-outgoing
Chain cali-nat-outgoing (1 references)
target     prot opt source               destination
MASQUERADE  all  --  0.0.0.0/0            0.0.0.0/0            /* cali:flqWnvo8yq4ULQLa */ match-set cali40masq-ipam-pools src ! match-set cali40all-ipam-pools dst random-fully

 

Pod 배포 및 외부 통신 확인

  • Node (k8s-w1)에 POd 1개를 생성합니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# cat node1-pod1.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
  
(⎈|SsoonLab:N/A) root@k8s-m:~# kubectl apply -f node1-pod1.yaml
pod/pod1 created

(⎈|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          21s   172.16.158.6   k8s-w1   <none>           <none>

🧿 외부 통신 확인

  • Calico 네트워크 플러그인을 사용해 외부로 나가는 트래픽에 대한 NAT(Network Address Translation) 처리 확인
root@k8s-w1:~# iptables -n -v -t nat --list cali-nat-outgoing
Chain cali-nat-outgoing (1 references)
 pkts bytes target     prot opt in     out     source               destination
    9   590 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:flqWnvo8yq4ULQLa */ match-set cali40masq-ipam-pools src ! match-set cali40all-ipam-pools dst random-fully
  • Pod1과 연결된 veth 인터페이스 이름을 VETH1이라는 변수에 저장합니다.
(⎈|SsoonLab:N/A) root@k8s-m:~# VETH1=$(calicoctl get workloadEndpoint | grep pod1 | awk '{print $4}')
(⎈|SsoonLab:N/A) root@k8s-m:~# echo $VETH1
calice0906292e2
  • Node (k8s-w1) 에도 변수를 저장합니다.
root@k8s-w1:~# VETH1=calice0906292e2
  •  Pod1에서 8.8.8.8로 ping 테스트가 정상적으로 동작하고 있는것을 확인합니다.,
 pod1  ~   ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=47 time=33.4 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 33.429/33.429/33.429/0.000 ms

🧿 모든 네트워크 인터페이스에서 ICMP 패킷을 캡처합니다.

  • -i any: 모든 네트워크 인터페이스에서 패킷을 캡처하라는 뜻입니다. any를 사용하면 여러 네트워크 인터페이스에서 발생하는 트래픽을 동시에 모니터링할 수 있습니다.
  • -nn: IP 주소와 포트를 이름으로 변환하지 않고 숫자로 표시합니다. (예: DNS 이름이 아닌 8.8.8.8과 같은 숫자로 표시)
  • calice0906292e2 In 172.16.158.6 > 8.8.8.8: ICMP echo request
    • Pod1(172.16.158.6)이 Google DNS 서버(8.8.8.8)로 Ping 요청(ICMP echo request)을 보냈고, 이 패킷이 Pod1과 연결된 네트워크 인터페이스(calice0906292e2)를 통해 들어왔습니다.
  • ens5 Out 192.168.10.101 > 8.8.8.8: ICMP echo request
    • Pod1(172.16.158.6)이 Google DNS 서버로 보낸 Ping 요청이 서버의 물리 인터페이스 ens5에서 NAT되어 Node (k8s-w1) 의 IP 주소(192.168.10.101)로 외부로 전송되었습니다.
  • ens5 In 8.8.8.8 > 192.168.10.101: ICMP echo reply
    • Google DNS 서버(8.8.8.8)에서 Node (k8s-w1)의 (192.168.10.101)로 Ping 요청에 대한 응답 패킷이 도착한 상황입니다.
  • calice0906292e2 Out 8.8.8.8 > 172.16.158.6: ICMP echo reply
    • 서버는 받은 Ping 응답 패킷을 Pod1의 IP 주소(172.16.158.6)로 다시 전달하고 있으며, Pod1과 연결된 네트워크 인터페이스(calice0906292e2) 를 통해 이루어집니다.
root@k8s-w1:~# tcpdump -i any -nn icmp
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
14:41:19.218866 calice0906292e2 In  IP 172.16.158.6 > 8.8.8.8: ICMP echo request, id 81, seq 1, length 64
14:41:19.218924 ens5  Out IP 192.168.10.101 > 8.8.8.8: ICMP echo request, id 29030, seq 1, length 64
14:41:19.252236 ens5  In  IP 8.8.8.8 > 192.168.10.101: ICMP echo reply, id 29030, seq 1, length 64
14:41:19.252278 calice0906292e2 Out IP 8.8.8.8 > 172.16.158.6: ICMP echo reply, id 81, seq 1, length 64

🧿 Pod1과 연결된 가상 네트워크 인터페이스(calice0906292e2) ICMP 패킷을 캡처합니다.

root@k8s-w1:~# tcpdump -i $VETH1 -nn icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on calice0906292e2, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:41:53.443558 IP 172.16.158.6 > 8.8.8.8: ICMP echo request, id 85, seq 1, length 64
14:41:53.476813 IP 8.8.8.8 > 172.16.158.6: ICMP echo reply, id 85, seq 1, length 64

🧿 tunl0 인터페이스에서 ICMP 패킷을 캡처합니다.

  • 정보가 조회되지 않습니다 -> tunl0을 통과하지 않습니다.
root@k8s-w1:~# tcpdump -i tunl0 -nn icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tunl0, link-type RAW (Raw IP), snapshot length 262144 bytes

🧿 ens5 네트워크 인터페이스에서 패킷을 캡처합니다.

  • IP 192.168.10.101 > 8.8.8.8: ICMP echo request, id 39774, seq 1, length 64
    • 192.168.10.101에서 8.8.8.8으로 핑 요청을 보낸 내용입니다.
  • IP 8.8.8.8 > 192.168.10.101: ICMP echo reply, id 39774, seq 1, length 64
    • 8.8.8.8에서 192.168.10.101으로 핑 응답을 보낸 내용입니다.
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
14:56:12.932274 IP 192.168.10.101 > 8.8.8.8: ICMP echo request, id 39774, seq 1, length 64
14:56:12.965583 IP 8.8.8.8 > 192.168.10.101: ICMP echo reply, id 39774, seq 1, length 64
  • Calico 네트워크 플러그인을 사용해 외부로 나가는 트래픽에 대한 NAT(Network Address Translation) 처리 확인
root@k8s-w1:~# iptables -n -v -t nat --list cali-nat-outgoing
Chain cali-nat-outgoing (1 references)
 pkts bytes target     prot opt in     out     source               destination
   21  1598 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:flqWnvo8yq4ULQLa */ match-set cali40masq-ipam-pools src ! match-set cali40all-ipam-pools dst random-fully
  • cali40masq-ipam-pools라는 이름의 집합을 조회합니다.
    • 이 집합은 IP 네트워크 주소를 저장하는 해시 테이블입니다. 
    • 현재 이 집합에는 172.16.0.0/16이라는 하나의 IP 범위가 포함되어 있습니다. 이 범위는 172.16.0.0부터 172.16.255.255까지의 모든 IP 주소를 포함합니다.
root@k8s-w1:~# ipset list cali40masq-ipam-pools
Name: cali40masq-ipam-pools
Type: hash:net
Revision: 7
Header: family inet hashsize 1024 maxelem 1048576 bucketsize 12 initval 0x0dbb885f
Size in memory: 504
References: 1
Number of entries: 1
Members:
172.16.0.0/16
Comments