istio从0到1:iptables设置

一、常用问题梳理

笔者落地的istio只是接管了http的rpc流量,端口是8090(做了去安全处理,实际产品不是8090端口),istio的iptables使用的是nat表。

接管流量过程中碰到的几个问题:

1.istio-proxy容器里面设置iptables,需要开启特权模式或者在启动阶段通过--cap-add开放一些系统能力,并提供net_admin能力 (要注意的是net_admin能力会对宿主机有影响)

2.iptables开启劫持流量前已经建立好的长链接流量不会被接管,需要业务实现旧链接的主动断开机制,或者重启pod,java的话,可以tomcat里面设置定时优雅关闭逻辑,通过http的Connection:close来主动断开链接。

3.iptables清理配置以后,存量已经接管流量的链接,劫持流量还在,需要主动关闭链接,可以利用envoy的drwain-connection来操作定时断开。

4.业务层面如果是单pod循环调用自己这个pod的话,上面iptables的设置有防止死循环配置,会导致流量不通,解决思路是业务服务发现禁止自己pod调用自己。

二、iptables使用介绍

1.iptables的配置数据:

$ sudo iptables -t nat -S

-P PREROUTING ACCEPT

-P INPUT ACCEPT

-P OUTPUT ACCEPT

-P POSTROUTING ACCEPT

-N ISTIO_INBOUND

-N ISTIO_IN_REDIRECT

-N ISTIO_OUTPUT

-N ISTIO_REDIRECT

-A PREROUTING -s 188.251.1.1/32 -i veth1 -m comment --comment "xxxx PREROUTING rules" -j RETURN

-A PREROUTING -p tcp -j ISTIO_INBOUND

-A OUTPUT -p tcp -j ISTIO_OUTPUT

-A POSTROUTING ! -s 19.82.45.42/32 -o eth0 -m comment --comment "xxxxx SNAT rules" -j MASQUERADE

-A ISTIO_INBOUND -p tcp -m tcp --dport 15008 -j RETURN

-A ISTIO_INBOUND -p tcp -m tcp --dport 8090 -j ISTIO_IN_REDIRECT

-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15006

-A ISTIO_OUTPUT -s 127.0.0.6/32 -o lo -j RETURN

-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --uid-owner 1337 -j ISTIO_IN_REDIRECT

-A ISTIO_OUTPUT -o lo -m owner ! --uid-owner 1337 -j RETURN

-A ISTIO_OUTPUT -m owner --uid-owner 1337 -j RETURN

-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -m owner --gid-owner 1337 -j ISTIO_IN_REDIRECT

-A ISTIO_OUTPUT -o lo -m owner ! --gid-owner 1337 -j RETURN

-A ISTIO_OUTPUT -m owner --gid-owner 1337 -j RETURN

-A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN

-A ISTIO_OUTPUT -p tcp -m tcp --dport 8080 -j ISTIO_REDIRECT

-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001

$

2.nat表数据流向总览:

数据包进入系统 → PREROUTING链 → 路由决策 →

├─ 到本机 → INPUT链 → 本机进程

├─ 转发 → FORWARD链 → POSTROUTING链 → 出系统

└─ 本机发出 → OUTPUT链 → POSTROUTING链 → 出系统

3.PREROUTING链调用树(入站和转发流量)

PREROUTING(nat表内置链)

├─ 规则1:-s 188.251.1.1/32 -i veth1 → RETURN(直接返回)

└─ 规则2:-p tcp → ISTIO_INBOUND(自定义链)

├─ 规则1:--dport 15008 → RETURN(返回PREROUTING)

└─ 规则2:--dport 8090 → ISTIO_IN_REDIRECT(自定义链)

└─ 规则1:-p tcp → REDIRECT --to-ports 15006(重定向)

调用顺序:

数据包进入 → PREROUTING链 →

↓ 匹配TCP协议

ISTIO_INBOUND链 →

↓ 匹配端口8090

ISTIO_IN_REDIRECT链 →

↓ 重定向到15006端口

处理完成,返回上层链

4.OUTPUT调用树(出口流量)

OUTPUT(nat表内置链)

└─ 规则1:-p tcp → ISTIO_OUTPUT(自定义链)

├─ 规则1:-s 127.0.0.6/32 -o lo → RETURN

├─ 规则2:! -d 127.0.0.1/32 -o lo --uid-owner 1337 → ISTIO_IN_REDIRECT

├─ 规则3:-o lo ! --uid-owner 1337 → RETURN

├─ 规则4:--uid-owner 1337 → RETURN

├─ 规则5:! -d 127.0.0.1/32 -o lo --gid-owner 1337 → ISTIO_IN_REDIRECT

├─ 规则6:-o lo ! --gid-owner 1337 → RETURN

├─ 规则7:--gid-owner 1337 → RETURN

├─ 规则8:-d 127.0.0.1/32 → RETURN

└─ 规则9:--dport 8090 → ISTIO_REDIRECT(自定义链)

