Nginx Ingress Contoller 通过 Envoy 代理和 Jaeger 进行分布式追踪(二)
时间:2023-08-21 23:29:38来源:博客园
1、概述

在《应用程序通过 Envoy 代理和 Jaeger 进行分布式追踪(一)》一文中,我们详细介绍了单个应用程序如何通过 Envoy 和 Jaeger 实现链路追踪的过程。然而,单独追踪单个应用程序的链路在实际场景中往往显得不够有意义。因此,在本文中,我们将进一步扩展链路追踪范围,演示如何将 Nginx Ingress Controller 与之前提到的应用程序一起使用,从而实现更为复杂的分布式链路追踪。


(资料图片)

2、通过 Nginx Ingress Controller 代理访问 http_request_printer 服务2.1 Nginx Ingress Controller 组件不注入边车,http_request_printer 服务不注入边车

流量走向:客户端 ——》Nginx Ingress contorller Pod 中的业务容器 ——》http_request_printer Pod中的业务容器

1)创建 Nginx Ingress contorller 资源使其能够管理 tracing 命名空间下的 Ingress 资源,注意 Nginx Ingress contorller 资源对象不要注入边车,步骤略

2)创建Ingress资源对象,并代理到 http_request_printer 服务

[root@master1 ~]# kubectl get ingress -n=tracing http-request-printer -o yamlapiVersion: networking.k8s.io/v1kind: Ingress  ......  name: http-request-printer  namespace: tracingspec:  rules:  - host: http-request-printer.xx.xx.xx.xx.nip.io    http:      paths:      - backend:          service:            name: http-request-printer            port:              number: 80        path: /        pathType: ImplementationSpecific

3)通过 Ingress 访问 http_request_printer 服务

4)通过容器日志查看请求信息

可以看到除了自定义 Header 和谷歌浏览器里面的 Postman 插件加了一些 Header 信息外 Nginx Ingress Controller 组件还帮我们加了一些 Header 信息,尤其注意Nginx Ingress Controller 组件默认会给一个请求生成 X-Request-Id Header 头信息,并且它加的这个 X-Request-Id Header 头信息和Envoy 产生的X-Request-Id Header 头信息(xxx-xxx-xxx)格式不一致。

注意,由于Nginx Ingress Controller 和 http_request_printer 都没接入 Jaeger,所以此时不管怎么访问在 Jaeger 里面都是查不到链路信息的。

2.2 Nginx Ingress Controller 组件不注入边车,http_request_printer 服务注入边车

流量走向:客户端 ——》Nginx Ingress contorller Pod 中的业务容器 ——》http_request_printer Pod 中的 Envoy 边车容器入站流量劫持 ——》http_request_printer Pod 中的业务容器

1)重复执行2.1中的步骤1)-3),唯一不同的是http_request_printer 注入边车

2)通过容器日志查看请求信息

查看 http_request_printer 服务对应容器日志,和2.1示例日志不一样在于除了自定义 Header、谷歌浏览器里面的 Postman 插件加了一些 Header 信息、以及 Nginx Ingress Controller 组件加的一些 Header 信息外 http_request_printer 服务注入的边车 Envoy 加了和链路追踪相关的 Header 头信息。

查看Nginx Ingress Controller组件对应容器日志,可以看到http_request_printer 服务使用的X-Request-Id Header 头信息是 Nginx Ingress Controller 组件生成并传递给http_request_printer 这个上游服务的,注意Nginx Ingress Controller 组件它加的这个 X-Request-Id Header 头信息和Envoy 产生的X-Request-Id Header 头信息(xxx-xxx-xxx)格式不一致。

3) 查看 http_request_printer 服务上报的链路信息

整个请求访问链由于只有http_request_printer 组件注入了边车会向jaeger-collector 组件上报链路信息,所以整个请求链只有1个 span。

2.3 Nginx Ingress Controller 组件注入边车,http_request_printer 服务注入边车

流量走向:客户端 ——》Nginx Ingress contorller Pod 中的 Envoy 边车容器入站流量劫持 ——》Nginx Ingress contorller Pod 中的业务容器 ——》Nginx Ingress contorller Pod 中的 Envoy 边车容器出站流量劫持 ——》http_request_printer Pod 中的 Envoy 边车容器入站流量劫持 ——》http_request_printer Pod 中的业务容器

1)重复执行2.1中的步骤1)-3),唯一不同的是Nginx Ingress Controller 组件和 http_request_printer 服务都会注入边车。

注意 1, 定义 Nginx Ingress Contorller svc 资源对象时需要指定 Nginx Ingress Controller 服务应用层协议,因为 istio 需要知道服务提供什么七层协议,从而来为其配置相应协议的 filter chain,千万不要写成 tcp 协议,否则不会上报链路信息,详情参见《Istio 为服务指定协议》这篇博文。

apiVersion: v1kind: Servicemetadata:  name: nginx-ingress-controllerspec:  ports:  - name: http-80  #需要指定服务应用层协议,千万不要写成tcp协议,否则不会上报链路信息    port: 80    protocol: TCP    targetPort: 80  - name: http-443    port: 443    protocol: TCP    targetPort: 443  - name: http-10254    port: 10254    protocol: TCP    targetPort: 10254  selector:    app: nginx-ingress-controller  sessionAffinity: None  type: ClusterIP

2)通过容器日志查看请求信息

查看 http_request_printer 服务对应容器日志,和2.2示例日志不一样在于多了 X-B3-Parentspanid(父跨度ID)字段 。

查看Nginx Ingress Controller组件对应容器日志,可以看到Nginx Ingress Controller 组件的X-Request-Id Header头信息是 Nginx Ingress Controller组件边车生成的,然后Nginx Ingress Controller 组件将X-Request-Id Header 头信息传递给http_request_printer 这个上游服务的。

3) 查看 http_request_printer 服务上报的链路信息

整个请求Nginx Ingress contorller Pod 中的 Envoy 边车容器入站流量劫持、Nginx Ingress contorller Pod 中的 Envoy 边车容器出站流量劫持、http_request_printer Pod 中的 Envoy 边车容器入站流量劫持都会向jaeger-collector 组件上报链路信息,所以整个请求链有3个 span。

下面简单分析下这三个span。

Nginx Ingress contorller Pod 中的 Envoy 边车容器入站流量劫持 span:

Nginx Ingress contorller Pod 中的 Envoy 边车容器出站流量劫持 span:

http_request_printer Pod 中的 Envoy 边车容器入站流量劫持 span:

注意 1:通过2.2和2.3章节我们知道,即使 Nginx Ingress Controller 组件不注入边车,默认也会给一个请求生成 X-Request-Id Header 头信息,并且它加的这个 X-Request-Id Header 头信息是非标准形式形式的。而Nginx Ingress Controller 组件注入边车的话,流量先经过 Istio-Proxy 容器,自动加上标准形式的 X-Request-Id Header 头信息,再经过 Nginx 容器时,因为请求头中已经有了 X-Request-Id Header 头信息,因此就不会使用 Nginx 生成的非标准 requestID。

注意 2:为什么 Ingress 注入 Sidecar 跟不注入 Sidecar,X-Request-Id 形式不一样呢?

当请求访问 Ingress 时,会先经过一个 Sidecar Istio-Proxy Container 后,产生一个标准 ID(xxx-xxx-xxx)。请求转发至 Ingress Controller 的 Container,此时请求已经有了 RequestID,因此不会被 Nginx 覆盖。Nginx 配置文件如下:

# Reverse proxies can detect if a client provides a X-Request-ID header, and pass it on to the backend server.# If no such header is provided, it can provide a random value.map $http_x_request_id $req_id {  # http_x_request_id 是请求进来的requestId  default   $http_x_request_id; # 默认使用请求头中的requestID,即将http_x_request_id的值赋给req_id  ""        $request_id; # http_x_request_id是空,那么使用 request_id,request_id是Nginx默认的自带的变量,一个16位比特的随机数,用32位的16进制数表示。...}proxy_set_header X-Request-ID           $req_id;

注意 3:要使用Nginx Ingress Controller 作为 Istio 网格入口的话需要在 ingress 资源上添加如下注解,详情参见《利用Nginx Ingress Controller作为 Istio 网格入口》这篇博文。

nginx.ingress.kubernetes.io/service-upstream: "true"nginx.ingress.kubernetes.io/upstream-vhost: http-request-printer.tracing.svc.cluster.local

不加这两个注解的话,流量从 nginx ingress controller envoy 出站的时候直接通过 PodIp:Pod端口 访问上游服务,说明没有匹配 envoy 配置规则,这时候在链路追踪UI页面查询upstream_cluster 和 upstream_cluster.name 值的话都是PassthroughCluster。

3、总结

通过《应用程序通过 Envoy 代理和 Jaeger 进行分布式追踪(一)》这篇博文我们知道,Envoy 原生支持 Jaeger,追踪所需 x-b3 开头的 Header 和 x-request-id 在不同的服务之间由业务逻辑进行传递,并由 Envoy 上报给 Jaeger,最终 Jaeger 生成完整的追踪信息。为了将各种追踪 span 整合在一起以获得完整的追踪图,应用程序必须在传入和传出请求之间传播追踪上下文信息。特别是,Istio 依赖于应用程序传播 b3 追踪 Header 以及由 Envoy 生成的请求 ID,即应用程序服务请求时需携带这些 Header。如果请求中没有 B3 HTTP Header,Istio Sidecar 代理(Envoy) 会自动生成初始化的 Headers。

在本文我们进一步扩展链路追踪范围,演示了如何将 Nginx Ingress Controller 与之前提到的应用程序一起使用,从而实现更为复杂的分布式链路追踪。应用程序通过 Envoy 代理实现分布式链路追踪一定要注意以下几点:

Envoy 调用时会帮助应用程序生成 trace 信息,而调用链中关键的就是 trace_id 和 span,如果应用不传递的话,每次 Envoy 都会生成新的 trace_id,导致查看到的结果就是一个调用链中只有一个 span,所以应用程序必须在传入和传出请求之间传播追踪上下文信息,否则整个链路串不起来。定义 svc 资源对象时需要指定服务应用层协议,因为 istio 需要知道服务提供什么七层协议,从而来为其配置相应协议的 filter chain,千万不要写成 tcp 协议,否则不会上报链路信息。( 服务指定协议配置详情请参见《Istio 为服务指定协议》这篇博文)要使用Nginx Ingress Controller 作为 Istio 网格入口的话需要在 ingress 资源上添加配置nginx.ingress.kubernetes.io/service-upstream、nginx.ingress.kubernetes.io/upstream-vhost注解。 (Nginx Ingress Controller 作为 Istio 网格入口配置详情参见《利用Nginx Ingress Controller作为 Istio 网格入口》这篇博文)

参考:Jaeger讲解

标签:

生活指南
  • 激光点阵能去黑眼圈吗?

    激光点阵可以帮助改善黑眼圈,但并不能完全去除黑眼圈。激光点阵是一种

  • 梭边鱼的做法大全家常做法窍门(梭边鱼的做法)

    梭边鱼的做法有好几种的1、清炖梭鱼梭鱼,三条,鱼背上,横竖划几道(

  • 茶水可以增长睫毛吗_隔夜茶水涂睫毛有用吗

    七种方法可快速增长魅力睫毛怎么做才能拥有长长的卷翘睫毛?今天就告诉

  • 王一博救不了的体育电影,今年暑期卖出30亿票房

    今年夏天,体育类题材的电影收获很多,其中体育题材的《八角笼中》和《

  • 银河娱乐(00027)公布中期业绩,股东应占溢利28.9亿港元 同比扭亏为盈 拟派特别息每股0.2港元

    银河娱乐(00027)公布2023年上半年业绩,公司净收益同比上升141%至157

  • 怎么可以领淘金币(淘金币怎么领取)

    怎么可以领淘金币,淘金币怎么领取这个很多人还不知道,现在让我们一起

  • 哈尔滨市推进部门、媒体安全宣传融合机制创新工作

    中新网黑龙江新闻8月17日电(记者刘锡菊)近日,哈尔滨市安委办召开推进

  • 京投发展涨停

    中国经济网北京8月16日讯京投发展(SH:600683)今日股价涨停,截至收盘报

  • 西湖大学教授获未来科学大奖!施一公曾多次讲述他的故事:输在起跑线上并不重要,关键看后程发力

    今天,未来科学大奖颁出2023年获奖名单,共8位科研工作者获奖。其中,

  • “此之臭味,彼之美食”,品牌如何玩转两极分化的“臭东西”?

    图片来源@视觉中国口味融合、联名营销……臭味食品还有多大的想象空

  • 日本上市企业一季度净利润同比增长46% 许多企业宣布上调业绩

    8月15日电,日本上市企业2023财年一季度(4至6月)财报已基本出炉,净

  • 团贷网还款充值失败是怎么回事-团贷网还款充值失败是怎么回事啊

    随着现代科技的发展,各种金融类应用软件层出不穷,为广大用户带来便捷

  • 【星岛热评】​夜市非灵丹妙药,港人旅客消费变成因多

    ​香港疫后复常逾半年,访港旅客虽大幅回升,但经济复苏力度不似预期,

  • Epomaker海外推出TH80-X键盘:旋钮屏幕、三模连接,99.99美元

    IT之家8月15日消息,Epomaker海外推出了TH80-X键盘,售价99 99美元(IT

  • 2023《sky光遇》8月14日每日任务攻略

    Sky光遇通过其精心设计的场景、音乐和故事情节,将玩家的情感引导到一

  • 多款产品月流水破亿,这家广州垂类大厂为何能全球通吃?

    似乎《原神》之后,国产游戏的出海节奏更快了。一方面腾讯、米哈游、莉

  • 民生
    • 8月19日上午!又有5位“母老虎”被查,个个漂亮却很贪,看看有谁

    • 双城论坛29日登场 蒋万安率团赴上海

    • 中泰股份全资子公司收到行政处罚决定书

    • 蔷薇花联句(关于蔷薇花联句简述)