Istio Hands-on Study [1기]
[8주차] Istio Traffic Flow : IP테이블 조작 분석
구구달스
2025. 5. 28. 10:47
CloudNet@ 가시다님이 진행하는 Istio Hands-on Study [1기]
https://jimmysong.io/en/blog/sidecar-injection-iptables-and-traffic-routing/#iptables-manipulation-analysis
의 내용을 정리
🚀 Istio에서 iptables 분석 쉽게 이해하기
- Istio는 Kubernetes 환경에서 네트워크 트래픽을 관리하는 서비스 메쉬입니다.
🌐 iptables란 무엇인가요?
- iptables는 리눅스에서 네트워크 트래픽을 제어하는 도구입니다.
트래픽을 가로채거나, 특정 포트로 보내거나, 차단하는 규칙을 설정할 수 있습니다.
Istio에서는 iptables를 사용해 Pod로 들어오고 나가는 트래픽을 Sidecar(Envoy 프록시)로 리다이렉트합니다. - 비유하자면, iptables는 도로 위 교통 경찰과 같습니다. 차량(트래픽)을 원하는 방향으로 안내하거나 멈추게 할 수 있죠. Istio는 이런 교통 경찰을 활용해 트래픽을 Sidecar로 보내고, Sidecar가 트래픽을 관리합니다.
iptables는 트래픽을 제어하는 도구로,
Istio에서 Sidecar로 트래픽을 리다이렉트하는 데 사용됩니다.
📋 NAT 테이블의 iptables 규칙
- iptables는 여러 테이블로 나뉘며, Istio는 NAT(Network Address Translation) 테이블을 주로 사용합니다.
NAT 테이블은 트래픽의 주소를 변환하거나 리다이렉트하는 데 사용됩니다. 규칙을 확인하는 명령어는 다음과 같습니다:
iptables -t nat -L -v
- 주요 체인과 규칙
# View the details of the rule configuration in the NAT table.
$ iptables -t nat -L -v
# PREROUTING chain: Used for Destination Address Translation (DNAT) to jump all incoming TCP traffic to the ISTIO_INBOUND chain.
Chain PREROUTING (policy ACCEPT 2701 packets, 162K bytes)
pkts bytes target prot opt in out source destination
2701 162K ISTIO_INBOUND tcp -- any any anywhere anywhere
# INPUT chain: Processes incoming packets and non-TCP traffic will continue on the OUTPUT chain.
Chain INPUT (policy ACCEPT 2701 packets, 162K bytes)
pkts bytes target prot opt in out source destination
# OUTPUT chain: jumps all outbound packets to the ISTIO_OUTPUT chain.
Chain OUTPUT (policy ACCEPT 79 packets, 6761 bytes)
pkts bytes target prot opt in out source destination
15 900 ISTIO_OUTPUT tcp -- any any anywhere anywhere
# POSTROUTING CHAIN: All packets must first enter the POSTROUTING chain when they leave the network card, and the kernel determines whether they need to be forwarded out according to the packet destination.
Chain POSTROUTING (policy ACCEPT 79 packets, 6761 bytes)
pkts bytes target prot opt in out source destination
# ISTIO_INBOUND CHAIN: Redirects all inbound traffic to the ISTIO_IN_REDIRECT chain, except for traffic destined for ports 15090 (used by Prometheus) and 15020 (used by Ingress gateway for Pilot health checks), and traffic sent to these two ports will return to the call point of the iptables rule chain, the successor POSTROUTING to the INPUT chain.
Chain ISTIO_INBOUND (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN tcp -- any any anywhere anywhere tcp dpt:ssh
2 120 RETURN tcp -- any any anywhere anywhere tcp dpt:15090
2699 162K RETURN tcp -- any any anywhere anywhere tcp dpt:15020
0 0 ISTIO_IN_REDIRECT tcp -- any any anywhere anywhere
# ISTIO_IN_REDIRECT chain: jumps all inbound traffic to the local 15006 port, thus successfully blocking traffic to the sidecar.
Chain ISTIO_IN_REDIRECT (3 references)
pkts bytes target prot opt in out source destination
0 0 REDIRECT tcp -- any any anywhere anywhere redir ports 15006
# ISTIO_OUTPUT chain: see the details bellow
Chain ISTIO_OUTPUT (1 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- any lo 127.0.0.6 anywhere
0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner UID match 1337
0 0 RETURN all -- any lo anywhere anywhere ! owner UID match 1337
15 900 RETURN all -- any any anywhere anywhere owner UID match 1337
0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner GID match 1337
0 0 RETURN all -- any lo anywhere anywhere ! owner GID match 1337
0 0 RETURN all -- any any anywhere anywhere owner GID match 1337
0 0 RETURN all -- any any anywhere localhost
0 0 ISTIO_REDIRECT all -- any any anywhere anywhere
# ISTIO_REDIRECT chain: redirects all traffic to Sidecar (i.e. local) port 15001.
Chain ISTIO_REDIRECT (1 references)
pkts bytes target prot opt in out source destination
0 0 REDIRECT tcp -- any any anywhere anywhere redir ports 15001
주요 체인과 역할
1. PREROUTING 체인
- 역할: 서버로 들어오는 패킷을 처음 처리합니다.
- 동작: 모든 TCP 트래픽을 ISTIO_INBOUND 체인으로 보냅니다.
2. INPUT 체인
- 역할: 서버로 들어오는 패킷을 처리합니다.
- 동작: TCP가 아닌 트래픽은 OUTPUT 체인으로 넘어갑니다.
3. OUTPUT 체인
- 역할: 서버에서 나가는 패킷을 처리합니다.
- 동작: 모든 TCP 트래픽을 ISTIO_OUTPUT 체인으로 보냅니다.
4. POSTROUTING 체인
- 역할: 패킷이 네트워크로 나가기 직전에 처리됩니다.
- 동작: 패킷을 그대로 내보냅니다.
5. ISTIO_INBOUND 체인
- 역할: 들어오는 트래픽을 포트별로 분류합니다.
- 동작:
- 포트 22(SSH), 15090(Prometheus), 15020(Ingress Gateway) 트래픽은 그대로 둡니다(RETURN).
- 나머지 TCP 트래픽은 ISTIO_IN_REDIRECT로 보냅니다.
6. ISTIO_IN_REDIRECT 체인
- 역할: 트래픽을 로컬 포트로 보냅니다.
- 동작: 모든 TCP 트래픽을 로컬 포트 15006(Istio 사이드카)으로 리다이렉트합니다.
7. ISTIO_OUTPUT 체인
- 역할: 나가는 트래픽을 관리합니다.
- 동작:
- 로컬 루프백(127.0.0.6) 트래픽은 그대로 둡니다.
- 사용자/그룹 ID 1337의 트래픽은 조건에 따라:
- 로컬이 아닌 경우 ISTIO_IN_REDIRECT로 보냅니다.
- 특정 조건(로컬호스트, ID 1337 등)은 그대로 둡니다.
- 나머지 트래픽은 ISTIO_REDIRECT로 보냅니다.
8. ISTIO_REDIRECT 체인
- 역할: 트래픽을 Istio의 기본 포트로 보냅니다.
- 동작: 모든 TCP 트래픽을 로컬 포트 15001(Istio 사이드카)으로 리다이렉트합니다.
전체 흐름
- 들어오는 트래픽: PREROUTING → ISTIO_INBOUND → (특정 포트 제외) → ISTIO_IN_REDIRECT → 포트 15006.
- 나가는 트래픽: OUTPUT → ISTIO_OUTPUT → (특정 조건 제외) → ISTIO_REDIRECT → 포트 15001.
- Istio의 역할: 트래픽을 포트 15006과 15001로 보내 Istio 프록시(Envoy)가 통신을 관리합니다.
비유로 이해하기
- NAT 테이블은 우체국 같습니다:
- 패킷은 편지, 체인은 처리 단계입니다.
- 들어오는 편지(PREROUTING)는 특정 창구(ISTIO_INBOUND)로 갑니다. SSH 같은 특별한 편지는 그대로 보내고, 나머지는 15006번 창구로!
- 나가는 편지(OUTPUT)는 다른 창구(ISTIO_OUTPUT)에서 확인 후, 15001번 창구로 보냅니다.
- Istio는 편지 흐름을 관리하는 우체국장입니다.
왜 이런 설정인가?
- Istio는 마이크로서비스 환경에서 트래픽을 관리하기 위해 이 설정을 사용합니다.
트래픽을 포트 15006과 15001로 보내 프록시가 모니터링, 라우팅, 보안을 처리합니다.
SSH나 Prometheus 같은 포트는 Istio 관리 없이 동작해야 하므로 제외됩니다.
NAT 테이블의 규칙은
인바운드 트래픽을 Sidecar 포트(15006)로 리다이렉트합니다.
🔍 ISTIO_OUTPUT 체인의 9가지 규칙 분석
- ISTIO_OUTPUT 체인은 아웃바운드 트래픽을 처리하는 중요한 체인입니다. 규칙은 순서대로 실행되며, 조건에 맞는 첫 번째 규칙이 적용됩니다.
Rule | target | in | out | source | destination |
1 | RETURN | any | lo | 127.0.0.6 | anywhere |
2 | ISTIO_IN_REDIRECT | any | lo | anywhere | !localhost owner UID match 1337 |
3 | RETURN | any | lo | anywhere | anywhere !owner UID match 1337 |
4 | RETURN | any | any | anywhere | anywhere owner UID match 1337 |
5 | ISTIO_IN_REDIRECT | any | lo | anywhere | !localhost owner GID match 1337 |
6 | RETURN | any | lo | anywhere | anywhere !owner GID match 1337 |
7 | RETURN | any | any | anywhere | anywhere owner GID match 1337 |
8 | RETURN | any | any | anywhere | localhost |
9 | ISTIO_REDIRECT | any | any | anywhere | anywhere |
규칙 1: Envoy에서 애플리케이션으로의 트래픽 허용
- Envoy 프록시가 Pod 내 애플리케이션 컨테이너로 보내는 트래픽(127.0.0.6)을 허용합니다. 이 트래픽은 다시 Sidecar로 돌아가지 않도록 바로 POSTROUTING으로 보냅니다. 127.0.0.6은 Istio에서 정의한 IP로, Passthrough 용도로 사용됩니다.
127.0.0.6 트래픽은 Sidecar를 거치지 않고 애플리케이션으로 바로 전달됩니다.
규칙 2, 5: Pod 내부 트래픽 처리 (UID/GID 1337)
- Envoy 프록시(UID/GID 1337)가 localhost가 아닌 목적지로 보내는 트래픽을 ISTIO_IN_REDIRECT로 보냅니다. 이는 Pod 내부 트래픽(예: Pod IP로의 요청)을 Inbound Handler로 처리하기 위함입니다.
Envoy가 보내는 내부 트래픽은 Inbound Handler로 리다이렉트됩니다.
규칙 3, 6: 애플리케이션 내부 트래픽 허용
- Envoy가 아닌 애플리케이션에서 발생한 내부 트래픽(예: localhost 요청)을 허용합니다. 이 트래픽은 POSTROUTING으로 보내져 목적지에 도달합니다.
Envoy가 아닌 내부 트래픽은 바로 목적지로 전달됩니다.
규칙 4, 7: Envoy의 아웃바운드 트래픽 허용
- Envoy가 보내는 아웃바운드 트래픽을 허용합니다. 이 트래픽은 POSTROUTING을 거쳐 외부 목적지로 전달됩니다.
Envoy의 아웃바운드 트래픽은 외부로 바로 전달됩니다.
규칙 8: localhost로의 요청 허용
- Pod 내부에서 localhost로 보내는 요청을 허용합니다. 이 트래픽은 POSTROUTING을 거쳐 localhost로 전달됩니다.
localhost 요청은 바로 처리됩니다.
규칙 9: 나머지 트래픽 리다이렉트
- 위 규칙에 해당하지 않는 모든 트래픽을 ISTIO_REDIRECT로 보냅니다. ISTIO_REDIRECT는 트래픽을 Sidecar의 포트 15001로 리다이렉트합니다:
나머지 트래픽은 Sidecar의 Outbound Handler(포트 15001)로 리다이렉트됩니다.
- 규칙은 도로 위 신호등과 같습니다. 각 신호등은 특정 차량(트래픽)을 어디로 보낼지 결정합니다. Istio에서는 이런 신호등을 설정해 트래픽이 Sidecar를 거치거나 바로 목적지로 가도록 관리합니다.
- RETURN은 "통과"를 의미합니다. 규칙에 맞으면 더 이상 다른 규칙을 확인하지 않고 다음 단계(POSTROUTING)로 넘어갑니다. 이 규칙들은 무한 루프(트래픽이 계속 같은 경로를 맴도는 문제)를 방지하기 위해 설계되었습니다.
iptables 규칙은 신호등처럼 트래픽을 안내하며, 무한 루프를 방지합니다.
📌 핵심 요약
- iptables 역할: 트래픽을 제어하며, Istio에서 Sidecar로 트래픽을 리다이렉트합니다.
- Minikube 접근: minikube ssh, nsenter로 istio-proxy 네임스페이스에 접근해 iptables를 확인합니다.
- NAT 테이블: PREROUTING, OUTPUT, ISTIO_INBOUND 등이 인바운드 트래픽을 Sidecar(포트 15006)로 보냅니다.
- ISTIO_OUTPUT 규칙:
- 규칙 1: 127.0.0.6 트래픽을 애플리케이션으로 바로 전달.
- 규칙 2, 5: Envoy의 내부 트래픽을 Inbound Handler로 리다이렉트.
- 규칙 3, 6: 애플리케이션 내부 트래픽을 바로 전달.
- 규칙 4, 7: Envoy의 아웃바운드 트래픽을 외부로 전달.
- 규칙 8: localhost 요청을 바로 전달.
- 규칙 9: 나머지 트래픽을 Sidecar(포트 15001)로 리다이렉트.
- iptables는 신호등처럼 트래픽을 안내하며, 무한 루프를 방지합니다.