服务网格间的流量流转机制

4,113 阅读4分钟

Kubernetes是分布式运行于多个主机之上、负责运行及管理应用程序的“云操作系统”,它将Pod作为运行应用的最小化组件和基础调度单元。

当流量进来来,具体会流转哪些地方呢。本文将会简单介绍流量流经的路径。

首先,先简单介绍集群内部的流量流转。

集群内部访问

在集群内部访问时,主要涉及 Pod 资源和 Service 资源。

Pod生成的ip并不固定,且属于非可再生类组件,在该背景下,Kubernetes定义了一种Service资源,用于为此类Pod对象提供一个固定、统一的访问接口及负载均衡能力。

k8s、istio流量.jpg

Service实际上是对一组特定Pod的抽象集合,基于标签选择器筛选出一组Pod对象,并通过自己的IP地址和端口将请求分发给这些筛选出的Pod对象。

上图中对应的配置可参考如下:

apiVersion: v1
kind: Service
metadata:
    name: hostnames
spec:
    selector:
        app: hostnames
    ports:
	- name: default
          protocol: TCP
	  port: 80
	  targetPort: 9376
---
apiVersion: v1
kind: Deployment
metadata:
    name: hostnames
spec:
    selector:
        matchLabels:
            app: hostnames
    replicas: 3
    template:
        metadata:
          labels:
            app: hostnames
        spec:
          containers:
              - name: hostnames
                image: k8s.gcr.io/serve_hostname
                ports:
                   - containerPort: 9376
                     protocol: TCP

Service对象的IP地址(可称为ClusterIP或ServiceIP)是虚拟地址ip(VIP),在其生命周期中保持不变。Service基于端口过滤到达其IP地址的客户端请求,并根据定义将请求转发至后端的Pod对象的相应端口之上。比如,上面配置中,Service的80端口代理的是Pod的9376端口。

Service并不直接连接至Pod对象,它们之间还有一个中间层-Endpoints资源对象,它是一个由IP地址和端口组成的列表。只有处于 Running 状态,且 readnessProbe 检查通过的Pod,才会出现在Endpoints列表中。如果某个pod出现问题,会自动从中移除。

但是Service的IP地址只能在集群内部访问,当外部流量访问时需要使用其他机制。

外部流量访问

NodePort和LoadBalancer类型的Service资源都能够把集群内部服务暴露给集群外部客户端使用,但两个负载均衡跃点必然产生更大的网络延迟,且增大组织在使用云服务方面的费用开销。

Kubernetes使用Ingress控制器作为统一的流量入口,管理内部各种服务,并通过Ingress这一API资源来描述如何区分流量以及内部的路由逻辑。

当接入Istio后,Istio服务网格中的Ingress Gateway承担了 Ingress controller 的角色。与Ingress相比,Gateway提供更广泛的自定义和灵活性,并允许将Istio功能(例如监控和路由规则)应用于进入集群的流量。

当我们配置Ingress Gateway及相关信息后,就可以通过浏览器等方式访问部署的应用。

首先,使用 Gateway为网格来管理入站和出站流量,然后将该网关指定路由,绑定到特定 VirtualService 中,VirtualService描述了寻址到名称的流量如何流向一组目的地。DestinationRule描述了服务的子集、负载均衡策略、连接池设置等信息。

具体相关配置,可以阅读该篇文章:
istio.io/latest/zh/d…

流量路径.jpg

最后,对整体流量路径进行简单总结。

当用户从浏览器等端侧请求时,首先经过DNS,解析域名,然后经过APIG和ELB,进入Ingress Gateway,通过VirtualService和DestinationRule配置的相关路由规则,确定对应的 Service 资源,Service资源通过Endpoints选择出一个Pod进行访问,Istio-proxy容器会先将流量劫持,然后再进入主业务容器。

但是在实际情况中,可能会涉及多个服务网格,在该背景下,流量流转机制发生了一些改动。

整体的流量流转图如图所示(以华为云为例):

不同服务网格.jpg

同一服务网格

在同一服务网格下,不同集群或者同一集群下,某一服务调用另一服务时,流量会先通过所在 pod 中的 istio-proxy 容器,然后发送至目标服务, 目标服务选择出一个 pod 进行处理,进入 pod 后,先被 istio-proy 容器流量劫持,然后进入到业务容器中进行处理。

不同服务网格

不同服务网格下的网络是不能连通的,需要使用 VPC 对等连接。

如图所示,服务网格2中的服务Z需要访问服务网格1中的服务Y。

请求会先经过 istio-proxy 容器,然后经过 Egress 出口网关,通过 VPCEP 对等连接访问到对应的 ELB,访问 Ingress 入口网关,通过 Virtual Service 配置的请求路由到对应的服务,之后被 istio-proxy 容器流量拦截,最后进行业务容器进行处理。