2.4 在Istio中部署第一个应用程序
在开始之前,确认上述Kubernetes集群中的Istio安装部署完毕,并正常启动。接下来我们在Istio环境中正式部署第一个应用程序。该示例应用是一个面向用户的投票应用程序,提供了两个投票选项:对于Istio和其他的服务网格你更喜欢哪个?此外,还有一个用于保存各个选项的投票数的存储组件,以及一个用于提供各个选项的投票详细信息的分析组件。
首先将部署投票应用程序的1.0版本及分析组件的1.0版本。此分析组件将对投票数进行简单计数。投票应用和分析组件与由Redis支持的存储组件1.0版本进行交互。
然后,将分析组件升级到提供计数和当前总数及百分比的2.0版本。一部分用户将通过灰度发布测试应用的2.0版本。确信该2.0版本按预期方式作用于该部分用户后,向所有用户推出2.0版本。
1.部署应用程序1.0版本
首先将应用程序部署到安装了Istio的Kubernetes集群中,可以是上述章节中介绍的Minikube、Docker Desktop for Kubernetes,也可以是公有云上的Kubernetes集群等。图2-17说明了本部分结束时运行的内容:所有组件的1.0版本及由Istio Ingress网关维护的入站请求。
图2-17 部署应用程序1.0的组件
该示例应用所需的项目可在GitHub存储库中获取,具体地址为https://github.com/osswangxining/istio-book。下载这些项目或克隆该存储库,并转到下载/克隆的存储库中的以下文件夹中,从此文件夹中运行所有后续步骤,如下所示:
cd/intelligent-routing-with-istio
首先,在Kubernetes集群中为投票应用示例创建命名空间,并命名为“voting”,如下所示:
kubectl create namespace voting
为此命名空间添加一个标签istio-injection=enabled,这个标签会指示Istio自动将Istio代理作为Sidecar注入到此命名空间中的所有pod中,如下所示
kubectl label namespace voting istio-injection=enabled
现在,我们将创建投票应用的组件,在上一个步骤所创建的voting命名空间中创建这些组件,执行如下命令:
kubectl apply -f kubernetes/step-1-create-voting-app.yaml --namespace voting
下面的示例输出说明已成功创建资源:
deployment.apps/voting-storage-1-0 created service/voting-storage created deployment.apps/voting-analytics-1-0 created service/voting-analytics created deployment.apps/voting-app-1-0 created service/voting-app created
使用kubectl get pods命令查看示例应用已创建的pod是否启动正常,如下所示:
kubectl get pods -n voting NAME READY STATUS RESTARTS AGE voting-analytics-1-0-645cfc8475-qb5l7 2/2 Running 0 3m voting-app-1-0-57f867bbd5-dt9z4 2/2 Running 0 3m voting-storage-1-0-f775b5df7-vjzh4 2/2 Running 0 3m
上面的示例输出显示了有三个pod实例,分别为一个投票应用pod实例、一个投票分析pod实例和一个投票存储pod实例。每个pod有两个容器,一个容器是组件,另一个是Istio代理。
使用kubectl describe pod查看pod的相关信息。将pod名称替换为前面输出的集群内的某个pod的名称,如下所示:
kubectl describe pod --namespace voting voting-app-1-0-..........
为了能在外部访问示例应用,需要创建Istio网关和虚拟服务。网关是位于服务网格边缘的组件,用于接收入站或出站HTTP和TCP流量。虚拟服务将定义一组适用于一个或多个目标服务的路由规则。这些Istio资源将来自默认Istio Ingress网关的流量路由到应用程序。
使用如下命令部署网关和虚拟服务yaml:
kubectl apply -f istio/step-1-create-voting-app-gateway.yaml --namespace voting
以Minikube或者公有云支持负载均衡器的Kubernetes为例,使用下面的命令获取Istio入口网关的端口:
使用http时的端口:
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
或者启用https时的端口:
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
如果使用的是公有云的Istio环境,例如阿里云容器服务上的托管Istio服务,并且启用了带有公网地址的负载均衡器,那么可以直接使用入口网关服务对应的负载均衡的地址和端口80来访问,如地址为http://121.41.17.241:80。
如果使用的是Docker Desktop for Kubernetes,那么打开浏览器,直接访问http://localhost,将显示投票应用示例,如图2-18所示。
图2-18 显示投票应用示例
屏幕底部的信息显示应用使用投票应用的1.0版本,并使用版本1.0(Redis)作为存储选项。
2.部署应用程序2.0版本
现在,我们来部署投票应用voting-app的新版本2.0,如图2-19所示。为简单起见,voting-app的2.0版本与1.0版本相比,去掉了页面下部的说明信息。同时,针对2.0版本做一定的约束,现在投票应用组件支持功能标记特性(通过cookie使用功能标记管理进行更改),可使用此功能标记针对用户子集测试Istio的灰度发布功能。只有已设置特定功能标记的用户可以访问投票应用组件的2.0版本,其他的请求仍然访问1.0版本。
图2-19 部署应用版本2.0
首先,更新Istio目标规则和虚拟服务,以适用于这些新组件。这些更新将确保不会以错误的方式将流量路由到新组件,并确保用户不会获得不需要的访问,命令如下所示:
kubectl apply -f istio/step-2a-update-voting-app-virtualservice.yaml --namespace voting
注意,该Istio资源定义了新的虚拟服务,描述了通过cookie进行限制的规则,代码如下:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: voting-app spec: hosts: - "*" gateways: - voting-app-gateway http: - match: - uri: prefix: / headers: cookie: regex: ".*(featureflag=on).*" route: - destination: host: voting-app.voting.svc.cluster.local subset: v2-0 port: number: 8080 - match: - uri: prefix: / rewrite: uri: / route: - destination: host: voting-app.voting.svc.cluster.local subset: v1-0 port: number: 8080
此外,还将策略添加到命名空间voting,以确保使用双向TLS和客户端证书保护服务之间的所有通信。使用kubectl create命令添加适用于所有其他组件的新策略以及新目标规则和虚拟服务。
其中,策略将peers.mtls.mode设置为STRICT,以确保在命名空间voting内的服务之间执行双向TLS。此外,还在所有目标规则中将traff icPolicy.tls.mode设置为ISTIO_MUTUAL。Istio为服务提供强标识,并使用双向TLS和客户端证书,以保障Istio以透明方式管理的服务之间进行通信。执行命令如下:
kubectl apply -f istio/step-2b-add-routing-for-all-components.yaml --namespace voting
关于虚拟服务(VirtualService)、目标规则(DestinationRule)、策略(Policy)的具体含义会在后续章节中详细介绍,在此简单归纳如下:
●虚拟服务将定义一组适用于一个或多个目标服务的路由规则。
●目标规则定义流量策略和特定于版本的策略。
●策略定义工作负载可以接受的身份验证方法。
接下来,为投票应用voting-app的2.0版本添加Kubernetes对象,执行如下命令:
kubectl apply -f kubernetes/step-2-update-voting-app-to-2.0.yaml --namespace voting
当2.0版本的pod处于运行状态之后,打开浏览器,直接访问上述步骤中用到的入口网关地址,将仍然显示投票应用示例的1.0版本,如图2-20所示。
图2-20 显示1.0版
点击页面下方的set链接,此时会创建一个cookie(名称为featuref lag,值为on),页面会跳转到2.0版本,如图2-21所示。
图2-21 显示2.0版
注意
只有清除掉该cookie,页面才会跳转到版本1.0,可以通过浏览器cookie清除功能去掉。
3.部署分析组件2.0版本
接下来,我们来部署分析组件的新版本。除每个类别的计数外,2.0版本还显示总数和百分比。
图2-22显示了此部分结束时运行的内容:仅投票分析组件的2.0版本具有路由自投票应用组件的流量。即使投票分析组件的1.0版本继续运行,并且投票分析服务引用了它,Istio代理也禁用它的往返流量。
图2-22 部署分析组件2.0
在voting命名空间中部署投票分析组件的2.0版本,执行如下命令:
kubectl apply -f kubernetes/step-2-update-voting-analytics-to-2.0.yaml --namespace voting
使用kubectl命令替换示例应用的虚拟服务定义,并添加适用于其他组件的目标规则和虚拟服务。由于存在要替换的投票应用的现有虚拟服务定义,因此使用kubectl replace命令,如下所示:
kubectl replace -f istio/step-3-add-routing-for-2.0-components.yaml --namespace voting
使用前面步骤中获取的Istio Ingress网关的IP地址与端口,重新在浏览器中打开应用示例。浏览器在两个版本页面之间交替。由于将Kubernetes服务用于了投票分析组件,并且仅有单个标签选择器(app:voting-analytics),因此Kubernetes在匹配该选择器的pod之间使用轮询机制的默认行为。在此示例中为投票分析pod的1.0版本和2.0版本。
投票分析服务的1.0版本只显示简单的计数,如图2-23所示。
图2-23 显示简单的计数
投票分析服务的2.0版本除了显示简单的计数之外,还会显示当前总数及百分比,如图2-24所示。
图2-24 显示百分数
此时,查看Kubernetes集群中的容器状态,可以得到如图2-25的结果。
图2-25 查看Kubernetes集群中的容器状态
4.全部切换到2.0版本
当前的存储服务仍然为1.0版本,我们也可以用类似方法部署2.0版本,并进行灰度流量切换。成功测试灰度发布后,更新投票应用虚拟服务,以将所有流量路由到投票应用组件的2.0版本。无论是否设置了功能标记,所有用户均会看到应用程序的2.0版本,如图2-26所示。
图2-26 全部切换到2.0版本的过程
更新所有的目标规则,以删除不想要激活的组件版本。然后更新所有虚拟服务,以停止引用这些版本,如图2-27所示。由于不再有任何流量到达这些组件的任何旧版本,因此现在可以安全地删除这些组件的所有部署。
图2-27 更新所有虚拟服务的过程
使用kubectl命令替换示例应用的虚拟服务定义,并添加适用于其他组件的目标规则和虚拟服务。由于存在要替换的投票应用的现有虚拟服务定义,因此使用kubectl replace命令,如下所示:
kubectl apply -f istio/step-4-update-voting-app-virtualservice.yaml --namespace voting
打开浏览器,直接访问上述步骤中用到的入口网关地址,将显示投票应用示例的2.0版本,如图2-28所示。