<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
作為分散式系統(或任何系統)的一個組成部分,監測基礎設施的重要性怎麼強調都不過分。監控不僅要跟蹤二進位制的 "上升 "和 "下降 "模式,還要參與到複雜的系統行為中。監測基礎設施的設定可以讓人們深入瞭解效能、系統健康和長期的行為模式。
這篇文章介紹了監控基礎設施的一個方面--分散式跟蹤。
Kubernetes已經成為微服務基礎設施和部署的事實上的協調器。這個生態系統非常豐富,是開源社群中發展最快的系統之一。帶有Prometheus、ElasticSearch、Grafana、Envoy/Consul、Jaeger/Zipkin的監控基礎設施構成了一個堅實的基礎,以實現整個堆疊的指標、紀錄檔、儀表盤、服務發現和分散式跟蹤。
分散式跟蹤能夠捕獲請求,並建立一個從使用者請求到數百個服務之間互動的整個呼叫鏈的檢視。它還能對應用程式的延遲(每個請求花了多長時間)進行檢測,跟蹤網路呼叫的生命週期(HTTP、RPC等),並通過獲得瓶頸的可見性來確定效能問題。
下面的章節將介紹在Kubernetes設定中使用Jaeger對gRPC服務進行分散式跟蹤。Jaeger Github Org有專門的Repo,用於Kubernetes中Jaeger的各種部署設定。這些都是很好的例子,我將嘗試分解每個Jaeger元件和它的Kubernetes部署。
Jaeger是一個開源的分散式跟蹤系統,實現了OpenTracing規範。Jaeger包括儲存、視覺化和過濾跟蹤的元件。
應用程式跟蹤儀表從Jaeger使用者端開始。下面的例子使用Jaeger Go庫從環境變數初始化追 蹤 器設定,並啟用使用者端指標。
package tracer import ( "io" "github.com/uber/jaeger-client-go/config" jprom "github.com/uber/jaeger-lib/metrics/prometheus" ) func NewTracer() (opentracing.Tracer, io.Closer, error) { // load config from environment variables cfg, _ := jaegercfg.FromEnv() // 部落格原來:janrs.com // create tracer from config return cfg.NewTracer( config.Metrics(jprom.New()), ) }
Go使用者端使通過環境變數初始化Jaeger設定變得簡單。一些需要設定的重要環境變數包括JAEGER_SERVICE_NAME、JAEGER_AGENT_HOST和JAEGER_AGENT_PORT。Jaeger Go使用者端支援的環境變數的完整列表列在這裡。
為了給你的gRPC微服務新增追蹤功能,我們將使用gRPC中介軟體來啟用gRPC伺服器和使用者端的追蹤功能。 grpc-ecosystem/go-grpc-middleware有一個很棒的攔截器集合,包括支援OpenTracing提供者的伺服器端和使用者端的攔截器。
grpc_opentracing包暴露了opentracing攔截器,可以用任何opentracing.Tracer實現來初始化。在這裡,我們用連鎖的單項和流攔截器初始化了一個gRPC伺服器。啟用它將建立一個根serverSpan,對於每個伺服器端的gRPC請求,追 蹤 器將為服務中定義的每個RPC呼叫附加一個Span。
package grpc_server import ( "github.com/opentracing/opentracing-go" "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing" "github.com/grpc-ecosystem/go-grpc-middleware" "google.golang.org/grpc" "github.com/masroorhasan/myapp/tracer" ) func NewServer() (*grpc.Server, error) { // initialize tracer tracer, closer, err := tracer.NewTracer() defer closer.Close() if err != nil { return &grpc.Server{}, err } opentracing.SetGlobalTracer(tracer) // initialize grpc server with chained interceptors # janrs.com s := grpc.NewServer( grpc.StreamInterceptor(grpc_middleware.ChainStreamServer( // add opentracing stream interceptor to chain grpc_opentracing.StreamServerInterceptor(grpc_opentracing.WithTracer(tracer)), )), grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( // add opentracing unary interceptor to chain grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(tracer)), )), ) return s, nil }
為了實現對gRPC服務的上游和下游請求的追蹤,gRPC使用者端也必須用使用者端開放追蹤攔截器進行初始化,如下例所示。
package grpc_client import ( "github.com/opentracing/opentracing-go" "github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing" "github.com/grpc-ecosystem/go-grpc-middleware" "google.golang.org/grpc" "github.com/masroorhasan/myapp/tracer" ) func NewClientConn(address string) (*grpc.ClientConn, error) { // initialize tracer #博文來源:janrs.com tracer, closer, err := tracer.NewTracer() defer closer.Close() if err != nil { return &grpc.ClientConn{}, err } // initialize client with tracing interceptor [#博文來源:janrs.com#] using grpc client side chaining return grpc.Dial( address, grpc.WithStreamInterceptor(grpc_middleware.ChainStreamClient( grpc_opentracing.StreamClientInterceptor(grpc_opentracing.WithTracer(tracer)), )), grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient( grpc_opentracing.UnaryClientInterceptor(grpc_opentracing.WithTracer(tracer)), )), ) }
由gRPC中介軟體建立的父跨度被注入到go上下文中,從而實現強大的跟蹤支援。opentracing go使用者端可以用來將子跨度附加到父跨度上,以實現更精細的追蹤,以及控制每個跨度的壽命,為追蹤新增自定義標籤等。
Jaeger代理是一個守護行程,它通過UDP接收來自Jaeger使用者端的跨度,並將它們分批轉發給收集器。該代理作為一個緩衝器,從客戶那裡抽象出批次處理和路由。
儘管代理是作為一個守護程式建立的,但在Kubernetes設定中,代理可以被設定為在應用Pod中作為一個sidecar容器執行,或作為一個獨立的DaemonSet。
下文討論了每種部署策略的優點和缺點。
Jaeger Sidecar 代理是一個容器,與你的應用容器放在同一個艙中。表示為Jaeger服務的應用程式myapp將通過localhost向代理傳送Jaeger跨度到6381埠。[#博文來源:janrs.com#]如前所述,這些設定是通過使用者端的環境變數JAEGER_SERVICE_NAME、JAEGER_AGENT_HOST和JAEGER_AGENT_PORT設定的。
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deployment namespace: default labels: app: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: masroorhasan/myapp ports: - containerPort: 80 env: - name: JAEGER_SERVICE_NAME value: myapp - name: JAEGER_AGENT_HOST value: localhost # default - name: JAEGER_AGENT_PORT value: "6831" resources: limits: memory: 500M cpu: 250m requests: memory: 500M cpu: 250m # sidecar agent - name: jaeger-agent image: jaegertracing/jaeger-agent:1.6.0 ports: - containerPort: 5775 protocol: UDP - containerPort: 5778 protocol: TCP - containerPort: 6831 protocol: UDP - containerPort: 6832 protocol: UDP command: - "/go/bin/agent-linux" - "--collector.host-port=jaeger-collector.monitoring:14267" resources: limits: memory: 50M cpu: 100m requests: memory: 50M cpu: 100m
通過這種方法,每個代理(也就是每個應用)都可以被設定為向不同的收集器(也就是不同的後端儲存)傳送痕跡。
然而,這種方法最大的缺點之一是將代理的生命週期和應用程式緊密結合在一起。追蹤的目的是在應用程式的生命週期內提供對其的洞察力。更有可能的是,代理側車容器在主應用容器之前被殺死,在應用服務關閉期間,任何/所有重要的追蹤都會丟失。這些痕跡的丟失對於理解複雜服務互動的應用生命週期行為可能是非常重要的。這個GitHub問題驗證了在關機期間正確處理SIGTERM的必要性。
另一種方法是通過Kubernetes中的DaemonSet工作負載,將代理作為叢集中每個節點的守護程式執行。DaemonSet工作負載可以確保當節點被擴充套件時,DaemonSet Pod的副本也隨之擴充套件。
在這種情況下,每個代理守護程式負責從其節點中安排的所有執行中的應用程式(設定了Jaeger使用者端)中獲取追蹤資訊。這是通過在使用者端設定JAEGER_AGENT_HOST指向節點中代理的IP來設定的。代理DaemonSet被設定為hostNetwork: true和適當的DNS策略,以便Pod使用與主機相同的IP。由於代理的6831埠是通過UDP接受jaeger.thrift訊息的,所以守護的Pod設定埠也與hostPort: 6831繫結。
# Auth : janrs.com apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deployment namespace: default labels: app: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: masroorhasan/myapp ports: - containerPort: 80 env: - name: JAEGER_SERVICE_NAME value: myapp - name: JAEGER_AGENT_HOST # NOTE: Point to the Agent daemon on the Node valueFrom: fieldRef: fieldPath: status.hostIP - name: JAEGER_AGENT_PORT value: "6831" resources: limits: memory: 500M cpu: 250m requests: memory: 500M cpu: 250m --- apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: jaeger-agent namespace: monitoring labels: app: jaeger jaeger-infra: agent-daemonset spec: template: metadata: labels: app: jaeger jaeger-infra: agent-instance spec: hostNetwork: true # NOTE: Agent is configured to have same IP as the host/node dnsPolicy: ClusterFirstWithHostNet containers: - name: agent-instance image: jaegertracing/jaeger-agent:1.6.0 command: - "/go/bin/agent-linux" - "--collector.host-port=jaeger-collector.monitoring:14267" - "--processor.jaeger-binary.server-queue-size=2000" - "--discovery.conn-check-timeout=500ms" ports: - containerPort: 5775 protocol: UDP - containerPort: 6831 protocol: UDP hostPort: 6831 - containerPort: 6832 protocol: UDP - containerPort: 5778 protocol: TCP resources: requests: memory: 200M cpu: 200m limits: memory: 200M cpu: 200m
人們可能會被誘 惑(就像我一樣),用Kubernetes服務來引導DaemonSet。這背後的想法是,不要把應用程式的痕跡繫結到當前節點的單一代理上。使用服務可以將工作負載(跨度)分散到叢集中的所有代理。這在理論上減少了在受影響節點的單個代理莢發生故障的情況下,應用範例丟失跨度的機會。
然而,當你的應用程式擴充套件時,這將不起作用,高負載會在需要處理的痕跡數量上產生巨大的峰值。使用Kubernetes服務意味著通過網路從使用者端向代理傳送追蹤資訊。很快,我就開始注意到大量的掉線現象。使用者端通過UDP thrift協定向代理傳送跨度,大量的峰值導致超過UDP最巨量資料包大小,從而導致丟包。
解決辦法是適當地分配資源,使Kubernetes在整個叢集中更均勻地排程pod。[#博文來源:janrs.com#]我們可以增加使用者端的佇列大小(設定JAEGER_REPORTER_MAX_QUEUE_SIZE環境變數),以便在代理失效時有足夠的緩衝空間。增加代理的內部佇列大小也是有益的(設定處理器.jaeger-binary.server-queue-size值),這樣他們就不太可能開始丟棄跨度。
Jaeger收集器負責從Jaeger代理那裡接收成批的跨度,通過處理管道執行它們,並將它們儲存在指定的儲存後端。跨度以jaeger.thrift格式從Jaeger代理處通過TChannel(TCP)協定傳送,埠為14267。
Jaeger收集器是無狀態的,可以根據需要擴充套件到任何數量的範例。因此,收集器可以由Kubernetes內部服務(ClusterIP)前置,可以從代理到不同收集器範例的內部流量進行負載平衡。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: jaeger-collector namespace: monitoring labels: app: jaeger jaeger-infra: collector-deployment spec: replicas: 1 strategy: type: Recreate template: metadata: labels: app: jaeger jaeger-infra: collector-pod spec: containers: - image: jaegertracing/jaeger-collector:1.6.0 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 resources: requests: memory: 300M cpu: 250m limits: memory: 300M cpu: 250m --- apiVersion: v1 kind: Service metadata: name: jaeger-collector namespace: monitoring labels: app: jaeger jaeger-infra: collector-service spec: ports: - name: jaeger-collector-tchannel port: 14267 protocol: TCP targetPort: 14267 selector: jaeger-infra: collector-pod type: ClusterIP view raw
查詢服務是支援使用者介面的Jaeger伺服器。它負責從記憶體中檢索痕跡,並將其格式化以顯示在使用者介面上。根據查詢服務的使用情況,它的資源佔用率非常小。
設定一個內部Jaeger使用者介面的入口,指向後端查詢服務。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: jaeger-query namespace: monitoring labels: app: jaeger jaeger-infra: query-deployment spec: replicas: 1 strategy: type: Recreate template: metadata: labels: app: jaeger jaeger-infra: query-pod spec: containers: - image: jaegertracing/jaeger-query:1.6.0 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 resources: requests: memory: 100M cpu: 100m limits: memory: 100M cpu: 100m volumes: - configMap: name: jaeger-configuration items: - key: query path: query.yaml name: jaeger-configuration-volume --- apiVersion: v1 kind: Service metadata: name: jaeger-query namespace: monitoring labels: app: jaeger jaeger-infra: query-service spec: ports: - name: jaeger-query port: 16686 targetPort: 16686 selector: jaeger-infra: query-pod type: ClusterIP --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: jaeger-ui namespace: monitoring annotations: kubernetes.io/ingress.class: traefik # or nginx or whatever ingress controller spec: rules: - host: jaeger.internal-host # your jaeger internal endpoint http: paths: - backend: serviceName: jaeger-query servicePort: 16686
Jaeger同時支援ElasticSearch和Cassandra作為儲存後端。使用ElasticSearch作為儲存,可以擁有一個強大的監控基礎設施,將跟蹤和紀錄檔記錄聯絡在一起。採集器處理管道的一部分是為其儲存後端索引跟蹤--這將使跟蹤顯示在你的紀錄檔UI(例如Kibana)中,也將跟蹤ID與你的結構化紀錄檔標籤繫結。你可以通過SPAN_STORAGE_TYPE的環境變數將儲存型別設定為ElasticSearch,並通過設定設定儲存端點。
Kubernetes ConfigMap用於設定一些Jaeger元件的儲存設定。例如,Jaeger收集器和查詢服務的儲存後端型別和端點。
apiVersion: v1 kind: ConfigMap metadata: name: jaeger-configuration namespace: monitoring labels: app: jaeger jaeger-infra: configuration data: span-storage-type: elasticsearch collector: | es: server-urls: http://elasticsearch:9200 collector: zipkin: http-port: 9411 query: | es: server-urls: http://elasticsearch:9200
如前所述,追蹤是監控基礎設施的一個重要組成部分。這意味著,甚至你的追蹤基礎設施的元件也需要被監控。
Jaeger在每個元件的特定埠上以Prometheus格式暴露指標。如果有正在執行的Prometheus節點匯出器(它絕對應該是)在特定的埠上刮取指標 - 然後將你的Jaeger元件的指標埠對映到節點匯出器正在刮取指標的埠。
這可以通過更新Jaeger服務(代理、收集器、查詢)來完成,將它們的指標埠(5778、14628或16686)對映到節點出口商期望搜刮指標的埠(例如8888/8080)。
一些需要跟蹤的重要指標。
Health of each component — memory usage: sum(rate(container_memory_usage_bytes{container_name=~”^jaeger-.+”}[1m])) by (pod_name)
Health of each component — CPU usage: sum(rate(container_cpu_usage_seconds_total{container_name=~"^jaeger-.+"}[1m])) by (pod_name)
Batch failures by Jaeger Agent: sum(rate(jaeger_agent_tc_reporter_jaeger_batches_failures[1m])) by (pod)
Spans dropped by Collector: sum(rate(jaeger_collector_spans_dropped[1m])) by (pod)
Queue latency (p95) of Collector: histogram_quantile(0.95, sum(rate(jaeger_collector_in_queue_latency_bucket[1m])) by (le, pod))
這些指標為了解每個元件的效能提供了重要的見解,歷史資料應被用來進行最佳設定。
以上就是Kubernetes上使用Jaeger分散式追蹤基礎設施詳解的詳細內容,更多關於Kubernetes Jaeger分散式追蹤的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45