首页 > 系统相关 >Nginx Ingress Contoller 通过 Envoy 代理和 Jaeger 进行分布式追踪(二)

Nginx Ingress Contoller 通过 Envoy 代理和 Jaeger 进行分布式追踪(二)

时间:2023-08-21 17:57:52浏览次数:37  
标签:Ingress Contoller http Jaeger request Nginx Controller printer

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 yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
  ......
  name: http-request-printer
  namespace: tracing
spec:
  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: v1
kind: Service
metadata:
  name: nginx-ingress-controller
spec:
  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 代理实现分布式链路追踪一定要注意以下几点:

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

标签:Ingress,Contoller,http,Jaeger,request,Nginx,Controller,printer
From: https://www.cnblogs.com/zhangmingcheng/p/17645986.html

相关文章

  • ingress 简单应用
    1.1、命令创建kubectlcreatesecrettlstls-secret--cert=cert.crt--key=privateKey.key1.2、yaml文件创建:apiVersion:v1kind:Secretmetadata:name:<secret-name>data:tls.crt:<base64-encoded-certificate>tls.key:<base64-encoded-private-......
  • k8s---使用ingress配置域名转发时的traefik路径规则详解
    ingress中traefik的使用方式如下:apiVersion:extensions/v1beta1kind:Ingressmetadata:name:spark-client-testnamespace:defaultannotations:kubernetes.io/ingress.class:traefiktraefik.frontend.rule.type:PathPrefixspec:rules:-host:......
  • Ingress-nginx安装(helm)
    NginxIngress简介在Kubernetes集群中,Ingress作为集群内服务对外暴露的访问接入点,其几乎承载着集群内服务访问的所有流量。Ingress是Kubernetes中的一个资源对象,用来管理集群外部访问集群内部服务的方式。您可以通过Ingress资源来配置不同的转发规则,从而达到根据不同的规则设置访问......
  • Ceph对象存储ingress配置https
    每当引用TLSSecrets时,指的是PEM编码的X.509、RSA(2048)Secrets。可以使用以下命令生成自签名证书和私钥:$opensslreq-x509-nodes-days3650-newkeyrsa:2048-keyout${KEY_FILE}-out${CERT_FILE}-subj"/CN=${HOST}/O=${HOST}"例如:$opensslreq-x509-nodes......
  • Kubernetes中的ingress问题
    大佬们想问一下我这个问题该如何解决啊,ip访问没问题,但是域名就有问题了     ......
  • 简述分布式链路追踪工具——Jaeger
    1、简介1.1Jaeger是什么Jaeger  是受到​ ​Dapper​​​和​ ​OpenZipkin​​​启发的由​ ​UberTechnologies​​作为开源发布的分布式跟踪系统,截止2023年8月3日最新稳定版本是1.47。其前端采用React语言实现,后端采用GO语言实现,适用于进行链路追踪,分布式跟踪消......
  • 链路追踪之选型Zipkin、Pinpoint、SkyWalking、CAT、jaeger
    https://www.pianshen.com/article/51782363885/ https://blog.csdn.net/A123638/article/details/123117142......
  • 安装ingress-nginx
    官方网站https://github.com/kubernetes/ingress-nginx查看自己的K8S版本选择ingres-nginx对应版本我的k8s版本是1.23安装的ingress-nginx版本是1.6.4wgethttps://github.com/kubernetes/ingress-nginx/blob/controller-v1.6.4/deploy/static/provider/cloud/deploy.yaml配......
  • Kubernetes Ingress
    一、Ingress和Ingress控制器1.1为什么需要Ingress资源Kubernetes上的NodePort和LoadBalancer类型的Service资源能够把集群内部服务暴露给集群外部客户端进行访问。但是由于生产环境中业务多为分布式,暗含复杂的调用关系,且业务数量不止一个,由此会带来如下问题:如何管理端口当需要对外......
  • Ingress:集群进出流量的总管
    Service很有用,但也只能说是“基础设施”,它对网络流量的管理方案还是太简单,离复杂的现代应用架构需求还有很大的差距,所以Kubernetes就在Service之上又提出了一个新的概念:Ingress。Service还有一个缺点,它比较适合代理集群内部的服务。如果想要把服务暴露到集群外部,就只能使用N......