方法一:忽略错误后,继续同步

备注:适用于主从数据库相差不大的情况

阅读全文 »

1、介绍

断路器是 Istio 提供的一个有用的技术。在微服务设置断路器可以有效保障微服务的抗操性。比如在断路器中,你可以设置服务并发连接次数限制或者服务调用失败次数,一旦达到设置的阈值,断路器将“跳闸”并停止与该主机的进一步连接。

因为断路器适用于负载平衡池中“真正”的服务网格(Istio 资源注入后的 Pod),因此可以在 Destination Rule 配置断路器,而 Destination Rule 最终会被翻译成 Envoy 的配置,然后作用在 Envoy 上。这样当流量进入到被 Istio 注入后的 Pod,流量就会被 Envoy 拦截,这样断路器就会针对流量发生作用。

阅读全文 »

1、介绍

Fortio 是 Istio 的负载测试工具,它提供了 web 控制台和命令行控制台的操作方式。因为后期我们在 Istio 断路器介绍中会使用到 Fortio,因此这节需要对 Fortio 进行安装和简单地操作。

2、安装

这里使用rpm装

1
2
curl -L https://github.com/fortio/fortio/releases/download/v1.3.1/fortio-1.3.1-1.x86_64.rpm -o fortio-1.3.1-1.x86_64.rpm
rpm -ivh fortio-1.3.1-1.x86_64.rpm

3、命令行

1
2
3
4
5
fortio load -c 5 -n 20 -qps 0 http://www.baidu.com
#命令解释如下:
-c 表示并发数
-n 一共多少请求
-qps 每秒查询数,0 表示不限制

image-20200601145601147

4、Web控制台

·· web 控制台方式就是提供给习惯使用 web 界面操作的同学一个途径来使用 Fortio。因为是基于 web 方式,所以就需要首先启动一个 web server,这样客户端浏览器才可以访问到 web server 提供的操作界面进行负载压测。默认情况 fortio server 会启动 8080 端口,如下图所示:

1
2
nohup fortio server &
tail -f nohup.out

image-20200601145803379

​ 打开浏览器,输入 http://192.168.10.11:8080/fortio,访问 Fortio server:

image-20200601145950124

​ 直接点击“start”按钮,将会看到压测效果:

image-20200601150029002

1、网络弹性介绍

​ 网络弹性也称为运维弹性,是指网络在遇到灾难事件时快速恢复和继续运行的能力。灾难事件的范畴很广泛,比如长时间停电、网络设备故障、恶意入侵等

2、Istio 超时实例

​ 需要结合 Istio 故障注入模拟被调用方响应请求慢的场景,该实例的架构图如下:

ht

​ 架构说明如下,本实例就是模拟客户端调用 nginx,nginx 将请求转发给 tomcat 的常见功能。tomcat 响应请求设置为 10s(通过故障注入实现,相当于 sleep 10s 逻辑),nginx 设置 client 的请求超时时间为 2s。因为 nginx 需要在 2s 内返回给 client,而 nginx 请求 tomcat 却需要 10s,因此模拟 client 调用 nginx 超时的情景。

2.1 部署客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: client
spec:
replicas: 1
selector:
matchLabels:
app: client
template:
metadata:
labels:
app: client
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "sleep 3600" ]

2.2 部署nginx和tomcat实例

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
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
server: nginx
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
server: nginx
spec:
replicas: 1
selector:
matchLabels:
server: nginx
template:
metadata:
labels:
server: nginx
spec:
containers:
- name: nginx
image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
selector:
server: tomcat
ports:
- name: http
port: 8080
targetPort: 8080
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat
labels:
server: tomcat
spec:
replicas: 1
selector:
matchLabels:
server: tomcat
template:
metadata:
labels:
server: tomcat
spec:
containers:
- name: tomcat
image: docker.io/kubeguide/tomcat-app:v1
imagePullPolicy: IfNotPresent

