利用virtualservice的mirror配置实现流量镜像
一、 背景
流量镜像,也称为影子流量,指的是在将新流量转发到原目标地址的同时,将流量给另一个目标地址镜像一份。可以将生产系统中宝贵的实际流量镜像一份到另一个系统上,完全不会对生产系统产生影响,降低部署的风险。
二、 简介
利用istio virtualservice中的mirror配置实现:
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 服务,并开启访问日志功能:
-
创建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
-
创建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
-
创建service
apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin spec: ports: - name: http port: 8000 targetPort: 80 selector: app: httpbin
-
创建客户端负载
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 管理流量
-
创建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
-
测试脚本
#! /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的v1
和v2
两个版本的日志。您可以看到v1
版本的访问日志条目,而v2
版本没有日志: -
配置镜像流量
镜像到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
字段来设置镜像流量的百分比,而不是镜像所有请求。如果没有这个属性,将镜像所有流量。 -
测试
影子负载也接收到全量的流量
现在就可以看到
v1
和v2
版本中都有了访问日志。v2 版本中的访问日志就是由镜像流量产生的,这些请求的实际目标是v1
版本。
四、总结建议
-
隔离测试数据库: 流量镜像到与数据处理相关的业务,可以使用空的数据存储并加载测试数据,针对该数据进行流量镜像的操作,实现测试数据的隔离,防止造成数据的污染。
-
可以使用
mirrorPercentage
属性下的value字段来设置镜像流量的百分比,而不是镜像所有请求。如果没有这个属性,将镜像所有流量 -
这些被镜像的流量是即发即弃的,当流量镜像到不同的服务时,会发生在请求的关键路径之外,这样流量镜像产生的任何问题都不会影响到生产,就是说镜像请求的响应会被丢弃。
- 点赞
- 收藏
- 关注作者
评论(0)