[zh] Translate ztunnel traffic redirection doc and sync #14611 into Chinese (#14712)

* Add ztunnel traffic redirection doc and sync  #14611 into Chinese

* Fix lint
This commit is contained in:
Wilson Wu 2024-03-09 18:20:22 +08:00 committed by GitHub
parent 96610c6a48
commit 83bd68686e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 250 additions and 35 deletions

View File

@ -1,11 +1,13 @@
---
---
{{< warning >}}
Ambient 目前处于 [Alpha 状态](/zh/docs/releases/feature-stages/#feature-phase-definitions)。
Ambient 模式目前处于 [Alpha](/zh/docs/releases/feature-stages/#feature-phase-definitions) 阶段
**请勿在生产环境中使用 Ambient 模式**
务必先行斟酌[特性阶段定义](/zh/docs/releases/feature-stages/#feature-phase-definitions)再行使用 Ambient。
具体而言,`alpha` 版本意味着存在已知的性能、稳定性和安全性问题,
还存在一些计划中的破坏性变更,其中某些变更可能会令升级失败。
这些是进阶至 `beta` 之前需要解决的问题。
特别是,在 Alpha 版本中存在已知的性能、稳定性和安全问题。
还有计划中的重大变更,包括一些会阻止升级的变更。
这些限制将在 Ambient 模式转入 Beta 版之前得到解决。
{{< /warning >}}

View File

@ -0,0 +1,173 @@
---
title: ztunnel 流量重定向
description: 了解流量如何在 Pod 和 ztunnel 节点代理之间重定向。
weight: 2
owner: istio/wg-networking-maintainers
test: no
---
在 Ambient 模式的上下文中,**流量重定向**指的是一项数据平面功能,
该功能拦截发送到和来自启用 Ambient 的工作负载的流量,
并通过处理核心数据路径的 {{< gloss >}}ztunnel{{< /gloss >}} 节点代理将其路由。
有时也使用术语**流量捕获**。
{{< boilerplate ambient-alpha-warning >}}
{{< tip >}}
本指南中描述的方法首次包含在 Istio 1.21.0 版本中,
并[替换之前的方法](/zh/blog/2024/inpod-traffic-redirection-ambient/)。
{{< /tip >}}
## Istio 的 in-Pod 流量重定向模型 {#istio-s-in-pod-traffic-redirection-model}
Ambient 模式 in-Pod 流量重定向的核心设计原则是 ztunnel
代理能够在工作负载 Pod 的 Linux 网络命名空间内执行数据路径捕获。
这是通过 [`istio-cni` 节点代理](/zh/docs/setup/additional-setup/cni/)和
ztunnel 节点代理之间的功能协作来实现的。该模型的一个主要优点是,
它使 Istio 的 Ambient 模式能够与任何 Kubernetes CNI 插件透明地协同工作,
并且不会影响 Kubernetes 网络功能。
下图说明了在启用 Ambient 的命名空间中启动(或添加)新工作负载 Pod 时的事件顺序。
{{< image width="100%"
link="./pod-added-to-ambient.svg"
alt="Pod 被添加到 Ambient 网格的流程"
>}}
`istio-cni` 节点代理响应 CNI 事件,例如 Pod 创建和删除,
还监视底层 Kubernetes API 服务器的事件,例如添加到 Pod 或命名空间的 Ambient 标签。
`istio-cni` 节点代理还会安装一个链式 CNI 插件,
该插件在 Kubernetes 集群中的主流 CNI 插件执行后由容器运行时执行。
其唯一目的是当容器运行时在已经以 Ambient 模式注册的命名空间中创建新的
Pod 时通知 `istio-cni` 节点代理,并将新的 Pod 上下文传播到 `istio-cni`
一旦 `istio-cni` 节点代理收到通知需要将 Pod 添加到网格中
(如果 Pod 是全新的,则来自 CNI 插件;如果 Pod 已在运行但需要添加,
则来自 Kubernetes API 服务器),将被执行以下操作序列:
- `istio-cni` 进入 Pod 的网络命名空间并建立网络重定向规则,
以便拦截进入和离开 Pod 的数据包并透明地重定向到在[已知端口](https://github.com/istio/ztunnel/blob/master/ARCHITECTURE.md#ports)
15008, 15006, 15001上侦听的节点本地 ztunnel 代理实例。
- 然后,`istio-cni` 节点代理通过 Unix 域套接字通知 ztunnel 代理,
它应该在 Pod 的网络命名空间内建立本地代理侦听端口(在端口 15008、15006 和 15001 上),
并为 ztunnel 提供代表 Pod 网络命名空间的低级 Linux [文件描述符](https://en.wikipedia.org/wiki/File_descriptor)。
- 虽然通常套接字是由实际在该网络命名空间内运行的进程在 Linux 网络命名空间内创建的,
但完全可以利用 Linux 的低级套接字 API
来允许在一个网络命名空间中运行的进程在另一个网络命名空间中创建侦听套接字,
假设目标网络命名空间在创建时已知。
- 节点本地 ztunnel 在内部启动一个新的代理实例和侦听端口集,专用于被新添加的 Pod。
- 一旦 in-Pod 重定向规则到位并且 ztunnel 建立了侦听端口,
Pod 就会被添加到网格中,并且流量开始流经节点本地 ztunnel。
默认情况下,网格中进出 Pod 的流量将使用 mTLS 完全加密。
现在,数据进入和离开 Pod 网络命名空间时将被加密。
网格中的每个 Pod 都能够执行网格策略并安全地加密流量,
即使 Pod 中运行的用户应用程序对此一无所知。
下图说明了新模型中 Ambient 网格中的 Pod 之间的加密流量如何流动:
{{< image width="100%"
link="./traffic-flows-between-pods-in-ambient.svg"
alt="HBONE 流量在 Ambient 网格中的 Pod 之间流动"
>}}
## Ambient 模式下流量重定向的观测与调试 {#observing-and-debugging-traffic-redirection-in-ambient-mode}
如果流量重定向在 Ambient 模式下无法正常工作,
可以进行一些快速检查以帮助缩小问题范围。要演示实际的流量重定向,
请首先按照 [ztunnel Layer 4 网络指南](/zh/docs/ops/ambient/usage/ztunnel)中描述的步骤进行操作,
包括在 Kubernetes 集群中部署启用 Ambient 模式的 Istio
以及在已被标记为 Ambient 模式的命名空间中部署 `httpbin``sleep`
验证应用程序在 Ambient 网格中成功运行后,您可以使用以下步骤来观察流量重定向。
### 检查 ztunnel 代理日志 {#check-the-ztunnel-proxy-logs}
当应用程序 Pod 是 Ambient 网格的一部分时,
您可以检查 ztunnel 代理日志以确认网格正在重定向流量。
如下例所示,与 `inpod` 相关的 ztunnel 日志表明已启用 Pod 内重定向模式,
代理已收到有关 Ambient 应用程序 Pod 的网络命名空间netns信息并已开始为其代理。
{{< text bash >}}
$ kubectl logs ds/ztunnel -n istio-system | grep inpod
Found 3 pods, using pod/ztunnel-hl94n
inpod_enabled: true
inpod_uds: /var/run/ztunnel/ztunnel.sock
inpod_port_reuse: true
inpod_mark: 1337
2024-02-21T22:01:49.916037Z INFO ztunnel::inpod::workloadmanager: handling new stream
2024-02-21T22:01:49.919944Z INFO ztunnel::inpod::statemanager: pod WorkloadUid("1e054806-e667-4109-a5af-08b3e6ba0c42") received netns, starting proxy
2024-02-21T22:01:49.925997Z INFO ztunnel::inpod::statemanager: pod received snapshot sent
2024-02-21T22:03:49.074281Z INFO ztunnel::inpod::statemanager: pod delete request, draining proxy
2024-02-21T22:04:58.446444Z INFO ztunnel::inpod::statemanager: pod WorkloadUid("1e054806-e667-4109-a5af-08b3e6ba0c42") received netns, starting proxy
{{< /text >}}
### 确认套接字的状态 {#confirm-the-state-of-sockets}
按照以下步骤确认端口 15001、15006 和 15008 上的套接字已打开并处于侦听状态。
{{< text bash >}}
$ kubectl debug $(kubectl get pod -l app=sleep -n ambient-demo -o jsonpath='{.items[0].metadata.name}') -it -n ambient-demo --image nicolaka/netshoot -- ss -ntlp
Defaulting debug container name to debugger-nhd4d.
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 127.0.0.1:15080 0.0.0.0:*
LISTEN 0 128 *:15006 *:*
LISTEN 0 128 *:15001 *:*
LISTEN 0 128 *:15008 *:*
{{< /text >}}
### 检查 iptables 规则设置 {#check-the-iptables-rules-setup}
要查看应用程序中一个 Pod 内的 iptables 规则设置,请执行以下命令:
{{< text bash >}}
$ kubectl debug $(kubectl get pod -l app=sleep -n ambient-demo -o jsonpath='{.items[0].metadata.name}') -it --image gcr.io/istio-release/base --profile=netadmin -n ambient-demo -- iptables-save
Defaulting debug container name to debugger-m44qc.
# Generated by iptables-save v1.8.7 on Wed Feb 21 20:38:16 2024
*mangle
:PREROUTING ACCEPT [320:53261]
:INPUT ACCEPT [23753:267657744]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [23352:134432712]
:POSTROUTING ACCEPT [23352:134432712]
:ISTIO_OUTPUT - [0:0]
:ISTIO_PRERT - [0:0]
-A PREROUTING -j ISTIO_PRERT
-A OUTPUT -j ISTIO_OUTPUT
-A ISTIO_OUTPUT -m connmark --mark 0x111/0xfff -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff
-A ISTIO_PRERT -m mark --mark 0x539/0xfff -j CONNMARK --set-xmark 0x111/0xfff
-A ISTIO_PRERT -s 169.254.7.127/32 -p tcp -m tcp -j ACCEPT
-A ISTIO_PRERT ! -d 127.0.0.1/32 -i lo -p tcp -j ACCEPT
-A ISTIO_PRERT -p tcp -m tcp --dport 15008 -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15008 --on-ip 0.0.0.0 --tproxy-mark 0x111/0xfff
-A ISTIO_PRERT -p tcp -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ISTIO_PRERT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j TPROXY --on-port 15006 --on-ip 0.0.0.0 --tproxy-mark 0x111/0xfff
COMMIT
# Completed on Wed Feb 21 20:38:16 2024
# Generated by iptables-save v1.8.7 on Wed Feb 21 20:38:16 2024
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [175:13694]
:POSTROUTING ACCEPT [205:15494]
:ISTIO_OUTPUT - [0:0]
-A OUTPUT -j ISTIO_OUTPUT
-A ISTIO_OUTPUT -d 169.254.7.127/32 -p tcp -m tcp -j ACCEPT
-A ISTIO_OUTPUT -p tcp -m mark --mark 0x111/0xfff -j ACCEPT
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -o lo -j ACCEPT
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -p tcp -m mark ! --mark 0x539/0xfff -j REDIRECT --to-ports 15001
COMMIT
{{< /text >}}
The command output shows that additional Istio-specific chains are added to the NAT and Mangle tables in netfilter/iptables within the application pod's network namespace. All TCP traffic coming into the pod is redirected to the ztunnel proxy for ingress processing. If the traffic is plaintext (source port != 15008), it will be redirected to the in-pod ztunnel plaintext listening port 15006. If the traffic is HBONE (source port == 15008), it will be redirected to the in-pod ztunnel HBONE listening port 15008. Any TCP traffic leaving the pod is redirected to ztunnel's port 15001 for egress processing, before being sent out by ztunnel using HBONE encapsulation.
命令输出显示,额外的 Istio 特定链已被添加到应用程序 Pod
网络命名空间内的 netfilter/iptables 中的 NAT 和 Mangle 表中。
所有进入 Pod 的 TCP 流量都会被重定向到 ztunnel 代理进行入口处理。
如果流量是明文(源端口不等于 15008会被重定向到 in-Pod ztunnel 明文侦听端口 15006。
如果流量是 HBONE源端口等于 15008会被重定向到 in-Pod ztunnel HBONE 侦听端口 15008。
任何离开 Pod 的 TCP 流量都会被重定向到 ztunnel 的端口 15001 进行出口处理,
然后由 ztunnel 使用 HBONE 封装发送出去。

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

View File

@ -59,30 +59,22 @@ Istio 在 Ambient 模式下的一些用例可以仅通过 L4 安全覆盖网络
## 当前注意事项 {#caveats}
当使用其中一种支持的安装方法安装 Istio Ambient 网格时,会自动安装 ztunnel 代理。
Istio Ambient 模式所需的最低 Istio 版本是 `1.18.0`
一般来说Ambient 模式下的 Istio 支持 Sidecar 代理模式下支持的现有 Istio API。
由于 Ambient 功能当前处于 Alpha 版本级别,
因此以下是 Istio Ambient 功能当前版本(自 `1.19.0` 版本起)中的功能限制或警告列表。
预计在 Ambient 进入 Beta 版本并最终正式发布时,这些限制将被解决/移除。
{{< boilerplate ambient-alpha-warning >}}
1. **仅限 KubernetesK8s**目前仅支持 Istio Ambient 模式在 Kubernetes 集群上部署。
目前不支持在虚拟机等非 Kubernetes 端点上部署。
以下是 Ambient 模式 Alpha 中的功能限制或警告列表。
这些限制计划在未来版本中得到解决或删除。
1. **仅限 Kubernetes**目前仅支持 Ambient 模式下的 Istio 在 Kubernetes 集群上部署。
目前不支持在虚拟机等非 Kubernetes 端点中部署。
1. **不支持 Istio 多集群:**Istio Ambient 模式当前仅支持单集群部署。
1. **K8s CNI 限制:**Ambient 模式下的 Istio 目前不适用于所有 Kubernetes CNI 实现。
此外,对于某些插件,某些 CNI 功能(特别是 Kubernetes `NetworkPolicy` 和 Kubernetes 服务负载均衡功能)
可能会在 Istio Ambient 模式存在的情况下被透明绕过。
已被支持的 CNI 插件的明确集合以及任何 CNI 功能警告目前正在测试中,
并将在 Istio Ambient 模式接近 Beta 版本时正式提供文档。
1. **仅限 TCP/IPv4**在当前版本中,基于 IPv4 的 TCP 是
Istio 安全覆盖隧道上唯一支持的传输协议(这包括在 TCP/IPv4 连接之上的应用程序层端点之间运行的 HTTP 等协议)。
1. **无法动态切换到 Ambient 模式:**Ambient 模式只能在使用 Ambient 配置文件或
Ambient Helm 配置部署的新 Istio 网格控制平面上启用。
例如,使用 Pre-Ambient 配置文件部署的现有 Istio 网格无法被动态切换至同时启用 Ambient 模式的状态
1. **无法将现有 Istio 部署透明地转换为 Ambient 模式:**Ambient 模式只能在使用 Ambient `istioctl`
配置文件或 Helm 配置部署的新 Istio 网格控制平面上启用。
使用 Sidecar 配置文件部署的现有 Istio 网格当前无法动态切换以启用 Ambient 模式。
1. **Istio `PeerAuthentication` 的限制:**截至撰写本文时Istio Ambient 模式下的所有组件(即 Waypoint 代理)
并不支持 `PeerAuthentication` 资源。因此,建议当前仅使用 `STRICT` mTLS 模式。
@ -94,9 +86,8 @@ Istio Ambient 模式所需的最低 Istio 版本是 `1.18.0`。
### 本指南使用的环境 {#environment-used-for-this-guide}
本指南中的示例在基于 `0.20.0``kind`
Kubernetes `1.27.3` 集群内的 Istio `1.19.0` 版本中运行。
Kubernetes `1.27.3` 集群内的 Istio `1.21.0` 版本中运行。
Ambient 功能所需的最低 Istio 版本是 1.18.0,所需的最低 Kubernetes 版本是 `1.24.0`
下面的示例需要一个具有超过 1 个工作节点的集群,以便解释跨节点流量的运行方式。
请参阅[安装用户指南](/zh/docs/ops/ambient/install/)或[入门指南](/zh/docs/ops/ambient/getting-started/)
了解关于在 Kubernetes 集群中安装 Ambient 模式 Istio 的信息。
@ -144,11 +135,22 @@ Pod C1、C2 和 C3 需要访问由 Pod S1 提供的服务,并且不需要高
(例如 L7 流量路由或 L7 流量管理),因此不需要 Waypoint 代理。
该图展示了在节点 W1 上运行的 Pod C1 和 C2 与在节点 W2 上运行的 Pod S1 连接,
它们的 TCP 流量通过在每个节点的 ztunnel 代理 Pod 之间创建的单个共享 HBONE 隧道实例进行隧道传输。
它们的 TCP 流量通过在每个节点的 ztunnel 代理 Pod 之间创建的 HBONE 隧道实例进行隧道传输。
双向 TLSmTLS用于加密以及隧道流量的相互身份验证。SPIFFE 身份用于识别连接两端的工作负载。
Istio Ambient 中使用的 `HBONE`(基于 HTTP 的覆盖网络封装HTTP Based Overlay Network Encapsulation概念是指一种透明、
安全地隧道传输封装在 HTTPS 数据包中的 TCP 数据包的技术。
以下小节提供了有关 HBONE 的一些简短附加说明。
有关数据路径的更多详细信息,包括 HBONE 和流量重定向详细信息,
请参阅 [ztunnel 流量重定向](/zh/docs/ops/ambient/usage/traffic-redirection)指南。
{{< tip >}}
注意:虽然图中显示 HBONE 隧道位于两个 ztunnel 代理之间,
但在 Istio 1.21.0 中引入的 Pod 内重定向实现中,
隧道实际上位于源 Pod 和目标 Pod 之间。
流量在源 Pod 本身的网络命名空间中进行 HBONE 封装和加密,
最终在目标工作节点上的目标 Pod 的网络命名空间中解封装和解密。
ztunnel 代理仍然在逻辑上处理 HBONE 传输所需的控制平面和数据平面,
但它能够从源 Pod 和目标 Pod 的网络命名空间内部执行此操作。
{{< /tip >}}
请注意,该图展示本地流量(从 Pod C3 到工作节点 W2 上的目标 Pod S1
无论是否跨越节点边界也会遍历本地 ztunnel 代理实例,
@ -197,7 +199,7 @@ caption="ztunnel 流量 Hair-pinning"
HBONEHTTP Based Overlay Network Encapsulation基于 HTTP 的覆盖网络封装)是 Istio 中特定的术语。
它是指通过 [HTTP CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT)
方法使用标准 HTTP 隧道来透明地传递应用程序数据包/字节流。
在 Istio 的当前实现中,它通过使用 HTTP CONNECT 方法透明地隧道传输 TCP 数据包,
在 Istio 的当前实现中,它通过使用 HTTP CONNECT 方法透明地隧道传输 TCP 数据包,
使用 [HTTP/2](https://httpwg.org/specs/rfc7540.html)
并通过[双向 TLS](https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/)
提供加密和相互身份验证且 HBONE 隧道本身在 TCP 端口 15008 上运行。
@ -208,12 +210,8 @@ link="hbone-packet.png"
caption="HBONE L3 数据包格式"
>}}
未来 Istio Ambient 还可能利用作为
[IETF MASQUE](https://ietf-wg-masque.github.io/)
工作组中一部分开发的 CONNECT-UDP 和 CONNECT-IP 等新标准支持基于
[HTTP/3QUIC](https://datatracker.ietf.org/doc/html/rfc9114)的传输,
并将用于传输原生 IPv4、IPv6、UDP 等所有类型的 L3 和 L4 数据包。
Istio Ambient 模式下的 HBONE 和 HTTP 隧道的此类附加用例目前还需进一步调研。
随着 Ambient 模式的发展,未来将研究 HBONE 和 HTTP 隧道的其他用例
(例如对 IPv6 和 UDP 数据包的支持)。
## 部署应用程序 {#deployapplication}
@ -289,7 +287,7 @@ sleep-69cfb4968f-rhhhp 1/1 Running 0 78m
请注意,为命名空间启用 Ambient 后,每个应用程序 Pod 仍然只有 1 个容器,
并且这些 Pod 的正常运行时间表明这些 Pod 没有为了启用 Ambient 模式而被重新启动
(与 `sidecar` 模式不同,当 Sidecar 代理被注入时,它会重新启动应用程序 Pod)。
(与 Sidecar 模式不同,当 Sidecar 代理被注入时,它需要 Pod 被重启)。
这会带来更好的用户体验和运维效率,因为就应用程序 Pod 而言,
可以完全透明地无缝启用或禁用Ambient 模式。
@ -395,7 +393,7 @@ $ kubectl exec -n istio-system deploy/istiod -- curl localhost:15014/debug/confi
将一些流量从客户端 `sleep` Pod 发送到 `httpbin` 服务。
{{< text bash >}}
$ kubectl -n ambient-demo exec deploy/sleep -- sh -c 'for i in $(seq 1 10); do curl -s -I http://httpbin:8000/; done'
$ kubectl -n ambient-demo exec deploy/sleep -- sh -c "for i in $(seq 1 10); do curl -s -I http://httpbin:8000/; done"
HTTP/1.1 200 OK
Server: gunicorn/19.9.0
--snip--
@ -460,7 +458,7 @@ deployment.apps/httpbin condition met
{{< /text >}}
{{< text bash >}}
$ kubectl -n ambient-demo exec deploy/sleep -- sh -c 'for i in $(seq 1 10); do curl -s -I http://httpbin:8000/; done'
$ kubectl -n ambient-demo exec deploy/sleep -- sh -c "for i in $(seq 1 10); do curl -s -I http://httpbin:8000/; done"
{{< /text >}}
{{< text bash >}}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

After

Width:  |  Height:  |  Size: 187 KiB