阿里高专王夕宁:Istio网关之南北向流量管理

王夕宁

读完需要

8

分钟

速读仅需 3 分钟

作者简介:王夕宁 阿里云高级技术专家,阿里云服务网格产品ASM及Istio on Kubernetes技术负责人,专注于Kubernetes、云原生、服务网格等领域。曾在IBM中国开发中心工作,担任过专利技术评审委员会主席,作为架构师和主要开发人员负责或参与了一系列在SOA中间件、云计算、IoT等领域的开发工作,拥有40多项相关领域的国际技术专利。著有《Istio服务网格技术解析与实践》一书;

我们将介绍将集群外部的客户端连接到集群内运行的服务,以及如何从集群内的服务访问集群外部的任何服务,即通常所说的南北向流量管理。其中介绍了 Istio 在南北向流量方面的路由控制能力,引出 Istio 网关的概念及其工作原理:

  • Istio 网关的工作机制

  • Istio 网关的负载均衡器原理

  • 入口网关(Ingress Gateway)的服务与部署的定义

  • 网关资源、网关虚拟服务的定义

  • 通过一个示例介绍如何调试入口网关可能遇到的问题

1

   

Istio 网关

网络社区中有一个术语 Ingress,是指入口请求到集群内服务的流量管理。Ingress 指的是源自本地网络之外的流量,指向本地集群网络中的端点。此流量首先路由到公开的入口点,以便通过执行一些本地网络的规则和策略来确认哪些流量被允许进入。如果流量未通过这些入口点,则无法与集群内的任何服务连接。如果入口点允许流量进入,则将其代理到本地网络中的合适节点。Istio 对入口流量的管理是由 Istio 网关进行的。

2

   

Istio 网关的工作原理

传统上,Kubernetes 使用 Ingress 控制器来处理从外部进入集群的流量。使用 Istio 时,情况不再如此。Istio 网关用新的 Gateway 资源和 VirtualServices 资源来控制入口流量,它们协同工作以将流量路由到网格中。在网格内部不需要 Gateways,因为服务可以通过集群本地服务名称相互访问。

那么 Istio 网关是怎样工作的?请求如何到达它想要的应用程序?基本步骤如下:

  1. 客户端在特定端口上发出请求。

  2. 负载均衡器在这个端口上进行侦听,并将请求转发到集群中(在相同或新的端口)。

  3. 在集群内部,请求被路由到 Istio IngressGateway 服务所侦听的负载均衡器转发过来的端口上。

  4. Istio IngressGateway 服务将请求(在相同或新的端口)转发到对应的 pod 上。

  5. 在 IngressGateway pod 上会配置 Gateway 资源和 VirtualService 资源定义。Gateway 会配置端口、协议以及相关安全证书。VirtualService 的路由配置信息用于找到正确的服务。

  6. Istio IngressGateway pod 会根据路由配置信息将请求路由到对应的应用服务上。

  7. 应用服务将请求路由到对应的应用 pod 上。

Istio网关的工作原理

3

   

Istio 网关的负载均衡作用

典型的服务网格具有一个或多个负载均衡器,也称为网关(Gateway),它们从外部网络终止 TLS 并允许流量进入网格。然后,流量通过边车网关(Sidecar gateway)流经内部服务。应用程序使用外部服务的场景也很常见,可以直接调用外部服务,或者在某些部署中强制通过专用出口网关(Egress Gateway)离开网格的所有流量。

Istio 具有入口网关的概念,它扮演网络入口点的角色,负责保护和控制来自集群外部的流量对集群的访问。

网关在网格中的使用情况

此外,Istio 的网关还扮演负载均衡和虚拟主机路由的角色。如图所示,可以看到默认情况下 Istio 使用 Envoy 代理作为入口代理。Envoy 是一个功能强大的服务到服务代理,但它也有负载均衡和路由的功能,可代理的流量包括从服务网格外部到其内部运行的服务,或者从集群内部服务到外部服务。在前面章节中介绍的 Envoy 的所有功能也可以在入口网关中使用。

Istio 的入口网关服务

对于入口流量管理,你可能会问:为什么不直接使用 Kubernetes Ingress API?

  • 第一个原因,Kubernetes Ingress 是一个面向 HTTP 工作负载的非常简单的规范。有 Kubernetes Ingress 的实现(如 Nginx、Heptio Contour 等),但每个都适用于 HTTP 流量。实际上,Ingress 规范只将端口 80 和端口 443 视为入口点。这严重限制了集群运维人员可以允许进入服务网格的流量类型。例如,如果你有 Kafka 工作负载,则可能希望向这些消息代理公开直接 TCP 连接。

  • 第二个原因,Kubernetes Ingress API 无法表达 Istio 的路由需求。Ingress 没有通用的方法来指定复杂的流量路由规则,如流量拆分或流量镜像等。这个领域缺乏规范会导致每个供应商重新设想如何更好地为每种类型的 Ingress 实现(如 HAProxy、Nginx 等)做好配置管理。Ingress 试图在不同的 HTTP 代理之间取一个公共的交集,因此只能支持最基本的 HTTP 路由。

  • 最后一个原因,由于事前没有明确规定,大多数供应商的选择是通过部署上的定制注释来做配置。供应商之间的注释各不相同,并且不可移植,如果 Istio 继续延续这种趋势,那么就会有更多的注释来解释 Envoy 作为边缘网关的所有功能。

