欢迎光临
我们一直在努力

探秘 Service Mesh 丝绸之路:Istio 是如何接管 Pod 之间的流量控制的

Istio 作为目前最流行的 Service Mesh 解决方案之一,其核心能力在于透明地接管和控制服务之间的所有网络流量。这种“透明”的魔力是如何实现的呢?答案藏在 Kubernetes Pod 内部的网络配置——尤其是 Linux 的强大防火墙工具 iptables

本文将深入探讨 Istio 如何利用 Sidecar 注入和 iptables 规则,实现对进出 Pod 流量的完全控制,并提供实际操作步骤来验证这些规则。

1. Istio 流量接管的核心机制

Istio 实现透明代理的关键在于两个组件:

  1. Envoy Sidecar Proxy: 注入到应用 Pod 中的轻量级代理,它负责处理所有的网络I/O。
  2. ****istio-init** 容器:** 这是一个 Init 容器,负责在主应用和 Envoy 启动之前,配置必要的 iptables 规则,确保所有流量都流经 Envoy。

当 Pod 启动时,istio-init 会运行,它通过配置 iptables 的 NAT 表,将原本流向或流出应用容器的网络数据包重定向到 Envoy Sidecar 监听的特定端口。

2. 理解关键的 iptables 链和端口

Istio 主要在 nat 表中创建规则,重点关注以下端口和链:

作用 目标端口 流量类型
PREROUTING (入站) 截获所有进入 Pod 的流量 15006 INBOUND
OUTPUT (出站) 截获所有源自 Pod 的流量 15001 OUTBOUND

Envoy 在端口 15001 上接收出站应用流量,并在 15006 上接收入站流量(如果配置了特定端口拦截)。

3. 实操:验证 Istio 的 iptables 规则

为了探究 Istio 实际是如何配置的,我们需要在一个启用了 Istio Sidecar 注入的命名空间中部署一个测试应用,并进入 Sidecar 容器查看其网络配置。

步骤 3.1 部署测试 Pod

首先,确保你的 Kubernetes 集群已经安装 Istio,并且目标命名空间已启用 Sidecar 注入(例如,标签 istio-injection=enabled)。

部署一个简单的 sleep Pod:

apiVersion: v1
kind: Pod
metadata:
  name: sleep-test
spec:
  containers:
  - name: sleep
    image: curlimages/curl
    command: ["/bin/sleep", "365d"]
    imagePullPolicy: IfNotPresent
# 部署 Pod
kubectl apply -f sleep-pod.yaml

# 确认 Pod 正在运行,并且有两个容器 (sleep 和 istio-proxy)
kubectl get pods sleep-test

步骤 3.2 检查 iptables 规则

我们可以通过进入 istio-proxy 容器来查看 Pod 命名空间内的网络配置,因为 istio-proxy 容器共享 Pod 的网络命名空间。

查看 nat 表中所有规则:

# 使用 istio-proxy 容器执行 iptables 命令
kubectl exec sleep-test -c istio-proxy -- iptables -t nat -L

你将看到类似如下的关键输出片段(细节可能因 Istio 版本和配置而异):

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
ISTIO_INBOUND  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ISTIO_OUTPUT   all  --  anywhere             anywhere

# ... 其他链定义 ...

Chain ISTIO_OUTPUT (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             127.0.0.6/32        # 排除特定的本地流量
ISTIO_REDIRECT  tcp  --  anywhere             anywhere            ! owner UID 1337 redir ports 15001 # 关键:重定向到 15001

Chain ISTIO_INBOUND (1 references)
target     prot opt source               destination
ISTIO_IN_REDIRECT  tcp  --  anywhere             anywhere            tcp dpt:80          # 示例:如果是访问应用端口 80

Chain ISTIO_REDIRECT (2 references)
target     prot opt source               destination
REDIRECT   all  --  anywhere             anywhere            redir ports 15001

规则解析

  1. 出站流量 (OUTPUT** -> ISTIO_OUTPUT):** 当 sleep-test Pod 中的应用尝试连接外部服务时,数据包进入 OUTPUT 链。它被重定向到 ISTIO_OUTPUT 链。这里的关键规则是使用 ! owner UID 1337 (即非 Envoy 自身发出的流量)将所有 TCP 流量导向 ISTIO_REDIRECT,最终通过 REDIRECT 规则将流量强制送往 Envoy 的 15001 端口。
  2. 入站流量 (PREROUTING** -> ISTIO_INBOUND):** 当外部流量到达 Pod IP 时,数据包进入 PREROUTING 链,并被导向 ISTIO_INBOUND。如果该流量的目标端口是应用容器监听的端口(例如 80),则会被重定向到 Envoy 的入站监听器(通常是 15006 端口)。

4. 总结

Istio 通过精心配置的 iptables 规则,实现了对应用流量的透明代理。应用容器无需知道 Envoy Sidecar 的存在,因为所有网络 I/O 在内核级别就被操作系统重定向了。正是这种底层网络的接管能力,使得 Istio 能够一致地应用路由策略、安全策略(mTLS)、可观测性(指标和追踪)等 Service Mesh 核心功能。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » 探秘 Service Mesh 丝绸之路:Istio 是如何接管 Pod 之间的流量控制的
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址