大家好!👋 今天,我们将深入探讨在Kubernetes环境中使用Istio时,如何安全高效地管理流向外部服务的流量。
提供的代码展示了一个场景,即集群内部的应用程序利用Istio的核心功能——Egress Gateway,访问外部的雅虎财经(finance.yahoo.com)。
但这并非简单的访问!🤫 应用程序可以方便地通过HTTP发送请求,但在离开集群时,Istio会自动将其升级为安全的HTTPS,这正是TLS Origination (TLS发起) 配置所处理的。
让我们逐一剖析这个配置是如何工作的,以及每个YAML文件扮演的角色吧?🔍

🎯 目标场景
- 我们的应用程序(Pod)向外部世界 http://finance.yahoo.com (端口80)发送请求。
- 此请求不会直接离开集群,而是首先转发到充当守门员角色的Istio Egress Gateway。
- Egress Gateway接收到此HTTP请求后,将其用HTTPS(TLS) 加密,然后发送到实际的雅虎服务器(端口443)。
通过这种方式,应用程序无需处理证书管理或加密的复杂性,即可与外部安全通信。很棒吧?😎
🧩 代码详细分析
提供的YAML代码由总共4个Istio资源组成。让我们看看每个拼图块是如何组合在一起的。
1️⃣ ServiceEntry: “雅虎!你是我管理的对象”
首先出现的是ServiceEntry。Istio服务网格默认情况下可能会阻止或无法正确管理流向其不了解的外部世界的流量。
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: yahoo-ext
spec:
hosts:
- finance.yahoo.com
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
resolution: DNS
- 作用: 在Istio的内部服务注册表中注册外部服务(finance.yahoo.com)。
- location: MESH_EXTERNAL: 明确指出此服务位于我们的网格(集群)之外。🌐
- ports & resolution: DNS: 告知Istio,雅虎财经使用80(HTTP)和443(HTTPS)端口,并且需要使用DNS查询来查找此地址。
- 💡 总结: “Istio啊,有一个叫finance.yahoo.com的外部朋友,我们与它通信时会使用80和443端口。请好好管理它!”
2️⃣ Gateway: “Egress守门员,打开这扇门”
接下来是Gateway资源。这里所说的Gateway指的是针对集群外部专用出口——Egress Gateway Pod的配置。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: yahoo-egressgateway
namespace: default
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- finance.yahoo.com
- 作用: 指示处理实际流量的Egress Gateway (Envoy代理)打开特定端口并等待。
- selector: istio: egressgateway: 确定此设置适用于谁。带有istio: egressgateway标签的Pod(实际的Egress Gateway实例)将应用此设置。🎯
- servers: 命令Egress Gateway“打开80端口(HTTP) 以处理流向雅虎财经(finance.yahoo.com)的流量”。
- 💡 总结: 在集群的出口(Egress Gateway)为前往雅虎的80端口流量敞开了大门。🚪
3️⃣ DestinationRule: “出去时请换上HTTPS的衣服!” (核心 ⭐)
这是此场景中最重要的部分之一,负责TLS Origination的DestinationRule。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: originate-tls-for-yahoo-com
spec:
host: finance.yahoo.com
trafficPolicy:
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
- 作用: 定义当流量流向目的地(finance.yahoo.com)时应应用何种策略。
- portLevelSettings -> port: 443: 仅对流向目的地443端口的流量应用设置。
- tls: mode: SIMPLE: 这是核心!💥 它的意思是“当流向443端口时,启动常规的TLS(HTTPS)加密”。Egress Gateway会根据此规则将HTTP请求升级为HTTPS请求。
- 💡 总结: “当连接到雅虎的443端口时,务必穿上安全的HTTPS防护服!”🔒
4️⃣ VirtualService: “流量的导航路径”
最后是虽然最复杂但却很重要的VirtualService。它扮演着导航员的角色,指引流量从何而来,应去往何处。这里定义了两种路径。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: direct-yahoo-through-egress-gateway
spec:
hosts:
- finance.yahoo.com
gateways:
- yahoo-egressgateway
- mesh
http:
# ... (详情见下文)
- gateways: [yahoo-egressgateway, mesh]: 这意味着此路由规则适用于两个地方:
- mesh: 集群内部的应用程序Sidecar。
- yahoo-egressgateway: 我们上面配置的Egress Gateway。
路径 1: 应用程序 → Egress Gateway (内部移动)
- name: mesh
match:
- port: 80
gateways:
- mesh
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
port:
number: 80
- 说明: 拦截网格内部(mesh)的应用程序向finance.yahoo.com的80端口发送的请求。然后将此流量重定向(Redirect)到集群内部的Egress Gateway服务的80端口,而不是实际的雅虎。
- 💡 总结: “应用程序们,如果你们调用雅虎(HTTP),我先把它发送到Egress Gateway。”➡️
路径 2: Egress Gateway → 实际雅虎服务器 (外部移动)
- name: yahoo-egressgateway
match:
- port: 80
gateways:
- yahoo-egressgateway
route:
- destination:
host: finance.yahoo.com
port:
number: 443
- 说明: 当流量到达yahoo-egressgateway的80端口时应用的规则。现在将其发送到真正的目的地——外部的finance.yahoo.com,重要的是将目的端口更改为443(HTTPS端口)。
- 💡 总结: “Egress Gateway啊,将从80端口进入的雅虎流量最终发送到实际雅虎地址的443端口!”↗️
🚀 整体流量流向一览
现在让我们总结一下当所有这些设置组合在一起时,实际会发生什么。
- 应用程序请求: 内部Pod调用 http://finance.yahoo.com (端口80)。🗣️
- Sidecar介入 (VirtualService – 路径 1): Pod旁边的Envoy Sidecar拦截流量并将其发送到istio-egressgateway服务(端口80)。
- Egress Gateway到达 (Gateway): Egress Gateway Pod打开80端口并等待,然后接收流量。👂
- 外部路由决策 (VirtualService – 路径 2): Egress Gateway决定将流量发送到实际finance.yahoo.com的443端口。
- TLS加密 (DestinationRule): 当尝试从443端口出去时,DestinationRule生效。“等等!443必须转换为TLS(HTTPS)才能出去!”并加密HTTP为HTTPS。🔐
- 最终离开: 加密的HTTPS请求通过互联网安全地传输到雅虎服务器。✈️
✨ 总结
通过此配置,我们无需修改任何应用程序代码,即可提高外部通信的安全性。应用程序只需关注简单的HTTP通信,而复杂的证书管理和安全连接则在基础设施层面(Istio)进行集中管理。
这正是使用服务网格的强大原因之一!👍
如果您有任何疑问,请随时留言!
发表回复