02.istio部署微服务
# 01.istio部署微服务
- https://istio.io/latest/docs/examples/bookinfo/#determine-the-ingress-ip-and-port
# 1.1 项目介绍
该应用由四个单独的微服务构成,这个应用模仿在线书店的一个分类,显示一本书的信息
页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。
Bookinfo 应用分为四个单独的微服务
1)
productpage
这个微服务会调用details
和reviews
两个微服务,用来生成页面;2)
details
这个微服务中包含了书籍的信息;3)
reviews
这个微服务中包含了书籍相关的评论,它还会调用 ratings 微服务;4)
ratings
这个微服务中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本
1)v1 版本不会调用 ratings 服务;
2)v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息;
3)v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。
# 1.2 注入Envoy sidecar
# 1、架构说明
- 要在 Istio 中运行这一应用,无需对应用自身做出任何改变。
- 只要简单的在 Istio 环境中对服务进行配置和运行,具体一点说就是把 Envoy sidecar 注入到每个服务之中。
- 所有的微服务都和 Envoy sidecar 集成在一起,被集成服务所有的出入流量都被 envoy sidecar 所劫持
- 这样就为外部控制准备了所需的 Hook,然后就可以利用 Istio 控制平面为应用提供服务路由、遥测数据收集以及策略实施等功能。
# 2、打标签注入
1、进入 istio 安装目录。
2、istio 默认自动注入 sidecar,需要为 default 命名空间打上标签 istio-injection=enabled
- 打完标签以后,default命名空间的所有pod会自动注入 sidecar代理
kubectl label namespace default istio-injection=enabled
- 3、使用 kubectl 部署应用
- 上面的命令会启动全部的四个服务,其中也包括了 reviews 服务的三个版本(v1、v2 以及 v3)
cd istio-1.10.1
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
2
# 3、istio-init和istio-proxy
这时候再去看下新的 Pod 信息,已经被自动注入了下面两个容器:istio-proxy、istio-init。
istio-init
- istio-init 的作用是配置 iptables 规则,将入站、出站流量交由 istio-proxy 代理
- istio-init 容器会在应用容器启动之前运行,并且执行完成后就退出了,通常用来完成一些初始化任务
istio-proxy
真正的 sidecar 代理,基于 Envoy 实现。
istio-proxy 是如何获取应用容器的入站和出站流量?答案就在 istio-init 这个容器的iptables规则中
iptables中会将出入流量重定向到 istio-proxy 容器对应的端口
-p 15001 表示出站流量被 iptable 重定向到 Envoy 的15001 端口 -z 15006 表示入站流量被 iptable 重定向到 Envoy 的15006 端口 -u 1337 用于排除用户ID 为1337 即 istio-proxy 自身的流量
1
2
3
# 02.部署服务
# 2.1 bookinfo.yaml
官方地址:
https://istio.io/latest/docs/examples/bookinfo/
https://raw.githubusercontent.com/istio/istio/release-1.15/samples/bookinfo/platform/kube/bookinfo.yaml
# 1、Details书籍信息
##################################################################################################
# Details service
##################################################################################################
apiVersion: v1
kind: Service # Service本质就是一个LB负载均衡器
metadata:
name: details
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount # ServiceAccount给pod里面的进程使用,为pod提供必要的身份认证
metadata:
name: bookinfo-details
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment # Deployment控制器管理Pod对象,滚动更新等
metadata:
name: details-v1 # 控制器的名字是 “details-v1”
labels:
app: details
version: v1
spec:
replicas: 1 # 指定 “details-v1”这个控制器管理的pod是1个
selector:
matchLabels: # 给pod指定标签
app: details
version: v1
template: # 上面控制器创建的pod使用的都是这个模板来定义的
metadata:
labels:
app: details # 指定创建的pod有那些标签
version: v1
spec:
serviceAccountName: bookinfo-details
containers:
- name: details # 指定容器的名字是 details
image: docker.io/istio/examples-bookinfo-details-v1:1.17.0 # 使用镜像版本
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
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
# 2、Ratings书籍评价
##################################################################################################
# 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
---
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
# 3、Reviews书籍评论v1,v2,v3
##################################################################################################
# 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: {}
---
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
# 4、Productpage前端
##################################################################################################
# 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: {}
---
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
# 2.2 bookinfo-gateway.yaml
https://raw.githubusercontent.com/istio/istio/release-1.15/samples/bookinfo/networking/bookinfo-gateway.yaml
网关接受到请求后会按照路由配置转发到VirtualService虚拟服务
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway # istio的网关资源
metadata:
name: bookinfo-gateway # 网关名字(这个资源是 ingressgateway)
spec:
selector:
istio: ingressgateway # 使用istio默认控制器(将ingressgateway关联到istio-ingressgateway全局网关)
# 外网是通过 istio-ingressgateway 网关来代理流量给 ingressgateway 的
servers:
- port:
number: 80 # 网关监听端口
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService # VirtualService虚拟服务
metadata:
name: bookinfo
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway # 将虚拟服务绑定到istio bookinfo-gateway这个网关
http:
- match: # 定义匹配规则,访问这些url就会转发到 productpage服务
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage # productpage是服务名字 默认后缀是 .default.svc.cluster.local
port:
number: 9080
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
配置ingressgateway网关
kubectl edit svc istio- ingressgateway-n istio-system
- 此时就可以使用
- xxx.example.com/producpage 访问页面
# 03.istio 核心资源
# 3.1 Gateway
- 在 Kubernetes 环境中,Ingress controller 用于管理进入集群的流量
- 在 Istio 服务网格中 Istio Ingress Gateway 承担相应的角色
- 它使用新的配置模型(Gateway 和 VirtualServices)完成流量管理的功能
- 注:
网关配置应用于在网格边缘运行的独立 Envoy 代理
,而不是与服务工作负载一起运行的 Sidecar Envoy 代理
- 所以我们配置的 gateway资源指的是 下图中的 ② istio-ingressgateway
# 1、访问流程
1、用户向某端口发出请求
2、负载均衡器监听端口,并将请求转发到集群中的某个节点上。
- Istio Ingress Gateway Service 会监听集群节点端口的请求
3、Istio Ingress Gateway Service 将请求交给 Istio Ingress Gateway Pod 处理。
- IngressGateway Pod 通过 Gateway 和 VirtualService 配置规则处理请求。
- 其中,Gateway 用来配置端口、协议和证书;VirtualService 用来配置一些路由信息(找到请求对应处理的服务 App Service)
4、Istio Ingress Gateway Pod 将请求转给 App Service
5、最终的请求会交给 App Service 关联的 App Deployment 处理
# 2、gateway.yaml
网关是一个运行在网格边缘的负载均衡器,用于接收传入或传出的 HTTP/TCP 连接。
主要工作是接受外部请求,把请求转发到内部服务。
网格边缘的 Ingress 流量,会通过对应的 Istio IngressGateway Controller 进入到集群内部。
在上面这个 yaml 里我们配置了一个监听 80 端口的入口网关,它会将 80 端口的 http 流量导入到集群内对应的 Virtual Service 上。
Istio Gateway告诉k8s的istio-ingressgateway pods可以打开哪些主机和端口
它这是通过使用
Kubernetes创造的标签选择器( label selector)
模式来实现
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: canary-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*" # *表示通配符,通过任何域名都可以访问
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3.2 VirtualService
- VirtualService 是 Istio 流量治理的一个核心配置,可以说是 Istio 流量治理中最重要、最复杂的。
- VirtualService 在形式上表示一个虚拟服务,将满足条件的流量都转发到对应的服务后端
- 这个服务后端可以是一个服务,也可以是在 DestinationRule 中定义的服务的子集。
# 1、virtual.yaml
- 这个虚拟服务会收到上一个 gateway 中所有 80 端口来的 http 流量
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: canary
spec:
hosts:
- "*" # *表示通配符,任何域名都可以,也可以配置具体域名 eg: www.example.com
# 1)hosts:虚拟主机名称,它是客户端向服务发送请求时使用的一个或多个地址
# 通过该字段提供的地址访问 virtual service,进而访问后端服务
# 在集群内部(网格内)使用时通常与 kubernetes 的 Service 同名
# 当需要在集群外部(网格外)访问时,该字段为 gateway 请求的地址,即与 gateway 的 hosts 字段相同
gateways:
- canary-gateway
http:
- route:
- destination:
host: canary.default.svc.cluster.local
subset: v1
weight: 90
- destination:
host: canary.default.svc.cluster.local
subset: v2
weight: 10
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 2、headers匹配
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user: # 此路由接收来自 ”jason“ 用户的所有请求,把请求发送到 destination 指定的 v2 子集
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination: # 不满足第一个路由规则的流量均流向一个默认的目标,第二条规则没有 match 条件,直接将流量导向 v3 子集
host: reviews
subset: v3
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 3、多路由规则
- 路由规则是将特定流量子集路由到指定目标地址的工具。
- 可以在流量端口、header 字段、URI 等内容上设置匹配条件。
- 例如,下面这个虚拟服务让用户发送请求到两个独立的服务:ratings 和 reviews,
- http://bookinfo.com/ratings 请求转发到
ratings
服务 - http://bookinfo.com/reviews 请求转发到
reviews
服务 - 虚拟服务规则根据请求的 URI 把请求路由到特定的目标地址
- http://bookinfo.com/ratings 请求转发到
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
# 1)hosts:虚拟主机名称,它是客户端向服务发送请求时使用的一个或多个地址
# 通过该字段提供的地址访问 virtual service,进而访问后端服务
# 在集群内部(网格内)使用时通常与 kubernetes 的 Service 同名
# 当需要在集群外部(网格外)访问时,该字段为 gateway 请求的地址,即与 gateway 的 hosts 字段相同
http:
- match:
- uri:
prefix: /reviews
route:
- destination:
host: reviews # 路由的 destination 字段指定了匹配条件的流量的实际地址
# 与 virtual service 的主机不同,该host 必须是存在于 istio 的服务注册表
# (如 kubernetes services,consul services 等)中的真实目的地或由 ServiceEntries 声明的 hosts
# 否则 Envoy 不知道应该将流量发送到哪里
- match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
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
# 3.3 DestinationRule.yaml
destination rule 是 istio 流量路由功能的重要组成部分。
一个 virtual service 可以看作是如何将流量分发给特定的目的地,然后调用 destination rule 来配置分发到该目的地的流量。
destination rule 在 virtual service 的路由规则之后起作用,应用于真实的目的地。
- (即在 virtual service 的 math->route-destination 之后起作用,此时流量已经分发到真实的 service 上)
可以使用 destination rule 来指定命名的服务子集,例如根据版本对服务的实例进行分组
然后通过 virtual service 的路由规则中的服务子集将控制流量分发到不同服务的实例中。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: canary
spec:
host: canary.default.svc.cluster.local
subsets:
- name: v1
labels:
app: v1
- name: v2
labels:
app: v2
2
3
4
5
6
7
8
9
10
11
12
13