istio-opentracing鏈路追蹤方案


istio-opentracing鏈路追蹤方案

istio-opentracing鏈路追蹤主要是由sidecar(envoy)支持的,istio只是在上層進行配置的修改。

envoy鏈路追蹤

envoy主要用三個功能來支撐系統范圍內的跟蹤

  • 生成Request ID: envoy會在需要的時候生成UUID,並操作名為[x-request-id]的HTTP Header。應用可以轉發這個Header用於統一的記錄和追蹤。
  • 集成外部追蹤服務: envoy支持可插件的外部跟蹤可視化服務。目前支持LightStepzipkin或者Zipkin兼容的后端(例如:jaeger).另外可自己添加其它的追蹤服務。
  • 客戶端跟蹤ID連接: x-client-trace-id Header 可以用來把不信任的請求 ID 連接到受信的 x-request-id Header 上。

初始化追蹤

有多種途勁初始化追蹤

跟蹤上下文信息

不管使用的是哪個跟蹤服務,都應該傳播x-request-id,這樣在被調用服務中啟動相關性的記錄。

  • 如果使用了 LightStep 跟蹤器,在發送 HTTP 請求到其他服務,Envoy 依賴這個服務來傳播 x-ot-span-context Header。
  • 如果使用的是 Zipkin,Envoy 要傳播的是 B3 Header.(x-b3-traceid, x-b3-spanid, x-b3-parentspanid, x-b3-sampled,以及 x-b3-flags)也可以由外部客戶端提出,用來啟用或者禁用某個服務的跟蹤請求。

istio鏈路追蹤

鏈路追蹤參數

istio鏈路追蹤提供了全局配置zipkinAddress。istio的sidecar流量攔截后上報到鏈路系統,envoy的上報地址通過proxy_init的--zipkinAddress參數傳入。由上面可知envoy的鏈路追蹤主要的原生支持是jaeger。

istio的鏈路追蹤並不能在sidecar中全部處理,是有侵入性的。業務需要存儲幾個特殊字段,在要調用下個服務時,把這幾個字段帶上。這樣才能把整條鏈路串起來。具體可看上面的跟蹤上下文信息,istio鏈路追蹤例子。

mix模塊中的telemetry和policy這兩個的鏈路追蹤是通過參數--trace_zipkin_url=http://zipkin:9411/api/v1/spans 來配置的。

采樣率

鏈路的采樣率istio中只提供了一個全局的配置,通過配置pilot的參數PILOT_TRACE_SAMPLING來控制,其范圍是0.0-100.0,最小可配參數0.01,默認100。

修改方式:

  • helm安裝時參數選項:[pilot.traceSampling](https://istio.io/docs通過kubectl -n Istio-system edit deploy Istio-pilot修改PILOT_TRACE_SAMPLING變量。/reference/config/installation-options/)。
  • 生成的yaml文件中修改PILOT_TRACE_SAMPLING變量,重新apply。
  • 通過kubectl -n Istio-system edit deploy Istio-pilot修改PILOT_TRACE_SAMPLING變量。

jaeger

istio的tracing默認使用jaeger來實現日志追蹤的發送,存儲,查詢。
先來看jaeger的架構圖:

jaeger主要由以下幾部分組成

  • jaeger-client為不同語言實現的OpenTracing標准的SDK.應用程序通過API寫入數據,然后按照指定策略把trace傳遞給jaeger-agent.
  • agent是一個UDP中轉服務,它將數據批量發送給collector.它是一個基礎組件,布在所有機器上.
  • collector接收agent發送來的數據,然后將數據寫入后端.collector是一個無狀態組件,可以建任意數量.
  • data-store后端存儲被設計成一個可插拔的組件.支持CassandraElasticSearch
  • query從存儲中提取數據並通過UI展示.

istio中jaeger現狀

istio目前官方自帶的是all-in-one的鏡像,所有的組件都包含在一個鏡像中.數據的存儲是存在內存中,pod刪除或重啟,所有的數據就全沒有了.這沒法線上使用.

為此,我們需要考慮將數據存儲為指定的存儲服務,采用官方自帶的肯定不行,需要自己重新部署一套jaeger。

jaeger持久化存儲

k8s部署jaeger

根據官方文檔部署基於k8s的Jaeger的生產環境下的容器,這個要采用Production這個生成的部署方式。

這種方式的部署比較麻煩,需要對jaeger有一定的理解,對存儲服務如ES都需要有一定的研究。因此這種試不推薦。

接入自己的ES服務

istio的鏈路追蹤通過zipkin直接傳輸到jaeger-collector,jaeger-collector將數據發送到自己現有的ES集群進行存儲,jaeger-query直接去現有ES集群查詢。

鏈路追蹤發送到jaeger-collector

如果不在同個namespace下,需要修改zipkin地址為jaeger的zipkin收集地址。envoy這個proxy會默認使用環境變量來設置zipkinAddress地址,默認地址是zipkin.istio-system:9411。可在yaml下查找zipkinAddress來修改,然后更新就可以。如果后繼有helm update更新,需要去修改charts,在install/kubernetes/helm/istio//templates/configmap.yamlinstall/kubernetes/helm/istio//charts/mixer/templates 這兩個下面的zipkin地址。 mix相關的trace_zipkin_url的zipkin也要改成對應的地址。

  • 修改istio的zipkin地址需要重新啟動pod。
  • jaeger-agent這個服務,因為我們是直接配置到jaeger-collector因些不需要。
jaeger-collector到ES集群

這個官方的jaeger是支持發送到kafka,但由於jaeger會生成3個index(jaeger-span,jaeger-service,jager-dependencies),而kafka發送到ES時,要區分有點麻煩。暫時先直接發送到ES。

jaeger-query

這個配置只需將查詢地址改為ES的地址。

jaeger-query的dependencies服務生成圖需要自己配置spark-dependencies

線上例子

jaeger-collector的ES配置參數可通過下面來查看,jaeger-query的參數也是一樣的

docker run \
  -e SPAN_STORAGE_TYPE=elasticsearch \
  jaegertracing/jaeger-collector:1.8 \
  --help

k8s jaeger的configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: jaeger-configuration
  namespace: istio-system
  labels:
    app: jaeger
    jaeger-infra: configuration
data:
  span-storage-type: elasticsearch
  collector: |
    es:
      server-urls: http://example1.com:9200,http://example2.com:9200
      index-prefix: online-opentracing 
    collector:
      zipkin:
        http-port: 9411
  query: |
    es:
      server-urls: http://example1.com:9200,http://example2.com:9200
      index-prefix: online-opentracing

k8s jaeger-collector和jaeger-query

apiVersion: v1
kind: List
items:
- apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: jaeger-collector
    namespace: istio-system
    labels:
      app: jaeger
      jaeger-infra: collector-deployment
  spec:
    replicas: 3
    strategy:
      type: Recreate
    template:
      metadata:
        labels:
          app: jaeger
          jaeger-infra: collector-pod
        annotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "14268"
      spec:
        containers:
        - image: jaegertracing/jaeger-collector:1.8.2
          name: jaeger-collector
          args: ["--config-file=/conf/collector.yaml"]
          ports:
          - containerPort: 14267
            protocol: TCP
          - containerPort: 14268
            protocol: TCP
          - containerPort: 9411
            protocol: TCP
          readinessProbe:
            httpGet:
              path: "/"
              port: 14269
          volumeMounts:
          - name: jaeger-configuration-volume
            mountPath: /conf
          env:
          - name: SPAN_STORAGE_TYPE
            valueFrom:
              configMapKeyRef:
                name: jaeger-configuration
                key: span-storage-type
        volumes:
          - configMap:
              name: jaeger-configuration
              items:
                - key: collector
                  path: collector.yaml
            name: jaeger-configuration-volume
- apiVersion: v1
  kind: Service
  metadata:
    name: jaeger-collector
    namespace: istio-system
    labels:
      app: jaeger
      jaeger-infra: collector-service
  spec:
    ports:
    - name: jaeger-collector-tchannel
      port: 14267
      protocol: TCP
      targetPort: 14267
    - name: jaeger-collector-http
      port: 14268
      protocol: TCP
      targetPort: 14268
    - name: jaeger-collector-zipkin
      port: 9411
      protocol: TCP
      targetPort: 9411
    selector:
      jaeger-infra: collector-pod
    type: ClusterIP
- apiVersion: v1
  kind: Service
  metadata:
    name: zipkin
    namespace: istio-system
    labels:
      app: jaeger
      jaeger-infra: zipkin-service
  spec:
    ports:
    - name: jaeger-collector-zipkin
      port: 9411
      protocol: TCP
      targetPort: 9411
    selector:
      jaeger-infra: collector-pod
    type: ClusterIP
- apiVersion: extensions/v1beta1
  kind: Deployment
  metadata:
    name: jaeger-query
    namespace: istio-system
    labels:
      app: jaeger
      jaeger-infra: query-deployment
  spec:
    replicas: 1
    strategy:
      type: Recreate
    template:
      metadata:
        labels:
          app: jaeger
          jaeger-infra: query-pod
        annotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "16686"
      spec:
        containers:
        - image: jaegertracing/jaeger-query:1.8.2
          name: jaeger-query
          args: ["--config-file=/conf/query.yaml"]
          ports:
          - containerPort: 16686
            protocol: TCP
          readinessProbe:
            httpGet:
              path: "/"
              port: 16687
          volumeMounts:
          - name: jaeger-configuration-volume
            mountPath: /conf
          env:
          - name: SPAN_STORAGE_TYPE
            valueFrom:
              configMapKeyRef:
                name: jaeger-configuration
                key: span-storage-type
        volumes:
          - configMap:
              name: jaeger-configuration
              items:
                - key: query
                  path: query.yaml
            name: jaeger-configuration-volume
- apiVersion: v1
  kind: Service
  metadata:
    name: jaeger-query
    namespace: istio-system
    labels:
      app: jaeger
      jaeger-infra: query-service
  spec:
    type: NodePort
    ports:
    - name: jaeger-query
      port: 80
      protocol: TCP
      targetPort: 16686
      nodePort: 32686
    selector:
      jaeger-infra: query-pod

參考文檔:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM