kubernetes NodePort Networking 분석 New version
[kubernetes kube-proxy 관련 글 목록]
Kubernetes kube-proxy IPVS Mode 설정
Kubernetes NodePort Networking 분석 (kube-proxy : iptable mode)
Kubernetes NodePort Networking 분석 (kube-proxy : iptable mode)- New version
kubernetes LoadBalancer Networking 분석 (kube-proxy : iptable mode)
목적
환경
apiVersion: apps/v1
kind: Deployment
metadata:
name: iksoon-deployment
labels:
app: iksoon-tomcat
spec:
replicas: 3
selector:
matchLabels:
app: iksoon-pod-tomcat
template:
metadata:
labels:
app: iksoon-pod-tomcat
spec:
containers:
- name: iksoon-tomcat
image: peksoon/iksoon_tomcat:1.0.6
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: iksoon-tomcat-service
labels:
name: service-tomcat-service
spec:
type: NodePort
ports:
- name: "iksoon-tomcat8-network-setting"
port: 8088
protocol: TCP
targetPort: 8080
nodePort: 30001
selector:
app: iksoon-pod-tomcat
글을 읽는데 필요한 기초 개념
Netfilter란?
- NF_IP_PRE_ROUTING: 외부에서 온 Packet이 Linux Kernel의 Network Stack을 통과하기 전에 발생하는 Hook이다. Packet을 Routing하기 전에 발생
- NF_IP_LOCAL_IN: Packet이 Routing된 후 목적지가 자신일 경우, Packet을 Process에 전달하기 전에 발생
- NF_IP_FORWARD: Packet이 Routing된 후 목적지가 자신이 아닐 경우, Packet을 다른 곳으로 Forwarding하는 경우 발생
- NF_IP_LOCAL_OUT: Packet이 Process에서 나와 Network Stack을 통과하기 전 발생
- NF_IP_POST_ROUTING: Packet이 Network Stack을 통과한 후 밖으로 보내기 전 발생
-
packet을 drop할지 전달할지 결정
-
Packet NAT(Network Address Translation)을 위한 table. packet의 source/destination address를 변경
-
Packet의 IP header를 바꿈. Packet의 TTL 변경, Marking하여
-
다른 iptables의 Table이나 Network tool에서 Packet을 구분 할 수 있도록 함
-
Netfilter Framework는 Hook 뿐만 아니라 Connection Tracking 기능을 제공.
-
이전에 도착한 Packet들을 바탕으로 방금 도착한 Packet의 Connection을 추적함.
-
Raw Table은 특정 Packet이 Connection Tracking에서 제외되도록 설정함.
-
SELinux에서 Packet을 어떻게 처리할지 결정하기 위한 Table
Netfilter, iptables와 tcpdump 우선순위
Chain 종류
- PREROUTING (DNAT) = 패킷의 도착지(deatination) 주소를 변경한다. D(estination)NAT
- POSTROUTING (SNAT 또는 masquerade) = 패킷의 출발지(source) 주소를 변경한다. S(ource)NAT
- OUTPUT = 호스트에서 밖으로 흐르는 패킷의 도착지(destination) 주소를 변경한다.
- INPUT = 밖에서 호스트로 흐르는 패킷의 출발지(source) 주소를 변경한다.
NAT
- PREROUTING : DNAT을 이용하여 패킷이 생길 때 사용됨.
- POSTROUTING : SNAT을 이용하여 패킷이 나갈 때 사용됨.
SNAT 개념
DNAT 개념
lsof 명령
tcpdump External -> Master Node IP:NodePort-> Container
예제 환경
Routing 요약
1. Master Node : enp0s3
tcpdump -i enp0s3 -ne tcp port 30001 -vv -c 10
[MAC 정보]
출발지 : 52:54:00:12:35:00 (virtualbox router mac)
도착지 : 08:00:27:33:4f:49 (Master Node의 enp0s3 인터페이스 MAC주소)
[IP주소 정보]
출발지 : 192.168.56.1 (external에서 접근한 ip주소)
도착지 : 10.0.2.15 (Master Node의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : pago-services1 (설정된 NodePort 번호)
|
패킷 흐름 분석
2. Master Node : kube-proxy
lsof -i:30001
netstat -nap | grep kube-proxy
2.1. kube-proxy Mode 확인
3. Master Node : kube-proxy iptables Routing 분석
3.0. kube-proxy Netfiler (iptables) 도식화
3.1. raw PREROUTING 확인
iptables -t raw -L PREROUTING
3.2. mangle PREROUTING 확인
iptables -t mangle -L PREROUTING
3.3. nat PREROUTING 확인
nat table
iptables -t nat -L PREROUTING
3.3.0. nat table - PREROUTING chain 도식화
3.3.1. KUBE-SERVICES Chain의 Rule을 확인
iptables -t nat -L KUBE-SERVICES -n | column -t
[MAC 정보]
출발지 : 52:54:00:12:35:00 (virtualbox router mac)
도착지 : 08:00:27:33:4f:49 (Master Node의 enp0s3 인터페이스 MAC주소)
[IP주소 정보]
출발지 : 192.168.56.1 (external에서 접근한 ip주소)
도착지 : 10.0.2.15 (Master Node의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : pago-services1 (설정된 NodePort 번호)
|
3.3.2. KUBE-NODEPORTS Chain의 Rule을 확인
iptables -t nat -L KUBE-NODEPORTS -n | column -t
[MAC 정보]
출발지 : 52:54:00:12:35:00 (virtualbox router mac)
도착지 : 08:00:27:33:4f:49 (Master Node의 enp0s3 인터페이스 MAC주소)
[IP주소 정보]
출발지 : 192.168.56.1 (external에서 접근한 ip주소)
도착지 : 10.0.2.15 (Master Node의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : pago-services1 (설정된 NodePort 번호)
|
3.3.3. KUBE-SVC-D7CQFPLTU3IZSXTJ Chain의 Rule을 확인
iptables -t nat -L KUBE-SVC-D7CQFPLTU3IZSXTJ -n
watch -n 1 iptables -t nat -L KUBE-SVC-D7CQFPLTU3IZSXTJ -nv
3.3.4. KUBE-SEP-EIUFBJG7JND3UXZR Chain의 Rule을 확인
iptables -t nat -L KUBE-SEP-EIUFBJG7JND3UXZR -n
[MAC 정보]
출발지 : 52:54:00:12:35:00 (virtualbox router mac)
도착지 : 08:00:27:33:4f:49 (Master Node의 enp0s3 인터페이스 MAC주소)
[IP주소 정보]
출발지 : 192.168.56.1 (external에서 접근한 ip주소)
도착지 : 10.0.2.15 (Master Node의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : pago-services1 (설정된 NodePort 번호)
|
watch -n 1 iptables -t nat -L KUBE-SEP-EIUFBJG7JND3UXZR -nv
[MAC 정보]
출발지 : 52:54:00:12:35:00 (virtualbox router mac)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 192.168.56.1 (external에서 접근한 ip주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소로 변경)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : 8080 (30001 NodePort에 맵핑된 목적지 Pod의 Port번호로 변경)
|
3.4. Routing
[MAC 정보]
출발지 : 52:54:00:12:35:00 (virtualbox router mac)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 192.168.56.1 (external에서 접근한 ip주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소로 변경)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : 8080 (30001 NodePort에 맵핑된 목적지 Pod의 Port번호로 변경)
|
3.5. mangle FORWARD
iptables -t mangle -L FORWARD
3.6. filter FORWARD
filter table
- ACCEPT : 패킷을 허용한다.
- DROP : 패킷을 차단한다.
- REJECT : 패킷을 거부한다.
- RETURN : 패킷을 맨 아래 규칙으로 내린다.
- MARK : 패킷에 마크를 표시한다.
- LOG : 로그를 남긴다.(/var/log/messages)
- MASQUERADE : 패킷의 출발지를 나가는 장치의 아이피로 바꾼다.
- SNAT : 패킷의 출발지를 지정한 아이피로 바꾼다.
- DNAT : 패킷의 도착지를 지정한 아이피로 바꾼다.
iptables -t filter -L FORWARD | column -t
3.6.1. KUBE-FORWARD Chain의 Rule을 확인
iptables -t filter -L KUBE-FORWARD | column -t
watch -n 1 iptables -t filter -L KUBE-FORWARD -nv
iptables -t filter -L KUBE-SERVICES | column -t
3.6.3. KUBE-EXTERNAL-SERVICES Chain의 Rule을 확인
iptables -t filter -L KUBE-EXTERNAL-SERVICES | column -t
3.7. mangle POSTROUTING
iptables -t mangle -L POSTROUTING | column -t
3.8. nat POSTROUTING
3.7.1. KUBE-POSTROUTING Chain의 Rule을 확인
iptables -t nat -L KUBE-POSTROUTING | column -t
watch -n 1 iptables -t nat -L KUBE-POSTROUTING -nv
[MAC 정보]
출발지 : 56:61:6c:31:0f:4f (Master Node flannel.1인터페이스 MAC주소)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 10.244.0.0 (Master Node의 flannel.1 인터페이스 ip주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소로 변경)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : 8080 (30001 NodePort에 맵핑된 목적지 Pod의 Port번호로 변경)
|
4. Master Node : flannel.1
[MAC 정보]
출발지 : 56:61:6c:31:0f:4f (Master Node flannel.1인터페이스 MAC주소)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소로 변경)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : 8080 (30001 NodePort에 맵핑된 목적지 Pod의 Port번호로 변경)
|
tcpdump -i flannel.1 -ne tcp -vv -c 10
[MAC 정보]
출발지 : 56:61:6c:31:0f:4f (Master Node flannel.1인터페이스 MAC주소)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소로 변경)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : 8080 (30001 NodePort에 맵핑된 목적지 Pod의 Port번호로 변경)
|
5. Master Node : flannel.1의 ARP Table확인
kubectl get pod -o wide -n kube-system
kubectl -it exec kube-flannel-ds-dphph -n kube-system -- arp -a
[MAC 정보]
출발지 : 56:61:6c:31:0f:4f (Master Node의 flannel.1인터페이스 MAC주소)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip 주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : webcache (목적지 Pod의 tomcat container port = 8080)
|
6. Master Node : enp0s3
tcpdump -i enp0s3 -ne udp -vv -c 10
Outer-packet
[MAC 정보]
출발지 : 08:00:27:33:4f:49 (Master Node의 enp0s3 인터페이스의 MAC)
도착지 : 08:00:27:31:b4:a1 (Worker Node 2의 enp0s3 인터페이스의 MAC)
[IP주소 정보]
출발지 : 10.0.2.15 (Master Node의 IP)
도착지 : 10.0.2.7 (Worker Node의 IP)
[Port 정보]
출발지 : 랜덤한 Port 번호
도착지 : 8472(otv)
VXLAN으로 캡슐화 된 패킷 정보
[MAC 정보]
출발지 : 56:61:6c:31:0f:4f (Master Node의 flannel.1인터페이스 MAC주소)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip 주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : webcache (목적지 Pod의 tomcat container port = 8080)
|
7. Worker Node : enp0s3
tcpdump -i enp0s3 -ne udp -vv -c 10
Outer-packet
[MAC 정보]
출발지 : 08:00:27:33:4f:49 (Master Node의 enp0s3 인터페이스의 MAC)
도착지 : 08:00:27:31:b4:a1 (Worker Node 2의 enp0s3 인터페이스의 MAC)
[IP주소 정보]
출발지 : 10.0.2.15 (Master Node의 IP)
도착지 : 10.0.2.7 (Worker Node의 IP)
[Port 정보]
출발지 : 랜덤한 Port 번호
도착지 : 8472(otv)
VXLAN으로 캡슐화 된 패킷 정보
[MAC 정보]
출발지 : 56:61:6c:31:0f:4f (Master Node의 flannel.1인터페이스 MAC주소)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip 주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : webcache (목적지 Pod의 tomcat container port = 8080)
|
8. Worker Node : flannel.1
tcpdump -i flannel.1 -ne tcp -vv -c 10
VXLAN으로 캡슐화 된 패킷 정보
[MAC 정보]
출발지 : 56:61:6c:31:0f:4f (Master Node의 flannel.1인터페이스 MAC주소)
도착지 : f2:3b:9f:cb:37:fd (Worker Node의 flannel.1인터페이스 MAC주소)
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip 주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : webcache (목적지 Pod의 tomcat container port = 8080)
|
9. Worker Node : cni0
tcpdump -i cni0 -ne tcp and dst 10.244.1.2 -vv -c 10
VXLAN으로 캡슐화 된 패킷 정보
[MAC 정보]
출발지 : 82:32:81:9c:27:23 (Worker Node의cni0 인터페이스의 MAC)
도착지 : d2:f2:43:1f:e2:1e
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip 주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : webcache (목적지 Pod의 tomcat container port = 8080)
|
kubectl -it exec kube-flannel-ds-5qrzc -n kube-system -- arp -a | grep 10.244.1.117
9. Worker Node : vethbf625505 (목적지 Pod)
tcpdump -i vethd92f7dc2 -ne tcp -vv -c 10
tcpdump -ne tcp -vv -c 10
VXLAN으로 캡슐화 된 패킷 정보
[MAC 정보]
출발지 : 82:32:81:9c:27:23 (Worker Node의cni0 인터페이스의 MAC)
도착지 : d2:f2:43:1f:e2:1e
[IP주소 정보]
출발지 : 10.244.0.0 (master node의 flannel.1 인터페이스 ip 주소)
도착지 : 10.244.1.2 (목적지 Pod의 IP주소)
[Port]
출발지 : 랜덤한 Port 번호
도착지 : webcache (목적지 Pod의 tomcat container port = 8080)
|
분석 완료
제 글을 복사할 시 출처를 명시해주세요.
글에 오타, 오류가 있다면 댓글로 알려주세요! 바로 수정하겠습니다!
'Kubernetes > 네트워크' 카테고리의 다른 글
CNI 리서치 : CNI 개념 (0) | 2024.08.06 |
---|---|
kube-proxy가 iptables를 update하는 시점 (0) | 2024.07.15 |
kubernetes CNI 종류 확인 방법 (0) | 2021.11.04 |
kubernetes NodePort Networking 분석 (kube-proxy : IPVS mode) (0) | 2021.05.07 |
kubernetes LoadBalancer Networking 분석 (kube-proxy : iptable mode) (0) | 2021.05.06 |