Istio 大型微服务系统管理工具
背景
在基于的微服务体系结构中,都会存在一些需要解决的问题,例如当我们的不同服务(应用)直接进行交互访问,如何进行流量控制、鉴权、服务熔断、治理等问题,不同的微服务架构实现这些功能方式不一,像Spring Cloud与Netflix OSS是偏向于通过使用微服务的框架来实现,而基于Kubernetes的微服务体系是通过服务网格方式来进行实现
什么是服务网格(Service Mesh):服务网格指的是专门处理服务通讯的基础设施层,目前比较主流的有Istio
简介
Istio 是一个由谷歌、IBM 与 Lyft 共同开发的开源项目,旨在提供一种统一化的微服务连接、安全保障、管理与监控方式。Istio 项目能够为微服务架构提供流量管理机制,同时亦为其它增值功能(包括安全性、监控、路由、连接管理与策略等)创造了基础。这款软件利用久经考验的 Lyft Envoy 代理进行构建,可在无需对应用程序代码作出任何发动的前提下实现可视性与控制能力。
Envoy 服务代理扩展了 Kubernetes,以建立一个可编程的、可感知的应用程序网络。Istio 与 Kubernetes 和传统工作负载一起使用,为复杂的部署带来了标准的通用流量管理、遥测和安全性。
特点
流量管理:部署服务间路由,故障恢复和负载平衡等功能。
可观测性:提供流量和服务性能的端到端视图。
安全:跨服务进行加密,基于角色的访问和身份验证。
概念
流量管理
流量管理指的是在Client调用到我们服务的过程中对其进行管理,包括其路由到指定服务,负载均衡,服务熔断超时重试等
- Gateway:它控制网络边界,指定了从外部网络进入Istio网络的请求如何被处理。Gateway定义了负责处理请求的服务器,以及请求的进入端点。
- VirtualService:它控制网络流量,指定了请求如何被路由到服务。VirtualService定义了请求如何到达特定的服务,以及在路由到服务时的其他流量控制策略。
- DestinationRule:它控制服务流量,指定了请求如何被路由到服务的具体实例。DestinationRule定义了服务的抖动行为、负载均衡策略和请求的拆分策略。
虚拟服务(VirtualService)
虚拟服务(Virtual Service)是Istio组件之一,用于将服务网格内的请求路由到对应的服务,每个虚拟服务包含一组路由规则
1 |
|
- hosts:虚拟服务主机地址,即用户指定的目标或是路由规则设定的目标。这是客户端向服务发送请求时使用的一个或多个地址。可以是IP、域名、通配符
- match:路由匹配,支持正则
- destination:目的地址
更多参考官方文档:https://istio.io/latest/zh/docs/reference/config/networking/virtual-service/
目标规则(Destination Rule)
目标规则(Destination Rule)配合虚拟服务,用于配置目的地址的负载均衡,服务子集版本等
1 |
|
负载均衡支持
- 随机:请求以随机的方式转到池中的实例。
- 权重:请求根据指定的百分比转到实例。
- 最少请求:请求被转到最少被访问的实例。
网关(Gateway)
网关主要用于管理入站和出栈流量, Istio 的网关资源可以配置 4-6 层的负载均衡属性,如对外暴露的端口、TLS 设置等
1 |
|
这个网关配置让 HTTPS 流量从 ext-host.example.com 通过 443 端口流入网格,但没有为请求指定任何路由规则。为想要工作的网关指定路由,您必须把网关绑定到虚拟服务上
1 |
|
服务入口(Service Entry)
使用服务入口(Service Entry) 来添加一个入口到 Istio 内部维护的服务注册中心。添加了服务入口后,Envoy 代理可以向服务发送流量,就好像它是网格内部的服务一样。配置服务入口允许你管理运行在网格外的服务的流量,它包括以下几种能力:
- 为外部目标 redirect 和转发请求,例如来自 web 端的 API 调用,或者流向遗留老系统的服务。
- 为外部目标定义重试、超时和故障注入策略。
- 添加一个运行在虚拟机的服务来扩展您的网格。
示例:将 ext-resource 外部依赖项添加到 Istio 的服务注册中心:
1 |
|
配置DR设置超时时间
1 |
|
边车(Sidecar)
sidecar主要的作用是:
- 微调 Envoy 代理接受的端口和协议集。
- 限制 Envoy 代理可以访问的服务集合。
原理
应用
安装Istio
获取istio
1
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.16.2 TARGET_ARCH=arm_64 sh -
移动可执行二进制文件到
1
cp istioctl /usr/bin/
查看版本
1
istioctl version
安装istio
1
istioctl install --set profile=demo -y
给命名空间添加标签,指示 Istio 在部署应用的时候,自动注入 Envoy 边车代理:
1
kubectl label namespace default istio-injection=enabled
部署应用
官方案例
Bookinfo 应用分为四个单独的微服务:
- productpage. 这个微服务会调用 details 和 reviews 两个微服务,用来生成页面。
- details. 这个微服务中包含了书籍的信息。
- reviews. 这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
- ratings. 这个微服务中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本:
- v1 版本不会调用 ratings 服务。
- v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
- v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。
部署
1
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343# Copyright Istio Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##################################################################################################
# This file defines the services, service accounts, and deployments for the Bookinfo sample.
#
# To apply all 4 Bookinfo services, their corresponding service accounts, and deployments:
#
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
#
# Alternatively, you can deploy any resource separately:
#
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount
# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment
##################################################################################################
##################################################################################################
# Details service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: details
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-details
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: details-v1
labels:
app: details
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: details
version: v1
template:
metadata:
labels:
app: details
version: v1
spec:
serviceAccountName: bookinfo-details
containers:
- name: details
image: docker.io/istio/examples-bookinfo-details-v1:1.17.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Ratings service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: ratings
labels:
app: ratings
service: ratings
spec:
ports:
- port: 9080
name: http
selector:
app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-ratings
labels:
account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v1
labels:
app: ratings
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v1
template:
metadata:
labels:
app: ratings
version: v1
spec:
serviceAccountName: bookinfo-ratings
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v1:1.17.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Reviews service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
labels:
app: reviews
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.17.0
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
labels:
app: reviews
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.17.0
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.17.0
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-productpage
labels:
account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
labels:
app: productpage
version: v1
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.17.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {}
---1
2
3
4
5
6
7
8
9
10
11
12
13
14service/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查看Service
1
2
3
4
5
6
7
8
9[root@k8s-master01 bookinfo]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo ClusterIP 10.105.133.95 <none> 80/TCP 91d
details ClusterIP 10.98.114.171 <none> 9080/TCP 3m26s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 98d
nginx ClusterIP None <none> 80/TCP 14d
productpage ClusterIP 10.102.82.121 <none> 9080/TCP 3m15s
ratings ClusterIP 10.101.219.48 <none> 9080/TCP 3m15s
reviews ClusterIP 10.111.191.190 <none> 9080/TCP 3m15s查看Pod
1
kubectl get pod
访问
1
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>"
1
<title>Simple Bookstore App</title>
对外开放
经上述步骤部署成功后我们需要对其进行提供外部访问,需要创建 Istio 入站网关(Ingress Gateway), 它会在网格边缘把一个路径映射到路由。
把应用关联到istio网关
1
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
查看集群是否支持外部负载均衡
1
kubectl get svc istio-ingressgateway -n istio-system
1
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.96.248.193 <pending> 15021:31675/TCP,80:30703/TCP,443:32396/TCP,31400:31654/TCP,15443:30816/TCP 88m设置 EXTERNAL-IP 的值之后, 您的环境就有了一个外部的负载均衡器,可以将其用作入站网关。 但如果 EXTERNAL-IP 的值为
(或者一直是 状态), 则您的环境则没有提供可作为入站流量网关的外部负载均衡器。 在这个情况下,您还可以用服务(Service)的节点端口访问网关。 通过节点端口访问网关,设置入站端口
1
2export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')设置入站访问入口
1
2
3export INGRESS_HOST=worker-node-address
//如
export INGRESS_HOST=192.168.100.211
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
设置环境变量
1
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
查看访问Endpoint
1
echo "$GATEWAY_URL"
验证外部访问
1
echo "http://$GATEWAY_URL/productpage"
1
http://192.168.100.21:30703/productpage
我们在访问的时候会随机的打到三个服务上,
修改路由把全部流量指向v1
1
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: details
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
---
安装仪表盘
创建可视化仪表盘
创建可视化仪表盘
1
2kubectl apply -f samples/addons
kubectl rollout status deployment/kiali -n istio-system访问仪表盘
1
2
3istioctl dashboard kiali
#上面的只能是集群内部访问,想要外部访问可以指定开发的节点地址
istioctl dashboard kiali --address 192.168.100.21
以上案例体验完后想删除可直接直接clean脚本进行清除1
samples/bookinfo/platform/kube/cleanup.sh
案例
配置请求路由
如何将请求动态路由到微服务的多个版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16apiVersion: 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所有请求指向同一个版本
1
2
3
4
5
6
7
8
9
10
11
12apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1基于用户身份的路由
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
故障注入
此任务说明如何注入故障并测试应用程序的弹性。
流量转移
展示如何将流量从旧版本迁移到新版本的服务。
TCP 流量转移
展示如何将一个服务的 TCP 流量从旧版本迁移到新版本。
设置请求超时
本任务用于示范如何使用 Istio 在 Envoy 中设置请求超时。
熔断
本任务展示如何为连接、请求以及异常检测配置熔断。
镜像
此任务演示了 Istio 的流量镜像/影子功能。
地域负载均衡
本系列任务演示如何在 Istio 中配置地域负载均衡。
Ingress
控制 Istio 服务网格的入口流量。
Egress
控制 Istio 服务网格的出口流量。