Kubernetes

Iptables와 Kubernetes ClusterIP의 Iptables

mokpolar 2024. 10. 8. 15:17
반응형

iptables는 리눅스 기반 시스템에서 네트워크 패킷을 필터링하고 포워딩하기 위한 방화벽 도구입니다.

 

주로 패킷의 전달 및 차단, 그리고 포워딩을 위한 규칙을 정의하는 데 사용됩니다.

이를 통해 네트워크의 보안을 강화할 수 있습니다.

 

iptables는 리눅스 커널의 netfilter 프레임워크 위에서 작동하며, 네트워크 패킷이 특정 조건을 만족할 때 지정된 동작을 수행하도록 규칙을 설정할 수 있습니다.

 

iptables의 테이블 구조

iptables는 아래와 같은 네 가지 주요 테이블로 나누어져 있습니다.
각 테이블은 다른 목적을 가지고 있으며, 필요한 경우 맞춤형으로 사용됩니다.

 

iptables의 chains

각 체인은 아래와 같은 규칙(rule) 리스트로 구성되며, 패킷은 처음부터 끝까지 규칙을 하나씩 검사합니다.
규칙이 패킷에 적용되면 그 다음 규칙은 검사하지 않고 동작이 수행됩니다.

 

 

테이블과 체인 간의 관계

각 테이블은 다양한 체인에 포함되며, 각 체인에서는 특정 테이블에 정의된 규칙이 적용됩니다.
아래 도식은 Chain과 Table의 Workflow입니다.

 

iptables는 connection tracking 이라는 방법을 사용해서, 연결을 감시하고 제한할 수 있게 합니다.

참조 : https://commons.wikimedia.org/wiki/File:Iptables_diagram.png

 

iptables 규칙의 기본 문법

iptable 사용법은 아래와 같습니다.

iptables [-t table] [action] [chain] [match] [-j target]

예를 들어,
아래와 같이 사용할 수 있습니다.

iptables -t 테이블 -A 체인 -m 모듈 -p 프로토콜 --dport 포트번호 -j 동작
  • -t 테이블: 사용할 테이블을 지정합니다. 생략하면 기본적으로 filter 테이블을 사용합니다.
  • -A 체인: 체인에 규칙을 추가합니다. INPUT, OUTPUT, FORWARD 등의 체인을 지정할 수 있습니다.
  • -m 모듈: 추가로 사용할 모듈을 지정합니다. 예를 들어, 상태 추적을 위해 -m state를 사용할 수 있습니다.
  • -p 프로토콜: 특정 프로토콜을 지정합니다. 예를 들어, -p tcp, -p udp 등을 사용할 수 있습니다.
  • --dport 포트번호: 특정 포트를 지정합니다. 예를 들어, --dport 80은 HTTP 트래픽을 처리하는 규칙입니다.
  • -j 동작: 규칙이 일치할 때 수행할 동작을 지정합니다. ACCEPT, DROP, REJECT 등이 있습니다.

주요 동작

  • ACCEPT: 패킷을 허용합니다.
  • DROP: 패킷을 아무런 응답 없이 차단합니다.
  • REJECT: 패킷을 차단하고 송신자에게 에러 메시지를 보냅니다.
  • SNAT: 출발지 NAT를 수행합니다. 주로 네트워크 출발지 주소를 변환할 때 사용됩니다.
  • DNAT: 목적지 NAT를 수행합니다. 주로 패킷의 목적지 주소를 변환할 때 사용됩니다.

SSH 트래픽 허용

TCP 22번 포트를 통해 들어오는 SSH 트래픽을 허용하는 규칙을 추가합니다.

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

 

HTTP 트래픽 차단

TCP 80번 포트를 통한 HTTP 트래픽을 차단합니다.

iptables -A INPUT -p tcp --dport 80 -j DROP

 

패킷 포워딩

FORWARD 체인 규칙 설정포워딩을 활성화한 후, iptables를 통해 패킷을 특정 목적지로 전달할 수 있습니다.
eth0 인터페이스로 들어온 트래픽을 eth1 인터페이스로 포워딩합니다.

iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT

 

NAT 설정

nat 테이블과 POSTROUTING 체인을사용하여 네트워크 주소 변환을 설정합니다.

eth0 인터페이스를 통해 나가는 모든 트래픽의 출발지 IP 주소를 해당 인터페이스의 IP 주소로 변경하는 NAT 규칙을 추가합니다.

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

 

Kubernetes kube-proxy mode에서의 iptables

kube-proxy mode를 iptables로 설정했을 때, kube-proxy pod는 해당 노드의 iptables 규칙을 업데이트 하는 방식으로 동작합니다.

도식으로 표현하면 아래와 같은 형태입니다.

 

Kubernetes ClusterIP 에서의 iptables

Kubernetes에서 ClusterIP Service를 생성하면 kube-proxy pod에 의해
해당 노드에 새로운 chain이 생겨납니다.

 

예를 들어, ClusterIP에 3개의 Pod가 Selector로서 연결되어있다고 가정해보겠습니다.

PREROUTING chain에 매칭되면 KUBE_SERVICES chain으로 넘어가는 처리를 하게 됩니다.


그리고 순서대로 KUBE-SVC-YYY, KUBE-SVC-ZZZ(1, 2, 3) chain에 매칭됩니다.

 

PREROUTING chain에 적용되어 있는 규칙을 확인합니다.

iptables -t nat -S PREROUTING

-P PREROUTING ACCEPT
-A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES

 

KUBE-SERVICES chain에 적용되어 있는 규칙을 확인합니다.

iptables -t nat -S KUBE-SERVICES

-N KUBE-SERVICES
-A KUBE-SERVICES -d 10.200.1.111/32 -p tcp -m comment --comment "default/svc1:webport cluster IP" -m tcp --dport 9000 -j KUBE-SVC-GQ7VJ6DFEMRF2SE7
...

 

KUBE-SVC-YYY chain에 적용되어 있는 규칙을 확인합니다.
현재 3개의 Pod에 연결되어 3개의 Endpoint가 존재합니다.

 

그래서 아래 규칙을 보면 SVC-YYY 규칙은 3개중 1개로 도달하기 위해 처음에 33% 확률로 랜덤 부하 분산이 Endpoint KUBE-SEP-ZZZ 로 연결됩니다.

 

하나가 선택 되었으면 그 다음에는 Endpoint 둘 중 하나가 남기 때문에 50% 확률로 연결되고
그 다음에 마지막 Endpoint는 100%로 연결됩니다.

 

SEP는 Service Endpoint입니다. Pod의 IP와 Port를 의미합니다.

iptables -t nat -S KUBE-SVC-GQ7VJ6DFEMRF2SE7
...
-A KUBE-SVC-GQ7VJ6DFEMRF2SE7 -m comment --comment "default/svc1:webport" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-LJHSFKRTIUY4RZDJ
-A KUBE-SVC-GQ7VJ6DFEMRF2SE7 -m comment --comment "default/svc1:webport" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-SNIEU6WJR45JSB43
-A KUBE-SVC-GQ7VJ6DFEMRF2SE7 -m comment --comment "default/svc1:webport" -j KUBE-SEP-B76ETNTWTG5XSE5J
...

 

KUBE-SEP-ZZZ chain에 적용되어 있는 규칙을 확인합니다.
해당 체인의 규칙은 webpod1 172.16.158.1:80(TCP) 로 DNAT 처리하여 전달된다는 것을 의미합니다.

iptables -t nat -S KUBE-SEP-LJHSFKRTIUY4RZDJ
...
-A KUBE-SEP-LJHSFKRTIUY4RZDJ -p tcp -m comment --comment "default/svc1:webport" -m tcp -j DNAT --to- destination 172.16.158.1:80

 

나머지도 동일합니다.

iptables -t nat -S KUBE-SEP-SNIEU6WJR45JSB43
...
-A KUBE-SEP-SNIEU6WJR45JSB43 -p tcp -m comment --comment "default/svc1:webport" -m tcp -j DNAT --to- destination 172.16.184.2:80

 

iptables -t nat -S KUBE-SEP-B76ETNTWTG5XSE5J
...
-A KUBE-SEP-B76ETNTWTG5XSE5J -p tcp -m comment --comment "default/svc1:webport" -m tcp -j DNAT --to- destination 172.16.24.3:80

 

 

결과적으로 아래와 같은 형태로 통신이 일어나게 됩니다.
ClusterIP 주소로 접속을 시도하고, iptables 의 chain에 매칭되어 DNAT이 일어납니다.

 

또한 NAT시의 연결 정보를 기록하여, 대상 pod에서 되돌아온 트래픽을 확인 후 원래대로 돌아갑니다.

 

 

Reference

반응형