介绍
在引入新版本的服务时,在逐步淘汰旧版本的过程中,通常需要将受控的用户流量的百分比转移到新版本的服务。
Kubernetes集群操作员可以自行使用标签和部署进行指定部署。 然而,这一技术有某些局限性:流量分配和复制计数是结合的,这实际上意味着复制比率必须人工控制,以便限制流量到金丝雀放行. 换句话说,要将10%的交通量用于金丝雀部署,你需要有一个10个舱位的集合,一个舱位接收10%的用户流量,另外9个舱位接收其余的.
使用 Istio服务网格部署可以通过允许复制件数和流量管理之间的清晰分离来解决这个问题。Istio网格允许精细的流量控制,将流量分布和管理从复制件规模化中分离出来。
在本教程中,您将使用 Istio 和 Kubernetes 创建一个 Canary 部署,您将部署两个版本的演示应用程序 Node.js,并使用 Virtual Service 和 Destination Rule 资源来配置流量路由到新版本和旧版本。
前提条件
- 启用了基于角色访问控制(RBAC)的 Kubernetes 1.10+ 集群. 此设置将使用三个节点的 DigitalOcean Kubernetes 集群,但您可以自由地使用其他方法创建一个集群(https://andsky.com/tech/tutorials/how-to-create-a-kubernetes-1-11-cluster-using-kubeadm-on-ubuntu-18-04)。
<$>[注] 注: 我们强烈建议为此设置使用至少8GB可用内存和4vCPU的集群。
- 联合国
kubectl' 命令行工具安装在一个开发服务器上,并配置到连接到您的集群。 您可以在 [官方文档] (https://kubernetes.io/docs/tasks/tools/install-kubectl/ 中读取更多关于安装
kubectl` 的内容。 - 安装在您的开发服务器上。 如果您与 Ubuntu 18.04 合作, 请遵循 [如何在 Ubuntu 18. 04 上安装和使用 Docker (https://andsky.com/tech/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04) 步骤 1 和 2 ; 否则, 请遵循 [正式文件] (https://docs.docker.com/install/) , 以了解安装其他操作系统的信息 。 如链接教程步骤2所描述的,请将您的非根用户添加到
docker
组中 。 - ADocker Hub账户。 有关如何设置的概述,请参见 [本引言 (https://docs.docker.com/docker-hub/)到多克枢纽.
- Istio按照[如何安装和使用Istio With Kubernetes(https://andsky.com/tech/tutorials/how-to-install-and-use-istio-with-kubernetes)中的指示安装和配置。 您还应当启用和配置用于外部访问的 [Grafana] (https://grafana.com/ ) 遥测加通。 .
步骤1 - 包装应用程序
在前提教程中, How To Install and Use Istio With Kubernetes,你 创建了一个节点演示
的Docker图像运行一个鲨鱼信息应用程序,并将此图像推到Docker Hub。
我们的原始演示应用程序在其 Shark Info 页面上强调了一些关于鲨鱼的友好事实:
但是,我们决定在我们新的加拿大版本中强调一些更可怕的事实:
我们的第一步是将这个应用程序的第二个版本的代码克隆到一个名为node_image
的目录中。 使用以下命令,将 nodejs-canary-app repository从 DigitalOcean Community GitHub 帐户克隆出来。
1git clone https://github.com/do-community/nodejs-canary-app.git node_image
导航到node_image
目录:
1cd node_image
该目录包含了我们最新版本的鲨鱼信息应用程序的文件和文件夹,该目录为用户提供关于鲨鱼的信息,就像原始应用程序一样,但强调了可怕的事实。
要测试应用程序代码和 Dockerfile 是否按预期工作,您可以使用 docker build
命令构建和标记图像,然后使用图像运行演示容器。
用以下命令构建图像:
1docker build -t your_dockerhub_username/node-demo-v2 .
命令中的 .
表示构建背景是当前的目录. 我们已将图像命名为 node-demo-v2
,以参考在 How To Install and Use Istio With Kubernetes中所创建的 node-demo
图像。
一旦构建过程完成,您可以将您的图像列为 docker images
:
1docker images
您将看到以下输出,确认图像构建:
1[secondary_label Output]
2REPOSITORY TAG IMAGE ID CREATED SIZE
3your_dockerhub_username/node-demo-v2 latest 37f1c2939dbf 5 seconds ago 77.6MB
4node 10-alpine 9dfa73010b19 2 days ago 75.3MB
接下来,您将使用docker run
创建一个基于此图像的容器,我们将包含三个旗帜以此命令:
-p
:这将发布集装箱上的端口,并将其地图到我们的主机上的端口。我们将使用端口80
在主机上,但如果您有其他过程在该端口上运行的情况下,您可以随意修改该端口。
运行以下命令来构建容器:
1docker run --name node-demo-v2 -p 80:8080 -d your_dockerhub_username/node-demo-v2
检查您的运行容器用 docker ps
:
1docker ps
您将看到确认您的应用程序容器正在运行的输出:
1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
349a67bafc325 your_dockerhub_username/node-demo-v2 "docker-entrypoint.s…" 8 seconds ago Up 6 seconds 0.0.0.0:80->8080/tcp node-demo-v2
您现在可以在浏览器中访问您的服务器 IP 来测试您的设置:http://your_server_ip`. 您的应用程序将显示以下定位页面:
点击获取鲨鱼信息
按钮,进入恐怖鲨鱼信息:
现在你已经测试了应用程序,你可以停止运行容器. 再次使用docker ps
来获取你的CONTAINER ID
:
1docker ps
1[secondary_label Output]
2CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
349a67bafc325 your_dockerhub_username/node-demo-v2 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:80->8080/tcp node-demo-v2
请确保将这里列出的CONTAINER ID
替换为自己的应用程序CONTAINER ID
:
1docker stop 49a67bafc325
现在您已经测试了图像,您可以将其推到 Docker Hub. 首先,请在前提条件下登录您创建的 Docker Hub 帐户:
1docker login -u your_dockerhub_username
当被提示时,请输入您的 Docker Hub 帐户密码. 以此方式登录将创建一个 ~/.docker/config.json
文件,在您的非根用户的主目录中与您的 Docker Hub 凭证。
使用 docker push
命令将应用程序图像推到 Docker Hub。 请记住用自己的 Docker Hub 用户名替换 your_dockerhub_username
:
1docker push your_dockerhub_username/node-demo-v2
现在你有两个应用程序图像存储到Docker Hub:node-demo
图像和node-demo-v2
。我们现在将修改你在前提教程中创建的宣言(How To Install and Use Istio With Kubernetes)(https://andsky.com/tech/tutorials/how-to-install-and-use-istio-with-kubernetes),以将流量引导到你的应用程序的加拿大版本。
步骤 2 — 更改应用部署
在 How To Install and Use Istio With Kubernetes,您为您的应用程序 Service和 Deployment对象创建了一个应用程序 manifest specifications。
当您遵循前提教程中的设置指示时,您创建了一个名为istio_project
的目录和两个yaml
示例:node-app.yaml
,其中包含服务和部署对象的规格,以及node-istio.yaml
,其中包含您的Istio虚拟服务和网关资源的规格。
现在导航到istio_project
目录:
1cd
2cd istio_project
使用nano
或您最喜欢的编辑器打开node-app.yaml
,以便对您的应用程序进行更改:
1nano node-app.yaml
目前,檔案看起來如下:
1[label ~/istio_project/node-app.yaml]
2apiVersion: v1
3kind: Service
4metadata:
5 name: nodejs
6 labels:
7 app: nodejs
8spec:
9 selector:
10 app: nodejs
11 ports:
12 - name: http
13 port: 8080
14---
15apiVersion: apps/v1
16kind: Deployment
17metadata:
18 name: nodejs
19 labels:
20 version: v1
21spec:
22 replicas: 1
23 selector:
24 matchLabels:
25 app: nodejs
26 template:
27 metadata:
28 labels:
29 app: nodejs
30 version: v1
31 spec:
32 containers:
33 - name: nodejs
34 image: your_dockerhub_username/node-demo
35 ports:
36 - containerPort: 8080
对于本文件的内容的完整解释,请参阅 步骤 3的 如何安装和使用Istio与Kubernetes 。
我们已经在我们的部署元数据
和模板
字段中包含了版本标签,随后我们可以为第二个部署对象添加规格,这将代表我们的应用程序的第二个版本,并快速更改我们的第一个部署对象的名称
。
首先,更改现有部署对象的名称为nodejs-v1
:
1[label ~/istio_project/node-app.yaml]
2...
3apiVersion: apps/v1
4kind: Deployment
5metadata:
6 name: nodejs-v1
7 labels:
8 version: v1
9...
接下来,在本部署的规格下方,添加您第二次部署的规格。
1[label ~/istio_project/node-app.yaml]
2...
3---
4apiVersion: apps/v1
5kind: Deployment
6metadata:
7 name: nodejs-v2
8 labels:
9 version: v2
10spec:
11 replicas: 1
12 selector:
13 matchLabels:
14 app: nodejs
15 template:
16 metadata:
17 labels:
18 app: nodejs
19 version: v2
20 spec:
21 containers:
22 - name: nodejs
23 image: your_dockerhub_username/node-demo-v2
24 ports:
25 - containerPort: 8080
与第一个部署一样,本部署使用版本
标签来指定与本部署相符的应用程序版本.在这种情况下,v2
将区分与本部署相关的应用程序版本,而v1
则与我们的第一个部署相符。
我们还确保了由v2
部署管理的 Pods将运行我们在上一个步骤中构建的node-demo-v2
卡纳里图像。
保存并关闭文件,当你完成编辑。
隨著您的應用程式變更,您可以繼續對您的 node-istio.yaml
檔案進行變更。
第3步:使用虚拟服务衡量流量并添加目的地规则
在 How To Install and Use Istio With Kubernetes中,您创建了网关和虚拟服务对象,以允许外部流量进入 Istio 网格,并将其路由到您的应用程序服务中。
打开node-istio.yaml
文件:
1nano node-istio.yaml
目前,檔案看起來如下:
1[label ~/istio_project/node-istio.yaml]
2apiVersion: networking.istio.io/v1alpha3
3kind: Gateway
4metadata:
5 name: nodejs-gateway
6spec:
7 selector:
8 istio: ingressgateway
9 servers:
10 - port:
11 number: 80
12 name: http
13 protocol: HTTP
14 hosts:
15 - "*"
16---
17apiVersion: networking.istio.io/v1alpha3
18kind: VirtualService
19metadata:
20 name: nodejs
21spec:
22 hosts:
23 - "*"
24 gateways:
25 - nodejs-gateway
26 http:
27 - route:
28 - destination:
29 host: nodejs
对于本宣言中的规格的完整解释,请参阅 步骤 4的 如何安装和使用Istio与Kubernetes 。
目前,这个资源通过我们的nodejs-gateway
向我们的nodejs
应用程序服务路由流量进入网格,我们想做的是配置一条路由规则,将 80% 的流量发送到我们的原始应用程序,20%发送到更新的版本。
作为我们在原始宣言中所做的,我们将为我们的应用程序子集添加目的地
字段,而不是向一个单一的目的地
:原始版本(‘v1’)和加纳语(‘v2’)。
对虚拟服务进行以下添加以创建此路由规则:
1[label ~/istio_project/node-istio.yaml]
2...
3apiVersion: networking.istio.io/v1alpha3
4kind: VirtualService
5metadata:
6 name: nodejs
7spec:
8 hosts:
9 - "*"
10 gateways:
11 - nodejs-gateway
12 http:
13 - route:
14 - destination:
15 host: nodejs
16 subset: v1
17 weight: 80
18 - destination:
19 host: nodejs
20 subset: v2
21 weight: 20
我们添加的策略包括两个目的地:我们nodejs
服务的子集
运行我们的应用程序的原始版本v1
和运行的canary
的子集``v2
。
接下来,我们将添加一个目的地规则,该规则将在流量被路由到相应的服务后应用于流量。
在您的虚拟服务定义下方添加以下代码:
1[label ~/istio_project/node-istio.yaml]
2...
3---
4apiVersion: networking.istio.io/v1alpha3
5kind: DestinationRule
6metadata:
7 name: nodejs
8spec:
9 host: nodejs
10 subsets:
11 - name: v1
12 labels:
13 version: v1
14 - name: v2
15 labels:
16 version: v2
我们的规则确保我们的服务子集v1
和v2
的流量以适当的标签到达Pod:版本:v1
和版本:v2
。
但是,如果我们愿意,我们也可以在子集级别应用特定的交通政策,从而在我们的加那利地区部署中提供进一步的具体性。
保存并关闭文件,当你完成编辑。
随着应用程序宣言的修订,您已经准备好应用配置更改,并使用Grafana远程测量插件检查应用程序流量数据。
步骤 4 — 应用配置更改和访问流量数据
应用程序宣言正在更新,但我们仍然需要将这些更改应用到我们的Kubernetes集群中。我们将使用命令 kubectl apply
来应用我们的更改,而不会完全重写现有配置。
将配置应用于您的应用程序服务和部署对象:
1kubectl apply -f node-app.yaml
您将看到以下结果:
1[secondary_label Output]
2service/nodejs unchanged
3deployment.apps/nodejs-v1 created
4deployment.apps/nodejs-v2 created
接下来,将您所做的配置更新应用于 `node-istio.yaml',其中包括对虚拟服务和新目的地规则的更改:
1kubectl apply -f node-istio.yaml
您将看到以下结果:
1[secondary_label Output]
2gateway.networking.istio.io/nodejs-gateway unchanged
3virtualservice.networking.istio.io/nodejs configured
4destinationrule.networking.istio.io/nodejs created
但是,在这样做之前,先检查,以确保您有grafana
服务运行:
1kubectl get svc -n istio-system | grep grafana
1[secondary_label Output]
2grafana ClusterIP 10.245.233.51 <none> 3000/TCP 4d2h
也检查相关的Pods:
1kubectl get svc -n istio-system | grep grafana
1[secondary_label Output]
2grafana-67c69bb567-jpf6h 1/1 Running 0 4d2h
最后,检查grafana-gateway
网关和grafana-vs
虚拟服务:
1kubectl get gateway -n istio-system | grep grafana
1[secondary_label Output]
2grafana-gateway 3d5h
1kubectl get virtualservice -n istio-system | grep grafana
1[secondary_label Output]
2grafana-vs [grafana-gateway] [*] 4d2h
如果您看不到这些命令的输出,请查看 如何安装和使用 Istio 与 Kubernetes的步骤 2和 5,这些步骤讨论如何在安装 Istio 时启用 Grafana 远程扩展,以及如何启用 HTTP 访问 Grafana 服务。
您现在可以在浏览器中访问您的应用程序。 要做到这一点,您需要与您的istio-ingressgateway
服务相关的外部 IP,这是一个 LoadBalancer 服务类型。 在 How To Install and Use Istio With Kubernetes中写我们的Gateway 宣言
时,我们与这个控制器匹配了我们的nodejs-gateway
通道。 有关通道宣言的更多细节,请参阅该教程的 Step 4。
使用以下命令获取istio-ingressgateway
服务的外部 IP:
1kubectl get svc -n istio-system
你会看到这样的输出:
1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
3grafana ClusterIP 10.245.85.162 <none> 3000/TCP 42m
4istio-citadel ClusterIP 10.245.135.45 <none> 8060/TCP,15014/TCP 42m
5istio-galley ClusterIP 10.245.46.245 <none> 443/TCP,15014/TCP,9901/TCP 42m
6istio-ingressgateway LoadBalancer 10.245.171.39 ingressgateway_ip 15020:30707/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:30285/TCP,15030:31668/TCP,15031:32297/TCP,15032:30853/TCP,15443:30406/TCP 42m
7istio-pilot ClusterIP 10.245.56.97 <none> 15010/TCP,15011/TCP,8080/TCP,15014/TCP 42m
8istio-policy ClusterIP 10.245.206.189 <none> 9091/TCP,15004/TCP,15014/TCP 42m
9istio-sidecar-injector ClusterIP 10.245.223.99 <none> 443/TCP 42m
10istio-telemetry ClusterIP 10.245.5.215 <none> 9091/TCP,15004/TCP,15014/TCP,42422/TCP 42m
11prometheus ClusterIP 10.245.100.132 <none> 9090/TCP 42m
istio-ingressgateway
应该是唯一具有TYPE``LoadBalancer
的服务,也是唯一具有外部IP的服务。
在您的浏览器中导航到此外部 IP: http://ingressgateway_ip
。
你应该看到下面的登陆页面:
点击获取鲨鱼信息
按钮,您将看到两个鲨鱼信息页面之一:
点击此页面上更新几次. 您应该比更可怕的版本更频繁地看到更友好的鲨鱼信息页面。
一旦你通过刷新五次或六次产生了一些负荷,你可以转向你的Grafana仪表板。
在您的浏览器中,导航到以下地址,再次使用您的istio-ingressgateway
外部IP和在Grafana Gateway中定义的端口: http://ingressgateway_ip:15031
。
您将看到以下登陆页面:
点击页面顶部的 主页 将带您到一个具有 ** istio** 文件夹的页面. 要查看下载选项的列表,请点击 ** istio** 文件夹图标:
从此选项列表中,单击 Istio 服务仪表板 。
这将带你到一个定位页面,另一个下载菜单:
从可用的选项列表中选择nodejs.default.svc.cluster.local
。
如果您导航到页面的服务工作负载
部分,您将能够查看目的地和响应代码
中的接收请求
:
在这里,你会看到200和304 HTTP响应代码的组合,表示成功的OK
和未修改
响应.标记为nodejs-v1
的响应应该超过标记为nodejs-v2
的响应,这表明流量正在根据我们在宣言中定义的参数向我们的应用程序子集路由。
结论
在本教程中,您使用 Istio 和 Kubernetes 部署了 Node.js 演示应用程序的谷歌版本,您创建了虚拟服务和目的地规则资源,使您能够将 80% 的流量发送到原始应用程序服务和 20% 到更新的版本。
有关 Istio 交通管理的更多信息,请参阅文档中的相关 高级概述,以及使用 Istio 的 bookinfo
和 helloworld
样本应用的具体示例。