流量镜像,也称影子,是一个功能强大的概念,允许功能团队以尽可能小的风险将更改带到生产环境中,镜像将实时通信的副本发送到镜像服务。镜像通信发生在主服务的关键请求路径的带外。
在此任务中,您将首先强制所有流量到测试服务的V1,然后,您将应用一个规则来将一部分流量映射到V2。
1.准备工作
首先部署两个启用了访问日志记录的httpbin服务版本:
[root@k8s-master01 httpbin]# kubectl delete -n istio dr httpbin
destinationrule.networking.istio.io "httpbin" deleted
[root@k8s-master01 httpbin]#
[root@k8s-master01 httpbin]# kubectl delete -n istio deploy fortio-deploy
deployment.apps "fortio-deploy" deleted
[root@k8s-master01 httpbin]#
[root@k8s-master01 httpbin]# kubectl delete -n istio svc httpbin fortio
service "httpbin" deleted
service "fortio" deleted
[root@k8s-master01 httpbin]# kubectl delete -n istio deployments.apps httpbin
deployment.apps "httpbin" deleted
部署httpbin-v1
[root@k8s-master01 httpbin]# vim httpbin.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-v1
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn","--access-logfile","-","-b","0.0.0.0:80","httpbin:app"]
ports:
- containerPort: 80
部署httpbin-v2
[root@k8s-master01 httpbin]# vim httpbin-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-v2
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v2
template:
metadata:
labels:
app: httpbin
version: v2
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn","--access-logfile","-","-b","0.0.0.0:80","httpbin:app"]
ports:
- containerPort: 80
部署httpbin服务。
[root@k8s-master01 httpbin]# kubectl apply -f httpbinsvc.yaml -n istio
service/httpbin created
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
启动sleep的服务,才能使用curl
2.创建默认的路由策略
默认的情况下,kubernetes在两个版本的httpbin服务之间进行负载平衡,在此步骤中,您将更改行为,以便所有的流量
都到v1。
1.创建默认的路由规则去路由所有的流量到V1
[root@k8s-master01 httpbin]# kubectl apply -f httpbin-virtualservices.yaml -n istio
virtualservice.networking.istio.io/httpbin created
destinationrule.networking.istio.io/httpbin created
[root@k8s-master01 httpbin]# vim httpbin-virtualservices.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- httpbin
http:
- route:
- destination:
host: httpbin
subset: v1
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
2.使用sleep服务做测试,并查看httpbin v1和v2的日志输出
[root@k8s-master01 httpbin]# export SLEEP_POD=$(kubectl get pod -n istio -l app=sleep -o jsonpath={.items..metadata.name})
[root@k8s-master01 httpbin]# echo $SLEEP_POD
sleep-7fb47cd85-zkmmx
检查httpbin的V1和V2日志,应该看到V1版本有日志,V2版本没有
[root@k8s-master01 httpbin]# kubectl exec -it $SLEEP_POD -n istio -c sleep -- sh -c 'curl http://httpbin:8000/headers'
{
"headers": {
"Accept": "*/*",
"Host": "httpbin:8000",
"User-Agent": "curl/7.35.0",
"X-B3-Parentspanid": "0de9aa91f882f4be",
"X-B3-Sampled": "1",
"X-B3-Spanid": "0ba02704174193e0",
"X-B3-Traceid": "be5fad41aa0f20300de9aa91f882f4be",
"X-Envoy-Attempt-Count": "1",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/istio/sa/httpbin;Hash=bc25dbce7c86189303563c3e62ff0105955f8b7b36c700c6062dfc0f6001f457;Subject=\"\";URI=spiffe://cl
uster.local/ns/istio/sa/default" }
}
[root@k8s-master01 httpbin]#
[root@k8s-master01 httpbin]# kubectl logs -n istio -f httpbin-v1-5b6fd5859b-7cznn -c httpbin
[2023-05-25 15:28:36 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2023-05-25 15:28:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2023-05-25 15:28:36 +0000] [1] [INFO] Using worker: sync
[2023-05-25 15:28:36 +0000] [9] [INFO] Booting worker with pid: 9
127.0.0.6 - - [26/May/2023:13:45:58 +0000] "GET /headers HTTP/1.1" 200 521 "-" "curl/7.35.0"
^C
[root@k8s-master01 httpbin]#
[root@k8s-master01 httpbin]#
[root@k8s-master01 httpbin]# kubectl logs -n istio -f httpbin-v2-86dc78d89-2kjct -c httpbin
[2023-05-25 15:25:51 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2023-05-25 15:25:51 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2023-05-25 15:25:51 +0000] [1] [INFO] Using worker: sync
[2023-05-25 15:25:51 +0000] [9] [INFO] Booting worker with pid: 9
1.改变路由规则去镜像流量到V2
[root@k8s-master01 httpbin]# kubectl apply -f httpbin-virtualservices-v2.yaml -n istio
Warning: using deprecated setting "mirrorPercent", use "mirrorPercentage" instead
virtualservice.networking.istio.io/httpbin configured
此路由规则将流量100%发送到V1,最后一节指定您希望镜像到httpbin:v2服务,当流量被镜像时,请求被发送到镜像服务
,其host/Authority报头被附加上 -shadow,例如,cluster-1变成 cluster-1-shadow
另外需要注意,这些请求被镜像为“fire and forget”,这意味响应被丢弃。
可以使用mirror_percent 字段来镜像一部分流量,而不是镜像所有的请求,如果该字段不存在,为了与旧版本兼容,所有流量都被镜像。
2.发送流量
[root@k8s-master01 httpbin]# kubectl exec -it $SLEEP_POD -n istio -c sleep -- sh -c 'curl http://httpbin:8000/headers'
{
"headers": {
"Accept": "*/*",
"Host": "httpbin:8000",
"User-Agent": "curl/7.35.0",
"X-B3-Parentspanid": "6eef83813cc4d2a4",
"X-B3-Sampled": "1",
"X-B3-Spanid": "c9ddc1dfbdaa29ff",
"X-B3-Traceid": "771f64058dca8b296eef83813cc4d2a4",
"X-Envoy-Attempt-Count": "1",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/istio/sa/httpbin;Hash=bc25dbce7c86189303563c3e62ff0105955f8b7b36c700c6062dfc0f6001f457;Subject=\"\";URI=spiffe://cl
uster.local/ns/istio/sa/default" }
}
[root@k8s-master01 httpbin]# kubectl logs -n istio -f httpbin-v1-5b6fd5859b-7cznn -c httpbin
[2023-05-25 15:28:36 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2023-05-25 15:28:36 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2023-05-25 15:28:36 +0000] [1] [INFO] Using worker: sync
[2023-05-25 15:28:36 +0000] [9] [INFO] Booting worker with pid: 9
127.0.0.6 - - [26/May/2023:13:45:58 +0000] "GET /headers HTTP/1.1" 200 521 "-" "curl/7.35.0"
127.0.0.6 - - [26/May/2023:14:01:37 +0000] "GET /headers HTTP/1.1" 200 521 "-" "curl/7.35.0"
现在看到v1和v2的访问日志记录,在v2中创建的访问日志实际上是指向v1的镜像请求。
[root@k8s-master01 httpbin]# kubectl logs -n istio -f httpbin-v2-86dc78d89-2kjct -c httpbin
[2023-05-25 15:25:51 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2023-05-25 15:25:51 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2023-05-25 15:25:51 +0000] [1] [INFO] Using worker: sync
[2023-05-25 15:25:51 +0000] [9] [INFO] Booting worker with pid: 9
127.0.0.6 - - [26/May/2023:14:01:31 +0000] "GET /headers HTTP/1.1" 200 521 "-" "curl/7.35.0"
127.0.0.6 - - [26/May/2023:14:01:35 +0000] "GET /headers HTTP/1.1" 200 521 "-" "curl/7.35.0"
清理实验服务
[root@k8s-master01 httpbin]# kubectl delete vs httpbin -n istio
virtualservice.networking.istio.io "httpbin" deleted
[root@k8s-master01 httpbin]# kubectl delete dr httpbin -n istio
destinationrule.networking.istio.io "httpbin" deleted
[root@k8s-master01 httpbin]# kubectl delete deploy httpbin-v1 -n istio
deployment.apps "httpbin-v1" deleted
[root@k8s-master01 httpbin]# kubectl delete deploy httpbin-v2 -n istio
deployment.apps "httpbin-v2" deleted
[root@k8s-master01 httpbin]#
[root@k8s-master01 httpbin]# kubectl delete svc httpbin -n istio