2.3 Istio 虚拟服务资源

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
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
spec:
hosts:
- nginx-svc
http:
- route:
- destination:
host: nginx-svc
timeout: 2s
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: tomcat-vs
spec:
hosts:
- tomcat-svc
http:
- fault:
delay:
percentage:
value: 100
fixedDelay: 10s
route:
- destination:
host: tomcat-svc

2.4 部署以上示例,并进行istio注入

1
2
istioctl kube-inject -f test-client.yaml | kubectl apply -f -
istioctl kube-inject -f test-deploy.yaml | kubectl apply -f -

image-20200529155003268

3、配置nginx转发tomcat

1
2
3
4
kubectl exec -it nginx-579d7f7ff-9pspn /bin/sh
修改完后让配置生效
nginx -t
nginx -s reload

修改内容如下

image-20200529155832030

4、客户端验证

1
2
3
kubectl exec -it client-8496866cdf-vkmcw /bin/sh
wget -q -O - http://nginx-svc
wget -q -O - http://tomcat-svc:8080

image-20200529160213693

image-20200529160225140

为了实验效果,设置长了时间,和设置的nginx 2s和tomcat 10s是吻合的,除去操作时间

1、虚拟服务(Virtual Service)

​ 虚拟服务(Virtual Service)以及目标规则(Destination Rule)是 Istio 流量路由的两大基石。虚拟服务可以将流量路由到 Istio 服务网格中的服务。每个虚拟服务由一组路由规则组成,这些路由规则按顺序进行评估。

​ 如果没有 Istio virtual service,仅仅使用 k8s service 的话,那么只能实现最基本的流量负载均衡转发,但是就不能实现类似按百分比来分配流量等更加复杂、丰富、细粒度的流量控制了。

备注:虚拟服务相当于 K8s 服务的 sidecar,在原本 K8s 服务的功能之上,提供了更加丰富的路由控制。

2、虚拟服务示例

​ 以下介绍使用 “虚拟服务(virtual service)+目标规则(destination rule)” 实现一个流量分流的例子。本示例共需要四种资源,k8s 和 istio 各两种:

​ k8s 资源介绍如下:

1
2
1、两个deployment,一个nginx,一个tomcat
2、一个service关联上面两个deploy

​ istio资源介绍如下:

1
2
1、一个destination  rule       #设置目标规则定义
2、一个VirtualService关联上面的svc,用来设置分流权重,以及设置分流目标规则定义

3、部署k8s资源

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
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: test
spec:
replicas: 1
selector:
matchLabels:
type: web
app: nginx
template:
metadata:
labels:
type: web
app: nginx
spec:
containers:
- image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
name: port
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deploy
namespace: test
spec:
replicas: 1
selector:
matchLabels:
type: web
app: tomcat
template:
metadata:
labels:
type: web
app: tomcat
spec:
containers:
- image: docker.io/kubeguide/tomcat-app:v1
imagePullPolicy: IfNotPresent
name: tomcat
ports:
- containerPort: 8080
name: port
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
namespace: test
spec:
ports:
- name: port
port: 8080
protocol: TCP
targetPort: 8080
selector:
type: web
sessionAffinity: None
type: NodePort

​ 自此,k8s 层面的资源文件准备完毕,现在通过访问 service,可以发现自动实现了RoundBin的负载均衡策略,即分配到 tomcat 和 nginx 的流量各为 50%。

4、部署istio资源

​ Istio 资源共有两类,分别为虚拟服务(Virtual Service)和目的地规则(Destination Rule)。虚拟服务作用在 k8s 服务之上,并加强了原 k8s 服务的功能:

  1. 指定目的地(tomcat 或 nginx)
  2. 重新分配流量(即不再是 50% / 50%,而是 75% / 25%)

4.1 目的地规则文件

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-dr
spec:
host: web-svc
subsets:
- name: tomcat
labels:
app: tomcat
- name: nginx
labels:
app: nginx

​ 上面的目的地资源文件作用在 web-svc 这个 k8s 服务上,通过 labels 字段指定不同的 pod,然后通过 name 字段提供给下面的 virtual service,起到关联到具体 pod 的作用。

