-
[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 으로 변경되어야 합니다.
반응형'Kubernetes' 카테고리의 다른 글
[Kubernetes] PodDisruptionBudget 과 Out of Memory ( OOM ) 관계 알아보기 (0) 2024.06.08 [Kubernetes] LoadBalancer 타입 Service 이해하기 (0) 2024.06.01 [Kubernetes] last-applied-configuration annotation 알아보기 (0) 2024.04.20 [Kubernetes] HPA 알아보기 ( Horizontal Pod Autoscaler ) (0) 2024.02.16 [Kubernetes] QoS 알아보기 (Quality of Service) (0) 2024.02.04