Istio服务网格技术解析与实践
上QQ阅读APP看书,第一时间看更新

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所示。