4.2 虚拟服务文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtual-svc
spec:
hosts:
- "web-svc"
http:
- route:
- destination:
host: web-svc
subset: nginx
weight: 25
- destination:
host: web-svc
subset: tomcat
weight: 75

4.3 istio注入

执行如下命令进行 Istio 注入:

1
istioctl kube-inject -f  test-deploy.yaml |kubectl  apply  -f  -

image-20200511140020661

然后exec进入nginx-deploy的pod中修改配置文件监听端口为8080

1
vi /etc/nginx/conf.d/default.conf

image-20200511113829313

修改完保存退出,并重新加载nginx配置:

1
2
nginx -s reload
netstat -auntlp #查看监听端口

image-20200511114004584

备注:如果不想每次注入,就给ns注入sidecar

1
2
kubectl label namespaces test istio-injection=enabled
kubectl get ns test --show-labels

image-20200511140620317

4.4 通过客户端访问测试

1
2
kubectl run --namespace=test busybox --rm -ti --image busybox /bin/sh
wget -q -O - http://web-svc:8080

​ 会发现出现页面的比例和设置的权重是一致的。

​ emmmm…不想麻烦就直接在nginx的pod中去测试,这样能看到welcome nginx的页面,在其他pod中访问nginx页面503,没研究出来为啥看不到nginx欢迎界面!

5、destination rule介绍

​ destination rules 是 Istio 流量路由的关键功能,它不能独自使用,必须跟 Virtual Service 共同发挥作用。当 destination rules 跟 virtual service 共同使用的时候,virtual service 决定将流量路由到逻辑地址,而 destination rules 则决定流量路由到物理地址。

​ virtual service 跟 destination rules 路由关系就像变量到内存的地址映射一样,destination 代表内存实际地址,而 virtual service 作用就像程序的指针。

​ destination rules 通常用在微服务的版本分组上(例如可以通过 version 标签将微服务进行分组)。通过 destination rules 的分组规则可以实现将流量路由到服务的不同版本中,进而实现类似灰度、金丝雀、蓝绿等版本分流的策略。

​ destination rules 不仅可以决定把流量路由到何处,还可以制定如何路由流量(比如是轮询路由流量,还是随机路由流量等等)

6、路由策略

​ 默认情况下,Istio 使用轮询的负载均衡路由策略(round-robin),也就是说服务所有实例按顺序接收请求。当然 Istio 也支持如下的模型,这些模型都可以通过在 destination rule 中进行指定:

  1. Random:请求被随机分配给服务的实例
  2. Weighted:请求基于权重被分配给服务的实例
  3. Least requests:请求被分配给服务最少被访问的实例

1、介绍

​ Istio 故障注入与其他在网络层引入错误(例如延迟数据包或者直接杀死 Pod)的机制不同,Istio 允许在应用程序层注入故障。这使得可以注入更多相关的故障,比如 HTTP 错误代码等。

​ Istio 可以注入两种类型的故障,而这两种故障都是使用虚拟服务来配置的:

1
2
3
延迟:模拟增加网络延迟或上游服务过载。

中止:模拟服务故障而导致调用服务不可用。中止通常以 HTTP 错误代码或 TCP 连接失败表示

2、使用系统配置

1)注入HTTP延迟故障

1
2
3
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

经过上面的配置,下面是请求的流程:

  • productpagereviews:v2ratings (针对 jason 用户)
  • productpagereviews:v1 (其他用户)

为了测试微服务应用程序 Bookinfo 的弹性,将为用户 jasonreviews:v2ratings 服务之间注入一个 7 秒的延迟。

1
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml

2)测试延迟配置

  1. 通过浏览器打开Bookinfo应用

  2. 使用用户Jason登录到/prodectpage页面,会发现大约7秒钟加载完成并没有错误,但Reviews部分显示了错误消息

    image-20210517111211879

  3. 查看页面的相应时间大约6s

    image-20210517111330802

3)造成原理

按照预期,引入的 7 秒延迟不会影响到 reviews 服务,因为 reviewsratings 服务间的超时被硬编码为 10 秒。 但是,在 productpagereviews 服务之间也有一个 3 秒的硬编码的超时,再加 1 次重试,一共 6 秒。 结果,productpagereviews 的调用在 6 秒后提前超时并抛出错误了。Istio 的故障注入规则可以帮助您识别此类异常,而不会影响最终用户。

