Istio(十三):Istio项目实际案例——Online Boutique

一.模块概览

在本模块中,我们将部署名为 Online Boutique 的微服务应用程序,试用 Istio 的不同功能。

Online Boutique 是一个云原生微服务演示应用程序。Online Boutique 是一个由 10 个微服务组成的应用。该应用是一个基于 Web 的电子商务应用,用户可以浏览商品,将其添加到购物车,并购买商品。

二.系统环境

服务器版本 docker软件版本 Kubernetes(k8s)集群版本 Istio软件版本 CPU架构
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 Istio1.14 x86_64

三.创建Kubernetes(k8s)集群

3.1 创建Kubernetes(k8s)集群

我们需要一套可以正常运行的Kubernetes集群,关于Kubernetes(k8s)集群的安装部署,可以查看博客《Centos7 安装部署Kubernetes(k8s)集群》https://www.cnblogs.com/renshengdezheli/p/16686769.html

3.2 Kubernetes集群环境

Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点

服务器 操作系统版本 CPU架构 进程 功能描述
k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

四.安装istio

4.1 安装Istio

Istio最新版本为1.15,因为我们Kubernetes集群版本为1.21.9,所以我们选择安装Istio 1.14版本。

[root@k8scloude1 ~]# kubectl get node NAME         STATUS   ROLES                  AGE    VERSION k8scloude1   Ready    control-plane,master   288d   v1.21.9 k8scloude2   Ready    <none>                 288d   v1.21.9 k8scloude3   Ready    <none>                 288d   v1.21.9 

我们将安装 Istio的demo 配置文件,因为它包含所有的核心组件,启用了跟踪和日志记录,便于学习不同的 Istio 功能
关于istio的详细安装部署,请查看博客《Istio(二):在Kubernetes(k8s)集群上安装部署istio1.14》https://www.cnblogs.com/renshengdezheli/p/16836404.html

也可以按照如下使用 GetMesh CLI 在Kubernetes集群中安装 Istio 。

下载 GetMesh CLI:

 curl -sL https://istio.tetratelabs.io/getmesh/install.sh | bash 

安装 Istio:

 getmesh istioctl install --set profile=demo 

Istio安装完成后,创建一个命名空间online-boutique,新的项目就部署在online-boutique命名空间下,给命名空间online-boutique设置上 istio-injection=enabled 标签,启用sidecar 自动注入。

#创建命名空间online-boutique [root@k8scloude1 ~]# kubectl create ns online-boutique namespace/online-boutique created  #切换命名空间 [root@k8scloude1 ~]# kubens online-boutique Context "kubernetes-admin@kubernetes" modified. Active namespace is "online-boutique".  #让命名空间online-boutique启用sidecar 自动注入 [root@k8scloude1 ~]# kubectl label ns online-boutique istio-injection=enabled namespace/online-boutique labeled  [root@k8scloude1 ~]# kubectl get ns -l istio-injection --show-labels  NAME              STATUS   AGE   LABELS online-boutique   Active   16m   istio-injection=enabled,kubernetes.io/metadata.name=online-boutique 

五.部署online Boutique应用

5.1 部署 Online Boutique 应用

在集群和 Istio 准备好后,我们可以克隆 Online Boutique 应用库了。istio和k8s集群版本如下:

[root@k8scloude1 ~]# istioctl version client version: 1.14.3 control plane version: 1.14.3 data plane version: 1.14.3 (1 proxies)  [root@k8scloude1 ~]# kubectl get nodes NAME         STATUS   ROLES                  AGE    VERSION k8scloude1   Ready    control-plane,master   283d   v1.21.9 k8scloude2   Ready    <none>                 283d   v1.21.9 k8scloude3   Ready    <none>                 283d   v1.21.9 

使用git克隆代码仓库:

#安装git [root@k8scloude1 ~]# yum -y install git  #查看git版本 [root@k8scloude1 ~]# git version git version 1.8.3.1  #创建online-boutique目录,项目放在该目录下 [root@k8scloude1 ~]# mkdir online-boutique  [root@k8scloude1 ~]# cd online-boutique/  [root@k8scloude1 online-boutique]# pwd /root/online-boutique  #git克隆代码 [root@k8scloude1 online-boutique]# git clone https://github.com/GoogleCloudPlatform/microservices-demo.git 正克隆到 'microservices-demo'... remote: Enumerating objects: 8195, done. remote: Counting objects: 100% (332/332), done. remote: Compressing objects: 100% (167/167), done. remote: Total 8195 (delta 226), reused 241 (delta 161), pack-reused 7863 接收对象中: 100% (8195/8195), 30.55 MiB | 154.00 KiB/s, done. 处理 delta 中: 100% (5823/5823), done.  [root@k8scloude1 online-boutique]# ls microservices-demo 

前往 microservices-demo 目录,istio-manifests.yaml,kubernetes-manifests.yaml是主要的安装文件

[root@k8scloude1 online-boutique]# cd microservices-demo/  [root@k8scloude1 microservices-demo]# ls cloudbuild.yaml     CODEOWNERS       docs  istio-manifests       kustomize  pb         release        SECURITY.md    src CODE_OF_CONDUCT.md  CONTRIBUTING.md  hack  kubernetes-manifests  LICENSE    README.md  renovate.json  skaffold.yaml  terraform  [root@k8scloude1 microservices-demo]# cd release/  [root@k8scloude1 release]# ls istio-manifests.yaml  kubernetes-manifests.yaml 

查看所需的镜像,可以在k8s集群的worker节点提前下载镜像

关于gcr.io镜像的下载方式可以查看博客《轻松下载k8s.gcr.io,gcr.io,quay.io镜像 》https://www.cnblogs.com/renshengdezheli/p/16814395.html

[root@k8scloude1 release]# ls istio-manifests.yaml  kubernetes-manifests.yaml  [root@k8scloude1 release]# vim kubernetes-manifests.yaml   #可以看到安装此项目需要13个镜像,gcr.io表示是Google的镜像 [root@k8scloude1 release]# grep image kubernetes-manifests.yaml          image: gcr.io/google-samples/microservices-demo/emailservice:v0.4.0           image: gcr.io/google-samples/microservices-demo/checkoutservice:v0.4.0         image: gcr.io/google-samples/microservices-demo/recommendationservice:v0.4.0           image: gcr.io/google-samples/microservices-demo/frontend:v0.4.0         image: gcr.io/google-samples/microservices-demo/paymentservice:v0.4.0         image: gcr.io/google-samples/microservices-demo/productcatalogservice:v0.4.0         image: gcr.io/google-samples/microservices-demo/cartservice:v0.4.0         image: busybox:latest         image: gcr.io/google-samples/microservices-demo/loadgenerator:v0.4.0         image: gcr.io/google-samples/microservices-demo/currencyservice:v0.4.0         image: gcr.io/google-samples/microservices-demo/shippingservice:v0.4.0         image: redis:alpine         image: gcr.io/google-samples/microservices-demo/adservice:v0.4.0  [root@k8scloude1 release]# grep image kubernetes-manifests.yaml | uniq | wc -l 13  #在k8s集群的worker节点提前下载镜像,以k8scloude2为例 #把gcr.io换为gcr.lank8s.cn,比如gcr.io/google-samples/microservices-demo/emailservice:v0.4.0换为gcr.lank8s.cn/google-samples/microservices-demo/emailservice:v0.4.0 [root@k8scloude2 ~]# docker pull gcr.lank8s.cn/google-samples/microservices-demo/emailservice:v0.4.0 。。。。。。 其他那些镜像就按照此方法下载...... 。。。。。。 [root@k8scloude2 ~]# docker pull gcr.lank8s.cn/google-samples/microservices-demo/adservice:v0.4.0  #镜像下载之后,使用sed把kubernetes-manifests.yaml文件中的gcr.io修改为gcr.lank8s.cn [root@k8scloude1 release]# sed -i 's/gcr.io/gcr.lank8s.cn/' kubernetes-manifests.yaml  #此时kubernetes-manifests.yaml文件中的镜像就全被修改了 [root@k8scloude1 release]# grep image kubernetes-manifests.yaml         image: gcr.lank8s.cn/google-samples/microservices-demo/emailservice:v0.4.0           image: gcr.lank8s.cn/google-samples/microservices-demo/checkoutservice:v0.4.0         image: gcr.lank8s.cn/google-samples/microservices-demo/recommendationservice:v0.4.0           image: gcr.lank8s.cn/google-samples/microservices-demo/frontend:v0.4.0         image: gcr.lank8s.cn/google-samples/microservices-demo/paymentservice:v0.4.0         image: gcr.lank8s.cn/google-samples/microservices-demo/productcatalogservice:v0.4.0         image: gcr.lank8s.cn/google-samples/microservices-demo/cartservice:v0.4.0         image: busybox:latest         image: gcr.lank8s.cn/google-samples/microservices-demo/loadgenerator:v0.4.0         image: gcr.lank8s.cn/google-samples/microservices-demo/currencyservice:v0.4.0         image: gcr.lank8s.cn/google-samples/microservices-demo/shippingservice:v0.4.0         image: redis:alpine         image: gcr.lank8s.cn/google-samples/microservices-demo/adservice:v0.4.0  #istio-manifests.yaml 文件没有镜像 [root@k8scloude1 release]# vim istio-manifests.yaml  [root@k8scloude1 release]# grep image istio-manifests.yaml  

创建 Kubernetes 资源:

[root@k8scloude1 release]# pwd /root/online-boutique/microservices-demo/release  [root@k8scloude1 release]# ls istio-manifests.yaml  kubernetes-manifests.yaml  #在online-boutique命名空间创建k8s资源 [root@k8scloude1 release]# kubectl apply -f /root/online-boutique/microservices-demo/release/kubernetes-manifests.yaml -n online-boutique 

检查所有 Pod 都在运行:

[root@k8scloude1 release]# kubectl get pod -o wide NAME                                     READY   STATUS    RESTARTS   AGE   IP               NODE         NOMINATED NODE   READINESS GATES adservice-9c6d67f96-txrsb                2/2     Running   0          85s   10.244.112.151   k8scloude2   <none>           <none> cartservice-6d7544dc98-86p9c             2/2     Running   0          86s   10.244.251.228   k8scloude3   <none>           <none> checkoutservice-5ff49769d4-5p2cn         2/2     Running   0          86s   10.244.112.148   k8scloude2   <none>           <none> currencyservice-5f56dd7456-lxjnz         2/2     Running   0          85s   10.244.251.241   k8scloude3   <none>           <none> emailservice-677bbb77d8-8ndsp            2/2     Running   0          86s   10.244.112.156   k8scloude2   <none>           <none> frontend-7d65884948-hnmh6                2/2     Running   0          86s   10.244.112.154   k8scloude2   <none>           <none> loadgenerator-77ffcbd84d-hhh2w           2/2     Running   0          85s   10.244.112.147   k8scloude2   <none>           <none> paymentservice-88f465d9d-nfxnc           2/2     Running   0          86s   10.244.112.149   k8scloude2   <none>           <none> productcatalogservice-8496676498-6zpfk   2/2     Running   0          86s   10.244.112.143   k8scloude2   <none>           <none> recommendationservice-555cdc5c84-j5w8f   2/2     Running   0          86s   10.244.251.227   k8scloude3   <none>           <none> redis-cart-6f65887b5d-42b8m              2/2     Running   0          85s   10.244.251.236   k8scloude3   <none>           <none> shippingservice-6ff94bd6-tm6d2           2/2     Running   0          85s   10.244.251.242   k8scloude3   <none>           <none> 

创建 Istio 资源:

[root@k8scloude1 microservices-demo]# pwd /root/online-boutique/microservices-demo  [root@k8scloude1 microservices-demo]# ls istio-manifests/ allow-egress-googleapis.yaml  frontend-gateway.yaml  frontend.yaml  [root@k8scloude1 microservices-demo]# kubectl apply -f ./istio-manifests serviceentry.networking.istio.io/allow-egress-googleapis created serviceentry.networking.istio.io/allow-egress-google-metadata created gateway.networking.istio.io/frontend-gateway created virtualservice.networking.istio.io/frontend-ingress created virtualservice.networking.istio.io/frontend created 

部署了一切后,我们就可以得到入口网关的 IP 地址并打开前端服务:

[root@k8scloude1 microservices-demo]# INGRESS_HOST="$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')"  [root@k8scloude1 microservices-demo]# echo "$INGRESS_HOST" 192.168.110.190  [root@k8scloude1 microservices-demo]# kubectl get service -n istio-system istio-ingressgateway -o wide NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                                                                      AGE   SELECTOR istio-ingressgateway   LoadBalancer   10.107.131.65   192.168.110.190   15021:30093/TCP,80:32126/TCP,443:30293/TCP,31400:30628/TCP,15443:30966/TCP   27d   app=istio-ingressgateway,istio=ingressgateway  

在浏览器中打开 INGRESS_HOST,你会看到前端服务,浏览器访问http://192.168.110.190/,如下图所示:

Istio(十三):Istio项目实际案例——Online Boutique

我们需要做的最后一件事是删除 frontend-external 服务。frontend-external 服务是一个 LoadBalancer 服务,它暴露了前端。由于我们正在使用 Istio 的入口网关,我们不再需要这个 LoadBalancer 服务了。

删除frontend-external服务,运行:

[root@k8scloude1 ~]# kubectl get svc | grep frontend-external frontend-external       LoadBalancer   10.102.0.207     192.168.110.191   80:30173/TCP   4d15h  [root@k8scloude1 ~]# kubectl delete svc frontend-external service "frontend-external" deleted  [root@k8scloude1 ~]# kubectl get svc | grep frontend-external 

Online Boutique 应用清单还包括一个负载发生器,它正在生成对所有服务的请求——这是为了让我们能够模拟网站的流量。

六.部署可观察性工具

6.1 部署可观察性工具

接下来,我们将部署可观察性、分布式追踪、数据可视化工具,下面两种方法任选一种;

关于prometheus,grafana,kiali,zipkin更详细的安装方法可以查看博客《Istio(三):服务网格istio可观察性:Prometheus,Grafana,Zipkin,Kiali》https://www.cnblogs.com/renshengdezheli/p/16836943.html

#方法一: [root@k8scloude1 ~]# kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/prometheus.yaml  [root@k8scloude1 ~]# kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/grafana.yaml  [root@k8scloude1 ~]# kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/kiali.yaml  [root@k8scloude1 ~]# kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/extras/zipkin.yaml   #方法二:下载istio安装包istio-1.14.3-linux-amd64.tar.gz安装分析工具 [root@k8scloude1 ~]# ls istio* -d istio-1.14.3  istio-1.14.3-linux-amd64.tar.gz    [root@k8scloude1 ~]# cd istio-1.14.3/  [root@k8scloude1 addons]# pwd /root/istio-1.14.3/samples/addons  [root@k8scloude1 addons]# ls extras  grafana.yaml  jaeger.yaml  kiali.yaml  prometheus.yaml  README.md  [root@k8scloude1 addons]# kubectl apply -f prometheus.yaml    [root@k8scloude1 addons]# kubectl apply -f grafana.yaml    [root@k8scloude1 addons]# kubectl apply -f kiali.yaml   [root@k8scloude1 addons]# ls extras/ prometheus-operator.yaml  prometheus_vm_tls.yaml  prometheus_vm.yaml  zipkin.yaml [root@k8scloude1 addons]# kubectl apply -f extras/zipkin.yaml   

