K8s中Service我们知道是网络方面的服务,而Virtual Service
是istio中的概念, 虚拟服务(Virtual Service
)以及目标规则(Destination Rule
)是 Istio 流量路由的两大基石。虚拟服务可以将流量路由到 Istio 服务网格中的服务。每个虚拟服务由一组路由规则组成,这些路由规则按顺序进行评估。
虚拟服务相当于 K8s 服务的 sidecar,在原本 K8s 服务的功能之上,提供了更加丰富的路由控制。
在之前的文章中以istio自带的示例做了一些演示,但是有的地方还是比较难懂,在这里再参考一下九析大佬的文章,再进行有目的的学习。
创建虚拟服务
首先再创建一个ns并开启自动注入进行试验。
[root@localhost ~]# kubectl create ns test
[root@localhost ~]# kubectl label ns test istio-injection=enabled
首先创建两个deployment并创建相应的svc关联到deploy
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
type: web ##共有的label
app: nginx
name: nginx-deploy ##创建nginx的deploy
spec:
replicas: 1
selector:
matchLabels:
app: nginx
type: web
template:
metadata:
labels:
app: nginx
type: web
spec:
containers:
- name: nginx
image: nginx:1.14-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: port
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
type: web ##共有的label
app: nginx
name: tomcat-deploy ##创建tomcat的deploy
spec:
replicas: 1
selector:
matchLabels:
app: tomcat
type: web
template:
metadata:
labels:
app: tomcat
type: web
spec:
containers:
- name: tomcat
image: docker.io/kubeguide/tomcat-app:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: port
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
ports:
- name: port
port: 8080
protocol: TCP
targetPort: 8080
selector:
type: web ##将有type=web标签的deploy和svc绑定起来
创建完成之后apply一下(nginx和tomcat的端口不一样,所以访问的时候应该只能访问到tomcat的8080端口,访问nginx时会报错,这时候需要进入pod手动去更改端口)
[root@localhost ~]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
nginx-deploy-64f67cc576-dhj2j 2/2 Running 0 6m34s
tomcat-deploy-5b9c4b6b64-j7hwr 2/2 Running 0 4m53s
[root@localhost ~]# kubectl get svc -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-svc ClusterIP 10.68.56.93 <none> 8080/TCP 4m7s
这样的做法在访问服务时,就会出现一次tomcat一次nginx这个时默认50-50的轮询。
[root@localhost ~]# curl 10.68.56.93:8080
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Apache Tomcat/8.0.35</title>
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="tomcat.css" rel="stylesheet" type="text/css" />
</head>
...
[root@localhost ~]# curl 10.68.56.93:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
如果想要更细的控制,那就需要引入istio中的一些概念
1、首先用DR指定目的地
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule ##创建DR
metadata:
name: test-dr ##DR的名字
spec:
host: web-svc ##走web-svc这个svc
subsets: ##在web-svc这个svc上创建相应的目的地
- name: tomcat ##规则名字叫tomcat
labels: ##选择一个标签有app=tomcat的pod作为目的地
app: tomcat
- name: nginx ##nginx同理
labels:
app: nginx
创建完成后可以查看
[root@localhost test]# kubectl apply -f dr-test.yaml -n test
destinationrule.networking.istio.io/test-dr created
[root@localhost test]# kubectl get -n test destinationrules.networking.istio.io
NAME HOST AGE
test-dr web-svc 21s
2、再创建vsvc,将vsvc也绑定到k8s中的svc再细化时通过DR去设定规则
apiVersion: networking.istio.io/v1beta1
kind: VirtualService ##创建vsvc
metadata:
name: test-virtual-svc ##vsvc的名字
spec:
hosts:
- web-svc ##host绑定web-svc的svc
http:
- route:
- destination: ##设定规则,在web-svc之上通过DR这个目的地路由的规则
host: web-svc
subset: nginx
weight: 25 ##权重25%
- destination:
host: web-svc
subset: tomcat
weight: 75
[root@localhost test]# kubectl apply -f vsvc-test.yaml -n test
virtualservice.networking.istio.io/test-virtual-svc created
[root@localhost test]# kubectl get virtualservices.networking.istio.io -n test
NAME GATEWAYS HOSTS AGE
test-virtual-svc ["web-svc"] 2m14s
设置完成再来看看效果
随便进入一个被注入的容器,
curl web-svc:8080
这个时候就可以看到效果,大部分的返回都是tomcat的,而少部分是nginx,多试几次就可以算出差不多是三比一的概率。