K8s相关资料可参考改链接 Kubernetes简介
1 什么是Service Mesh
Service Mesh 是一个专门处理服务通讯的基础设施层。它的职责是在由云原生应用组成服务的复杂拓扑结构下进行可靠的请求传送。在实践中,它是一组和应用服务部署在一起的轻量级的网络代理,并且对应用服务透明。
以上这段话有四个关键点:
- 本质:基础设施层。
- 功能:请求分发。
- 部署形式:网络代理。
- 特点:透明。
下图是Service Mesh整体架构图。整个系统分为控制平面(上面深蓝色框)和数据平面(下面所有的虚线框)。
图中每个虚线框代表一个节点(相当于kubernetes中的worker node),绿色的APP是在节点中运行的各类应用程序,浅蓝色的Sidecar相当于是一个网络通信的代理,每个节点需要与外界通信,都是通过这个代理完成的。控制平面通过xDS协议把配置信息下发给Sidecar,这些配置信息包括节点的路由信息,需要监听的端口等。
2 Istio
Service Mesh是一种理念,而Istio则是这种理念的一个具体实现方案。我们Service Mesh的CDN架构也是基于Istio来做的,并且按照实际需求做了一些实现上的修改。
Istio 提供了一个完整的解决方案,可以以统一的方式去管理和监测你的微服务应用。同时,它还具有管理流量、实施访问策略、收集数据等方面的能力,而所有的这些都对应用透明,几乎不需要修改业务代码就能实现。
下图是Istio的架构图,也分为控制平面和数据平面,控制平面实现配置的下发,安全认证,流量监控等功能。数据平面是承载服务的主题,即Kubernetes中的worker node。图中的Proxy即是Service Mesh中的Sidecar,负责节点流量的转发。在Istio官方使用的Proxy是Envoy。而MOSN是阿里开发的一个开源的Proxy。(MOSN的相关知识可参考官网文档https://mosn.io/docs/)
Istio 流量管理的核心组件就是 Pilot。Pilot 主要功能就是管理和配置部署在特定 Istio 服务网格中的所有 sidecar 代理实例。它管理 sidecar 代理之间的路由流量规则,并配置故障恢复功能,如超时、重试和熔断。
当在Kubernetes中使用Istio的时候,其作用主要有如下几点:
- 监控服务注册中心(如 Kubernetes)的服务注册情况。在 Kubernetes 环境下,会监控 service、endpoint、pod、node 等资源信息。
- 监控 Istio 控制面信息变化,在 Kubernetes 环境下,会监控包括 RouteRule、 VirtualService、Gateway、EgressRule、ServiceEntry 等以 Kubernetes CRD(K8s自定义资源) 形式存在的 Istio 控制面配置信息。
- 将上述两类信息合并组合为 sidecar 可以理解的(遵循 Envoy data plane api 的)配置信息,并将这些信息以 gRPC 协议提供给 sidecar。
由以上几点看出,pilot起到了连接Kubernetes和数据平面的作用,它将由kubernetes产生的配置信息转化成数据平面可以识别的格式然后下发给数据平面。
3 资源
3.1 Service
Service相关字段说明:metadata.name:给服务命名,该名称在命名空间内唯一,用于标识该服务。
spec.ports.name:给服务使用的端口命名。
spec.ports.port:外部访问该服务时使用的端口。
spec.ports.protocol:该服务的协议。
spec.ports.targetPort:提供服务的pod实际使用的端口。
spec.selector:选择具有指定标签的pod作为提供服务的实体。
spec.type:类型被指定为ClusterIP后,系统会自动为该服务分配一个IP地址,该IP地址可用于对该服务进行访问,该IP地址是一个虚拟的IP,没有承载实体,也就是说该IP不能ping通,只有结合该服务的端口使用。
apiVersion: v1 kind: Service metadata: labels: XXXX:XXX name: test-cdn-svc-cm-agent-1 namespace: test spec: ports: - name: test-agent port: 3400 protocol: TCP targetPort: 3400 selector: XXXX:XXX sessionAffinity: None type: ClusterIP status: loadBalancer: {}
3.2 Gateway
Gateway相关字段说明:
spec.selector:指定执行该gateway定义的路由规则的pod。即该gateway定义的规则会下发到具有这些标签的pod上去。
spec.servers.hosts:gateway指向的服务的域名,*号表示任意域名都满足要求。
spec.servers.port:指定gateway需要监听的端口名称,端口号,协议。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: labels: XXX: XXX name: test-http-gateway-1 namespace: test-node spec: selector: XXXX:XXX servers: - hosts: - '*' port: name: test1httpListener number: 13401 protocol: HTTP
3.3 Virtualservice
Virtualservice相关字段说明:
spec.gateways:virtualservice必须关联gateway来使用,此处指定关联的gateway。(Istio官方规定virtualservice可关联gateway使用,也可以不关联gateway,但是在我们的实现方案中,是必须关联gateway,这点需要注意)
spec.http:是一个具体的路由项,这里的意识是当前缀匹配到“/”时(即任意前缀),指定路由目的地址为test-1-cdn-http.cdn-cn2827.svc.cluster.local,端口为3401。timeout表示连接超时时间。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: labels: XXX:XXX name: test-cdn-http-vs-1 namespace: test-node spec: gateways: - test-http-gateway-1 hosts: - '*' http: - match: - uri: prefix: / route: - destination: host: test-1-cdn-http.cdn-cn2827.svc.cluster.local port: number: 3401 timeout: 4s
关于gateway和virtualservice的说明:
gateway和virtualservice都是在Istio中定义的资源,Kubernetes中没有这个资源。
它们的关系如下图,从图中可见,gateway是把流量引进来,然后流量具体要交个哪个服务处理是由virtualservice决定的,在virtualservice后面还有destinationrule这个资源,destinationrule可以将流量进行更加细化的区分,比如可以根据同一个服务的不同版本来决定流量的转发。destinationrule可以用于实现金丝雀发布,灰度发布等功能。
参考资料:MARKO LUKŠA. Kubernetes in Action. Manning Publications Co. 2018
https://martinfowler.com/articles/microservices.html https://www.redhat.com/zh/topics/microservices/what-is-istio https://jimmysong.io/kubernetes-handbook/cloud-native/cloud-native-definition.html
https://www.servicemesher.com/istio-handbook/
https://kubernetes.io/docs/home/
https://istio.io/latest/docs/