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

相关推荐
江畔何人初9 分钟前
MySQL 服务器进程的三层结构
linux·运维·服务器·云原生·mysal
陈桴浮海10 分钟前
MySQL 主从复制与 GTID 环形复制
linux·mysql·云原生
sryyd_0231 分钟前
云原生-高可用集群keepalived
服务器·网络·云原生
王码码203511 小时前
Flutter for OpenHarmony:Flutter 三方库 bluez 玩转 Linux 风格的蓝牙操作(蓝牙底层互操作)
linux·运维·服务器·前端·flutter·云原生·harmonyos
努力搬砖的咸鱼11 小时前
一个域名搞定前后端:用 Ingress 配置 / 和 /api 路由
微服务·云原生·容器·架构·kubernetes
王da魔17 小时前
Keepalived
网络·云原生
悠闲蜗牛�21 小时前
云原生架构下的可观测性体系建设:从日志、监控到全链路追踪的工程实践
云原生·架构
老葱头蒸鸡1 天前
(1)Docker架构与组件简介
云原生·eureka
cyber_两只龙宝1 天前
Tomcat--企业级web应用服务器详细介绍与整合Nginx配置流程
linux·运维·前端·nginx·云原生·tomcat·负载均衡
糟糕喔1 天前
k8s运维-pod篇(1)
云原生·容器·kubernetes