在早期,我们的服务是单体应用,一个应用提供了所有的服务,所有的模块都包含在这个应用里面,但随着需求的增多,模块也越来越多,单体应用越来越庞大,模块与模块之间耦合程度越来越高,这样会极易发生因为改变一个组件而导致整个单体应用出现问题。
然后,发展到这个阶段,一般都会进行服务拆分,也就是现在流行的微服务架构,比如从业务上进行拆分,拆分之后,业务与业务之间有相互调用的需求,从原先的单个应用下的模块与模块之间的直接调用变成服务与服务之间的调用。
微服务要考虑的点:① 服务注册与发现;② 负载均衡。
Spring Cloud是基于Spring Boot的一整套实现微服务的框架,提供了微服务开发所需的配置管理、服务发现、微服务网关、智能路由、负载均衡等模块。但也存在一定的不足,比如微服务治理对代码侵入性较强等。
Service Mesh(服务网格)为微服务架构提供了全新的解决方案,也被称为微服务的2.0时代。Istio是当前Service Mesh形态上比较热门的实现方案,能够和k8s深度结合,更快速、更便捷的实现服务治理。
Table of Contents
Toggle1. 什么是 Service Mesh
Service Mesh是一种软件架构,在搭建基础服务中,它是服务到服务之间通讯的一种架构模式,通过代理的方式,拦截服务之间的流量信息,进行加工处理,从而达到管理服务之间交互的目的,它不是”服务“网格,而是服务可以插入的”代理“网格,从而从应用程序代码中抽象出网格。
这里的服务间的通讯包括了负载均衡、熔断、安全、追踪、观测等功能,Service Mesh通过将这些服务治理相关的功能,独立到一种专门的架构,从而让原本的服务专注于业务实现。
服务网格由与应用程序中的每个服务配对的网络代理和一组任务管理进程组成。代理称为数据平面,管理进程称为控制平面。数据平面拦截不同服务之间的调用并进行处理;控制平面是网格的大脑,协调代理的行为,并为运维人员提供API来操纵和观察整个网络。
服务网格架构如下:
控制平面:
在Service Mesh方案中,服务治理规则的管理、服务治理行为、应用本身都是互相独立,这使得应用可以专注于业务,而服务治理逻辑则完全可以抽离出来由运维团队进行统一管理。服务网格运维人员可以操控控制平面,以配置服务网格中的数据平面行为,比如,将流量配置作用于控制平面——翻译配置并将其推送到数据平面。
数据平面:
在Service Mesh方案中,数据平面就是具体实现服务治理行为的代理。在Istio中,数据平面由负责路由、负载均衡、服务发现、健康检查和授权/认证的Envoy代理组成。这些代理再每个服务实例的旁边运行(在k8s中,与应用容器运行在同一个Pod),拦截所有传入和传出的用户流量,并在这一过程中,根据控制平面下发的服务治理规则进行流量管理。
Sidecar Proxy:
在Service Mesh方案中,给每个微服务实例部署一个Sidecar Proxy。Sidecar是Service Mesh中的重要组成部分,在软件系统架构中指边车模式,这个模式实现了数据平面(业务逻辑)和控制平面的解耦。
我们知道kube-proxy有三种模式,在v1.8之前使用的是iptables以及userspace两种模式,在之后引入了ipvs模式,其中iptables和ipvs都是内核态也就是基于netfilter,只有userspace模式是用户态。在k8s中,ClusterIP解决了服务之间相互访问的问题,但它只提供了服务发现和基本的LB功能,如果要用灵活的路由规则以及Metrics collection等服务管控功能,就需要Istio的服务网格功能了。在部署Istio后,Istio通过iptables和Sidecar Proxy接管服务之间的通信,服务间的相互通信不再通过kube-proxy,而是通过Istio的Sidecar Proxy进行。值得注意的是,kube-proxy工作在四层,而Sidecar Proxy则是一个七层代理,可以针对HTTP等应用层的语义进行处理和转发。
2. Istio
Istio解决了开发人员和运营商在分布式微服务架构中面临的挑战。
2.1 什么是Istio
Istio是一个开源服务网格,他透明的分层到现有的分布式应用程序上。Istio的强大功能提供了一种统一且更有效的方式来保护、连接和监控服务。Istio是实现负载均衡、服务到服务身份验证和监控的途径,几乎不需要更改服务代码。其强大的控制平面带来了重要的功能,包括:
-
- 使用TLS加密、基于身份的强大身份验证和授权在集群中保护服务到服务的通信
-
- HTTP、gRPC、WebSocket和TCP流量的自动负载平衡
-
- 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制
-
- 支持访问控制、速率限制和配额的可插入策略层和配置API
-
- 集群内所有流量的自动指标、日志和跟踪,包括集群入口和出口
2.2 Istio架构
Istio服务网格从逻辑上分为数据平面和控制平面。
-
- 数据平面:由一组智能代理(Envoy)组成,被部署为Sidecar。这些代理负责协调和控制微服务之间的所有网络通信。他们还收集和报告所有网格流量的遥测数据。
-
- 控制平面:管理并配置代理来进行流量路由。
每个平面的不同组件如下图:
核心组件概述如下:
(1)Envoy:
Envoy是一种L7代理和通信总线,专为大型现代面向服务的架构而设计。
Envoy是以C++开发的高性能代理,其内置服务发现和动态配置、高级负载均衡、HTTP/2、gRPC、健康检查、前端/边缘代理支持等功能。Envoy主要面向SOA(面向服务的架构)的网络代理,所以,非常适合用于微服务,主要用来调解Service Mesh中所有服务的入站和出站流量。架构图如下:
架构中的一些概念:
-
- Downstream:下游主机,指连接到Envoy的主机,这些主机用来发送请求并接受响应。
-
- Upstream:上游主机,指接收来自Envoy连接和请求的主机,并返回响应。
-
- Listener:服务或程序的监听器,Envoy暴露一个或多个监听下游主机的请求,当监听到请求时,通过Filter Chain把对请求的处理全部抽象为Filter,例如ReadFilter、WriteFilter、HttpFilter等。
-
- Cluster:服务提供集群,指Envoy连接的一组逻辑相同的上游主机。Envoy通过服务发现功能来发现集群内的成员,通过负载均衡功能将流量路由到集群的各个成员。
-
- xDS:xDS中的x是一个代词,类似云计算的XaaS,可以指代IaaS、PaaS、SaaS等。DS为Discovery Service,即发现服务。xDS包括cds(cluster discovery service)、rds(route discovery service)、eds(endpoint discovery service)、ads(aggregated discovery service),其中ads称为聚合的发现服务,是对cds、rds、lds、eds服务的统一封装,解决cds、rds、lds、eds信息更新顺序依赖的问题,从而保证以一定的顺序童虎各类配置信息。
-
- endpoint:一个具体的”应用实例“,类似于k8s中的一个Pod。
-
- cluster:可以理解”应用集群“,对应提供相同服务的一个或多个endpoint,类似k8s中Service概念,即一个Service提供多个相同服务的Pod。
-
- route:当做金丝雀发布部署时,同一个服务会有多个版本,这时需要route规则规定请求如何路由到我中的某个版本上。
Envoy正常的工作流程:Host A(下游主机)发送请求至上游主机(Host B、Host C、Host D等),Envoy通过Listener监听到有下游主机的请求,收到请求后的Envoy将所有请求流量劫持至Envoy内部,并将请求内容抽象为Filter Chains路由至某个上游主机中,从而实现路由转发以及负载均衡能力。
Istio使用Envoy代理的扩展版本。Envoy代理是唯一与数据平面流量交互的Istio组件。
Envoy代理被部署为服务的Sidecar,在逻辑上为服务增加了Envoy的许多内置特性。这种Sidecar部署允许Istio可以执行策略决策,并提取丰富的遥测数据,接着将这些数据发送到监视系统以提供有关征哥网格行为的信息。
由Envoy代理启用的一些Istio的功能和任务包括:
-
- 流量控制功能:通过丰富的HTTP、gRPC、WebSocket和TCP流量路由规则来执行细粒度的流量控制。
-
- 网络弹性特性:重试设置、故障转移、熔断器和故障注入。
-
- 安全性和身份认证特性:执行安全性策略,并强制实行通过配置API定义的访问控制和速率限制。
-
- 基于WebAssembly的可插拔扩展模型,允许通过自定义策略执行和生成网格流量的遥测。
(2)Istiod:
Istiod提供服务发现、配置和证书管理。
Istiod将控制流量行为的高级路由规则转换为Envoy特定的配置,并在运行时将其传播给Sidecar。Pilot提取特定平台的服务发现机制,并将其综合为一种标准格式,任何符合Envoy API的Sidecar都可以使用。
Istio可以支持发现多种环境,如Kubernetes或VM。可以使用Istio流量管理API让LIstiod重新构造Envoy的配置,以便对服务网格中的流量进行更精准的控制。
Istiod安全通过内置的身份和凭证管理,实现了强大的服务对服务和终端用户认证。可以使用Istio来升级服务网格中未加密的流量。使用Istio,运营商可以基于服务身份而不是相对不稳定的第3层或第4层网络标识来执行策略。此外,可以使用Istio的授权功能控制谁可以访问您的服务。
Istiod充当证书授权(CA),并生成证书以允许在数据平面中进行安全的mTLS通信。
2.3 怎么运行
Istio由两个部分组成:控制平面和数据平面。
数据平面是业务之间的通信平面。如果没有一个服务网格,网络就无法理解正在传送的流量,也无法根据它是哪种类型的流量,或者它从谁那里来,到谁那里去做出任何决定。
服务网格使用代理拦截所有的网络流量,允许根据设置的配置提供广泛的应用程序感知功能。代理与集群中启动的每个服务一起部署,或者与运行在虚拟机上的服务一起运行。
控制平面获取所需的配置和服务视图,并动态的对代理服务器进行编程,随着规则或环境的变化更新它们。
3. 牛刀小试部署Istio
(1)下载Istio
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 TARGET_ARCH=x86_64 sh -
上面执行的命令实际上是去执行downloadIstioCandidate.sh
地址:https://github.com/istio/istio/blob/2024024e2ba6032eac247187ec059690c782f41e/release/downloadIstioCandidate.sh
[root@k8s-master Istio]# curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 TARGET_ARCH=x86_64 sh -
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 101 100 101 0 0 67 0 0:00:01 0:00:01 --:--:-- 67
100 4856 100 4856 0 0 2047 0 0:00:02 0:00:02 --:--:-- 2064k
Downloading istio-1.17.2 from https://github.com/istio/istio/releases/download/1.17.2/istio-1.17.2-linux-amd64.tar.gz ...
下载包时,有时会出现一些情况:① Downloading时卡着不动;② curl: (35) Encountered end of file。
我们可以在hosts加上:
[root@k8s-master Istio]# vim /etc/hosts
185.199.110.133 raw.githubusercontent.com
当然,github的istio上直接提供了istio-1.17.2-linux-amd64.tar.gz
我们可以直接从上面下载下来
用curl下载成功后如下:
[root@k8s-master Istio]# curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.2 TARGET_ARCH=x86_64 sh -
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 101 100 101 0 0 66 0 0:00:01 0:00:01 --:--:-- 66
100 4856 100 4856 0 0 2052 0 0:00:02 0:00:02 --:--:-- 4742k
Downloading istio-1.17.2 from https://github.com/istio/istio/releases/download/1.17.2/istio-1.17.2-linux-amd64.tar.gz ...
Istio 1.17.2 Download Complete!
Istio has been successfully downloaded into the istio-1.17.2 folder on your system.
Next Steps:
See https://istio.io/latest/docs/setup/install/ to add Istio to your Kubernetes cluster.
To configure the istioctl client tool for your workstation,
add the /usr/local/mysoft/Istio/istio-1.17.2/bin directory to your environment path variable with:
export PATH="$PATH:/usr/local/mysoft/Istio/istio-1.17.2/bin"
Begin the Istio pre-installation check by running:
istioctl x precheck
Need more information? Visit https://istio.io/latest/docs/setup/install/
我们进入istio-1.17.2,有如下文件
[root@k8s-master Istio]# ll
total 4
drwxr-x--- 6 root root 4096 Apr 4 05:31 istio-1.17.2
[root@k8s-master Istio]# cd istio-1.17.2/
[root@k8s-master istio-1.17.2]# ll
total 40
drwxr-x--- 2 root root 4096 Apr 4 05:31 bin
-rw-r--r-- 1 root root 11348 Apr 4 05:31 LICENSE
drwxr-xr-x 5 root root 4096 Apr 4 05:31 manifests
-rw-r----- 1 root root 839 Apr 4 05:31 manifest.yaml
-rw-r--r-- 1 root root 6595 Apr 4 05:31 README.md
drwxr-xr-x 24 root root 4096 Apr 4 05:31 samples
drwxr-xr-x 3 root root 4096 Apr 4 05:31 tools
下载成功后有个提示:export PATH=”$PATH:/usr/local/mysoft/Istio/istio-1.17.2/bin”,我这里就把istioctl通过cp 拷贝到其他目录中去
[root@k8s-master bin]# ll
total 92720
-rwxr-xr-x 1 root root 94941184 Apr 4 05:31 istioctl
[root@k8s-master bin]# cp istioctl /usr/local/bin/istioctl
[root@k8s-master bin]# istioctl version
no running Istio pods in "istio-system"
1.17.2
上面有个提示:no running Istio pods in “istio-system”,那是因为在k8s集群中没有名为istio-system的namespace,自然也没有相关的Pod。
(2)安装Istio
本次安装,我们采用demo配置组合,选择它是因为包含了一组专为测试准备的功能集合,另外还有用于生产或性能测试的配置组合。
[root@k8s-master bin]# istioctl install --set profile=demo -y
The Kubernetes version v1.22.0 is not supported by Istio 1.17.2. The minimum supported Kubernetes version is 1.23.
Proceeding with the installation, but you might experience problems. See https://istio.io/latest/docs/setup/platform-setup/ for a list of supported versions.
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete Making this installation the default for injection and validation.
Thank you for installing Istio 1.17. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/hMHGiwZHPU7UQRWe9
安装完成后,有个提示:The Kubernetes version v1.22.0 is not supported by Istio 1.17.2. The minimum supported Kubernetes version is 1.23.(17.2不支持Kubernetes v1.22.0版本。Kubernetes支持的最低版本是1.23。)到了这一步,只有往下接着测试了。
[root@k8s-master Istio]# kubectl get ns
NAME STATUS AGE
default Active 47d
harbor Active 42d
istio-system Active 56s
[root@k8s-master Istio]# kubectl get po -n istio-system
NAME READY STATUS RESTARTS AGE
istio-egressgateway-5dbb585c6-cjjzs 1/1 Running 0 57s
istio-ingressgateway-796c869f8b-7bxxj 1/1 Running 0 57s
istiod-74559ff88b-h4fq4 1/1 Running 0 68s
给命名空间添加标签,指示Istio在部署应用的时候,自动注入Envoy边车代理。给default命名空间开启Sidecar的自动注入:
[root@k8s-master Istio]# kubectl label namespace default istio-injection=enabled
namespace/default labeled
[root@k8s-master Istio]# kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 47d istio-injection=enabled,kubernetes.io/metadata.name=default
harbor Active 42d kubernetes.io/metadata.name=harbor
istio-system Active 18m kubernetes.io/metadata.name=istio-system
kube-node-lease Active 47d kubernetes.io/metadata.name=kube-node-lease
kube-public Active 47d kubernetes.io/metadata.name=kube-public
kube-system Active 47d kubernetes.io/metadata.name=kube-system
monitor-sa Active 47d kubernetes.io/metadata.name=monitor-sa
nfs Active 42d kubernetes.io/metadata.name=nfs
(3)部署示例应用
① 部署Bookinfo示例应用
[root@k8s-master kube]# pwd
/usr/local/mysoft/Istio/istio-1.17.2/samples/bookinfo/platform/kube
[root@k8s-master kube]# ll
total 72
-rw-r--r-- 1 root root 914 Apr 4 05:31 bookinfo-certificate.yaml
-rw-r--r-- 1 root root 1387 Apr 4 05:31 bookinfo-db.yaml
-rw-r--r-- 1 root root 1409 Apr 4 05:31 bookinfo-details-v2.yaml
-rw-r--r-- 1 root root 1519 Apr 4 05:31 bookinfo-details.yaml
-rw-r--r-- 1 root root 1743 Apr 4 05:31 bookinfo-ingress.yaml
-rw-r--r-- 1 root root 2009 Apr 4 05:31 bookinfo-mysql.yaml
-rw-r--r-- 1 root root 988 Apr 4 05:31 bookinfo-ratings-discovery.yaml
-rw-r--r-- 1 root root 1596 Apr 4 05:31 bookinfo-ratings-v2-mysql-vm.yaml
-rw-r--r-- 1 root root 1825 Apr 4 05:31 bookinfo-ratings-v2-mysql.yaml
-rw-r--r-- 1 root root 1927 Apr 4 05:31 bookinfo-ratings-v2.yaml
-rw-r--r-- 1 root root 1519 Apr 4 05:31 bookinfo-ratings.yaml
-rw-r--r-- 1 root root 1643 Apr 4 05:31 bookinfo-reviews-v2.yaml
-rw-r--r-- 1 root root 920 Apr 4 05:31 bookinfo-versions.yaml
-rw-r--r-- 1 root root 7975 Apr 4 05:31 bookinfo.yaml
-rwxr-xr-x 1 root root 2517 Apr 4 05:31 cleanup.sh
-rw-r--r-- 1 root root 1026 Apr 4 05:31 productpage-nodeport.yaml
-rw-r--r-- 1 root root 137 Apr 4 05:31 README.md
[root@k8s-master kube]# kubectl apply -f bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
② 应用很快启动起来。当每个Pod准备就绪时,Istio边车将伴随应用一起部署
[root@k8s-master kube]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.104.234.177 <none> 9080/TCP 35s
productpage ClusterIP 10.110.228.199 <none> 9080/TCP 35s
ratings ClusterIP 10.108.67.237 <none> 9080/TCP 35s
reviews ClusterIP 10.105.19.225 <none> 9080/TCP 35s
[root@k8s-master kube]# kubectl get po
NAME READY STATUS RESTARTS AGE
details-v1-6758dd9d8d-54kt2 2/2 Running 0 3m45s
productpage-v1-797d845774-zlskb 2/2 Running 0 3m45s
ratings-v1-f849dc6d-k8kg4 2/2 Running 0 3m45s
reviews-v1-74fb8fdbd8-d78xd 2/2 Running 0 3m45s
reviews-v2-58d564d4db-lv8gc 2/2 Running 0 3m45s
reviews-v3-55545c459b-j7br5 2/2 Running 0 3m45s
③ 确认上面的操作都正确后,运行下面命令,通过检查返回的页面标题来验证应用是否已在集群中运行,并提供网页服务
[root@k8s-master kube]# kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
通过结果查看,已经部署成功。
(4)对外开放应用程序
此时,BookInfo应用已经部署好了,但还不能被外界访问。要开放访问,需要创建Istio入站网关(Ingress Gateway),它会在网格边缘把一个路径映射到路由。
① 把应用关联到Istio网关
[root@k8s-master ~]# cd /usr/local/mysoft/Istio/
[root@k8s-master Istio]# ll
total 4
drwxr-x--- 6 root root 4096 Apr 4 05:31 istio-1.17.2
[root@k8s-master Istio]# cd istio-1.17.2/
bin/ manifests/ samples/ tools/
[root@k8s-master Istio]# cd istio-1.17.2/samples/bookinfo/networking/
[root@k8s-master networking]# ll
total 84
-rw-r--r-- 1 root root 708 Apr 4 05:31 bookinfo-gateway.yaml
-rw-r--r-- 1 root root 622 Apr 4 05:31 certmanager-gateway.yaml
-rw-r--r-- 1 root root 1176 Apr 4 05:31 destination-rule-all-mtls.yaml
-rw-r--r-- 1 root root 972 Apr 4 05:31 destination-rule-all.yaml
-rw-r--r-- 1 root root 307 Apr 4 05:31 destination-rule-reviews.yaml
-rw-r--r-- 1 root root 885 Apr 4 05:31 egress-rule-google-apis.yaml
-rw-r--r-- 1 root root 522 Apr 4 05:31 fault-injection-details-v1.yaml
-rw-r--r-- 1 root root 804 Apr 4 05:31 virtual-service-all-v1.yaml
-rw-r--r-- 1 root root 194 Apr 4 05:31 virtual-service-details-v2.yaml
-rw-r--r-- 1 root root 396 Apr 4 05:31 virtual-service-ratings-db.yaml
-rw-r--r-- 1 root root 405 Apr 4 05:31 virtual-service-ratings-mysql-vm.yaml
-rw-r--r-- 1 root root 402 Apr 4 05:31 virtual-service-ratings-mysql.yaml
-rw-r--r-- 1 root root 423 Apr 4 05:31 virtual-service-ratings-test-abort.yaml
-rw-r--r-- 1 root root 422 Apr 4 05:31 virtual-service-ratings-test-delay.yaml
-rw-r--r-- 1 root root 290 Apr 4 05:31 virtual-service-reviews-50-v3.yaml
-rw-r--r-- 1 root root 290 Apr 4 05:31 virtual-service-reviews-80-20.yaml
-rw-r--r-- 1 root root 290 Apr 4 05:31 virtual-service-reviews-90-10.yaml
-rw-r--r-- 1 root root 332 Apr 4 05:31 virtual-service-reviews-jason-v2-v3.yaml
-rw-r--r-- 1 root root 334 Apr 4 05:31 virtual-service-reviews-test-v2.yaml
-rw-r--r-- 1 root root 290 Apr 4 05:31 virtual-service-reviews-v2-v3.yaml
-rw-r--r-- 1 root root 196 Apr 4 05:31 virtual-service-reviews-v3.yaml
[root@k8s-master networking]# kubectl apply -f bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
② 确保配置文件没有问题
[root@k8s-master networking]# istioctl analyze
✔ No validation issues found when analyzing namespace: default.
(5)确定入站IP和端口
执行下面命令判断k8s集群环境是否支持外部负载均衡:
[root@k8s-master networking]# kubectl get svc istio-ingressgateway -n istio-system
设置 EXTERNAL-IP的值后,环境就有了一个外部的负载均衡器,可以将其用作入站网关。但如果EXTERNAL-IP的值为<none>(或者一直处于<pending>状态),则环境没有提供可作为入站流量网关的外部负载均衡器,这个情况下,可以服务(Service)的节点端口访问网关。
设置入站的端口:
[root@k8s-master networking]# export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
[root@k8s-master networking]# echo $INGRESS_PORT
(6)验证外部访问
用浏览器查看BookInfo应用的产品页面,验证BookInfo是否实现了外部访问:
经验证,BookInfo实现了外部访问。
(7)查看仪表板
Istio和几个遥测应用做了集成。遥测能帮助了解服务网格的结构、展示网络的拓扑结构、分析网格的健康状态。
现在来部署Kiali仪表板、Prometheus、Grafana以及Jaeger。
① 安装Kiali和其他插件,等待部署完成。
[root@k8s-master istio-1.17.2]# kubectl apply -f samples/addons
serviceaccount/grafana created
configmap/grafana created
service/grafana created
deployment.apps/grafana created
configmap/istio-grafana-dashboards created
configmap/istio-services-grafana-dashboards created
deployment.apps/jaeger created
service/tracing created
service/zipkin created
service/jaeger-collector created
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali created
serviceaccount/prometheus created
configmap/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
service/prometheus created
deployment.apps/prometheus created
[root@k8s-master istio-1.17.2]# kubectl rollout status deployment/kiali -n istio-system
Waiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available...
deployment "kiali" successfully rolled out
注意:如果在安装插件时出错,再运行一次命令。有一些和时间相关的问题,再次运行就能解决。
② 访问Kiali仪表板
[root@k8s-master istio-1.17.2]# istioctl dashboard --address 10.0.18.13 -p20001 kiali
http://10.0.18.13:20001/kiali
通过浏览器查看,如下图:
③ 在左侧的导航菜单,选择Graph,然后再Namespace下拉列表中,选择default。
要查看追踪数据,必须向服务发送请求。请求的数量取决于Istio的采样率。采样率在安装Istio时设置,默认采样速率为1%。在第一个跟踪可见之前,需要发送至少100个请求。使用如下命令向productpage服务发送1000个请求:
[root@k8s-master istio-1.17.2]# for i in `seq 1 1000`; do curl -s -o /dev/null http://10.0.18.13:31481/productpage; done
Kiali仪表板展示了网格的概览以及BookInfo示例应用的各个服务之间的关系。它还提供过滤器来可视化流量的流动。
4. 流量管理
为了在网格中导流,Istio需要知道所有的endpoint在哪和属于哪个服务。为了定位到service registry(服务注册中心),Istio会连接到一个服务发现系统。例如,如果在Kubernetes集群上安装了Istio,那么它将自动检测该集群中的服务和endpoint。
使用此服务注册中心,Envoy代理可以将流量定向到相关服务。大多数基于微服务的应用程序,每个服务的工作负载都有多个实例来处理流量,称为负载均衡池。默认情况下,Envoy代理基于轮询调度模型在服务的负载均衡池内分发流量,按顺序讲请求发送给池中每个成员,一旦所有服务实例均接收过一次请求后,重新回到第一个池成员。
在许多情况下,可能希望对网格的流量情况进行更细粒度的控制。作为A/B测试的一部分,我们可能想将特定百分比的流量定向到新版本的服务,或者为特定的服务实例子集应用不同的负载均衡策略,还可能想对进出网格的流量应用特殊的负责,或者将网格的外部依赖项添加到服务注册中心,那么,通过使用Istio的流量管理API将流量配置添加到Istio,就可以完成所有这些甚至更多的工作。
虚拟服务
虚拟服务(Virtual Service)和目标规则(Destination Rule)是Istio流量路由功能的关键拼图。虚拟服务让我们的配置如何在服务网格内请求路由到服务,这基于Istio和平台提供的基本的连通性和服务发现能力。每个虚拟服务包含一组路由规则,Istio按顺序评估它们,Istio将每个给定的请求匹配到虚拟服务指定的实际目标地址。
4.1 配置请求路由
① 不同服务版本访问规则
我们先创建Destination Rule对象,Destination Rule对象是Virtual Service路由生效后配置应用与请求的策略集,用来将Virtual Service中指定的subset与对应的Pod关联起来。
在destination-rule-all.yaml文件中有定义该应用中所有要用到的Destination Rule资源对象:
[root@k8s-master networking]# cat destination-rule-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
......
[root@k8s-master networking]# kubectl apply -f destination-rule-all.yaml
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created
我们创建好Destination Rule资源后,可以查看我们网格中的Destination Rule:
[root@k8s-master networking]# kubectl get destinationrule
NAME HOST AGE
details details 3m12s
productpage productpage 3m12s
ratings ratings 3m12s
reviews reviews 3m12s
接着,我们来创建路由规则,路由到版本3。使用virtual-service-reviews-v3.yaml,如下:
[root@k8s-master networking]# cat virtual-service-reviews-v3.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v3
这样,所有访问reviews服务的流量就会被引导到reviews服务对应的subset为v3的Pod中:
[root@k8s-master networking]# kubectl apply -f virtual-service-reviews-v3.yaml
virtualservice.networking.istio.io/reviews created
查看路由规则:
[root@k8s-master networking]# kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
bookinfo ["bookinfo-gateway"] ["*"] 25h
reviews ["reviews"] 71s
然后,我们去多次刷新页面,看看效果:
多次刷新后,页面始终展示的是v3版本,带红色星的,说明我们Virtual Service的配置成功了。
② 基于权重的服务访问规则
排除对环境的影响,我们先把刚刚创建的Virtual Service对象删除:
[root@k8s-master networking]# kubectl delete virtualservice reviews
virtualservice.networking.istio.io "reviews" deleted
[root@k8s-master networking]# kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
bookinfo ["bookinfo-gateway"] ["*"] 25h
现在,我们查看文件virtual-service-reviews-80-20.yaml:
[root@k8s-master networking]# cat virtual-service-reviews-80-20.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 80
- destination:
host: reviews
subset: v2
weight: 20
这个规则定义了80%的流量流入v1,20%的流量流入v2,我们创建这个资源对象:
[root@k8s-master networking]# kubectl apply -f virtual-service-reviews-80-20.yaml
virtualservice.networking.istio.io/reviews created
[root@k8s-master networking]# kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
bookinfo ["bookinfo-gateway"] ["*"] 25h
reviews ["reviews"] 17s
在浏览器上访问BookInfo,经过多次刷新,可以发现,没有出现Ratings的次数与出现黑色星的Ratings的比例大概在4:1时,而且也没有出现红色星,说明我们基于权重的配置已经生效了。
参考链接:
https://istio.io/latest/docs/setup/getting-started/
https://zhuanlan.zhihu.com/p/421986295
https://cloud.tencent.com/developer/article/2023843
https://blog.nsfocus.net/istio%E7%B3%BB%E5%88%97%E4%BA%8C%EF%BC%9Aenvoy%E7%BB%84%E4%BB%B6%E5%88%86%E6%9E%90/