服务网格(Service mesh)是以后新兴的架构模式,越来越受到人们的青眼。与Kubernetes一起,服务网格能够造成一个弱小的平台,它能够解决在微服务集群或服务基础设施上发现的高度分布式环境中呈现的技术需要。服务网格是一个专门的基础设施层,用于促成微服务之间的服务到服务通信。
服务网格解决了基于微服务的利用中典型的通信需要,包含加密隧道、健康检查、断路器、负载平衡以及流量许可。如果来到微服务来解决这些需要,会导致开发过程中产生昂扬的费用和耗时。
在本文中,咱们将对服务网格架构模式解决的最常见的微服务通信需要进行概述。
微服务动静和外在挑战
当你意识到微服务实现了相当多的与最后调配给它们的业务逻辑无关的代码时,问题就呈现了。此外,有可能你有多个微服务在非标准化的流程中实现了相似的性能。换句话说,微服务开发团队应该专一于业务逻辑,并将低级通信能力留给特定的层。
持续推动咱们的计划,须要思考微服务的外在动静。在给定的工夫内,你可能因为以下几个起因而领有一个微服务的多个实例:
- 吞吐量(Throughput):依据传入的申请,你可能领有更多或更少的微服务实例
- 金丝雀公布
- 蓝绿部署
- A/B测试
简而言之,微服务到微服务的通信有特定的需要和问题须要解决。以下图片展现了这一计划:
该图示形容了几个技术挑战。显然,Microservice 1的主要职责是平衡所有Microservice 2实例之间的负载。因而,Microservice 1必须弄清楚咱们在申请时刻有多少个Microservice 2实例。换句话说,Microservice 1必须实现服务发现和负载平衡。
另一方面,Microservice 2必须实现一些服务注册性能以告知Microservice 1何时有全新的实例。
想要领有一个齐全动静的环境,以下这些性能应该是微服务开发的一部分:
- 流量管制:负载平衡的天然演变。咱们想指定应该发送到每个Microservice 2实例的申请数量。 在Microservice
1和2之间加密通信 - 借助断路器和健康检查以解决和克服网络问题
总而言之,次要问题是开发团队破费了大量资源编写十分复杂的代码,而这些代码与微服务预期交付的业务逻辑不间接相干。
有后劲的解决方案
如何将所有微服务都能够调用的内部标准化组件中的所有非性能和操作性能内部化?例如,下图编译了所有性能,这些性能不属于给定的微服务。因而,在确定所有性能之后,咱们须要决定在哪里实现它们。
Solution #1 :将所有性能封装在一个library中
开发者将负责调用library提供的函数来解决微服务通信需要。
这个解决方案有几个毛病:
这是一个严密耦合的解决方案,意味着微服务高度依赖于library
这个模式对于散布和降级新版本的library来说并不容易
这不合乎微服务多语言的准则,因为这会将不同的编程语言利用于不同的上下文。
Solution #2:通明代理(Transparent Proxy)
这个解决方案实现了同样的性能汇合。然而,采纳了一种十分不同的办法:每个微服务都有一个特定的组件,表演代理的角色,负责解决它的传入和传出流量。代理解决了咱们之前形容的库的毛病,具体如下:
- 代理是通明的,这意味着微服务不会意识到它正在左近运行并实现了与其余微服务进行通信所需的所有性能。
- 因为它是一个通明的代理,开发者不须要扭转代码来援用代理。因而,从微服务开发的角度来看,降级代理将是一个并不会对开发流程造成太大影响。
- 代理能够应用微服务应用的不同技术和编程语言进行开发。
服务网格架构模式
尽管通明代理的办法给微服务开发团队和微服务通信需要带来了一些益处,但仍有一些缺失的局部:
- 代理只是执行策略来实现通信需要,例如负载平衡、金丝雀公布等。
- 由什么来负责定义这样的策略,并在所有运行的代理上公布呢?
解决方案架构须要另一个组件,这些组件将被管理员用来定义策略,它将负责向代理流传策略。
以下图片展现了最终架构,也就是服务网格模式:
如你所见,该模式蕴含了咱们所形容的两个次要组件。
- 数据立体:也被称为sidecar,它扮演着通明代理的角色。同样,每个微服务都会有本人的数据立体,拦挡所有的入站和出站流量,并利用之前形容的策略。
- 管制立体:由管理员用来定义策略并公布到数据立体。
一些重要的事件须要留神:
- 这是一个 "push-based "的架构。数据立体不做 "调用 "来获取策略——那将会耗费网络。
- 数据立体通常向管制立体或特定的基础设施报告应用指标。
手把手教你应用Rancher、Kong和Kong Mesh
Kong提供了一个企业级的综合服务连贯平台,其包含了API gateway、Kubernetes ingress controller以及服务网格实现。该平台容许用户部署多个环境,如本地、混合云、多区域以及多云环境。
让咱们借助运行在独立于云架构(cloud-agnostic)的Kubernetes集群上的金丝雀公布来实现服务网格,该集群可能包含GKE集群或任何其余的Kubernetes发行版。服务网格将由Kong Mesh实现,并由Kong for Kubernetes作为Kubernetes Ingress Controller。一般而言,ingress controller负责定义进入你的Kubernetes集群的入口点,裸露部署在其外部的微服务,并对其履行生产策略。
首先,确保你曾经装置Rancher以及正在运行一个由Rancher治理的Kubernetes集群。在登录到Rancher之后,选在咱们将要应用的Kubernetes集群,在本例中为“kong-rancher”。点击Cluster Explorer。你将会重定向到以下页面:
当初,让咱们从服务网格开始:
1、 Kong Mesh Helm Chart
回到Rancher Cluster Manger主页并再次抉择你的集群。点击菜单栏的“Tools”选项而后点击Catalogs,以创立一个新的catalog。点击Add Catalog按钮,将Kong Mesh的Helm chart收录其中(https://kong.github.io/kong-m...
抉择Global作为范畴,Helm v3作为Helm版本。
当初点击Apps和Launch来查看在Catalog中可用的Kong Mesh。请留神,Kong作为Rancher的合作伙伴默认提供了Kong for Kubernetes的Helm chart:
2、 装置Kong Mesh
点击顶部菜单栏Namespaces选项并创立一个“kong-mesh-system”命名空间。
将鼠标移到kong-rancher顶部菜单选项上,点击kong-rancher流动集群。
点击Launch kubetcl
创立一个名为“license.json”的文件,用于寄存你从Kong Mesh收到的license。格局如下:
{“license”:{“version”:1,“signature”:“6a7c81af4b0a42b380be25c2816a2bb1d761c0f906ae884f93eeca1fd16c8b5107cb6997c958f45d247078ca50a25399a5f87d546e59ea3be28284c3075a9769”,“payload”:{“customer”:“Kong_SE_Demo_H1FY22”,“license_creation_date”:“2020-11-30”,“product_subscription”:“Kong Enterprise Edition”,“support_plan”:“None”,“admin_seats”:“5”,“dataplanes”:“5”,“license_expiration_date”:“2021-06-30”,“license_key”:“XXXXXXXXXXXXX”}}}
当初应用以下命令创立一个Kubernetes通用密钥:
kubectl create secret generic kong-mesh-license -n kong-mesh-system --from-file=./license.json
敞开kubectl会话,点击Default我的项目以及顶部菜单栏的Apps。点击Launch按钮并抉择kong-mesh Helm chart。
点击Use an existing namespace并抉择咱们刚刚创立的那个。这有几个参数(https://artifacthub.io/packag... Mesh,但咱们将保留所有默认值。点击Launch之后,你应该看到Kong Mesh应用程序部署实现。
你能够再次应用Rancher Cluster Explorer来查看装置。点击左侧菜单的Pods并抉择kong-mesh-system的命名空间。
你也能够像这样应用kubectl:
NAMESPACE NAME READY STATUS RESTARTS AGEcattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75mfleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75mkong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16mkube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76mkube-system fluentbit-gke-xqsdv 2/2 Running 0 76mkube-system gke-metrics-agent-gjrqr 1/1 Running 0 76mkube-system konnectivity-agent-4c4hf 1/1 Running 0 76mkube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76mkube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76mkube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76mkube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76mkube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75mkube-system prometheus-to-sd-fdf9j 1/1 Running 0 76mkube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 75m
3、 微服务部署
咱们的Service Mesh部署是基于一个简略的微服务到微服务的通信场景。因为咱们运行的是金丝雀公布,被调用的微服务有两个版本:
“magnanimo”:通过Kong裸露Kubernetes ingress controller。
“benigno”:提供了一个 “hello” endpoint,在这个端点中,它响应了以后的datetime。它有一个金丝雀公布,会发送一个略微不同的响应。
下图展现了这一架构:
创立一个带有sidecar注入正文的命名空间。你能够再次应用Rancher Cluster Manager:抉择你的集群,而后单击Projects/Namespaces。点击Add Namespace。输出 “kong-mesh-app” 作为名称,并蕴含一个带有 “kuma.io/sidecar-injection” 键和 “enabled” 作为其值的正文。
当然,你也能够抉择应用kubectl
kubectl create namespace kong-mesh-appkubectl annotate namespace kong-mesh-app kuma.io/sidecar-injection=enabledSubmit the following declaration to deploy Magnanimo injecting the Kong Mesh data planecat <<EOF | kubectl apply -f -apiVersion: apps/v1kind: Deploymentmetadata:name: magnanimonamespace: kong-mesh-appspec:replicas: 1selector:matchLabels:app: magnanimotemplate:metadata:labels:app: magnanimospec:containers:- name: magnanimoimage: claudioacquaviva/magnanimoports:- containerPort: 4000---apiVersion: v1kind: Servicemetadata:name: magnanimonamespace: kong-mesh-applabels:app: magnanimospec:type: ClusterIPports:- port: 4000name: httpselector:app: magnanimoEOF
应用Rancher Cluster Manager查看你的部署。将鼠标挪动至kong-rancher菜单上,点击Default我的项目,能够看到以后的部署状况:
点击magnanimo查看部署的细节,包含其pods:
点击magnanimo pod,查看其外部运行的容器。
咱们能够看到,pod有两个运行的容器:
- magnanimo:微服务理论运行的中央。
- kuma-sidecar:在部署的时候注入,作为Kong Mesh的数据立体。
同理,部署Benigno的时候,也有本人的sidecar:
cat <<EOF | kubectl apply -f -apiVersion: apps/v1kind: Deploymentmetadata:name: benigno-v1namespace: kong-mesh-appspec:replicas: 1selector:matchLabels:app: benignotemplate:metadata:labels:app: benignoversion: v1spec:containers:- name: benignoimage: claudioacquaviva/benignoports:- containerPort: 5000---apiVersion: v1kind: Servicemetadata:name: benignonamespace: kong-mesh-applabels:app: benignospec:type: ClusterIPports:- port: 5000name: httpselector:app: benignoEOFAnd finally, deploy Benigno canary release. Notice that the canary release will be abstracted by the same Benigno Kubernetes Service created before:cat <<EOF | kubectl apply -f -apiVersion: apps/v1kind: Deploymentmetadata:name: benigno-v2namespace: kong-mesh-appspec:replicas: 1selector:matchLabels:app: benignotemplate:metadata:labels:app: benignoversion: v2spec:containers:- name: benignoimage: claudioacquaviva/benigno\_rcports:- containerPort: 5000EOF
应用以下命令查看部署和Pods:
$ kubectl get pod --all-namespacesNAMESPACE NAME READY STATUS RESTARTS AGEcattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75mfleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75mkong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 110skong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 30skong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 5m3skong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16mkube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76mkube-system fluentbit-gke-xqsdv 2/2 Running 0 76mkube-system gke-metrics-agent-gjrqr 1/1 Running 0 76mkube-system konnectivity-agent-4c4hf 1/1 Running 0 76mkube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76mkube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76mkube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76mkube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76mkube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75mkube-system prometheus-to-sd-fdf9j 1/1 Running 0 76mkube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 75m$ kubectl get service --all-namespacesNAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdefault kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 79mkong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 4m6skong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 7m18skong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 18mkube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 79mkube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 79mkube-system metrics-server ClusterIP 10.0.20.174 <none> 443/TCP 79m
你也能够应用Kong Mesh控制台来查看微服务和数据立体。在Terminal上运行以下命令:
kubectl port-forward service/kuma-control-plane -n kong-mesh-system 5681
重定向你的浏览器到http://localhost:5681/gui。点... to Dashboard和All Data Plane Proxies:
启动一个循环,看看金丝雀公布的运行状况。留神服务曾经被部署为ClusterIP类型,所以你须要用 “port-forward”间接裸露它们。下一步将展现如何用Ingress Controller裸露服务。
在本地terminal上运行:
kubectl port-forward service/magnanimo -n kong-mesh-app 4000
关上另一个Terminal,开始循环。申请要到Magnanimo提供的4000端口。门路“/hw2 ”将申请路由到Benigno服务,它前面有两个endpoint,与Benigno两个版本无关:
while [1]; do curl http://localhost:4000/hw2; echo; done
你应该看到相似下方的后果:
Hello World, Benigno: 2020-11-20 12:57:05.811667Hello World, Benigno: 2020-11-20 12:57:06.304731Hello World, Benigno, Canary Release: 2020-11-20 12:57:06.789208Hello World, Benigno: 2020-11-20 12:57:07.269674Hello World, Benigno, Canary Release: 2020-11-20 12:57:07.755884Hello World, Benigno, Canary Release: 2020-11-20 12:57:08.240453Hello World, Benigno: 2020-11-20 12:57:08.728465Hello World, Benigno: 2020-11-20 12:57:09.208588Hello World, Benigno, Canary Release: 2020-11-20 12:57:09.689478Hello World, Benigno, Canary Release: 2020-11-20 12:57:10.179551Hello World, Benigno: 2020-11-20 12:57:10.662465Hello World, Benigno: 2020-11-20 12:57:11.145237Hello World, Benigno, Canary Release: 2020-11-20 12:57:11.618557Hello World, Benigno: 2020-11-20 12:57:12.108586Hello World, Benigno, Canary Release: 2020-11-20 12:57:12.596296Hello World, Benigno, Canary Release: 2020-11-20 12:57:13.093329Hello World, Benigno: 2020-11-20 12:57:13.593487Hello World, Benigno, Canary Release: 2020-11-20 12:57:14.068870
4、 管制金丝雀公布的老本
正如咱们所见,两个Benigno微服务公布的申请应用了循环策略。也就是说,咱们无法控制金丝雀公布的花销。Service Mesh容许咱们定义何时以及如何将金丝雀公布裸露给咱们的consumer(在本例中指Magnanimo微服务)。
要定义一个策略来管制流向两个版本的流量,须要应用上面这个申明。它说90%的流量应该流向以后版本,而只有10%的流量应该重定向到金丝雀公布。
cat <<EOF | kubectl apply -f -apiVersion: kuma.io/v1alpha1kind: TrafficRoutemesh: defaultmetadata:namespace: defaultname: route-1spec:sources:- match:kuma.io/service: magnanimo\_kong-mesh-app\_svc\_4000destinations:- match:kuma.io/service: benigno\_kong-mesh-app\_svc\_5000conf:split:- weight: 90destination:kuma.io/service: benigno\_kong-mesh-app\_svc\_5000version: v1- weight: 10destination:kuma.io/service: benigno\_kong-mesh-app\_svc\_5000version: v2EOF
利用申明之后,你应该看到如下后果:
Hello World, Benigno: 2020-11-20 13:05:02.553389Hello World, Benigno: 2020-11-20 13:05:03.041120Hello World, Benigno: 2020-11-20 13:05:03.532701Hello World, Benigno: 2020-11-20 13:05:04.021804Hello World, Benigno: 2020-11-20 13:05:04.515245Hello World, Benigno, Canary Release: 2020-11-20 13:05:05.000644Hello World, Benigno: 2020-11-20 13:05:05.482606Hello World, Benigno: 2020-11-20 13:05:05.963663Hello World, Benigno, Canary Release: 2020-11-20 13:05:06.446599Hello World, Benigno: 2020-11-20 13:05:06.926737Hello World, Benigno: 2020-11-20 13:05:07.410605Hello World, Benigno: 2020-11-20 13:05:07.890827Hello World, Benigno: 2020-11-20 13:05:08.374686Hello World, Benigno: 2020-11-20 13:05:08.857266Hello World, Benigno: 2020-11-20 13:05:09.337360Hello World, Benigno: 2020-11-20 13:05:09.816912Hello World, Benigno: 2020-11-20 13:05:10.301863Hello World, Benigno: 2020-11-20 13:05:10.782395Hello World, Benigno: 2020-11-20 13:05:11.262624Hello World, Benigno: 2020-11-20 13:05:11.743427Hello World, Benigno: 2020-11-20 13:05:12.221174Hello World, Benigno: 2020-11-20 13:05:12.705731Hello World, Benigno: 2020-11-20 13:05:13.196664Hello World, Benigno: 2020-11-20 13:05:13.680319
5、 装置Kong for Kubernetes
让咱们回到Rancher中装置咱们的Kong for Kubernetes Ingress Controller,并管制服务网格的裸露。在Rancher Catalog页面中,点击Kong图标。承受默认值,而后点击Launch:
你应该看到Kong和Kong Mesh这两个应用程序都曾经部署实现:
再次应用kubectl查看装置:
$ kubectl get pod --all-namespacesNAMESPACE NAME READY STATUS RESTARTS AGEcattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 84mfleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 83mkong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 10mkong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 8m47skong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 13mkong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 24mkong kong-kong-754cd6947-db2j9 2/2 Running 1 72skube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 85mkube-system fluentbit-gke-xqsdv 2/2 Running 0 84mkube-system gke-metrics-agent-gjrqr 1/1 Running 0 84mkube-system konnectivity-agent-4c4hf 1/1 Running 0 84mkube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 84mkube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 84mkube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 84mkube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 85mkube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 84mkube-system prometheus-to-sd-fdf9j 1/1 Running 0 84mkube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 84m$ kubectl get service --all-namespacesNAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEdefault kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 85mkong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 10mkong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 13mkong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 24mkong kong-kong-proxy LoadBalancer 10.0.26.38 35.222.91.194 80:31867/TCP,443:31039/TCP 78skube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 85mkube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 85mkube-system metrics-server ClusterIP 10.0.20.174 <none> 443/TCP 85m
6、 创立Ingress
通过上面的申明,咱们将通过一个Ingress和它的路由 “/route1” 来裸露Magnanimo微服务。
cat <<EOF | kubectl apply -f -apiVersion: extensions/v1beta1kind: Ingressmetadata:name: route1namespace: kong-mesh-appannotations:konghq.com/strip-path: "true"spec:rules:- http:paths:- path: /route1backend:serviceName: magnanimoservicePort: 4000EOF
当初,长期的 “port-forward” 裸露机制能够被正式的Ingress所取代。而咱们的循环也能够开始耗费Ingress,后果如下: