流量镜像

    • 遵循安装指南设置Istio。
    • 启动两个版本的httpbin服务,并确保对其日志的访问能力。

    httpbin-v1:

    httpbin-v2:

    1. cat <<EOF | kubectl create -f -
    2. apiVersion: extensions/v1beta1
    3. kind: Deployment
    4. metadata:
    5. name: httpbin-v2
    6. spec:
    7. replicas: 1
    8. template:
    9. metadata:
    10. labels:
    11. app: httpbin
    12. version: v2
    13. spec:
    14. containers:
    15. - image: docker.io/kennethreitz/httpbin
    16. imagePullPolicy: IfNotPresent
    17. name: httpbin
    18. command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:8080", "httpbin:app"]
    19. ports:
    20. - containerPort: 8080
    21. EOF

    httpbin的Kubernetes Service:

    1. cat <<EOF | kubectl create -f -
    2. apiVersion: v1
    3. metadata:
    4. name: httpbin
    5. labels:
    6. app: httpbin
    7. spec:
    8. ports:
    9. - name: http
    10. port: 8080
    11. selector:
    12. app: httpbin
    13. EOF
    • 启动sleep服务,然后我们就可以使用curl产生负载了。

    服务

    创建缺省的路由规则,把所有流量导向v1版本的httpbin服务。

    1. cat <<EOF | istioctl create -f -
    2. apiVersion: config.istio.io/v1alpha2
    3. kind: RouteRule
    4. metadata:
    5. name: httpbin-default-v1
    6. spec:
    7. destination:
    8. name: httpbin
    9. precedence: 5
    10. route:
    11. - labels:
    12. version: v1
    13. EOF

    现在所有流量都进入httpbin v1服务,我们尝试发送一些请求:

    1. export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
    2. kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers'
    3. {
    4. "headers": {
    5. "Accept": "*/*",
    6. "Host": "httpbin:8080",
    7. "User-Agent": "curl/7.35.0",
    8. "X-B3-Sampled": "1",
    9. "X-B3-Spanid": "eca3d7ed8f2e6a0a",
    10. "X-B3-Traceid": "eca3d7ed8f2e6a0a",
    11. "X-Ot-Span-Context": "eca3d7ed8f2e6a0a;eca3d7ed8f2e6a0a;0000000000000000"
    12. }
    13. }

    如果我们检查一下v1v2两个版本的httpbin服务的所属Pod的日志,会发现只有v1版本的Pod中出现了访问记录:

    创建到的镜像

    1. cat <<EOF | istioctl create -f -
    2. apiVersion: config.istio.io/v1alpha2
    3. kind: RouteRule
    4. metadata:
    5. name: mirror-traffic-to-httbin-v2
    6. spec:
    7. destination:
    8. name: httpbin
    9. precedence: 11
    10. route:
    11. - labels:
    12. version: v1
    13. weight: 100
    14. - labels:
    15. version: v2
    16. weight: 0
    17. mirror:
    18. name: httpbin
    19. labels:
    20. version: v2
    21. EOF

    这一规则指定100%的流量进入v1,进入v2的流量是0%。目前这样的古怪设置是必须的,我们需要这样的一条来通知后端,根据这一内容对Envoy集群进行配置,我们会在这方面进行改进,以便今后不再需要制定0%权重的路由。

    最后一段要求对流量进行复制,发送给httpbin v2服务。当流量被镜像的同时,这些请求会在Host/Authority头部加入-shadow字样,发送给镜像服务。例如cluster-1变成了cluster-1-shadow。另外,镜像请求是发完即忘的,对于镜像流量的请求响应是会被丢弃的。

    kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers'

    我们会在v1v2两个版本的Pod中都看到访问记录。v2中看到的访问日志实际上是访问v1的流量的镜像引发的。

    1. 删除规则

      1. istioctl delete routerule mirror-traffic-to-httbin-v2
    2. 关闭httpbin服务和客户端。

    阅读镜像配置参考,可以获得更多流量复制配置方面的信息。