系列文章:
总目录索引:九析带你轻松完爆 istio 服务网格系列教程
目录
1 前言
2 邀约
3 虚拟服务(Virtual Service)
4 虚拟服务跟 K8s 服务的关系
5 虚拟服务实例
5.1 k8s 资源
5.2 Istio 资源
5.3 Istio 注入
5.4 创建客户端和客户端 Istio 注入
1 前言
如果你对博客有任何疑问,请告诉我。
2 邀约
你可以从 b 站搜索 “九析”,获取免费的、更生动的视频资料:
3 虚拟服务(Virtual Service)
虚拟服务(Virtual Service)以及目标规则(Destination Rule)是 Istio 流量路由的两大基石。虚拟服务可以将流量路由到 Istio 服务网格中的服务。每个虚拟服务由一组路由规则组成,这些路由规则按顺序进行评估。
如果没有 Istio virtual service,仅仅使用 k8s service 的话,那么只能实现最基本的流量负载均衡转发,但是就不能实现类似按百分比来分配流量等更加复杂、丰富、细粒度的流量控制了。
4 虚拟服务跟 K8s 服务的关系
虚拟服务相当于 K8s 服务的 sidecar,在原本 K8s 服务的功能之上,提供了更加丰富的路由控制。
5 虚拟服务实例
以下介绍使用 “虚拟服务(virtual service)+目标规则(destination rule)” 实现一个流量分流的例子。本示例共需要四种资源,k8s 和 istio 各两种:
k8s 资源介绍如下:
1 两个 deployment,一个 tomcat,一个 nginx
2 一个 service 关联上面这两个 deployment
Istio 资源介绍如下:
1 一个 destination rule,设置目标规则定义
2 一个 virtual service 关联上面的 service,用来设置分流权重(weight)和设置分流目标规则定义)
5.1 k8s 资源
k8s 资源共有两类,分别为 deployment 和 service,其中 deployment 资源文件明细如下:
# jiuxi-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
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
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
部署上面的 jiuxi-deploy.yaml 文件,语句如下:
kubectl apply -f jiuxi-deploy.yaml
service 资源文件明细如下:
# jiuxi-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
ports:
- name: port
port: 8080
protocol: TCP
targetPort: 8080
selector:
type: web
部署上面的 service 文件,语句如下:
kubectl apply -f jiuxi-svc.yaml
自此,k8s 层面的资源文件准备完毕,现在通过访问 service,可以发现自动实现了RoundBin的负载均衡策略,即分配到 tomcat 和 nginx 的流量各为 50%。
5.2 Istio 资源
Istio 资源共有两类,分别为虚拟服务(Virtual Service)和目的地规则(Destination Rule)。虚拟服务作用在 k8s 服务之上,并加强了原 k8s 服务的功能:
指定目的地(tomcat 或 nginx)
重新分配流量(即不再是 50% / 50%,而是 75% / 25%)
目的地规则文件 jiux-dr.yaml 如下:
# jiuxi-dr.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: jiuxi-dr
spec:
host: jiuxi-svc
subsets:
- name: tomcat
labels:
app: tomcat
- name: nginx
labels:
app: nginx
上面的目的地资源文件作用在 jiux-svc 这个 k8s 服务上,通过 labels 字段指定不同的 pod,然后通过 name 字段提供给下面的 virtual service,起到关联到具体 pod 的作用。
如果这里你不好理解,可以这么来理解。以前 k8s service 跟 pod 关联是一维坐标关联,从上面例子可知,nginx 跟 tomcat 对 svc 而言是没什么区别的,因为都是相同的 labels 指定。但是如果采用了 virtual service 和 destination 相当于对 service 后面的 pod 使用了二维坐标关联,这样就可以明确定义 service 后面的 pod 到底有哪些业务含义了(比如一个是 nginx,另外一个是 tomcat)。这里大家仔细琢磨一下。
虚拟服务文件 jiuxi-vs.yaml 如下:
# jiuxi-vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: jiuxi-virtual-svc
spec:
hosts:
- jiuxi-svc
http:
- route:
- destination:
host: jiuxi-svc
subset: nginx
weight: 25
- destination:
host: jiuxi-svc
subset: tomcat
weight: 75
执行上面这两个资源文件:
kubectl apply -f jiuxi-dr.yaml
kubectl apply -f jiuxi-vs.yaml
命令执行后的结果如下截图所示:
5.3 Istio 注入
执行如下命令进行 Istio 注入:
istioctl kube-inject -f jiuxi-deploy.yaml | kubectl apply -f -
因为 nginx 默认启动是 80 端口,为了保持跟 tomcat 端口保持一致,这里需要登录到 pod 中修改 nginx 端口,操作方法如下:
# pod 后缀根据实际情况进行修改
kubectl exec -it nginx-deploy-957f689f5-7svdz -- sh
然后编辑 nginx 配置文件:
vi /etc/nginx/conf.d/default.conf
修改内容如下截图:
5.4 创建客户端和客户端 Istio 注入
创建客户端访问经过 Istio 流控过的 k8s 服务,客户端资源文件如下:
# jiuxi-busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
containers:
- name: nginx
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "sleep 3600" ]
执行如下 Istio 注入命令:
istioctl kube-inject -f jiuxi-busybox.yaml | kubectl apply -f -
Istio 注入成功后,通过 kubectl exec 登录到 busybox 容器中,然后执行如下语句,验证 virtual service 和 destination rule 功能:
注意这里的客户端也必须经过 Istio 注入,因为只有客户端被 Istio 注入,客户端才可以接收到来自 Pilot server 端有关 virtual service 和 destination rule 的配置信息,才可以保证 Istio 的 traffic management 真正生效。
自此,九析带你轻松完爆 Istio virtual service + Destination Rule 功能。