利用Nginx Ingress Controller作为 Istio 网格入口
1、概述
API 网关作为客户端访问后端的入口,已经存在很长时间了,它主要是用来管理”南北向“的流量;近几年服务网格开始流行,它主要是管理系统内部,即“东西向”流量,而像 Istio 这样的服务网格还内置了网关,从而将系统内外部的流量纳入了统一管控。这经常给初次接触 Istio 的人带来困惑——服务网格与 API 网关之间是什么关系?是不是使用了 Istio 就可以替代了 API 网关?Istio 的 API 网关是如何运作的?有哪些方式暴露 Istio mesh 中的服务?这篇文章给为你解答。
2、主要观点
- 服务网格诞生的初衷是为了解决分布式应用的内部流量的管理问题,而在此之前 API 网关已存在很久了。
- 虽然 Istio 中内置了Gateway,但是你仍可以使用自定义的 Ingress Controller 来代理外部流量。
- API 网关和服务网格正朝着融合的方向发展。
3、如何暴露 Istio mesh 中的服务?
下图展示了使用 Istio Gateway、Kubernetes Ingress、API Gateway 及 NodePort/LB 暴露 Istio mesh 中服务的四种方式。
其中阴影表示的是 Istio mesh,mesh 中的的流量属于集群内部(东西向)流量,而客户端访问 Kubernetes 集群内服务的流量属于外部(南北向)流量。不过因为 Ingress Controller、Istio Gateway 也是部署在 Kubernetes 集群内的,这些节点访问集群内其他服务的流量可以认为是内部间的访问(东西向)。
方式 | 控制器 | 功能 |
---|---|---|
NodePort/LoadBalancer | Kubernetes | 负载均衡 |
Kubernetes Ingress | Ingress Controller | 负载均衡、TLS、虚拟主机、流量路由 |
Istio Gateway | Istio | 负载均衡、TLS、虚拟主机、高级流量路由、其他 Istio 的高级功能 |
API 网关 | API Gateway | 负载均衡、TLS、虚拟主机、流量路由、API 生命周期管理、权限认证、数据聚合、账单和速率限制 |
以上4种方式方式都可以作为客户端访问Kubernetes集群内部服务的入口,其中Istio Gateway、Kubernetes Ingress、API网关都是以Pod形式部署在Kubernetes集群内部的,这三种方式访问集群内其他服务的流量都是内部间的访问。Istio Gateway与Kubernetes Ingress相比,Istio Gateway提供了更广泛的自定义和灵活性,并允许将 Istio 功能(例如监控和路由规则)应用于进入集群的流量,Istio官方文档建议使用Istio Gateway而不是 Ingress 来利用 Istio 提供的完整功能集;API网关一般都是以微服务的形式部署在Kubernetes集群内部作为客户端访问的入口,这个没什么好讲的一般都是使用开源的方案作为API网关例如Zuul;NodePort/LoadBalancer 是 Kubernetes 内置的基本的暴露服务的方式,一般测试使用。
由于目前我们生产环境一直都是使用Nginx Ingress Controller作为客户端访问Kubernetes集群内部服务的入口方式,并且没有使用到Istio Gateway的特有功能(API 生命周期管理、权限认证、数据聚合、账单和速率限制),所以本文只会介绍如何使用Nginx Ingress Controller暴露 Istio mesh 中的服务。
4、使用Kubernetes Ingress暴露服务
我们都知道 Kubernetes 集群的客户端是无法直接访问 Pod 的 IP 地址的,因为 Pod 是处于 Kubernetes 内置的一个网络平面中。我们可以将 Kubernetes 内的服务使用 NodePort 或者 LoadBlancer 的方式暴露到集群以外。同时为了支持虚拟主机、隐藏和节省 IP 地址,可以使用 Ingress 来暴露 Kubernetes 中的服务。Kubernetes Ingress 原理如下图所示。
简单的说,Ingress 就是从 Kubernetes 集群外访问集群的入口,将用户的 URL 请求转发到不同的服务上。Ingress 相当于 Nginx、Apache 等负载均衡方向代理服务器,其中还包括规则定义,即 URL 的路由信息,路由信息得的刷新由 Ingress controller来提供。
4.1 使用 Nginx Ingress Controller 作为 Istio 网格入口
1、首先需要给Nginx Ingress Controller所在的Pod进行Sidecar注入,这样Nginx Ingress Controller就可以和Kubernetes集群内其他注入Sidecar的服务进行流量治理。(SideCar注入本文不再讲解,详解见Istio1.12.1 Sidecar注入配置 )
nginx.ingress.kubernetes.io/service-upstream: 'true' nginx.ingress.kubernetes.io/upstream-vhost: <服务名>.<命名空间>.svc.cluster.local
下面解释写这两个注解的含义:
注解 | 类型/选项 | 功能描述 |
---|---|---|
nginx.ingress.kubernetes.io/service-upstream | true 或 false | 默认 Nginx 以 Service 中 Pod 的 IP 和端口为 Upstream 中的成员列表,该参数为 true 时,将以 Service 的 ClusterIP 和端口为被代理入口,该功能避免了因 Pod 漂移带来的 Upstream 的配置变化。 |
nginx.ingress.kubernetes.io/upstream-vhost |
string | 自定义发送到上游服务器的信息头字段中 Host 的内容,相当于 Nginx 配置指令 proxy_set_header Host $host 的设置,
Host 包含客户端访问的真实的域名和端口号。假设参数值为my-service.default.svc.cluster.local,相当于用此值覆盖了客户端真实访问的的域名。
|
参考:https://jimmysong.io/blog/istio-servicemesh-api-gateway/
参考:https://preliminary.istio.io/latest/zh/docs/tasks/traffic-management/ingress/kubernetes-ingress/