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

相关推荐
cyber_两只龙宝2 分钟前
【Nginx】Nginx反向代理之实现http的反向代理
linux·运维·nginx·http·云原生·反向代理
Traving Yu33 分钟前
Kubernetes(K8s)
云原生·容器·kubernetes
威联通网络存储2 小时前
云原生容器底座:Kubernetes 持久化存储与 CSI 架构解析
python·云原生·架构·kubernetes
正经教主15 小时前
【docker基础】第一课、从零开始理解容器技术
docker·云原生·容器·eureka
Cyber4K1 天前
【Kubernetes专项】K8s 包工具- Helm 入门到企业实战
云原生·容器·kubernetes
观无1 天前
微服务下的跨域问题
微服务·云原生·架构
Chuncheng's blog1 天前
K8S二进制部署exec unable to upgrade connection: Unauthorized异常解决方案
云原生·容器·kubernetes
FJW0208141 天前
HAProxy+Keepalived实现Kubernetes高可用集群部署
云原生·容器·kubernetes
倔强的胖蚂蚁1 天前
云原生服务器存储规划与磁盘选型实施
运维·服务器·云原生
观无1 天前
微服务架构核心技术知识全景总结
微服务·云原生·架构