LabHub
学习 学习路径 课程

ICA — Istio 认证助理

把网关与外部服务接起来

在 LabHub 中继续学习

目标

掌握使用 Gateway 声明入口、使用 VirtualService 附加路由这一职责分工,并尝试使用 ServiceEntry 和 Sidecar 扩大及缩小服务网格的边界。

为什么重要

Ingress 是服务网格中最容易发生事故的位置。原因通常是以下三种之一:Gateway 的 hosts 与 VirtualService 的 hosts 没有交集;遗漏 gateways 字段,导致规则只应用于网格内部;或者 credentialName 指向的 Secret 与网关 Pod 位于不同的命名空间。这三种情况都会成功 apply,却让流量悄无声息地失败,因此读懂清单是唯一的防线。

ServiceEntry 与 Sidecar 是方向完全相反的工具。前者把网格外服务纳入网格,以便施加策略和可观测性;后者缩小 Sidecar 需要了解的范围,从而节省内存。在大型服务网格中,使用 Sidecar 资源是解决 Envoy 内存问题的标准办法,这一点在考试和实际工作中都会出现。

Kubernetes 基础资源需要实际 apply,Istio CRD 则写成 /root/ica-gateway/ 下的文件。

步骤

  1. 创建命名空间 ica-gateway,并添加标签 istio-injection=enabled
  2. 在命名空间 ica-gateway 中部署 Deployment shop-api,副本数为 2(镜像 nginx:1.27-alpine,Pod 标签 app=shop-api),并创建同名 Service shop-api,端口为 8080,端口名称为 http
  3. 在命名空间 ica-gateway 中创建 Secret shop-tls,类型为 kubernetes.io/tls。其中包含 tls.crttls.key 两个键,值可以是占位字符串。
  4. /root/ica-gateway/gw-shop.yaml 中编写 Gateway shop-gatewayspec.selectoristio: ingressgateway,并包含两个 servers。第一个使用端口 443 / 协议 HTTPS / hosts shop.example.com / tls.mode: SIMPLE / tls.credentialName: shop-tls。第二个使用端口 15443 / 协议 TLS / hosts legacy.example.com / tls.mode: PASSTHROUGH,且不设置 credentialName。
  5. /root/ica-gateway/vs-shop.yaml 中编写 VirtualService。hostsshop.example.comgatewaysshop-gateway,http 路由目标是 shop-api.ica-gateway.svc.cluster.local 的端口 8080
  6. /root/ica-gateway/se-payment.yaml 中编写 ServiceEntry external-pghostsapi.pgprovider.examplelocationMESH_EXTERNALresolutionDNS,ports 使用编号 443 / 名称 https / 协议 TLS
  7. /root/ica-gateway/sidecar-default.yaml 中编写 Sidecar。metadata.namedefaultmetadata.namespaceica-gateway,并且 spec.egress[0].hosts 中只能准确放置三个条目:当前命名空间(./*)、控制平面(istio-system/*),以及第 6 步注册的外部主机(*/api.pgprovider.example)。

参考

创建网关实验命名空间

创建命名空间 ica-gateway,并添加标签 istio-injection=enabled

还必须添加自动注入标签,这样下一步的工作负载才能加入服务网格。

准备网关的后端目标

在命名空间 ica-gateway 中部署 Deployment shop-api,副本数为 2(镜像 nginx:1.27-alpine,Pod 标签 app=shop-api),并创建同名 Service shop-api,端口为 8080,端口名称为 http

网关只负责接收流量。必须先有实际响应的工作负载以及把它组织起来的 Service,才能形成路由目标。

创建 TLS Secret

在命名空间 ica-gateway 中创建 Secret shop-tls,类型为 kubernetes.io/tls。其中包含 tls.crttls.key 两个键,值可以是占位字符串。

类型很重要。credentialName 只识别 kubernetes.io/tls 类型的 Secret,其中必须包含 tls.crt 和 tls.key 两个键。该实验环境没有 CA,因此可以填入占位字符串。

在一个 Gateway 中配置两种 TLS 模式

/root/ica-gateway/gw-shop.yaml 中编写 Gateway shop-gatewayspec.selectoristio: ingressgateway,并包含两个 servers。第一个使用端口 443 / 协议 HTTPS / hosts shop.example.com / tls.mode: SIMPLE / tls.credentialName: shop-tls。第二个使用端口 15443 / 协议 TLS / hosts legacy.example.com / tls.mode: PASSTHROUGH,且不设置 credentialName。

终止 TLS 的 server 与透传 TLS 的 server 使用不同的协议标记。不终止 TLS 的一侧不会解析 HTTP,因此协议不是 HTTPS,也不需要持有证书。

将 VirtualService 绑定到网关

/root/ica-gateway/vs-shop.yaml 中编写 VirtualService。hostsshop.example.comgatewaysshop-gateway,http 路由目标是 shop-api.ica-gateway.svc.cluster.local 的端口 8080

绑定必须同时满足两个条件:gateways 字段中必须包含名称,并且 hosts 必须与 Gateway 的 server hosts 有交集。destination 中也要写明端口号。

将外部支付 API 注册到服务网格

/root/ica-gateway/se-payment.yaml 中编写 ServiceEntry external-pghostsapi.pgprovider.examplelocationMESH_EXTERNALresolutionDNS,ports 使用编号 443 / 名称 https / 协议 TLS

由于这是网格外的服务,location 值是固定的;若未填写 endpoints,还必须说明如何解析名称。443 端口的协议为 TLS。

使用 Sidecar 缩小视野

/root/ica-gateway/sidecar-default.yaml 中编写 Sidecar。metadata.namedefaultmetadata.namespaceica-gateway,并且 spec.egress[0].hosts 中只能准确放置三个条目:当前命名空间(./*)、控制平面(istio-system/*),以及第 6 步注册的外部主机(*/api.pgprovider.example)。

要成为命名空间的默认配置,名称是固定的。egress hosts 只保留当前命名空间、控制平面以及第 6 步注册的外部主机这三个条目。外部主机在命名空间位置使用通配符。