Istio介绍
istio代表的是Service Mesh的方案实现,Istio 有助于降低这些部署的复杂性,并减轻开发团队的压力。提供一种简单的方式来为已部署的服务建立网络,且提供具有负载均衡、服务间认证、监控、流量管理等功能。
服务网格(Service Mesh)
服务网格(Service Mesh)用于描述构成这些应用程序的微服务网络以及应用之间的交互。随着规模和复杂性的增长,服务网格越来越难以理解和管理。它的需求包括服务发现、负载均衡、故障恢复、指标收集和监控以及通常更加复杂的运维需求,例如 A/B 测试、金丝雀发布、限流、访问控制和端到端认证等。而istio刚好提供了一套完整的解决方案,通过控制整个服务器网格提供行为洞察和操作控制来满足微服务应用的多样化
架构
Istio 服务网格逻辑上分为数据平面和控制平面。
- 数据平面由一组以 sidecar 方式部署的智能代理(Envoy)组成。这些代理可以调节和控制微服务及 Mixer 之间所有的网络通信。
- 控制平面负责管理和配置代理来路由流量。此外控制平面配置 Mixer 以实施策略和收集遥测数据。
构成每个面板的不同组件:
istio 组件
- Envoy: Istio 使用 Envoy 代理的扩展版本,用于调解服务网格中所有服务的所有入站和出站流量,属于数据层面。Istio利用Envoy的内置功能实现如下指标:
- 动态服务发现
- 负载均衡
- TLS终止
- HTTP/2和gRPC代理
- 断路器
- 健康检查
- 分阶段推出,按百分比分配流量
- 故障注入
- 丰富的指标
- Mixer: 是一个独立于平台的组件,负责在服务网格上执行访问控制和使用策略,并从 Envoy 代理和其他服务收集遥测数据
- Pilot: 为 Envoy sidecar 提供服务发现功能,为智能路由(例如 A/B 测试、金丝雀部署等)和弹性(超时、重试、熔断器等)提供流量管理功能
- Citadel: 通过内置身份和凭证管理赋能强大的服务间和最终用户身份验证。可用于升级服务网格中未加密的流量,并为运维人员提供基于服务标识而不是网络控制的强制执行策略的能力
- Galley: 代表其他的 Istio 控制平面组件,用来验证用户编写的 Istio API 配置。随着时间的推移,Galley 将接管 Istio 获取配置、 处理和分配组件的顶级责任
Istion 安装
下载istio包
执行下载和自动解压缩
1 | # curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.4.0 sh - |
安装目录中包含:
在 install/
: 目录中包含了 Kubernetes 安装所需的 .yaml 文件samples/
: 目录中是示例应用istioctl
: istioctl客户端二进制文件。手动将Envoy作为Sidecar代理注入并创建路由规则和策略时,将使用此工具。istio.VERSION
: 配置文件
在kubernetes 集群中安装
Istio 会被安装到自己的 istio-system 命名空间,并且能够对所有其他命名空间的服务进行管理。这里采用helm进行安装,helm安装参考,我们需要为Kiali设置身份验证凭据(监视)。用于后面的登录认证
设置用户名和密码的环境变量
1 | # KIALI_USERNAME=$(read -p 'Kiali Username: ' uval && echo -n $uval | base64) |
创建命名空间
1 | # NAMESPACE=istio-system |
- 创建用于存储上面设置的用户名/密码的机密
1
2
3
4
5
6
7
8
9
10
11
12
13cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: kiali
namespace: $NAMESPACE
labels:
app: kiali
type: Opaque
data:
username: $KIALI_USERNAME
passphrase: $KIALI_PASSPHRASE
EOF
使用helm安装istio CRD
1 | # helm install install/kubernetes/helm/istio-init --name istio-init --namespace istio-system |
查看安装的CRD和pod
上述安装会把istio的23个crd都提交给kubernetes api 服务器。如果启用了证书管理,crd计数器为28个。我这里未启用证书管理,只有23个。还生成三个pod
CRD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33# kubectl get CustomResourceDefinition
NAME CREATED AT
adapters.config.istio.io 2019-10-29T08:41:31Z
attributemanifests.config.istio.io 2019-10-29T08:41:30Z
authorizationpolicies.rbac.istio.io 2019-10-29T08:41:36Z
certificates.certmanager.k8s.io 2019-10-29T08:41:38Z
challenges.certmanager.k8s.io 2019-10-29T08:41:40Z
clusterissuers.certmanager.k8s.io 2019-10-29T08:41:37Z
clusterrbacconfigs.rbac.istio.io 2019-10-29T08:41:26Z
destinationrules.networking.istio.io 2019-10-29T08:41:25Z
envoyfilters.networking.istio.io 2019-10-29T08:41:26Z
gateways.networking.istio.io 2019-10-29T08:41:26Z
handlers.config.istio.io 2019-10-29T08:41:33Z
httpapispecbindings.config.istio.io 2019-10-29T08:41:27Z
httpapispecs.config.istio.io 2019-10-29T08:41:28Z
instances.config.istio.io 2019-10-29T08:41:32Z
issuers.certmanager.k8s.io 2019-10-29T08:41:37Z
meshpolicies.authentication.istio.io 2019-10-29T08:41:27Z
orders.certmanager.k8s.io 2019-10-29T08:41:40Z
policies.authentication.istio.io 2019-10-29T08:41:27Z
quotaspecbindings.config.istio.io 2019-10-29T08:41:28Z
quotaspecs.config.istio.io 2019-10-29T08:41:29Z
rbacconfigs.rbac.istio.io 2019-10-29T08:41:31Z
rules.config.istio.io 2019-10-29T08:41:30Z
serviceentries.networking.istio.io 2019-10-29T08:41:25Z
servicerolebindings.rbac.istio.io 2019-10-29T08:41:31Z
serviceroles.rbac.istio.io 2019-10-29T08:41:31Z
sidecars.networking.istio.io 2019-10-29T08:41:34Z
templates.config.istio.io 2019-10-29T08:41:32Z
virtualservices.networking.istio.io 2019-10-29T08:41:25Z
# kubectl get crds | grep 'istio.io\|certmanager.k8s.io' | wc -l
23pod
1
2
3
4
5
6# kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
NAME READY STATUS RESTARTS AGE
istio-init-crd-10-1.4.0-pbtb8 0/1 Completed 0 47s
istio-init-crd-11-1.4.0-shx6q 0/1 Completed 0 47s
istio-init-crd-12-1.4.0-zmh2w 0/1 Completed 0 47s
使用helm安装各个组件
1 | helm install install/kubernetes/helm/istio --wait \ |
验证安装
验证文件里面的服务是否都部署在kubernetes 服务中。确保部署的pod 在对应的kubernetes namespace 里面,并正常启动。
这期间将创建所需的RBAC权限,并部署Istio-Pilot,Istio-Mixer,Istio-Ingress,Istio-Egress和Istio-CA(证书颁发机构)。
服务器验证
确保部署了以下Kubernetes服务:istio-pilot,istio-mixer,istio-ingress。
1 | # kubectl get svc -n istio-system |
pod 验证
确保已部署相应的Kubernetes Pod,并且所有容器都已启动并正在运行
1 | # kubectl get pods -n istio-system |
Istio 以一个项目的形式部署到 Kubernetes 集群中。我们可以看到,部署好的 pods 中,除了有 istio-citadel、、istio-ingressgateway、istio-pilot 等 Istio 本身的功能组件,还集成了微服务相关的监控工具,,如:grafana、jaeger-query、kiali、prometheus。这些功能丰富且强大的监控工具,帮助 Istio实现了微服务的可视化管理。
部署BookInfo用程序
现在开始部署 Bookinfo 示例程序。部署Bookinfo条件是集群中至少有4个节点,而且每个节点的内存不得低于4G。
可以部署安装随附的示例应用程序之一-BookInfo。这是一个简单的模拟书店应用程序,由四个服务组成,这些服务提供一个Web产品页面,书籍详细信息,评论(带有多个版本的评论服务)和评分-所有这些都使用Istio进行管理。
BookInfo应用程序分为四个单独的微服务:
- productpage :productpage 微服务会调用 details 和 reviews 两个微服务,用来生成页面。
- details :这个微服务包含了书籍的信息。
- reviews :这个微服务包含了书籍相关的评论。它还会调用 ratings 微服务。
- ratings :ratings 微服务中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本:
- v1 版本不会调用 ratings 服务.
- v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息
- v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息
下图展示了这个应用的端到端架构
打标签
为 default 命名空间打上标签 istio-injection=enabled,实现 Sidecar 自动注入。
1 | # kubectl label namespace default istio-injection=enabled |
- 注意: 此步骤先不执行,如果这这个执行了,在后面部署Bookinfo的时候会提示如下错误
Error creating: Internal error occurred: failed calling webhook "sidecar-injector.istio.io": Post https://istio-sidecar-injector.istio-system.svc:443/inject?timeout=30s: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
这一步有执行的可以执行以下命令进行删除。该错误已解决,详情参考
- 删除ns的label
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 2d4h istio-injection=enabled
istio-system Active 174m <none>
kube-node-lease Active 2d4h <none>
kube-public Active 2d4h <none>
kube-system Active 2d4h <none>
# kubectl label namespace default istio-injection-
namespace/default labeled
# kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 2d4h <none>
istio-system Active 175m <none>
kube-node-lease Active 2d4h <none>
kube-public Active 2d4h <none>
kube-system Active 2d4h <none>
部署Bookinfo
直接使用kubectl create其常规的YAML部署文件来部署我们的应用程序。将使用istioctl将Envoy容器注入到应用程序容器中:
1 | # kubectl create -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml) |
该命令将启动bookinfo应用程序体系结构图中显示的所有四个服务。已启动评论服务的所有3个版本,即v1,v2和v3。而在实际部署中,随着时间的推移会部署新版本的微服务,而不是同时部署所有版本。
检查部署
确认所有服务和Pod均已正确定义并正在运行。
检查 services
1
2
3
4
5
6
7# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.254.61.113 <none> 9080/TCP 2m27s
kubernetes ClusterIP 10.254.0.1 <none> 443/TCP 43d
productpage ClusterIP 10.254.130.5 <none> 9080/TCP 2m23s
ratings ClusterIP 10.254.186.181 <none> 9080/TCP 2m26s
reviews ClusterIP 10.254.200.107 <none> 9080/TCP 2m25s检查 pod
1
2
3
4
5
6
7
8
9
10# kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-c5b5f496d-lphgd 1/1 Running 0 15h
load-generator-7fbcc7489f-vbpnx 1/1 Running 2 20d
nginx-deploy-d494b9564-vx97s 1/1 Running 1 20d
productpage-v1-c7765c886-97spj 1/1 Running 0 15h
ratings-v1-f745cf57b-mdgxr 1/1 Running 0 15h
reviews-v1-75b979578c-ghqqm 1/1 Running 0 15h
reviews-v2-597bf96c8f-r659w 1/1 Running 0 15h
reviews-v3-54c6c64795-tvsmq 1/1 Running 0 15h确认Bookinfo应用程序正在运行,请通过curl某个pod中的命令向其发送请求
1
2# kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
在每个服务旁边都注入了Envoy,架构将如下
Bookinfo服务已启动并正在运行,您需要使该应用程序可以从Kubernetes集群外部访问,例如,从浏览器访问。Istio网关用于此目的。但是我在部署 bookinfo-gateway 的时候出现错误,错误如下;然后看了一下 bookinfo-gateway就是提供一个web访问的程序,既然是提供的一个web访问,我就使用了Traefix来提供这个服务。
1 | Error from server (Timeout): error when creating "samples/bookinfo/networking/bookinfo-gateway.yaml": Timeout: request did not complete within requested timeout 30s |
创建 bookinfo-gateway
- istio-Ingress.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# cat >istio-Ingress.yaml <<EOF
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: istio-web-ui
namespace:
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: istio.xxlaila.cn
http:
paths:
- path: /
backend:
serviceName: productpage
servicePort: 9080
EOF
在浏览器输入http://istio.xxlaila.cn
来访问。用 productpage以查看BookInfo网页。如果您多次刷新页面,您应该会看到产品页面上显示的评论版本不同,并以循环方式显示(红色星星,黑色星星,无星星),因为我们尚未使用Istio来控制版本路由
基本道这里,动态更改请求路由学习中,😂😂😂
监控方式
生成服务图
要验证Kiali是否在您的集群中运行
1 | # kubectl -n istio-system get svc kiali |
流量发送到网格,有三种选择:
1.在网络浏览器中访问http://istio.xxlaila.cn/productpage
2.多次使用以下命令
1 | # curl http://istio.xxlaila.cn/productpage |
3.使用以下watch命令连续发送请求:
1 | # watch -n 1 curl -o /dev/null -s -w %{http_code} http://istio.xxlaila.cn/productpage |
这里需要配置Kiali UI,我们同样适用Traefix来进行配置
- kiali–Ingress.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# cat > kiali--Ingress.yaml <<EOF
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kiali-web-ui
namespace: istio-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: istio-kiali.xxlaila.cn
http:
paths:
- path: /
backend:
serviceName: kiali
servicePort: 20001
在浏览器打开http://istio-kiali.xxlaila.cn , 要登录Kiali UI,请转到Kiali登录屏幕,然后输入存储在Kiali机密中的用户名和密码。账户密码是前面我们设置的
1.网格概述
登录后立即显示的“概述”页面中查看网格的概述。“概述”页面显示了网格中具有服务的所有名称空间。以下屏幕截图显示了类似的页面
2.空间图
要查看名称空间图,请在bookinfoBookinfo名称空间卡中单击图图标。图形图标位于名称空间卡的左下方,看起来像是一组相连的圈子。该页面类似于
分布式跟踪系统
启用Istio的应用程序可以配置为使用流行的Jaeger分布式跟踪系统来收集跟踪范围。分布式跟踪使您可以查看用户在系统中发出的请求流,而Istio的模型则允许这样做,而与构建应用程序所使用的语言/框架/平台无关。使用Traefix来提供这个服务。
Jaeger-Ingress.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18# cat > Jaeger-Ingress.yaml <<EOF
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jaeger-web-ui
namespace: istio-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: jaeger.xxlaila.cn
http:
paths:
- path: /
backend:
serviceName: jaeger-query
servicePort: 16686执行创建
1
2# kubectl apply -f Jaeger-Ingress.yaml
ingress.extensions/jaeger-web-ui unchanged
在浏览器打开http://jaeger.xxlaila.cn , 使用Bookinfo示例生成跟踪,要查看跟踪数据,必须将请求发送到服务。请求数量取决于Istio的采样率。您在安装Istio时设置此速率。默认采样率为1%。您需要至少发送100个请求,才能显示第一条跟踪。要将100个请求发送到productpage服务,请使用以下命令:
1 | # for i in `seq 1 100`; do curl -s -o /dev/null http://istio.xxlaila.cn/productpage; done |
在仪表板的左侧窗格中,从“服务”下拉列表中选择productpage.default,然后单击“查找跟踪”
单击顶部的最新跟踪以查看与对/ productpage的最新请求相对应的详细信息
监视Istio
如何设置和使用Istio仪表板监视网格流量。作为监控的一部分,需要将安装Grafana Istio插件,并使用基于Web的界面查看服务网格流量数据。Grafana将用于可视化普罗米修斯数据。在执行部署的时候也部署了这两个服务。
创建grafana Ingress
1 | # cat >grafana-istio-Ingress.yaml <<EOF |
- 执行创建,这里我们可以在以前的grafana里面添加数据库源,就不用在新起一个域名来进行访问
再次加载Bookinfo应用程序(http://istio.xxlaila.cn/productpage) , 刷新页面几次(或发送命令几次)以产生少量流量。再次查看Istio仪表板。它应该反映所产生的流量。
istio 还提供了网格的全局视图以及网格中的服务和工作负载。您可以通过导航到特定的仪表板来获取有关服务和工作负载的更多详细信息。
提供了有关服务指标的详细信息,然后是该服务的客户端工作负载(正在调用此服务的工作负载)和服务工作负载(正在提供该服务的工作负载)。
Istio 在grafana 提供了很多的监控指标,可以分别点击看看
查询Istio指标
Istio的数据是存储在prometheus里面的,这里我们通过prometheus进行直接数据的查询
查看prometheus服务
1 | # kubectl -n istio-system get svc prometheus |
prometheus traefix
通过traefix 来代理prometheus,然后我们将流量发送到网格。
prometheus-istio.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# cat > prometheus-istio-Ingress.yaml <<EOF
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: prometheus-istio-web-ui
namespace: istio-system
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: prometheus-istio.xxlaila.cn
http:
paths:
- path: /
backend:
serviceName: prometheus
servicePort: 9090
EOF执行创建
1
2# kubectl apply -f prometheus-istio-Ingress.yaml
ingress.extensions/prometheus-istio-web-ui created
在浏览器打开http://prometheus-istio.xxlaila.cn ,可以在输入框里面输入表达式来获取指,输入文本:istio_requests_total
其他查询尝试:
对productpage服务的所有请求总数:
1
istio_requests_total{destination_service="productpage.default.svc.cluster.local"}
对v3版本的评论服务的所有请求总数:
1
istio_requests_total{destination_service="reviews.default.svc.cluster.local", destination_version="v3"}
该查询将所有请求的当前总数返回到评论服务的v3。
- 过去5分钟内对productpage服务所有实例的请求率:
1
rate(istio_requests_total{destination_service=~"productpage.*", response_code="200"}[5m])
- 过去5分钟内对productpage服务所有实例的请求率: