服务网格(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 AGE
cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75m
fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75m
kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16m
kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76m
kube-system fluentbit-gke-xqsdv 2/2 Running 0 76m
kube-system gke-metrics-agent-gjrqr 1/1 Running 0 76m
kube-system konnectivity-agent-4c4hf 1/1 Running 0 76m
kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76m
kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76m
kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76m
kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76m
kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75m
kube-system prometheus-to-sd-fdf9j 1/1 Running 0 76m
kube-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-app
kubectl annotate namespace kong-mesh-app kuma.io/sidecar-injection=enabled
Submit the following declaration to deploy Magnanimo injecting the Kong Mesh data plane
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: magnanimo
namespace: kong-mesh-app
spec:
replicas: 1
selector:
matchLabels:
app: magnanimo
template:
metadata:
labels:
app: magnanimo
spec:
containers:
- name: magnanimo
image: claudioacquaviva/magnanimo
ports:
- containerPort: 4000
---
apiVersion: v1
kind: Service
metadata:
name: magnanimo
namespace: kong-mesh-app
labels:
app: magnanimo
spec:
type: ClusterIP
ports:
- port: 4000
name: http
selector:
app: magnanimo
EOF
应用 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/v1
kind: Deployment
metadata:
name: benigno-v1
namespace: kong-mesh-app
spec:
replicas: 1
selector:
matchLabels:
app: benigno
template:
metadata:
labels:
app: benigno
version: v1
spec:
containers:
- name: benigno
image: claudioacquaviva/benigno
ports:
- containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: benigno
namespace: kong-mesh-app
labels:
app: benigno
spec:
type: ClusterIP
ports:
- port: 5000
name: http
selector:
app: benigno
EOF
And 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/v1
kind: Deployment
metadata:
name: benigno-v2
namespace: kong-mesh-app
spec:
replicas: 1
selector:
matchLabels:
app: benigno
template:
metadata:
labels:
app: benigno
version: v2
spec:
containers:
- name: benigno
image: claudioacquaviva/benigno\_rc
ports:
- containerPort: 5000
EOF
应用以下命令查看部署和 Pods:
$ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 75m
fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 75m
kong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 110s
kong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 30s
kong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 5m3s
kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 16m
kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 76m
kube-system fluentbit-gke-xqsdv 2/2 Running 0 76m
kube-system gke-metrics-agent-gjrqr 1/1 Running 0 76m
kube-system konnectivity-agent-4c4hf 1/1 Running 0 76m
kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 76m
kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 76m
kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 76m
kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 76m
kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 75m
kube-system prometheus-to-sd-fdf9j 1/1 Running 0 76m
kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 75m
$ kubectl get service --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 79m
kong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 4m6s
kong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 7m18s
kong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 18m
kube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 79m
kube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 79m
kube-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.811667
Hello World, Benigno: 2020-11-20 12:57:06.304731
Hello World, Benigno, Canary Release: 2020-11-20 12:57:06.789208
Hello World, Benigno: 2020-11-20 12:57:07.269674
Hello World, Benigno, Canary Release: 2020-11-20 12:57:07.755884
Hello World, Benigno, Canary Release: 2020-11-20 12:57:08.240453
Hello World, Benigno: 2020-11-20 12:57:08.728465
Hello World, Benigno: 2020-11-20 12:57:09.208588
Hello World, Benigno, Canary Release: 2020-11-20 12:57:09.689478
Hello World, Benigno, Canary Release: 2020-11-20 12:57:10.179551
Hello World, Benigno: 2020-11-20 12:57:10.662465
Hello World, Benigno: 2020-11-20 12:57:11.145237
Hello World, Benigno, Canary Release: 2020-11-20 12:57:11.618557
Hello World, Benigno: 2020-11-20 12:57:12.108586
Hello World, Benigno, Canary Release: 2020-11-20 12:57:12.596296
Hello World, Benigno, Canary Release: 2020-11-20 12:57:13.093329
Hello World, Benigno: 2020-11-20 12:57:13.593487
Hello 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/v1alpha1
kind: TrafficRoute
mesh: default
metadata:
namespace: default
name: route-1
spec:
sources:
- match:
kuma.io/service: magnanimo\_kong-mesh-app\_svc\_4000
destinations:
- match:
kuma.io/service: benigno\_kong-mesh-app\_svc\_5000
conf:
split:
- weight: 90
destination:
kuma.io/service: benigno\_kong-mesh-app\_svc\_5000
version: v1
- weight: 10
destination:
kuma.io/service: benigno\_kong-mesh-app\_svc\_5000
version: v2
EOF
利用申明之后,你应该看到如下后果:
Hello World, Benigno: 2020-11-20 13:05:02.553389
Hello World, Benigno: 2020-11-20 13:05:03.041120
Hello World, Benigno: 2020-11-20 13:05:03.532701
Hello World, Benigno: 2020-11-20 13:05:04.021804
Hello World, Benigno: 2020-11-20 13:05:04.515245
Hello World, Benigno, Canary Release: 2020-11-20 13:05:05.000644
Hello World, Benigno: 2020-11-20 13:05:05.482606
Hello World, Benigno: 2020-11-20 13:05:05.963663
Hello World, Benigno, Canary Release: 2020-11-20 13:05:06.446599
Hello World, Benigno: 2020-11-20 13:05:06.926737
Hello World, Benigno: 2020-11-20 13:05:07.410605
Hello World, Benigno: 2020-11-20 13:05:07.890827
Hello World, Benigno: 2020-11-20 13:05:08.374686
Hello World, Benigno: 2020-11-20 13:05:08.857266
Hello World, Benigno: 2020-11-20 13:05:09.337360
Hello World, Benigno: 2020-11-20 13:05:09.816912
Hello World, Benigno: 2020-11-20 13:05:10.301863
Hello World, Benigno: 2020-11-20 13:05:10.782395
Hello World, Benigno: 2020-11-20 13:05:11.262624
Hello World, Benigno: 2020-11-20 13:05:11.743427
Hello World, Benigno: 2020-11-20 13:05:12.221174
Hello World, Benigno: 2020-11-20 13:05:12.705731
Hello World, Benigno: 2020-11-20 13:05:13.196664
Hello 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-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
cattle-system cattle-cluster-agent-785fd5f54d-r7x8r 1/1 Running 0 84m
fleet-system fleet-agent-77c78f9c74-f97tv 1/1 Running 0 83m
kong-mesh-app benigno-v1-fd4567d95-drnxq 2/2 Running 0 10m
kong-mesh-app benigno-v2-b977c867b-lpjpw 2/2 Running 0 8m47s
kong-mesh-app magnanimo-658b67fb9b-tzsjp 2/2 Running 0 13m
kong-mesh-system kuma-control-plane-5b9c6f4598-nvq8q 1/1 Running 0 24m
kong kong-kong-754cd6947-db2j9 2/2 Running 1 72s
kube-system event-exporter-gke-666b7ffbf7-n9lfl 2/2 Running 0 85m
kube-system fluentbit-gke-xqsdv 2/2 Running 0 84m
kube-system gke-metrics-agent-gjrqr 1/1 Running 0 84m
kube-system konnectivity-agent-4c4hf 1/1 Running 0 84m
kube-system kube-dns-66d6b7c877-tq877 4/4 Running 0 84m
kube-system kube-dns-autoscaler-5c78d65cd9-5hcxs 1/1 Running 0 84m
kube-system kube-proxy-gke-c-kpwnf-default-0-be059c1c-49qp 1/1 Running 0 84m
kube-system l7-default-backend-5b76b455d-v6dvg 1/1 Running 0 85m
kube-system metrics-server-v0.3.6-547dc87f5f-qntjf 2/2 Running 0 84m
kube-system prometheus-to-sd-fdf9j 1/1 Running 0 84m
kube-system stackdriver-metadata-agent-cluster-level-68d94db6-64n4r 2/2 Running 1 84m
$ kubectl get service --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.16.1 <none> 443/TCP 85m
kong-mesh-app benigno ClusterIP 10.0.20.52 <none> 5000/TCP 10m
kong-mesh-app magnanimo ClusterIP 10.0.30.251 <none> 4000/TCP 13m
kong-mesh-system kuma-control-plane ClusterIP 10.0.21.228 <none> 5681/TCP,5682/TCP,443/TCP,5676/TCP,5678/TCP,5653/UDP 24m
kong kong-kong-proxy LoadBalancer 10.0.26.38 35.222.91.194 80:31867/TCP,443:31039/TCP 78s
kube-system default-http-backend NodePort 10.0.19.10 <none> 80:32296/TCP 85m
kube-system kube-dns ClusterIP 10.0.16.10 <none> 53/UDP,53/TCP 85m
kube-system metrics-server ClusterIP 10.0.20.174 <none> 443/TCP 85m
6、创立 Ingress
通过上面的申明,咱们将通过一个 Ingress 和它的路由“/route1”来裸露 Magnanimo 微服务。
cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: route1
namespace: kong-mesh-app
annotations:
konghq.com/strip-path: "true"
spec:
rules:
- http:
paths:
- path: /route1
backend:
serviceName: magnanimo
servicePort: 4000
EOF
当初,长期的“port-forward”裸露机制能够被正式的 Ingress 所取代。而咱们的循环也能够开始耗费 Ingress,后果如下: