应用服务网格

流量标签

2025-08-13 09:32:15

ASM服务网格中可以通过自定义的资源(TrafficLabel)实现对请求流量的打标,进而可以基于流量的标签进行单服务及全链路的路由、策略控制等。本文介绍流量打标原理,流量标签管理,流量标签配置示例及详细说明。

流量打标原理

流量打标就是要给流量打上标签,进而可以对流量进行路由等策略配置。当前ASM服务网格支持从请求头部或者工作负载本身的标签中取值作为流量的标签;同时还支持在调用链中透传流量标签信息,用于实现全链路的标签路由策略。

下面是一个流量标签的配置示例,定义了一个流量标签userdefinelabel1,会取当前pod的CSM_TRAFFIC_TAG标签值作为userdefinelabel1的值添加到请求头部里面;同时还定义了另外一个userdefinelabel2标签,该标签定义优先从请求的x-traffic-tag头部取值,同时使用Envoy生成的x-request-id作为上下文key,在整个调用链路中透传该标签;如果打标失败了,会按照valueFrom数组中下一个定义继续取值,取到第一个非空值时停止。

apiVersion: istio.ctyun.cn/v1beta1

kind: TrafficLabel

metadata:

  name: traffic-label-example

  namespace: demo

spec:

  rule:

    labels:

    - name: userdefinelabel1

      valueFrom:

      - $getLabel(CSM_TRAFFIC_TAG)

    - name: userdefinelabel2

      valueFrom:

      - $getInboundRequestHeaderWithContext (x-traffic-tag, x-request-id)

      - $getLabel(CSM_TRAFFIC_TAG)

 

当前ASM服务网格支持的流量打标方式有以下几种:

函数

说明

示例

getInboundRequestHeader(headerName)

Inbound方向的请求header中取值;只应用于istio ingress网关

请求headerName:v1

打标后:

userdefinelabel: v1

getInboundRequestHeaderWithContext(headerName, contextKey)

Inbound方向的请求header取值,同时从contextKey头部取值作为流量标签在上下文透传的key,该头部可以是用于实现链路追踪上下文透传的头部,比如x-request-id、x-b3-traceid或者您的业务中使用的自定义头部;该函数只适用于sidecar

请求:

contextID: 1234abcd

headerName: v1

 

打标后:

contextID: 1234abcd

headerName: v1

userdefinelabel: v1

getOutboundRequestHeader(headerName)

outbound方向的请求头部取值,只适用于sidecar

请求headerName:v1

打标后:

userdefinelabel: v1

getLabel(labelName)

pod的标签取值;适用于istio ingress网关和sidecar

Pod标签:

labelName: v1

打标后:

userdefinelabel: v1

 

 

流量标签管理

创建流量标签

1. 通过服务网格控制台 流量管理中心 -> 流量标签菜单进入流量标签管理页面

2. 选择命名空间,选择左上角使用YAML创建

3. 基于模板编辑流量标签定义,保存即可

 

修改流量标签

1. 通过服务网格控制台 流量管理中心 -> 流量标签菜单进入流量标签管理页面

2. 选择命名空间,列表页会展示当前命名空间下定义的TrafficLabel对象

3. 选择操作栏的编辑,修改定义,保存即可

 

删除流量标签

1. 通过服务网格控制台 流量管理中心 -> 流量标签菜单进入流量标签管理页面

2. 选择命名空间,列表页会展示当前命名空间下定义的TrafficLabel对象

3. 选择操作栏的删除,即可删除已定义的TrafficLabel对象

 

TrafficLabel配置说明:

字段

类型

必选

说明

workload_selector

WorkloadSelector

No

工作负载选择器,选择当前流量标签生效的工作负载

rule

TrafficLabelRule

No

流量标签定义

 

TrafficLabelRule

流量标签的详细定义

字段

类型

必选

说明

labels

[]Label

No

流量标签定义

 

Label

字段

类型

必选

说明

name

string

No

流量标签名称,该标签会被添加到请求头部

value_from

[]string

No

流量标签取值, value_from为数组,按照顺序取到的第一个非空值作为该标签的取值

 

流量标签使用示例

准备工作

首先部署测试应用app1app2,调用关系为ingress -> app1-> app2

apiVersion: v1

kind: Service

metadata:

  name: app1

  labels:

    app: app1

    service: app1

spec:

  ports:

  - port: 8000

    name: http

  selector:

    app: app1

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1-base
  namespace: demo
  labels:
    app: app1
    CSM_TRAFFIC_TAG: base
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app1
      name: app1
      CSM_TRAFFIC_TAG: base
  template:
    metadata:
      labels:
        app: app1
        name: app1
        source: 云容器引擎
        CSM_TRAFFIC_TAG: base
    spec:
      containers:
      - name: default
        image: registry-vpc-crs-huadong1.cnsp-internal.ctyun.cn/library/trace-demo:v1.0.0
        imagePullPolicy: IfNotPresent
        env:
        - name: version
          value: base
        - name: app
          value: app1
        - name: upstream_url
          value: "http://app2:8000/"
        ports:
        - containerPort: 8000

---

apiVersion: v1

kind: Service

metadata:

  name: app2

  labels:

    app: app2

    service: app2

spec:

  ports:

  - port: 8000

    name: http

  selector:

    app: app2

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2-base
  namespace: demo
  labels:
    app: app2
    CSM_TRAFFIC_TAG: base
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app2
      name: app2
      CSM_TRAFFIC_TAG: base
  template:
    metadata:
      labels:
        app: app2
        name: app2
        source: 云容器引擎
        CSM_TRAFFIC_TAG: base
    spec:
      containers:
      - name: default
        image: registry-vpc-crs-huadong1.cnsp-internal.ctyun.cn/library/trace-demo:v1.0.0
        imagePullPolicy: IfNotPresent
        env:
        - name: version
          value: base
        - name: app
          value: app2
        ports:
        - containerPort: 8000

 

部署Gateway和VirtualService资源

apiVersion: networking.istio.io/v1beta1

kind: Gateway

metadata:

  name: trace-demo-gateway

spec:

  selector:

    istio: ingressgateway

  servers:

    - hosts:

        - "*"

      port:

        name: http

        number: 80

        protocol: HTTP

---

apiVersion: networking.istio.io/v1beta1

kind: VirtualService

metadata:

  name: vs-gateway-app1

spec:

  gateways:

  - trace-demo-gateway

  hosts:

    - "*"

  http:

  - route:

      - destination:

          host: app1

 

Ingress gateway流量打标

Ingress网关侧对流量打标之后我们看通过查看上游的app1服务收到的请求头部确认流量打标是否成功,首先定义流量标签策略:

apiVersion: istio.ctyun.cn/v1beta1

kind: TrafficLabel

metadata:

  name: traffic-label-example

  namespace: istio-system

spec:

  workloadSelector:

    labels:

      istio: ingressgateway

  rule:

    labels:

    - name: label-from-header

      valueFrom:

      - $getInboundRequestHeader(app-version-tag)

    - name: label-from-pod

      valueFrom:

      - $getLabel(app)

 

上面的配置在Ingress网关处定义了两个标签,label-from-header会从app-version-tag请求头部取值打标,label-from-podpod的app标签取值打标。我们通过Ingress网关访问app1服务,并带上app-version-tag: ccccc,查看app1的日志如下:

 

Sidear流量打标

首先定义sidecar流量打标规则,label1app-version-tag头部取值,同时使用trace-ctx-id字段做链路传递;label2outbound方向的trace-ctx-id字段;label3取应用的app标签值:

apiVersion: istio.ctyun.cn/v1beta1

kind: TrafficLabel

metadata:

  name: traffic-label-example

  namespace: default

spec:

  rule:

    labels:

    - name: label1

      valueFrom:

      - $getInboundRequestHeaderWithContext(app-version-tag, trace-ctx-id)

    - name: label2

      valueFrom:

      - $getOutboundRequestHeader(trace-ctx-id)

    - name: label3

      valueFrom:

      - $getLabel(app)

 

请求Ingress网关带上两个头部'app-version-tag: ccccc'  'trace-ctx-id: 1234',查看app2的日志,可以看到预期中的流量标签:


BLJP0Ar4uo5B