└─ 规则1:-p tcp → REDIRECT --to-ports 15001(重定向)

调用顺序:

本机进程发送数据包 → OUTPUT链 →

↓ 匹配TCP协议

ISTIO_OUTPUT链 →

↓ 按顺序匹配13条规则

├─ 匹配到规则1-8 → RETURN(返回OUTPUT)

└─ 匹配到规则9 → ISTIO_REDIRECT链 →

↓ 重定向到15001端口

处理完成,返回上层链

5.POSTROUTING链(SNAT处理)

POSTROUTING(nat表内置链)

└─ 规则1:! -s 19.82.45.42/32 -o eth0 → MASQUERADE

6.数据包完整路径分析:

场景1:外部访问pod 8090端口

外部客户端 → 节点eth0 → PREROUTING链 → ISTIO_INBOUND链 → ISTIO_IN_REDIRECT链

↓ 重定向到15006

Sidecar Envoy(15006端口) → 应用容器(8090端口)

场景2:pod内部访问外部8090端口

应用进程 → OUTPUT链 → ISTIO_OUTPUT链 → ISTIO_REDIRECT链

↓ 重定向到15001

Sidecar Envoy(15001端口) → POSTROUTING链(SNAT) → 外部网络

场景3:pod内部访问本地回环

应用进程 → OUTPUT链 → ISTIO_OUTPUT链

↓ 匹配规则8(-d 127.0.0.1/32)

RETURN → POSTROUTING链 → 本地回环

场景4:envoy自身流量

Envoy进程 → OUTPUT链 → ISTIO_OUTPUT链

↓ 匹配规则4(--uid-owner 1337)

RETURN(避免循环) → POSTROUTING链 → 出系统

7.链之间的返回关系

PREROUTING(内置)

|

↓ (TCP流量)

ISTIO_INBOUND(自定义)

/ \

(15008端口)RETURN (8090端口)ISTIO_IN_REDIRECT

| |

返回PREROUTING ↓

REDIRECT 15006

|

返回ISTIO_INBOUND

|

返回PREROUTING

|

路由决策

OUTPUT(内置)

|

↓ (TCP流量)

ISTIO_OUTPUT(自定义)

/ | \

(匹配1-8)RETURN (8090端口)ISTIO_REDIRECT

| |

返回OUTPUT ↓

REDIRECT 15001

|

返回ISTIO_OUTPUT

|

返回OUTPUT

|

POSTROUTING

8.外部访问pod 8090端口的数据包路径:

  1. 数据包到达 eth0

  2. nat表PREROUTING链匹配规则:-p tcp → 跳转到ISTIO_INBOUND

  3. ISTIO_INBOUND链匹配规则:--dport 8090 → 跳转到ISTIO_IN_REDIRECT

  4. ISTIO_IN_REDIRECT链执行:REDIRECT --to-ports 15006

  5. 数据包目标端口改为15006,返回ISTIO_INBOUND

  6. ISTIO_INBOUND返回PREROUTING

  7. PREROUTING没有更多规则,根据默认策略ACCEPT

  8. 路由决策,发现目标端口15006是本地端口

  9. 进入INPUT链(filter表),最终到达Sidecar Envoy进程

推荐的扩展阅读:

https://man7.org/linux/man-pages/man7/capabilities.7.html

https://blog.51cto.com/u_2010293/2781934

https://blog.csdn.net/weixin_44843710/article/details/124155548

https://www.json.cn/blog/2021/0107/p-16595.html

https://blog.csdn.net/biqioso/article/details/106334876

https://wangchujiang.com/linux-command/c/iptables.html

相关推荐
spider_xcxc2 小时前
Docker 实战:容器化多服务应用,Dockerfile 与 Compose 配置全解析
docker·云原生·eureka·虚拟化·容器化
hay_lee3 小时前
Kubernetes StatefulSet:OrderedReady 极简指南
云原生·容器·kubernetes
人间凡尔赛5 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
昕光xg5 小时前
Istio笔记04-基于Jaeger的分布式链路追踪
笔记·分布式·istio
Linux-187415 小时前
分布式链路追踪系统之docker-compose安装skywalking
云原生·docker-compose·skywalking·分布式链路追踪系统·应用程序性能监控
隔窗听雨眠21 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
Hui Baby1 天前
K8S使用CRD和控制器简单应用
云原生·容器·kubernetes
阿里云云原生1 天前
从“告警驱动”到“巡检驱动”:Agent 智能体如何实现前端体验治理的闭环?
云原生
AOwhisky1 天前
Python 学习笔记(第十三期)——运维自动化(下·前篇):远程命令执行——paramiko基础篇
运维·python·学习·云原生·自动化·运维开发·paramiko
AOwhisky1 天前
Python 学习笔记(第十四期)——运维自动化(下·中篇):远程文件传输——paramiko进阶篇
运维·python·学习·云原生·自动化·文件传输·paramiko