ABOUT ME

와주셔서 감사합니다. 좋은 글을 많이 쓰겠습니다.

Today
Yesterday
Total
  • [Kubernetes] kube-proxy 와 iptables 알아보기
    Kubernetes 2024. 6. 22. 07:49
    반응형

    - 목차

     

    들어가며.

    이번 글에서는 Kubernetes 에서 kube-proxy 의 역할과 Network Iptables 에 대해서 알아보려고 합니다.

    kube-proxy 는 Kubernetes 의 DaemonSet 으로 생성됩니다.

    그래서 모든 Node 는 각각 1개의 kube-proxy 를 내장하고 있습니다.

    아래의 명령어는 현재 실행 중인 kube-proxy Daemonset 을 확인하는 명령어이구요.

    저의 경우에는 5개의 Node 들이 실행 중이기 때문에 kube-proxy 의 Pod 갯수는 5개로 출력되고 있습니다.

     

    kubectl get daemonset --all-namespaces --field-selector metadata.name=kube-proxy
    NAMESPACE     NAME         DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
    kube-system   kube-proxy   5         5         5       5            5           kubernetes.io/os=linux   15h

     

    그리고 아래와 같이 5개의 kube-proxy Pod 들이 실행되고 있습니다.

     

    kubectl get pod --all-namespaces -l k8s-app=kube-proxy
    NAMESPACE     NAME               READY   STATUS    RESTARTS   AGE
    kube-system   kube-proxy-445qd   1/1     Running   0          15h
    kube-system   kube-proxy-hxcgc   1/1     Running   0          15h
    kube-system   kube-proxy-krl58   1/1     Running   0          15h
    kube-system   kube-proxy-q6hfs   1/1     Running   0          15h
    kube-system   kube-proxy-qlmjq   1/1     Running   0          15h

     

    이러한 Kubernetes 환경에서 kube-proxy 의 역할은 Kubernetes Service 와 관련이 깊습니다.

    간단하게 말씀드리면, Service 로의 Network 요청을 적절한 Pod 에거 라우팅할 수 있도록 Iptables 기반의 규칙을 설정하게 되는데요.

    이어지는 글에서 자세히 설명드리도록 하겠습니다.

     

    kube-proxy 와 Service 그리고 Iptables 알아보기.

    Kubernetes 의 각 Node 내에서 Iptables 의 라우팅 규칙이 어떻게 적용되는지 알아보도록 하겠습니다.

     

    iptables 이란 ?

    우선 iptables 에 대해서 아주 간단히 알아보도록 하겠습니다.

    iptables 은 리눅스의 커널의 네트워크와 관련됩니다.

    리눅스 커널는 네트워크 방화벽이라든지, NAT 와 같이 Source/Dest IP 를 변환한다던지 등과 같은 역할을 수행합니다.

    예를 들어, 특정 IP 에서의 요청을 차단하고자 한다면 아래와 같이 192.168.1.100 Source IP 의 Traffic 을 Drop 할 수 있구요.

    iptables -A INPUT -s 192.168.1.100 -j DROP

     

    그리고 AWS NAT Gateway 처럼 Private IP 가 외부로 전송될 때에 Public IP 로 치환하는 NAT 기능도 iptables 을 통해서 설정할 수 있습니다.

    아래의 예시는 Private IP 인 192.168.1.0/24 가 203.0.113.100 인 Public IP 로 치환되어 외부로 전송되는 예시입니다.

    iptables -t nat -A POSTROUTING \
    	-s 192.168.1.0/24 -o eth0 -j SNAT \
    	--to-source 203.0.113.100

     

    이러한 방식으로 Linux Kernel 의 Network Stack 에서 네트워크 트래픽을 어떻게 처리할지에 대한 규칙을 지정할 수 있습니다.

    Iptables 에 지정된 Network 처리 규칙에 의거해서 방화벽이나 Nat 등의 설정을 적용할 수 있습니다.

     

    Service 와 Iptables 의 관계.

    Kubernetes 의 Service 는 기본적으로 특정 Pod 들에게 Network Traffic 을 포워딩하는 전략을 수행합니다.

    예를 들어 아래와 같이 2개의 Pod 와 1개의 Service 가 존재할 때에 이는 아래의 그림과 같은 관계를 취하게 됩니다.

     

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-1
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
        ports:
        - containerPort: 80
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-2
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
        ports:
        - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      selector:
        app: my-app
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80

     

    Service 는 selector 에 의해서 적용된 모든 Pod 들을 대상으로 네트워크 트래픽을 로드밸런싱하여 네트워크 요청을 전달합니다.

    일종의 reverse proxy 로 동작하게 됩니다.

     

    하지만 Linux Kernel 입장에서 보았을 때에 이는 Iptables 를 활용한 네트워크를 포워딩하기 위한 규칙을 뿐입니다.

     

    Kuberentes Node 의 PREROUTING Rule.

    아래는 Kubernetes 의 한 Node 에서 확인한 PREROUTING 규칙입니다.

    iptables -t nat -L PREROUTING -vn
    Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
        0     0 KUBE-SERVICES  0    --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */

     

    이를 분석해보면 source 와 destination 이 모두 0.0.0.0/0 으로 설정되어 있습니다.

    이는 Node 로 유입되는 모든 Network Traffic 은 KUBE-SERVICES Chain 을 따르도록 합니다.

    아래의 내용을 확인해보면 destination 이 10.96.58.219 인 네트워크 트래픽은 KUBE-SVC-FXIYY6OHUSNBITIX 규칙을 따르도록 되어 있습니다.

     

    참고로 10.96.58.219 IP 는 위에서 생성했던 Service 의 ClusterIP 값입니다.

    즉, 외부에서 어떤 네트워크 요청이 Node 내부로 유입되었고 이 요청의 Destination 이 Service 인 경우에

    이와 같인 PREROUTING Rule 이 적용됩니다.

     

    iptables -t nat -L KUBE-SERVICES -v
    Chain KUBE-SERVICES (2 references)
     pkts bytes target     prot opt in     out     source               destination
        0     0 KUBE-SVC-FXIYY6OHUSNBITIX  tcp  --  any    any     anywhere             10.96.58.219         /* default/my-service cluster IP */ tcp dpt:http

     

    마지막으로 아래는 Service 와 관련된 IPTable Chain Rule 입니다.

    이는 위에서 생성된 2개의 Pod 로 50% 의 확률의 LoadBalancing 을 수행하는 규칙입니다.

     

    iptables -t nat -L KUBE-SVC-FXIYY6OHUSNBITIX -vn
    Chain KUBE-SVC-FXIYY6OHUSNBITIX (1 references)
     pkts bytes target     prot opt in     out     source               destination
        0     0 KUBE-MARK-MASQ  6    --  *      *      !10.244.0.0/16        10.96.58.219         /* default/my-service cluster IP */ tcp dpt:80
        0     0 KUBE-SEP-4UWZBYSYCGDXTWU5  0    --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/my-service -> 10.244.3.2:80 */ statistic mode random probability 0.50000000000
        0     0 KUBE-SEP-NNZ53NF5AEOX4ZY5  0    --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/my-service -> 10.244.4.2:80 */

     

    그리고 아래는 Network Traffic 의 Destination 을 Pod 의 IP 로 변경하기 위한 DNAT Rule 에 해당합니다.

     

    iptables -t nat -L KUBE-SEP-4UWZBYSYCGDXTWU5 -v
    Chain KUBE-SEP-4UWZBYSYCGDXTWU5 (1 references)
     pkts bytes target     prot opt in     out     source               destination
        0     0 KUBE-MARK-MASQ  all  --  any    any     10.244.3.2           anywhere             /* default/my-service */
        0     0 DNAT       tcp  --  any    any     anywhere             anywhere             /* default/my-service */ tcp to:10.244.3.2:80
        
    ptables -t nat -L KUBE-SEP-NNZ53NF5AEOX4ZY5 -v
    Chain KUBE-SEP-NNZ53NF5AEOX4ZY5 (1 references)
     pkts bytes target     prot opt in     out     source               destination
        0     0 KUBE-MARK-MASQ  all  --  any    any     10.244.4.2           anywhere             /* default/my-service */
        0     0 DNAT       tcp  --  any    any     anywhere             anywhere             /* default/my-service */ tcp to:10.244.4.2:80

     

    Kubernetes Node 의 Output Rule.

    Node 내부로 유입되는 Network Traffic 이 존재하는 것처럼 반대로 Output Going 형식의 송신 트래픽도 존재하겠죠.

    이러한 OutputBound Traffic 을 위한 IPTable 규칙이 Output Rule 입니다.

     

    iptables -t nat -L OUTPUT -vn
    Chain OUTPUT (policy ACCEPT 5 packets, 346 bytes)
     pkts bytes target     prot opt in     out     source               destination
       71  5818 KUBE-SERVICES  0    --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */

     

    OUTPUT Rule 은 위에서 설명한 KUBE_SERVICES 규칙을 그대로 따릅니다.

    즉, Destination 이 Kubernetes Service 인 Network Traffic 인 경우에 반드시 Pod 를 Destination 으로 변경되어야 합니다.

     

     

    반응형
Designed by Tistory.