Istio 网关通过将 L4-L6 配置与 L7 配置分离克服了 Ingress 的这些缺点。Istio 网关只用于配置 L4-L6 功能(例如,对外公开的端口、TLS 配置),所有主流的 L7 代理均以统一的方式实现了这些功能。然后,通过在 Gateway 上绑定 VirtualService 的方式,可以使用标准的 Istio 规则来控制进入 Gateway 的 HTTP 和 TCP 流量。负载均衡器可以手动配置或通过服务自动配置其类型,例如 type: LoadBalancer。在这种情况下,由于并非所有云都支持自动配置,假设手动配置负载均衡器以将流量转发到 IngressGateway Service 正在侦听的端口。例如如下的负载均衡器正在监听以下端口:

  • HTTP:端口 80,将流量转发到端口 30080

  • HTTPS:端口 443,将流量转发到端口 30443

  • MySQL:端口 3306,将流量转发到端口 30306 确保负载均衡器配置转发到所有工作节点。这将确保即使某些节点关闭也会转发流量。

4

   

入口网关服务

IngressGateway 服务(入口网关服务)必须监听上节介绍的所有端口,以便能够将流量转发到 IngressGateway pod 上。Kubernetes 服务不是“真正的”服务,该请求将由 Kubernetes 提供的 kube-proxy 转发到具有运行对应 pod 的节点上。在节点上,IP table 配置将请求转发到适当的 pod:

ports:
  - name: http2
    nodePort: 30000
    port: 80
    protocol: TCP
  - name: https
    nodePort: 30443
    port: 443
    protocol: TCP
  - name: mysql
    nodePort: 30306
    port: 3306
    protocol: TCP

5

   

入口网关部署

IngressGateway 部署是一个基于 Envoy 代理的封装,它的配置方式与服务网格中使用的 Sidecar 配置相同(实际上是同样的容器镜像)。当我们创建或更改一个 Gateway 或 VirtualService 时,Istio Pilot 控制器会检测到这些变更,并将这些变更信息转换为 Envoy 配置,然后将 Envoy 配置信息发送给相关 Envoy 代理,包括内部的 Envoy 和 IngressGateway 中的 Envoy。

注意:这里不要混淆 IngressGateway 与 Gateway,Gateway 资源是用于配置 IngressGateway 的一种 Kubernetes 的自定义资源。

由于不必在 Kubernetes pod 或部署中声明容器端口,因此我们不必在 IngressGateway Deployment 中声明端口。但是,如果查看部署内部,可以看到声明的许多端口。另外,在 IngressGateway 部署中需要关注 SSL 证书,为了能够访问 Gateway 资源内的证书,请确保已正确加载这些证书。

6

   

网关资源

网关资源用来配置 Envoy 的端口,前面的示例中已经使用该服务公开了三个端口,因此需要在 Envoy 中处理这些端口。此外,可以通过声明一个或多个 Gateways 来支持多端口能力。下面的示例中使用单个 Gateway,但可以分为两个或三个分别定义:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: default-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:

  - hosts:
    - '*'
    port:
      name: http
      number: 80
      protocol: HTTP

  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/tls.key
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt

  - hosts: # For TCP routing this fields seems to be ignored, but it is matched
    - '*'  # with the VirtualService, I use * since it will match anything.
    port:
      name: mysql
      number: 3306
      protocol: TCP

7

   

网关虚拟服务

VirtualService 资源与 Gateway 资源相互配合支持 Envoy 的配置。下面是一个支持 HTTP 服务的网关虚拟服务的基本配置:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: counter
spec:
  gateways:
  - default-gateway.istio-system.svc.cluster.local
  hosts:
  - counter.lab.example.com
  http:
  - match:
    - uri:
      prefix: /
    route:
    - destination:
        host: counter
        port:
          number: 80

现在,当我们添加一个 Gateway 和一个 VirtualService 时,路由已在 Envoy 配置中创建。要查看此内容,你可以使用如下命令:

kubectl port-forward istio-ingressgateway-xxxx-yyyy-n istio-system 15000
通过访问地址 http://localhost:15000/config_dump来查看配置。

8

   

调试入口网关

调试网络问题有时很困难,所以这里总结一些有用的命令用于调试。端口转发到第一个 istio-ingressgateway pod:

kubectl -n istio-system port-forward $(kubectl -n istio-system get pods -listio=ingressgateway -o=jsonpath="{.items[0].metadata.name}") 15000

然后,可以从端口转发的入口网关 pod 中获得 http 路由:

Curl --silent http://localhost:15000/config_dump |jq .configs[3].dynamic_route_configs[].route_config.virtual_hosts[]

端口转发的入口网关pod

查看上述端口转发的入口网关 pod 的日志信息:

kubectl -n istio-system logs $(kubectl -n istio-system get pods -listio=ingressgateway -o=jsonpath="{.items[0].metadata.name}") --tail=300

查看 Pilot pod 的日志信息:

kubectl -n istio-system logs $(kubectl -n istio-system get pods -listio=pilot -o=jsonpath="{.items[0].metadata.name}") discovery --tail=300

当启动端口转发到入口网关 istio-ingressgateway 之后,可以执行更多操作以获取更多信息,例如:

  • 要查看 Envoy 侦听器,请到如下网址浏览:http://localhost:15000/listeners ( http://localhost:15000/listeners )。

  • 要打开更详细的日志记录,请到如下网址:http://localhost:15000/logging ( http://localhost:15000/logging )。

  • 可以在根目录 http://localhost:15000/中找到更多信息。

9

   

推荐阅读

《Istio服务网格技术解析与实践》

推荐语:

Gartner认为,2020年服务网格将成为所有领先的容器管理系统的标配技术。本书适合所有对微服务和云原生感兴趣的读者,推荐大家对本书进行深入的阅读。

更多精彩回顾

 书单 | 5月书讯 | 华章IT图书上新啦!重磅新书在线投喂...

干货 | 73页PPT,教你从0到1构建用户画像系统(附下载)
榜单 | 423世界读书日 | 华章精品IT书单独家推荐

收藏 | 这10本书助你从容应对数字化转型中可能出现的各种挑战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值