4)修复错误

  1. 增加 productpagereviews 服务之间的超时或降低 reviewsratings 的超时
  2. 终止并重启修复后的微服务
  3. 确认 /productpage 页面正常响应且没有任何错误

将所有流量转移到 reviews:v3, 您可以尝试修改延迟规则为任何低于 2.5 秒的数值,例如 2 秒,然后确认端到端的流程没有任何错误。

image-20210517112024272

5)注入HTTP abort故障

将给 ratings 微服务为测试用户 jason 引入一个 HTTP abort。在这种情况下,希望页面能够立即加载,同时显示 Ratings service is currently unavailable 这样的消息。为用户 jason 创建一个发送 HTTP abort 的故障注入规则:

1
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml

6)测试终止配置

  1. 用浏览器打开 Bookinfo 应用。
  2. 使用用户 jason 登陆到 /productpage 页面。如果规则成功传播到所有的 pod,能立即看到页面加载并看到 Ratings service is currently unavailable 消息。
  3. 如果您注销用户 jason 或在匿名窗口(或其他浏览器)中打开 Bookinfo 应用程序, 将看到 /productpage 为除 jason 以外的其他用户调用了 reviews:v1(完全不调用 ratings)。 因此,您不会看到任何错误消息。

3、自定义配置

1. 故障延迟

1.1 客户端资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
name: client
spec:
replicas: 1
selector:
matchLabels:
app: client
template:
metadata:
labels:
app: client
spec:
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "sleep 3600" ]

部署并使用istio注入,最终得到以下

image-20200529112054698

1.2 服务端资源

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
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
server: nginx
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
server: nginx
spec:
replicas: 1
selector:
matchLabels:
server: nginx
template:
metadata:
labels:
server: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent

1.3 虚拟服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-vs
spec:
hosts:
- nginx-svc
http:
- fault:
delay:
percentage:
value: 100
fixedDelay: 10s
route:
- destination:
host: nginx-svc

2. 验证故障注入

进入客户端容器中,访问nginx服务

1
2
kubectl exec -it client-8496866cdf-vkmcw /bin/sh
wget -q -O - http://nginx-svc

image-20200529113929500

可以看出时间延迟在十多秒,加上操作时间,和上面设置的时间是吻合的。

3. 故障中止

修改虚拟服务文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-vs
spec:
hosts:
- nginx-svc
http:
- fault:
abort:
percentage:
value: 100
httpStatus: 503
route:
- destination:
host: nginx-svc

4. 再次进入客户端验证

1
2
kubectl exec -it client-8496866cdf-vkmcw /bin/sh
wget -q -O - http://nginx-svc

image-20200529114513795

1、命名空间注入sidecar

1
2
kubectl label namespaces test istio-injection=enabled
kubectl get ns test --show-labels

2、使用默认文件

2.1 安装

说明:istio有默认文件,也可自己写,默认的安装与查看如下

1
2
3
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl get virtualservices -o yaml #显示已定义的路由
kubectl get destinationrules -o yaml #显示相应的 subset 定义

将 Istio 配置为路由到 Bookinfo 微服务的 v1 版本,最重要的是 reviews 服务的版本 1。

2.2 测试

通过再次刷新 Bookinfo 应用程序的 /productpage 轻松测试新配置,无论刷新多少次,页面的评论部分都不会显示评级星标。这是因为将 Istio 配置为 将评论服务的所有流量路由到版本 reviews:v1,而此版本的服务不访问星级评分服务。

image-20210514140908986

2.3 基于用户身份路由

来自名为 Jason 的用户的所有流量将被路由到服务 reviews:v2,Istio 对用户身份没有任何特殊的内置机制。productpage 服务在所有到 reviews 服务的 HTTP 请求中都增加了一个自定义的 end-user 请求头,从而达到了本例子的效果。

1
2
3
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
kubectl get virtualservice reviews -o yaml #查看规则是否创建成功

image-20210514141504667

  1. 在 Bookinfo 应用程序的 /productpage 上,以用户 jason 身份登录。刷新浏览器,看到星级评分显示在每个评论旁边

    image-20210514154617085

  2. 以其他用户身份登录(选择您想要的任何名称)。刷新浏览器。现在星星消失了。这是因为除了 Jason 之外,所有用户的流量都被路由到 reviews:v1

    image-20210514154700329

成功配置 Istio 以根据用户身份路由流量。

2.4 理解原理

使用 Istio 将 100% 的请求流量都路由到了 Bookinfo 服务的 v1 版本。 然后设置了一条路由规则,它根据 productpage 服务发起的请求中的 end-user 自定义请求头内容,选择性地将特定的流量路由到了 reviews 服务的 v2 版本。

3、自定义相关资源

3.1 配置Deployment和Service

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
apiVersion: v1
kind: Service
metadata:
name: test-service
namespace: test
labels:
app: test
spec:
ports:
- name: http
nodePort:
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: test
sessionAffinity: None
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-v1
namespace: test
spec:
replicas: 1
template:
metadata:
labels:
app: test
version: v1
spec:
containers:
- name: test
image: docker.io/kubeguide/tomcat-app:v1
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 8080

创建deployment和service

3.2 gateway

​ 首先,需要为服务网格启用HTTP/HTTPS流量。 为此,我们需要创建一个Gateway。 Gateway描述了在网络边缘运行的负载均衡器,用于接收传入或传出的HTTP / TCP连接。

让我们创建一个test-gateway.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: test-gateway
namespace: test
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"

创建Gateway

​ 已经为集群启用了HTTP流量。 需要将之前创建的Kubernetes服务映射到Gateway。将使用VirtualService执行此操作。

3.3 VirtualService

VirtualService实际上将Kubernetes服务连接到Istio网关。它还可以执行更多操作,例如定义一组流量路由规则,以便在主机被寻址时应用

创建一个test-virtualservice.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtualservice
namespace: test
spec:
hosts:
- "*"
gateways:
- test-gateway
http:
- route:
- destination:
host: test-service

创建VirtualService,请注意,VirtualService与特定网关绑定,并定义引用Kubernetes服务的主机。

测试app v1版本

现在可以开始测试应用了,首先需要拿到Istio Ingress Gateway的外部端口。

1
kubectl get svc istio-ingressgateway -n istio-system

![image-20200330111235863](istio Gateway 设置路由.assets/image-20200330111235863.png)

image-20200330111255489

3.4 DestinationRule

​ 在某些时候,希望将应用更新为新版本。 也许想分割两个版本之间的流量。 您需要创建一个DestinationRule来定义那些版本,在Istio中称为子集。

首先,更新test.yaml文件,用v2版本的容器来定义v2的部署(Deployment)

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
apiVersion: v1
kind: Service
metadata:
name: test-service
namespace: test
labels:
app: test
spec:
ports:
- port: 8080
name: http
selector:
app: test
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-v1
namespace: test
spec:
replicas: 1
template:
metadata:
labels:
app: test
version: v1
spec:
containers:
- name: test
image: docker.io/kubeguide/tomcat-app:v1
imagePullPolicy: Always #IfNotPresent
ports:
- containerPort: 8080
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: test-v2
namespace: test
spec:
replicas: 1
template:
metadata:
labels:
app: test
version: v2
spec:
containers:
- name: test
image: tomcat:8.0
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 8080

创建一个新的部署(Deployment),如果刷新浏览器,你可以看到VirtualService 在v1 和v2 版本之间切换:

image-20200330114434642

image-20200330114459072

如果您想将服务仅限于v2该怎么办? 可以通过在VirtualService中指定子集来完成,但需要首先在DestinationRules中定义这些子集。 DestinationRule本质上将标签映射到Istio子集。

创建一个test-destinationrule.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: test-destinationrule
namespace: test
spec:
host: test-service
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

创建DestinnationRule,可以在VirtualService指向v2子集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: test-virtualservice
namespace: test
spec:
hosts:
- "*"
gateways:
- test-gateway
http:
- route:
- destination:
host: test-service
subset: v2

更新VirtualService,现在再刷新浏览器,你应该只会看到v2版本的内容了

image-20200330114936181

1、bookinfo 架构介绍

​ bookinfo 是 istio 的学习样例,通过 bookinfo 你可以对 istio 提供的路由、遥测等功能有更加深入的理解。下图是 bookinfo 在没有嵌入 istio 前的物理架构图:

     bookinfo 是一个在线书店应用,该应用由 4 个微服务组成,分别为 Product page、Reviews、Details 和  Ratings。为了表现 istio 的无侵入性,这 4 个微服务分别由 python、java、ruby 和 node  开发。下面分别说明如下:
1
2
3
4
Product page:聚合服务,内容由 Reviews 和 Details 内容聚合而成
Details: 图书详情服务
Reviews: 图书评价服务(多版本)。它也是一个聚合服务,聚合了 Ratings
Ratings: 图书预订排名服务

下图是 bookinfo 嵌入 istio 后的物理架构图:

​ 该架构图演示了嵌入 istio 后 bookinfo 的每个微服务都会新增一个 Envoy,这个 Envoy 就是所谓的 sidecar,它会接管跟它配对的微服务的所有网络进、出口流量。其实 Envoy(sidecar)的作用就像你的手机,它正在逐渐把你变成哑巴、聋子和植物人,它承接了你所有的信息入口和出口,某些别有用心的人和组织通过对手机进行监控、遥测、路由等控制,起到控制你的思维、舆论导向、审美爱好等目的。

2、bookinfo 配置与部署

2.1 配置istio自动注入

因为 bookinfo 会启动多个 pod,每次手动注入 sidecar 会特别繁琐,因此我们使用批注入的方式

1
2
kubectl label namespace default istio-injection=enabled
kubectl get ns default --show-labels

image-20210513151231150

2.2 部署bookinfo 应用

1
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

image-20210513151313446

执行如下命令查看 bookinfo 的 service 列表:

1
kubectl get svc -n test

执行如下命令查看 bookinfo 的 pod 列表:

1
kubectl get pod -n test

image-20210513151845476

2.3 验证 bookinfo 部署情况

在服务列表中寻找 productpage 服务,然后使用 curl 命令验证服务是否发布成功。

1
2
3
4
5
6
kubectl get svc
#验证方式一:
curl http://10.43.53.159:9080 | grep -o "<title>.*</title>"

#验证方式二:
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"

image-20210513152156733

3、设置 bookinfo 网关

此时,BookInfo 应用已经部署,但还不能被外界访问。 要开放访问,你需要创建 Istio 入站网关(Ingress Gateway), 它会在网格边缘把一个路径映射到路由。

1
2
3
4
5
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml     #定义 bookinfo 入口网关

kubectl get gateways.networking.istio.io #确认网关已创建

istioctl analyze #确保配置文件没问题

image-20210513152502733

4、 访问 bookinfo 应用

1
2
3
kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}'           # 获取 INGRESS_HOST

kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}' #获取 INGRESS_PORT

image-20210513152747077

根据此 host 和 port,打开浏览器进行访问,多刷新几次页面,你会发现 bookinfo 应用使用到的多个 reviews 版本,有时书评的输出包含星级评分,有时则不包含。 这是因为没有明确的默认服务版本路由,Istio 将以循环方式请求路由到所有可用版本。如下所示:

1
http://192.168.10.200:31862/productpage          #ip加端口会报404

image-20210513152930707

5、卸载 bookinfo 应用

1
/root/istio-1.10.0-rc.1/samples/bookinfo/platform/kube/cleanup.sh

image-20210513153250037

执行如下命令验证你是否成功卸载:

1
2
3
4
kubectl get virtualservices.networking.istio.io
kubectl get destinationrules.networking.istio.io
kubectl get gateways.networking.istio.io
kubectl get pod

1、注入

为了充分利用 Istio 的所有特性,网格中的 pod 必须运行一个 Istio sidecar 代理。

向 pod 中注入 Istio sidecar 的两种方法:使用 istioctl 手动注入或启用 pod 所属命名空间的 Istio sidecar 注入器自动注入。

手动注入直接修改配置,如 deployment,并将代理配置注入其中。

当 pod 所属命名空间启用自动注入后,自动注入器会使用准入控制器在创建 Pod 时自动注入代理配置。

通过应用 istio-sidecar-injector ConfigMap 中定义的模版进行注入。

2、手动注入sidecar

上一节实现了istio的安装,所有的pod都是running状态,但不知其作用,现在先创建一个deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14-alpine
ports:
- containerPort: 80

为了方便视图,创建一个新的名称空间

1
2
3
kubectl  create  namespace test
kubectl apply -f nginx.yml -n test
kubectl get pod -n test

image-20200316111616355

执行如下语句:

1
2
istioctl  kube-inject -f nginx.yml | kubectl apply  -n test -f -
kubectl get pod -n test

image-20200316112939899

稍等会儿就能看到原来一个pod变成了两个,如果你有类似 rancher 这样的 web 控制台,可以看得更仔细些,如

下图所示。

image-20200316113231845

从上图可知。此时 nginx pod 内部一共有 3 个容器,一个初始化容器 istio-init 已经运行成功并结束了,一个就是

nginx 本尊,另外一个就是本文的主角 istio-proxy 了,它就是 sidecar,作用是负责跟外部打交到用的。

3、命名空间注入sidecar

当你在一个命名空间中设置了 istio-injection=enabled 标签,且 injection webhook 被启用后,任何新的 pod 都有将在创建时自动添加 sidecar。

现在删除掉刚才创建的 nginx:

1
kubectl delete deploy nginx -n test

执行如下命令在命名空间内实现自动注入 sidecar:

1
2
kubectl label namespaces test istio-injection=enabled
kubectl get ns test --show-labels #查看状态

再次创建nginx的deploy文件

1
kubectl apply -f nginx.yml -n test

稍等会儿就能看到已经自动注入了

image-20200316114453004

1、环境介绍

image-20200116144218255

2、运行以下命令来自动下载并解压缩最新版本:

1
curl -L https://istio.io/downloadIstio | sh -

说明:由于k8s集群是1.21.0版本,这里使用的是istio最新测试版本

3、安装目录包含:

  • samples/ 目录下的示例应用程序
  • bin/ 目录下的 istioctl 客户端二进制文件

4、设置环境变量

1
2
3
4
5
6
7
8
9
10
11
12
cd cd istio-1.10.0-rc.1/
export PATH=$PATH:$PWD:/bin

vim tools/istioctl.bash
PWD=/root/istio-1.10.0-rc.1
export PATH=$PATH:$PWD/bin

cp tools/istioctl.bash /root/
vim /root/.bash_profile
source ~/istioctl.bash

source ~/.bash_profile

5、安装demo配置文件

  1. default: 根据默认的安装选项启用组件 (建议用于生产部署)。
  2. demo: 这一配置具有适度的资源需求,旨在展示 Istio 的功能。它适合运行 Bookinfo 应用程序和相关任务。
  3. minimal: 使用 Istio 的流量管理功能所需的最少组件集。
  4. sds: 和 default 配置类似,但是启用了 Istio 的 SDS (secret discovery service) 功能。 这个配置文件默认启用了附带的认证功能 (Strict Mutual TLS)。

image-20210513155002143

1
istioctl install --set profile=demo -y

image-20210513145557351

备注:这里有的镜像可能拉不下来,需要自己想办法,等待时间可能有点长

6、通过确保已部署以下Kubernetes服务来验证安装

1
2
kubectl get pod -n istio-system
kubectl get svc -n istio-system

说明:由于自建集群没有lb,所以会ingressgateway会处于pending状态,改成NodePort即可

image-20210513145858343

7、卸载会删除RBAC权限,istio-system名称空间以及它下面的层次结构中的所有资源

1
istioctl manifest generate --set profile=demo | kubectl delete -f -