流量镜像

发布时间 2023-05-26 16:45:58作者: FLOWERS_WAN

流量镜像,也称影子,是一个功能强大的概念,允许功能团队以尽可能小的风险将更改带到生产环境中,镜像将实时通信的副本发送到镜像服务。镜像通信发生在主服务的关键请求路径的带外。

在此任务中,您将首先强制所有流量到测试服务的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