Kubernetes是分布式运行于多个主机之上、负责运行及管理应用程序的“云操作系统”,它将Pod作为运行应用的最小化组件和基础调度单元。
当流量进来来,具体会流转哪些地方呢。本文将会简单介绍流量流经的路径。
首先,先简单介绍集群内部的流量流转。
集群内部访问
在集群内部访问时,主要涉及 Pod 资源和 Service 资源。
Pod生成的ip并不固定,且属于非可再生类组件,在该背景下,Kubernetes定义了一种Service资源,用于为此类Pod对象提供一个固定、统一的访问接口及负载均衡能力。
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…
最后,对整体流量路径进行简单总结。
当用户从浏览器等端侧请求时,首先经过DNS,解析域名,然后经过APIG和ELB,进入Ingress Gateway,通过VirtualService和DestinationRule配置的相关路由规则,确定对应的 Service 资源,Service资源通过Endpoints选择出一个Pod进行访问,Istio-proxy容器会先将流量劫持,然后再进入主业务容器。
但是在实际情况中,可能会涉及多个服务网格,在该背景下,流量流转机制发生了一些改动。
整体的流量流转图如图所示(以华为云为例):
同一服务网格
在同一服务网格下,不同集群或者同一集群下,某一服务调用另一服务时,流量会先通过所在 pod 中的 istio-proxy 容器,然后发送至目标服务, 目标服务选择出一个 pod 进行处理,进入 pod 后,先被 istio-proy 容器流量劫持,然后进入到业务容器中进行处理。
不同服务网格
不同服务网格下的网络是不能连通的,需要使用 VPC 对等连接。
如图所示,服务网格2中的服务Z需要访问服务网格1中的服务Y。
请求会先经过 istio-proxy 容器,然后经过 Egress 出口网关,通过 VPCEP 对等连接访问到对应的 ELB,访问 Ingress 入口网关,通过 Virtual Service 配置的请求路由到对应的服务,之后被 istio-proxy 容器流量拦截,最后进行业务容器进行处理。