基于 Istio 的多网关运行时:配置、部署和应用
1. 引言
Istio 是一个开源的服务网格,主要应用于简化微服务架构中的服务间通信、提供强大的监控能力以及加强服务的安全管理。通过利用 Sidecar 模式部署的 Envoy 代理,Istio 能够在几乎无需修改服务代码的情况下,实现服务发现、负载均衡、加密通信、访问控制等功能。本文将就如何在 Kubernetes 集群环境下,在 istio-system 之外的命名空间中配置、部署和应用用户自定义的网关运行时 Ingress Gateway 进行探讨。
2. Istio 处理入站请求的流程
在 Kubernetes 集群环境中,默认配置下的 Istio 将会部署至 istio-system 命名空间下,通过向 pod 中自动注入代理容器,Istio 将 pod 纳入服务网格的管理之中,实现对服务间通信的统一管理和控制。在 istio-system 命名空间中,网关运行时负责处理所有流入服务网格的外部流量。网关运行时将根据 CRD 资源 Gateway 中的定义监听特定的域名与端口,并根据 Virtual Service 与 Destination Rule 将请求智能地路由到后端的 Kubernetes Service,并最终访问到对应的微服务。
![](https://static001.geekbang.org/infoq/6c/6c726d2d8a4a6d3b04f7a5e7f040dfe7.png)
3. 为什么需要部署多个网关运行时 Ingress Gateway?
为了保证关键应用的可访问性,用户可能希望将关键应用与一般业务应用进行隔离或单独配置。此外,在多租户的情景下,仅利用 Istio-system 命名空间下的默认 Istio 进行管理可能会引起网关运行时宕机,进而导致在访问各租户部署的应用时出现异常。
为避免上述可能出现的问题,用户可以在其他命名空间中,为每个租户或一组相关服务单独地部署一套网关运行时 Ingress Gateway。这样做能够:
1. 有效隔离应用间的网络流量,减少相互影响,提高系统的稳定性和安全性;
2. 能够令用户根据自身需求定制化网络策略和配置,如不同的安全策略、路由规则等,而不受全局配置的限制;
3. 此外,在默认的 Ingress Gateway 出现问题而下线时,应用其它命名空间部署的网关运行时可以减少默认 Ingress Gateway 下线对关键应用的影响,便于故障排查和恢复,同时减少对整体服务的影响。
4. 用户自定义网关运行时 Ingress Gateway 的配置与部署
Ingress Gateway 在 Kubernetes 其他命名空间中的部署依赖于五类 Kubernetes 资源,它们默认位于 istio-system 命名空间下,其类型与默认名称如下所示:
1. Deployment: istio-ingressgateway;
2. Service: istio-ingressgateway;
3. ServiceAccount: istio-ingressgateway-service-account;
4. Role: istio-ingressgateway-sds;
5. RoleBinding: istio-ingressgateway-sds。
通过获取 istio-system 命名空间中的 Ingress Gateway 的上述五类资源的 YAML 文件,我们即可获得一个网关运行时的配置副本模板。之后,通过对上述资源 YAML 文件中的特定字段进行自定义,用户即可在自己拥有权限的命名空间中部署独立的 Ingress Gateway 管理应用流量。具体配置修改如下:
对于 Deployment,为了保证 Gateway 资源中的选择器 Selector 能够精准匹配到用户配置的 Ingress Gateway,需要对 Deployment 资源的 Label 进行单独配置,其中的 app 字段与 istio 字段可由用户自行定义,如 app: “user-defined”,istio: “user-ingressgateway” 等。之后,再在 Gateway 的 spec.selector 字段中配置上述 label。应保证 Gateway 资源 YAML 中 spec.selector 字段与用户自建的网关运行时的用户修改后的 Label 一致,否则会导致 Gateway 资源不能与用户自建的网关运行时关联。
![](https://static001.geekbang.org/infoq/ab/ab7e0c415c6cef48f13e6d98452ab246.png)
![](https://static001.geekbang.org/infoq/f4/f472843512616086c6107e8200ea01de.png)
为了防止 Istio 将用户命名空间中部署的 Ingress Gateway 作为普通应用纳入服务网格中管理,需要在其 Deployment 的 spec.template.annotations 字段中保证 sidecar.istio.io/inject: "false" 字段的存在。
![](https://static001.geekbang.org/infoq/c5/c5c81a12dab66f9d4d83dd790971c655.png)
而在 Service 中,可以根据实际需求修改 Service 的类型为 NodePort 或 LoadBalancer。在改为 NodePort 时,需要保证 Service 中配置的五个端口值(status-port,http2,https,tcp,tls)均未被占用。
对于 ServiceAccount、Role 与 RoleBinding,在修改 ServiceAccount 与 Role 的资源名后需要在 RoleBinding 中对应地更新资源名称。
![](https://static001.geekbang.org/infoq/a3/a3253539f3dac3843c51aadc2165ebfe.png)
通过利用修改后的 YAML 在 Kubernetes 集群的特定命名空间中进行部署,即可实现用户自定义的 Ingress Gateway。在完成 Gateway 的配置之后,后续的 Virtual Service 与 Destination Rule 的配置则与在默认的网关运行时上进行配置的步骤相同。
5. 用户自定义网关运行时 Ingress Gateway 的应用
在完成上述配置之后,便实现了用户自建的网关运行时 Ingress Gateway – Gateway – Virtual Service 等资源的联动,用户能够根据 Gateway 的定义利用域名:端口访问 Kubernetes 集群中的资源。下图为一个简单样例,展示了在按照上述流程设置成功后,访问集群中某命名空间中的 nginx 的测试页面。其中,在 Gateway 和 VirtualService 中配置了 a.cn 的路由规则,并在 host 文件中对 a.cn 配置了对应的 IP 地址,端口号为用户自建的网关运行时的 Service 中的 http2 对应的 Nodeport 端口。
![](https://static001.geekbang.org/infoq/54/54a1760229a9c60a2031ff1658a37691.png)
6. 总结
本文主要介绍了如何通过获取位于 Kubernetes 集群环境中的 istio-ingressgateway 的 yaml 资源模板,以及如何经过用户自行修改配置并在自己指定的命名空间中部署与应用。
种草环节:欢迎大家下载我们的inBuilder低代码平台开源社区版,可免费下载使用,加入我们,开启开发之旅!
评论