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

相关推荐
Cyber4K3 小时前
【Kubernetes专项】K8s 控制器 DaemonSet 从入门到企业实战应用
云原生·容器·kubernetes
切糕师学AI3 小时前
RKE(Rancher Kubernetes Engine) 是什么?
云原生·容器·kubernetes·rancher
麦兜*4 小时前
深入剖析云原生Service Mesh数据平面Envoy核心架构:基于xDS协议与WebAssembly实现动态流量管理与安全策略的微服务治理实战指南
云原生·架构·service_mesh
牛奶咖啡134 小时前
Prometheus+Grafana构建云原生分布式监控系统(十五)_Prometheus中PromQL使用(二)
云原生·prometheus·集合运算·对查询结果排序·直方图原理·统计掉线的实例·检查节点或指标是否存在
小义_4 小时前
【Docker】知识一
linux·docker·云原生·容器
龙飞054 小时前
Kubernetes 排障实战:PVC 一直 Pending 的原因与解决方案
运维·学习·云原生·容器·kubernetes
没有bug.的程序员5 小时前
Spring Boot 与 Swagger:API 文档自动化生成、版本管理与云原生协作深度实战指南
spring boot·云原生·自动化·api·swagger·版本管理·自动化生产
小二·6 小时前
Go 语言系统编程与云原生开发实战(第9篇)安全加固实战:认证授权 × 数据加密 × 安全审计(生产级落地)
安全·云原生·golang
研究司马懿6 小时前
【云原生】Gateway API介绍
云原生·gateway