如果你在安装 Kiali 的时候发现以下错误 No matches for kind "MonitoringDashboard" in version "monitoring.kiali.io/v1alpha1" 请重新运行以上命令。

prometheus,grafana,kiali,zipkin被安装在istio-system命名空间下,我们可以使用 getmesh istioctl dashboard kiali 打开 Kiali界面。

我们使用另外一种方法打开Kiali界面:

#可以看到prometheus,grafana,kiali,zipkin被安装在istio-system命名空间下 [root@k8scloude1 addons]# kubectl get pod -n istio-system  NAME                                    READY   STATUS    RESTARTS   AGE grafana-6c5dc6df7c-cnc9w                1/1     Running   2          27h istio-egressgateway-58949b7c84-k7v6f    1/1     Running   8          10d istio-ingressgateway-75bc568988-69k8j   1/1     Running   6          3d21h istiod-84d979766b-kz5sd                 1/1     Running   14         10d kiali-5db6985fb5-8t77v                  1/1     Running   0          3m25s prometheus-699b7cc575-dx6rp             2/2     Running   8          2d21h zipkin-6cd5d58bcc-hxngj                 1/1     Running   1          17h  #可以看到kiali这个service的类型为ClusterIP,外部环境访问不了 [root@k8scloude1 addons]# kubectl get service -n istio-system  NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)                                                                      AGE grafana                NodePort       10.100.151.232   <none>            3000:31092/TCP                                                               27h istio-egressgateway    ClusterIP      10.102.56.241    <none>            80/TCP,443/TCP                                                               10d istio-ingressgateway   LoadBalancer   10.107.131.65    192.168.110.190   15021:30093/TCP,80:32126/TCP,443:30293/TCP,31400:30628/TCP,15443:30966/TCP   10d istiod                 ClusterIP      10.103.37.59     <none>            15010/TCP,15012/TCP,443/TCP,15014/TCP                                        10d kiali                  ClusterIP      10.109.42.120    <none>            20001/TCP,9090/TCP                                                           7m42s prometheus             NodePort       10.101.141.187   <none>            9090:31755/TCP                                                               2d21h tracing                ClusterIP      10.101.30.10     <none>            80/TCP                                                                       17h zipkin                 NodePort       10.104.85.78     <none>            9411:30350/TCP                                                               17h #修改kiali这个service的类型为NodePort,这样外部环境就可以访问kiali了 #把type: ClusterIP 修改为 type: NodePort即可  [root@k8scloude1 addons]# kubectl edit service kiali -n istio-system  service/kiali edited  #现在kiali这个service的类型为NodePort,浏览器输入物理机ip:30754即可访问kiali网页了 [root@k8scloude1 addons]# kubectl get service -n istio-system  NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)                                                                      AGE grafana                NodePort       10.100.151.232   <none>            3000:31092/TCP                                                               27h istio-egressgateway    ClusterIP      10.102.56.241    <none>            80/TCP,443/TCP                                                               10d istio-ingressgateway   LoadBalancer   10.107.131.65    192.168.110.190   15021:30093/TCP,80:32126/TCP,443:30293/TCP,31400:30628/TCP,15443:30966/TCP   10d istiod                 ClusterIP      10.103.37.59     <none>            15010/TCP,15012/TCP,443/TCP,15014/TCP                                        10d kiali                  NodePort       10.109.42.120    <none>            20001:30754/TCP,9090:31573/TCP                                               8m42s prometheus             NodePort       10.101.141.187   <none>            9090:31755/TCP                                                               2d21h tracing                ClusterIP      10.101.30.10     <none>            80/TCP                                                                       17h zipkin                 NodePort       10.104.85.78     <none>            9411:30350/TCP                                                               17h 

k8scloude1机器的地址为192.168.110.130,我们可以在浏览器中打开 http://192.168.110.130:30754,进入 kiali,kiali首页如下:

Istio(十三):Istio项目实际案例——Online Boutique

在online-boutique命名空间点击Graph,查看服务的拓扑结构

Istio(十三):Istio项目实际案例——Online Boutique

下面是 Boutique 图表在 Kiali 中的样子:

该图向我们展示了服务的拓扑结构,并将服务的通信方式可视化。它还显示了入站和出站的指标,以及通过连接 Jaeger 和 Grafana(如果安装了)的追踪。图中的颜色代表服务网格的健康状况。红色或橙色的节点可能需要注意。组件之间的边的颜色代表这些组件之间的请求的健康状况。节点形状表示组件的类型,如服务、工作负载或应用程序。

Istio(十三):Istio项目实际案例——Online Boutique

七.流量路由

7.1 流量路由

我们已经建立了一个新的 Docker 镜像,它使用了与当前运行的前端服务不同的标头。让我们看看如何部署所需的资源并将一定比例的流量路由到不同的前端服务版本

