ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] Service Cluster IP란? Kubernetes Network? Kubernetes iptables?
    인프라/Kubernetes 2020. 11. 19. 18:57

    Service Cluster IP란 무엇이냐! Virtual IP 라고 하는데 무슨 의미인고 하니

    실제로 존재하지 않지만 kube-proxy에 의해 관리되어지는 IP인 것이다. Components에 대해 이야기할 떄 등장한 녀석인데 네트워크 관리를 담당한다는게 무슨뜻인지 그 당시에는 몰랐었다.

    그러나 알고보니 kube-proxy가 iptables에 규칙들을 생성하고 삭제하는 역할을 하면서 클러스터 내부의 통신, 외부와 내부의 통신을 가능하게끔하는 역할을 하는것이었다.

     


     

    생성된 Service에 대해 알아보자.

    kubectl get services -o wide

    여기서 kubernetes-bootcamp는 내가 만든 Service이다.

    "kubernetes-bootcamp" app은 pod에 8080번으로 접속하면 "Hello~~~%$#%"를 출력해주는 node.js application이다.

     

    kubectl describe services/kubernetes-bootcamp

    Service Type으로 NodePort로 만들었으며 이는 {공인IP}:31110 으로 접속하면 Cluster IP 10.111.14.255가 받아서 Pod속 Endpoints 172.16.0.3:8080 으로 전송한다는 뜻이다.

     


    지금부터는 누군가의 pc에서 192.168.5.1(쿠버네티스 클러스터환경인 pc의 공인IP):31110 으로 패킷을 보냈을 경우 패킷이 변화하는 과정을 알아볼 것이다.

    현재패킷 (어디서 들어왔는지는 상관없다 목적지가 중요하다)
    
    | sourceIP: ? | sourcePort: ? | destinationIP:192.168.5.1 | destinationPort:31110 |

    ipchain이 어떤형식으로 실행되는지 (webterror.net/?p=1622)를 참조하도록 하자.

     

    첫번째로 Service생성되면 kube-proxy에 의해 iptables규칙추가되는듯 하다.

     

    가장처음 PREROUTING Chain을 거친다.

    iptables -t nat -S PREROUTING

    cali-PREROUTING은 건너뛰고 KUBE-SERVICES로 점프

     

    iptables -t nat -S KUBE-SERVICES

    현재패킷
    | sourceIP: ? | sourcePort: ? | destinationIP:192.168.5.1 | destinationPort:31110 |state:NEW |

    -d 목적지에대한 IP에 맞는게 없으니 맨 마지막 정책 --dst-type LOCAL이 실행된다. LOCAL의 뜻은 현재 host pc가 가지고 있는 network interface가 목적지인지를 검사하는것인데 192.168.5.1ens33에 할당되어 있으니 만족한다!

    KUBE-NODEPORTS로 점프

     

    iptables -t nat -S KUBE-NODEPORTS

    --dport 31110 목적지 포트번호가 일치한다! KUBE-MARK-MASQ 으로 점프

    현재패킷
    | sourceIP: ? | sourcePort: ? | destinationIP:192.168.5.1 | destinationPort:31110 | mark:0x4000 |

     

    다시 돌아와서 다음 정책도 만족하니 KUBE-SVC-2TYZFXBKM236ELT2 로 점프

    KUBE-SEP-EOM7RMYQTXAH45UH 까지 바로 넘어와서 첫번째 -s 는 만족하지 않으니 패스하고 두번째 정책을 보면 DNAT --to-destination 172.16.0.3:8080 으로 목적지를 변경한다!

    현재패킷
    | sourceIP: ? | sourcePort: ? | destinationIP:172.16.0.3 | destinationPort:8080 | mark:0x4000 |

    DNAT으로 인해 PREROUTING -> FORWARD로 넘어간다!

    iptables -t filter -S KUBE-FORWARD

    KUBE-FORWARD 점프

    상태가 INVALID가 아니니 넘어가고, mark가 0x4000 으로 되어있으니 ACCEPT 되어서 FORWARD Chain은 통과된다.

     

    FORWARD -> POSTROUTING 으로!

    마크가 0x4000/0x4000 이니 건너뛰고 -j MARK --set-xmark 0x4000/0x0로 인하여 0이 되면서 mark가 사라진다?..

    --set-xmark 에 대해 좀 알아봐야겠다...

    현재패킷
    | sourceIP: ? | sourcePort: ? | destinationIP:172.16.0.3 | destinationPort:8080 |

    MASQUERADE 로 인하여 패킷은 나가게 된다!

     


    + 2020-11-20 추가

    iptables -t nat -I PREROUTING 1 -d 192.168.5.1/32 -p tcp -m tcp --dport 31110 -j LOG --log-prefix "192.168.5.1 log"
    iptables -t nat -I KUBE-NODEPORTS 2  -j LOG --log-prefix "KUBE-NODEPORTS "
    iptables -t nat -I KUBE-NODEPORTS 1 -p tcp --dport 31110 -j LOG --log-prefix "KUBE-NODEPORTS bf "
    iptables -t nat -I KUBE-NODEPORTS 3 -p tcp --dport 31110 -j LOG --log-prefix "KUBE-NODEPORTS af "
    iptables -t nat -I POSTROUTING -j LOG --log-prefix "POSTROUTING bf "
    iptables -t nat -I KUBE-POSTROUTING 2 -j LOG --log-prefix "MARK bf "
    iptables -t nat -I KUBE-POSTROUTING 4 -j LOG --log-prefix "MASQUERADE bf "

    Nov 20 15:20:51 kube-master kernel: 192.168.5.1 logIN=ens33 OUT= MAC=00:0c:29:1d:57:33:00:0c:29:e4:bc:6e:08:00 

    SRC=192.168.5.128 DST=192.168.5.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=27773 DF PROTO=TCP SPT=52930 DPT=31110 WINDOW=29200 RES=0x00 SYN URGP=0

     

    Nov 20 15:20:51 kube-master kernel: FORWARD before IN=ens33 OUT=tunl0 MAC=00:0c:29:1d:57:33:00:0c:29:e4:bc:6e:08:00 

    SRC=192.168.5.128 DST=172.16.0.4 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=27773 DF PROTO=TCP SPT=52930 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x4000

     

    Nov 20 15:20:51 kube-master kernel: POSTROUTING bf IN= OUT=tunl0 

    SRC=192.168.5.128 DST=172.16.0.4 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=27773 DF PROTO=TCP SPT=52930 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x4000

     

    Nov 20 15:20:51 kube-master kernel: MARK bf IN= OUT=tunl0 

    SRC=192.168.5.128 DST=172.16.0.4 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=27773 DF PROTO=TCP SPT=52930 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x4000

     

    Nov 20 15:20:51 kube-master kernel: MASQUERADE bf IN= OUT=tunl0 

    SRC=192.168.5.128 DST=172.16.0.4 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=27773 DF PROTO=TCP SPT=52930 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0

     

    실제 iptables에 LOG 모듈을 추가하여 로그를 찍어보니

    DNAT으로 인한 패킷의 목적지가 변한것을 확인할 수 있었다.

     

    마지막에 MASQUERADE 로그를 보면 최종적으로 tunl0 network interface를 통하여 나가라고 되어있다.

    그래서 최종적으로 나가게 되는 패킷의 SRC=172.16.0.128 으로 나가게될 것으로 예상된다. 그리고 next hop 으로 Slave Node로 향할 것이다.

     

    iptables -t nat -I PREROUTING  -p tcp -j LOG --log-prefix "PREROUTING bf "
    iptables -I INPUT -s 172.16.0.128 -j LOG --log-prefix "INPUT 1 "

    Nov 20 16:00:46 kube-node1 kernel: PREROUTING bf IN=tunl0 OUT= MAC= SRC=172.16.0.128 DST=172.16.0.4 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=59862 DF PROTO=TCP SPT=44589 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0
    Nov 20 16:00:46 kube-node1 kernel: INPUT 1 IN=tunl0 OUT=calie1760be6016 MAC= SRC=172.16.0.128 DST=172.16.0.4 LEN=60 TOS=0x00 PREC=0x00 TTL=62 ID=59862 DF PROTO=TCP SPT=44589 DPT=8080 WINDOW=29200 RES=0x00 SYN URGP=0 MARK=0x10000

     

    Slave Node의 iptables Log를 보면 tunl0 interface로 패킷을 받아서 calie1760be6016 이라는 생소한 인터페이스 로 내보낸다고 되어있다.

     

    cali~ 로시작하는 인터페이스는 우리가 CNI(Container Network Interface) plugin으로 calico를 설치했을 때 생성되는 네트워크 인터페이스이다. 그래서 이 인터페이스로 패킷이 가게되면 calico가 따로 관리하는 테이블을 보고 목적지가 172.16.0.4:8080 이므로 이에 맞는 container네트워크 인터페이스로 전송해줄 듯 하다.

     

    그런데 아직까지 Cluster-IP에 대해서 나오지 않았다 ... 아무리 찾아봐도 공인IP -> Cluster IP -> Pod IP 로의 변환과정을 제대로 찾질 못하겠다... 현재 그냥 보기로는 공인IP -> Pod IP로 바로 바뀌어버리는데 이게 NodePort Type으로 인한 효과인지 그리고 1개의 replica를 사용해서 그런지 모르겠다. 일단 2개 이상의 replica를 생성했을 때 다시 봐야겠다.

     

     

    아래 블로그를 참조하여 공부했다.

     

    [GCP][K8S] Kubernetes 네트워크 살펴보기

    Kubernetes에서 어떻게 pod간 네트워크, 외부(ingress, LB)와 네트워크가 동작하는지 살펴본다. 1. 환경 구성 Google Cloud Platform에 GKE로 구성(1.9.7 버전) Container address : 10.12.0.0/14 (Overlay Networ..

    www.kangtaeho.com

     

    댓글

Designed by Tistory.