Istio的流量镜像

一、理解流量镜像
  流量镜像(Mirroring/traffic-shadow),也叫作影子流量,是指通过一定的配置将线上的真实流量复制一份到镜像服务中去,我们通过流量镜像转发以达到在不影响线上服务的情况下对流量或请求内容做具体分析的目的,它的设计思想是只做转发而不接收响应(fire and forget)。这个功能在传统的微服务架构里是很难做到的,一方面,传统服务之间的通讯是由SDK支持的,那么对流量镜像就代表着在业务服务逻辑中有着镜像逻辑相关代码的侵入,这会影响业务服务的代码的整洁性。另一方面,流量镜像的功能是需要非常灵活的,多维度,可动态管控的一个组件。如果将这样的一个组件集成到SDK中去完成它的使命后却无法及时清除,这样的设计势必是臃肿而繁琐的。所幸的是,随着微服务架构的发展,Service Mesh登上了历史舞台,成为新一代的服务架构引领者。而Istio作为Service Mesh优秀的落地架构,利用它本身使用Envoy代理转发流量的特性,轻松的支持了流量镜像的功能,再加上它的实现不需要任何代码的侵入,只需要在配置文件中简单加上几个配置即可完成。

二、配置流量镜像
1)部署httpbin服务

➜  cat 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:
      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

➜  kubectl apply -f httpbin.yaml
deployment.apps/httpbin-v1 created

kubectl describe deploy httpbin
Name:                   httpbin-v1
Namespace:              default
CreationTimestamp:      Sun, 25 Jul 2021 17:25:28 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=httpbin,version=v1
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=httpbin
           version=v1
  Containers:
   httpbin:
    Image:      docker.io/kennethreitz/httpbin
    Port:       80/TCP
    Host Port:  0/TCP
    Command:
      gunicorn
      --access-logfile
      -
      -b
      0.0.0.0:80
      httpbin:app
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   httpbin-v1-75d9447d79 (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  64s   deployment-controller  Scaled up replica set httpbin-v1-75d9447d79 to 1

2)为httpbin服务创建service

➜  cat httpbin-service.yaml 
apiVersion: v1
kind: Service
metadata: 
  name: httpbin
  labels:
    app: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin

➜  kubectl apply -f httpbin-service.yaml
service/httpbin configured

➜  kubectl describe svc httpbin   
Name:              httpbin
Namespace:         default
Labels:            app=httpbin
Annotations:       <none>
Selector:          app=httpbin
Type:              ClusterIP
IP:                10.110.191.190
Port:              http  8000/TCP
TargetPort:        80/TCP
Endpoints:         10.1.8.247:80
Session Affinity:  None
Events:            <none>

3)为httpbin服务创建虚拟服务

➜  cat httpbin-virtualservice.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

➜  kubectl apply -f httpbin-virtualservice.yaml                     
virtualservice.networking.istio.io/httpbin configured
destinationrule.networking.istio.io/httpbin created

➜  kubectl describe vs httpbin   
Name:         httpbin
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  networking.istio.io/v1beta1
Kind:         VirtualService
Metadata:
  Creation Timestamp:  2021-07-03T09:39:26Z
  Generation:          1
  Managed Fields:
    API Version:  networking.istio.io/v1alpha3
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .:
          f:kubectl.kubernetes.io/last-applied-configuration:
      f:spec:
        .:
        f:gateways:
        f:hosts:
        f:http:
    Manager:         kubectl-client-side-apply
    Operation:       Update
    Time:            2021-07-03T09:39:26Z
  Resource Version:  633475
  Self Link:         /apis/networking.istio.io/v1beta1/namespaces/default/virtualservices/httpbin
  UID:               4bf50ddd-6d1c-4e3b-948e-56d04b5f2332
Spec:
  Gateways:
    httpbin-gateway
  Hosts:
    httpbin.example.com
  Http:
    Match:
      Uri:
        Prefix:  /status
      Uri:
        Prefix:  /delay
    Route:
      Destination:
        Host:  httpbin
        Port:
          Number:  8000
Events:            <none>

➜  kubectl describe dr  httpbin                 
Name:         httpbin
Namespace:    default
Labels:       <none>
Annotations:  <none>
API Version:  networking.istio.io/v1beta1
Kind:         DestinationRule
Metadata:
  Creation Timestamp:  2021-07-25T09:31:42Z
  Generation:          1
  Managed Fields:
    API Version:  networking.istio.io/v1alpha3
    Fields Type:  FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .:
          f:kubectl.kubernetes.io/last-applied-configuration:
      f:spec:
        .:
        f:host:
        f:subsets:
    Manager:         kubectl-client-side-apply
    Operation:       Update
    Time:            2021-07-25T09:31:42Z
  Resource Version:  666137
  Self Link:         /apis/networking.istio.io/v1beta1/namespaces/default/destinationrules/httpbin
  UID:               4a99e110-906a-431d-b587-b1c0eae8e4ba
Spec:
  Host:  httpbin
  Subsets:
    Labels:
      Version:  v1
    Name:       v1
    Labels:
      Version:  v2
    Name:       v2
Events:         <none>

4)使用sleep服务做测试,并查看httpbin v1和v2的日志输出

➜  export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) 
➜  kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8000/headers' 
{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin:8000", 
    "User-Agent": "curl/7.77.0-DEV", 
    "X-B3-Parentspanid": "bd6f44226089fb4b", 
    "X-B3-Sampled": "1", 
    "X-B3-Spanid": "377f317ffc2235b3", 
    "X-B3-Traceid": "48b8f6202e115aafbd6f44226089fb4b", 
    "X-Envoy-Attempt-Count": "1", 
    "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/default;Hash=95c72738e0374abbc3de04ac172bb19aade9e5002af28031e0b326682a903dbd;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
  }
}

➜  kubectl logs -f  httpbin-v1-75d9447d79-2hsxp  -c httpbin
[2021-07-25 09:25:34 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2021-07-25 09:25:34 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2021-07-25 09:25:34 +0000] [1] [INFO] Using worker: sync
[2021-07-25 09:25:34 +0000] [9] [INFO] Booting worker with pid: 9
127.0.0.6 - - [25/Jul/2021:09:34:29 +0000] "GET /headers HTTP/1.1" 200 527 "-" "curl/7.77.0-DEV"

127.0.0.6 - - [25/Jul/2021:09:35:16 +0000] "GET /headers HTTP/1.1" 200 527 "-" "curl/7.77.0-DEV"

➜  kubectl logs -f  httpbin-v2-34asd47d59-4tffx  -c httpbin
[2021-07-25 09:25:34 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2021-07-25 09:25:34 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2021-07-25 09:25:34 +0000] [1] [INFO] Using worker: sync
[2021-07-25 09:25:34 +0000] [9] [INFO] Booting worker with pid: 9

5)创建流量镜像的虚拟服务

➜  kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
    - '*'
  gateways:
    - istio-system/ingressgateway
  http:
  - match:
    - uri:
        prefix: /httpbin
    rewrite:
      uri: /
    route:
    - destination:
        host: httpbin
        subset: v1
      weight: 100
    mirror:
      host: httpbin
      subset: v2
    mirror_percent: 100
EOF
Warning: using deprecated setting "mirrorPercent", use "mirrorPercentage" instead
virtualservice.networking.istio.io/httpbin configured

➜  kubectl describe vs  httpbin  | grep mirror
    mirror_percent:  100

6)再次访问httpbin服务并查看v1和v2的日志

➜  kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8000/headers' 
{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin:8000", 
    "User-Agent": "curl/7.77.0-DEV", 
    "X-B3-Parentspanid": "a54f646bc4278c3a", 
    "X-B3-Sampled": "1", 
    "X-B3-Spanid": "7c821b85706fe417", 
    "X-B3-Traceid": "acaf9443d7661acea54f646bc4278c3a", 
    "X-Envoy-Attempt-Count": "1", 
    "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/default;Hash=95c72738e0374abbc3de04ac172bb19aade9e5002af28031e0b326682a903dbd;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
  }
}

➜  kubectl logs -f  httpbin-v1-75d9447d79-2hsxp  -c httpbin                         
[2021-07-25 09:25:34 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2021-07-25 09:25:34 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2021-07-25 09:25:34 +0000] [1] [INFO] Using worker: sync
[2021-07-25 09:25:34 +0000] [9] [INFO] Booting worker with pid: 9
127.0.0.6 - - [25/Jul/2021:09:34:29 +0000] "GET /headers HTTP/1.1" 200 527 "-" "curl/7.77.0-DEV"

127.0.0.6 - - [25/Jul/2021:09:43:57 +0000] "GET /headers HTTP/1.1" 200 527 "-" "curl/7.77.0-DEV"

➜  kubectl logs -f  httpbin-v2-34asd47d59-4tffx  -c httpbin
[2021-07-25 09:25:34 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2021-07-25 09:25:34 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2021-07-25 09:25:34 +0000] [1] [INFO] Using worker: sync
[2021-07-25 09:25:34 +0000] [9] [INFO] Booting worker with pid: 9

127.0.0.6 - - [25/Jul/2021:09:43:57 +0000] "GET /headers HTTP/1.1" 200 527 "-" "curl/7.77.0-DEV"

7)清理

➜  kubectl delete vs httpbin                  
virtualservice.networking.istio.io "httpbin" deleted
➜  kubectl delete dr  httpbin
destinationrule.networking.istio.io "httpbin" deleted
➜  kubectl delete deploy  httpbin-v1
deployment.apps "httpbin-v1" deleted
➜  kubectl delete deploy  httpbin-v2
deployment.apps "httpbin-v2" deleted
➜  kubectl delete svc  httpbin   
service "httpbin" deleted
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容