在我们创建任何资源之前,让我们删除现有的前端部署(kubectl delete deploy frontend

[root@k8scloude1 ~]# kubectl get deploy | grep frontend frontend                1/1     1            1           4d21h  [root@k8scloude1 ~]# kubectl delete deploy frontend deployment.apps "frontend" deleted  [root@k8scloude1 ~]# kubectl get deploy | grep frontend 

重新创建一个前端deploy,名字还是frontend,但是指定了一个版本标签设置为 original 。yaml文件如下:

[root@k8scloude1 ~]# vim frontend-original.yaml  [root@k8scloude1 ~]# cat frontend-original.yaml  apiVersion: apps/v1 kind: Deployment metadata:   name: frontend spec:   selector:     matchLabels:       app: frontend       version: original   template:     metadata:       labels:         app: frontend         version: original       annotations:         sidecar.istio.io/rewriteAppHTTPProbers: "true"     spec:       containers:         - name: server           image: gcr.lank8s.cn/google-samples/microservices-demo/frontend:v0.2.1           ports:           - containerPort: 8080           readinessProbe:             initialDelaySeconds: 10             httpGet:               path: "/_healthz"               port: 8080               httpHeaders:               - name: "Cookie"                 value: "shop_session-id=x-readiness-probe"           livenessProbe:             initialDelaySeconds: 10             httpGet:               path: "/_healthz"               port: 8080               httpHeaders:               - name: "Cookie"                 value: "shop_session-id=x-liveness-probe"           env:           - name: PORT             value: "8080"           - name: PRODUCT_CATALOG_SERVICE_ADDR             value: "productcatalogservice:3550"           - name: CURRENCY_SERVICE_ADDR             value: "currencyservice:7000"           - name: CART_SERVICE_ADDR             value: "cartservice:7070"           - name: RECOMMENDATION_SERVICE_ADDR             value: "recommendationservice:8080"           - name: SHIPPING_SERVICE_ADDR             value: "shippingservice:50051"           - name: CHECKOUT_SERVICE_ADDR             value: "checkoutservice:5050"           - name: AD_SERVICE_ADDR             value: "adservice:9555"           - name: ENV_PLATFORM             value: "gcp"           resources:             requests:               cpu: 100m               memory: 64Mi             limits:               cpu: 200m               memory: 128Mi 

创建deploy

[root@k8scloude1 ~]# kubectl apply -f frontend-original.yaml  deployment.apps/frontend created  #deploy创建成功 [root@k8scloude1 ~]# kubectl get deploy | grep frontend frontend                1/1     1            1           43s  #pod也正常运行 [root@k8scloude1 ~]# kubectl get pod | grep frontend frontend-ff47c5568-qnzpt                 2/2     Running   0          105s 

现在我们准备创建一个 DestinationRule,定义两个版本的前端——现有的(original)和新的(v1)。

[root@k8scloude1 ~]# vim frontend-dr.yaml  [root@k8scloude1 ~]# cat frontend-dr.yaml  apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata:   name: frontend spec:   host: frontend.online-boutique.svc.cluster.local   subsets:     - name: original       labels:         version: original     - name: v1       labels:         version: 1.0.0 

创建DestinationRule

[root@k8scloude1 ~]# kubectl apply -f frontend-dr.yaml  destinationrule.networking.istio.io/frontend created  [root@k8scloude1 ~]# kubectl get destinationrule NAME       HOST                                         AGE frontend   frontend.online-boutique.svc.cluster.local   12s 

接下来,我们将更新 VirtualService,并指定将所有流量路由到子集。在这种情况下,我们将把所有流量路由到原始版本original的前端。

[root@k8scloude1 ~]# vim frontend-vs.yaml  [root@k8scloude1 ~]# cat frontend-vs.yaml  apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: frontend-ingress spec:   hosts:     - '*'   gateways:     - frontend-gateway   http:   - route:     - destination:         host: frontend.online-boutique.svc.cluster.local         port:           number: 80         subset: original 

更新 VirtualService 资源

[root@k8scloude1 ~]# kubectl apply -f frontend-vs.yaml  virtualservice.networking.istio.io/frontend-ingress created  [root@k8scloude1 ~]# kubectl get virtualservice NAME               GATEWAYS               HOSTS                                    AGE frontend                                  ["frontend.default.svc.cluster.local"]   5d14h frontend-ingress   ["frontend-gateway"]   ["*"]                                    14s  #修改frontend这个virtualservice的hosts为frontend.online-boutique.svc.cluster.local [root@k8scloude1 ~]# kubectl edit virtualservice frontend virtualservice.networking.istio.io/frontend edited  [root@k8scloude1 ~]# kubectl get virtualservice NAME               GATEWAYS               HOSTS                                            AGE frontend                                  ["frontend.online-boutique.svc.cluster.local"]   5d14h frontend-ingress   ["frontend-gateway"]   ["*"]                                            3m24s 

现在我们将 VirtualService 配置为将所有进入的流量路由到 original 子集,我们可以安全地创建新的前端部署。

[root@k8scloude1 ~]# vim frontend-v1.yaml  [root@k8scloude1 ~]# cat frontend-v1.yaml  apiVersion: apps/v1 kind: Deployment metadata:   name: frontend-v1 spec:   selector:     matchLabels:       app: frontend       version: 1.0.0   template:     metadata:       labels:         app: frontend         version: 1.0.0       annotations:         sidecar.istio.io/rewriteAppHTTPProbers: "true"     spec:       containers:         - name: server           image: gcr.lank8s.cn/tetratelabs/boutique-frontend:1.0.0           ports:           - containerPort: 8080           readinessProbe:             initialDelaySeconds: 10             httpGet:               path: "/_healthz"               port: 8080               httpHeaders:               - name: "Cookie"                 value: "shop_session-id=x-readiness-probe"           livenessProbe:             initialDelaySeconds: 10             httpGet:               path: "/_healthz"               port: 8080               httpHeaders:               - name: "Cookie"                 value: "shop_session-id=x-liveness-probe"           env:           - name: PORT             value: "8080"           - name: PRODUCT_CATALOG_SERVICE_ADDR             value: "productcatalogservice:3550"           - name: CURRENCY_SERVICE_ADDR             value: "currencyservice:7000"           - name: CART_SERVICE_ADDR             value: "cartservice:7070"           - name: RECOMMENDATION_SERVICE_ADDR             value: "recommendationservice:8080"           - name: SHIPPING_SERVICE_ADDR             value: "shippingservice:50051"           - name: CHECKOUT_SERVICE_ADDR             value: "checkoutservice:5050"           - name: AD_SERVICE_ADDR             value: "adservice:9555"           - name: ENV_PLATFORM             value: "gcp"           resources:             requests:               cpu: 100m               memory: 64Mi             limits:               cpu: 200m               memory: 128Mi 

创建前端部署frontend-v1

[root@k8scloude1 ~]# kubectl apply -f frontend-v1.yaml  deployment.apps/frontend-v1 created  #deploy正常运行 [root@k8scloude1 ~]# kubectl get deploy | grep frontend-v1 frontend-v1             1/1     1            1           54s  #pod正常运行 [root@k8scloude1 ~]# kubectl get pod | grep frontend-v1 frontend-v1-6457cb648d-fgmkk             2/2     Running   0          70s 

如果我们在浏览器中打开 INGRESS_HOST,我们仍然会看到原始版本的前端。浏览器打开http://192.168.110.190/,显示的前端如下:

Istio(十三):Istio项目实际案例——Online Boutique

让我们更新 VirtualService 中的权重,开始将 30% 的流量路由到 v1 的子集。

[root@k8scloude1 ~]# vim frontend-30.yaml   [root@k8scloude1 ~]# cat frontend-30.yaml  apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: frontend-ingress spec:   hosts:     - '*'   gateways:     - frontend-gateway   http:   - route:     - destination:         host: frontend.online-boutique.svc.cluster.local         port:           number: 80         subset: original       weight: 70     - destination:         host: frontend.online-boutique.svc.cluster.local         port:           number: 80         subset: v1       weight: 30 

更新 VirtualService

[root@k8scloude1 ~]# kubectl apply -f frontend-30.yaml  virtualservice.networking.istio.io/frontend-ingress configured  [root@k8scloude1 ~]# kubectl get virtualservices NAME               GATEWAYS               HOSTS                                            AGE frontend                                  ["frontend.online-boutique.svc.cluster.local"]   5d14h frontend-ingress   ["frontend-gateway"]   ["*"]                                            20m 

浏览器访问http://192.168.110.190/,查看前端界面,如果我们刷新几次网页,我们会注意到来自前端 v1 的更新标头,一般显示$75,如下所示:

Istio(十三):Istio项目实际案例——Online Boutique

多刷新几次页面显示$30,如下所示:

Istio(十三):Istio项目实际案例——Online Boutique

我们可以在浏览器中打开 http://192.168.110.130:30754,进入 kiali界面查看服务的拓扑结构,选择online-boutique命名空间,查看Graph

Istio(十三):Istio项目实际案例——Online Boutique

服务的拓扑结构如下,我们会发现有两个版本的前端在运行:

Istio(十三):Istio项目实际案例——Online Boutique

八.故障注入

8.1 故障注入

我们将为推荐服务引入 5 秒的延迟。Envoy 将为 50% 的请求注入延迟。

[root@k8scloude1 ~]# vim recommendation-delay.yaml  [root@k8scloude1 ~]# cat recommendation-delay.yaml  apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: recommendationservice spec:   hosts:   - recommendationservice.online-boutique.svc.cluster.local   http:   - route:       - destination:           host: recommendationservice.online-boutique.svc.cluster.local     fault:       delay:         percentage:           value: 50         fixedDelay: 5s 

将上述 YAML 保存为 recommendation-delay.yaml,然后用 kubectl apply -f recommendation-delay.yaml 创建 VirtualService。

[root@k8scloude1 ~]# kubectl apply -f recommendation-delay.yaml  virtualservice.networking.istio.io/recommendationservice created  [root@k8scloude1 ~]# kubectl get virtualservice NAME                    GATEWAYS               HOSTS                                                         AGE frontend                                       ["frontend.online-boutique.svc.cluster.local"]                6d13h frontend-ingress        ["frontend-gateway"]   ["*"]                                                         23h recommendationservice                          ["recommendationservice.online-boutique.svc.cluster.local"]   7s 

我们可以在浏览器中打开 INGRESS_HOST http://192.168.110.190/,然后点击其中一个产品。推荐服务的结果显示在屏幕底部的”Other Products You Might Light“部分。如果我们刷新几次页面,我们会注意到,该页面要么立即加载,要么有一个延迟加载页面。这个延迟是由于我们注入了 5 秒的延迟。

我们可以打开 Grafana(getmesh istioctl dash grafana)和 Istio 服务仪表板,或者使用如下方法打开Grafana界面:

#查看grafana的端口号 [root@k8scloude1 ~]# kubectl get svc -n istio-system | grep grafana grafana                NodePort       10.100.151.232   <none>            3000:31092/TCP                                                               24d     

http://192.168.110.130:31092/打开grafana界面。点击istio-service-dashboard进入istio服务界面

Istio(十三):Istio项目实际案例——Online Boutique

确保从服务列表中选择recommendationsservice,在 Reporter 下拉菜单中选择 source,并查看显示延迟的 Client Request Duration,如下图所示:

Istio(十三):Istio项目实际案例——Online Boutique

点击View放大Client Request Duration图表

Istio(十三):Istio项目实际案例——Online Boutique

同样地,我们可以注入一个中止。在下面的例子中,我们为发送到产品目录服务的 50% 的请求注入一个 HTTP 500。

[root@k8scloude1 ~]# vim productcatalogservice-abort.yaml   [root@k8scloude1 ~]# cat productcatalogservice-abort.yaml  apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: productcatalogservice spec:   hosts:   - productcatalogservice.online-boutique.svc.cluster.local   http:   - route:       - destination:           host: productcatalogservice.online-boutique.svc.cluster.local     fault:       abort:         percentage:           value: 50         httpStatus: 500  

创建VirtualService。

[root@k8scloude1 ~]# kubectl apply -f productcatalogservice-abort.yaml virtualservice.networking.istio.io/productcatalogservice created  [root@k8scloude1 ~]# kubectl get virtualservice NAME                    GATEWAYS               HOSTS                                                         AGE frontend                                       ["frontend.online-boutique.svc.cluster.local"]                6d13h frontend-ingress        ["frontend-gateway"]   ["*"]                                                         23h productcatalogservice                          ["productcatalogservice.online-boutique.svc.cluster.local"]   8s recommendationservice                          ["recommendationservice.online-boutique.svc.cluster.local"]   36m 

如果我们刷新几次产品页面,我们应该得到如下图所示的错误信息。

Istio(十三):Istio项目实际案例——Online Boutique

请注意,错误信息说,失败的原因是故障过滤器中止。如果我们打开 Grafana(getmesh istioctl dash grafana),我们也会注意到图中报告的错误。

删除productcatalogservice这个VirtualService:

[root@k8scloude1 ~]# kubectl delete virtualservice productcatalogservice  virtualservice.networking.istio.io "productcatalogservice" deleted   [root@k8scloude1 ~]# kubectl get virtualservice NAME                    GATEWAYS               HOSTS                                                         AGE frontend                                       ["frontend.online-boutique.svc.cluster.local"]                6d14h frontend-ingress        ["frontend-gateway"]   ["*"]                                                         23h recommendationservice                          ["recommendationservice.online-boutique.svc.cluster.local"]   44m 

九.弹性

9.1 弹性

为了演示弹性功能,我们将在产品目录服务部署中添加一个名为 EXTRA_LATENCY 的环境变量。这个变量会在每次调用服务时注入一个额外的休眠

通过运行 kubectl edit deploy productcatalogservice 来编辑产品目录服务部署。

[root@k8scloude1 ~]# kubectl get deploy NAME                    READY   UP-TO-DATE   AVAILABLE   AGE adservice               1/1     1            1           6d14h cartservice             1/1     1            1           6d14h checkoutservice         1/1     1            1           6d14h currencyservice         1/1     1            1           6d14h emailservice            1/1     1            1           6d14h frontend                1/1     1            1           24h frontend-v1             1/1     1            1           28h loadgenerator           1/1     1            1           6d14h paymentservice          1/1     1            1           6d14h productcatalogservice   1/1     1            1           6d14h recommendationservice   1/1     1            1           6d14h redis-cart              1/1     1            1           6d14h shippingservice         1/1     1            1           6d14h  [root@k8scloude1 ~]# kubectl edit deploy productcatalogservice deployment.apps/productcatalogservice edited 

这将打开一个编辑器。滚动到有环境变量的部分,添加 EXTRA_LATENCY 环境变量。

 ...      spec:        containers:        - env:          - name: EXTRA_LATENCY            value: 6s  ... 

Istio(十三):Istio项目实际案例——Online Boutique

保存并推出编辑器。

如果我们刷新http://192.168.110.190/页面,我们会发现页面需要 6 秒的时间来加载(那是由于我们注入的延迟)

让我们给产品目录服务添加一个 2 秒的超时

[root@k8scloude1 ~]# vim productcatalogservice-timeout.yaml  [root@k8scloude1 ~]# cat productcatalogservice-timeout.yaml  apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: productcatalogservice spec:   hosts:   - productcatalogservice.online-boutique.svc.cluster.local   http:   - route:     - destination:         host: productcatalogservice.online-boutique.svc.cluster.local     timeout: 2s 

创建 VirtualService。

[root@k8scloude1 ~]# kubectl apply -f productcatalogservice-timeout.yaml  virtualservice.networking.istio.io/productcatalogservice created   [root@k8scloude1 ~]# kubectl get virtualservice NAME                    GATEWAYS               HOSTS                                                         AGE frontend                                       ["frontend.online-boutique.svc.cluster.local"]                6d14h frontend-ingress        ["frontend-gateway"]   ["*"]                                                         24h productcatalogservice                          ["productcatalogservice.online-boutique.svc.cluster.local"]   10s recommendationservice                          ["recommendationservice.online-boutique.svc.cluster.local"]   76m 

如果我们刷新页面http://192.168.110.190/,我们会注意到一个错误信息的出现:

Istio(十三):Istio项目实际案例——Online Boutique

 rpc error: code = Unavailable desc = upstream request timeout  could not retrieve products 

该错误表明对产品目录服务的请求超时了。原因为:我们修改了服务,增加了 6 秒的延迟,并将超时设置为 2 秒

让我们定义一个重试策略,有三次尝试,每次尝试的超时为 1 秒。

[root@k8scloude1 ~]# vim productcatalogservice-retry.yaml  [root@k8scloude1 ~]# cat productcatalogservice-retry.yaml  apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: productcatalogservice spec:   hosts:   - productcatalogservice.online-boutique.svc.cluster.local   http:   - route:     - destination:         host: productcatalogservice.online-boutique.svc.cluster.local     retries:       attempts: 3       perTryTimeout: 1s  [root@k8scloude1 ~]# kubectl apply -f productcatalogservice-retry.yaml  virtualservice.networking.istio.io/productcatalogservice configured  [root@k8scloude1 ~]# kubectl get virtualservice NAME                    GATEWAYS               HOSTS                                                         AGE frontend                                       ["frontend.online-boutique.svc.cluster.local"]                6d14h frontend-ingress        ["frontend-gateway"]   ["*"]                                                         24h productcatalogservice                          ["productcatalogservice.online-boutique.svc.cluster.local"]   10m recommendationservice                          ["recommendationservice.online-boutique.svc.cluster.local"]   86m 

由于我们在产品目录服务部署中留下了额外的延迟,我们仍然会看到错误。

Istio(十三):Istio项目实际案例——Online Boutique

让我们打开 Zipkin 中的追踪,看看重试策略的作用。使用 getmesh istioctl dash zipkin 来打开 Zipkin 仪表盘。或者使用如下方法打开zipkin界面

#查看zipkin端口为30350 [root@k8scloude1 ~]# kubectl get svc -n istio-system | grep zipkin zipkin                 NodePort       10.104.85.78     <none>            9411:30350/TCP                                                               23d 

浏览器输入http://192.168.110.130:30350/打开zipkin界面。

Istio(十三):Istio项目实际案例——Online Boutique

点击 + 按钮,选择 serviceNamefrontend.online-boutique。为了只得到至少一秒钟的响应(这就是我们的 perTryTimeout),选择 minDuration,在文本框中输入 1s。点击RUN QUERY搜索按钮,显示所有追踪。

Istio(十三):Istio项目实际案例——Online Boutique

点击 Filter 按钮,从下拉菜单中选择 productCatalogService.online-boutique。你应该看到花了 1 秒钟的 trace。这些 trace 对应于我们之前定义的 perTryTimeout

Istio(十三):Istio项目实际案例——Online Boutique

点击SHOW

Istio(十三):Istio项目实际案例——Online Boutique

详细信息如下:

Istio(十三):Istio项目实际案例——Online Boutique

运行 kubectl delete vs productcatalogservice 删除 VirtualService。

[root@k8scloude1 ~]# kubectl get virtualservice NAME                    GATEWAYS               HOSTS                                                         AGE frontend                                       ["frontend.online-boutique.svc.cluster.local"]                6d15h frontend-ingress        ["frontend-gateway"]   ["*"]                                                         24h productcatalogservice                          ["productcatalogservice.online-boutique.svc.cluster.local"]   37m recommendationservice                          ["recommendationservice.online-boutique.svc.cluster.local"]   113m  [root@k8scloude1 ~]# kubectl delete virtualservice productcatalogservice virtualservice.networking.istio.io "productcatalogservice" deleted  [root@k8scloude1 ~]# kubectl get virtualservice NAME                    GATEWAYS               HOSTS                                                         AGE frontend                                       ["frontend.online-boutique.svc.cluster.local"]                6d15h frontend-ingress        ["frontend-gateway"]   ["*"]                                                         24h recommendationservice                          ["recommendationservice.online-boutique.svc.cluster.local"]   114m 

发表评论

评论已关闭。

相关文章