利用virtualservice的mirror配置实现流量镜像

举报
可以交个朋友 发表于 2023/12/11 10:44:37 2023/12/11
【摘要】 可以将生产系统中宝贵的实际流量镜像一份到另一个系统上,完全不会对生产系统产生影响,降低部署的风险。

一、 背景

流量镜像,也称为影子流量,指的是在将新流量转发到原目标地址的同时,将流量给另一个目标地址镜像一份。可以将生产系统中宝贵的实际流量镜像一份到另一个系统上,完全不会对生产系统产生影响,降低部署的风险。


二、 简介

利用istio virtualservice中的mirror配置实现:
image.png

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
    - httpbin
  http:
  - route:
    - destination:
        host: httpbin
        subset: v1
      weight: 100
    mirror:
      host: httpbin
      subset: v2

HTTP 流量镜像,在将流量转发到原目标地址的同时,将流量给另一个目标地址镜像一份。


三、 实践操作

演示会分为两部分,分别是不配置流量镜像的效果,和配置流量镜像后的效果。

3.1 环境准备

首先部署两个版本的 Httpbin 服务,并开启访问日志功能:

  1. 创建v1版本

    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:
          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
    
  2. 创建v2版本

    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:
          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
    
  3. 创建service

    apiVersion: v1
    kind: Service
    metadata:
      name: httpbin
      labels:
        app: httpbin
    spec:
      ports:
      - name: http
        port: 8000
        targetPort: 80
      selector:
        app: httpbin
    
    
  4. 创建客户端负载

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          containers:
          - name: sleep
            image: curlimages/curl
            command: ["/bin/sleep","3650d"]
            imagePullPolicy: IfNotPresent
    

3.2、 创建istio crd 管理流量

  1. 创建vs进行流量管理: 默认没有使用影子流量

    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. 测试脚本

    #! /bin/bash
    date
    set -v
    
    # 1. 访问
    export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
    kubectl exec "${SLEEP_POD}" -c sleep -- curl -sS http://httpbin:8000/headers
    
    # 2. 查看日志
    
    export V1_POD=$(kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items..metadata.name})
    kubectl logs "$V1_POD" -c httpbin
    
    export V2_POD=$(kubectl get pod -l app=httpbin,version=v2 -o jsonpath={.items..metadata.name})
    kubectl logs "$V2_POD" -c httpbin
    
    

    测试结果: 分别查看 httpbin Pod的 v1v2 两个版本的日志。您可以看到 v1 版本的访问日志条目,而 v2 版本没有日志:

    image-20230919160228405.png

  3. 配置镜像流量
    镜像到v2版本服务: 镜像流量的目标通过destination 结构描述,可以是httpbin服务的一个版本,或者是服务网格的另一个服务,也可以是通过seviceentry定义的服务网格外部的服务。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      hosts:
        - httpbin
      http:
      - route:
        - destination:
            host: httpbin
            subset: v1
          weight: 100
        mirror:
          host: httpbin
          subset: v2
        mirrorPercentage:
          value: 100.0
    
    

    这个路由规则发送 100% 流量到 v1 版本。最后一节表示您将 100% 的相同流量镜像(即发送)到 httpbin:v2 服务。 当流量被镜像时,请求将发送到镜像服务中,并在 headers 中的 Host/Authority 属性值上追加 -shadow。 例如 cluster-1 变为 cluster-1-shadow

    此外,重点注意这些被镜像的流量是『即发即弃』的,就是说镜像请求的响应会被丢弃。

    可以使用 mirrorPercentage 属性下的 value 字段来设置镜像流量的百分比,而不是镜像所有请求。如果没有这个属性,将镜像所有流量。

  4. 测试
    影子负载也接收到全量的流量
    image-20230919171542635.png

    现在就可以看到 v1v2 版本中都有了访问日志。v2 版本中的访问日志就是由镜像流量产生的,这些请求的实际目标是 v1 版本。


四、总结建议

  1. 隔离测试数据库: 流量镜像到与数据处理相关的业务,可以使用空的数据存储并加载测试数据,针对该数据进行流量镜像的操作,实现测试数据的隔离,防止造成数据的污染。

  2. 可以使用 mirrorPercentage 属性下的value字段来设置镜像流量的百分比,而不是镜像所有请求。如果没有这个属性,将镜像所有流量

  3. 这些被镜像的流量是即发即弃的,当流量镜像到不同的服务时,会发生在请求的关键路径之外,这样流量镜像产生的任何问题都不会影响到生产,就是说镜像请求的响应会被丢弃。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。