使用适用于 Kubernetes 的 NGINX 入口控制器启用 OpenTracing

过去几年,人们对 Kubernetes 的兴趣稳步增长,许多企业正在其生产环境中将其与微服务架构一起采用。然而,采用分布式服务带来了新的挑战。了解和调试基于微服务的应用程序中发生的情况可能很困难,尤其是在存在大量服务的情况下。为了发现故障或性能问题,您需要一个分布式跟踪工具,当数据在构成应用程序的微服务之间传递时,该工具可以端到端地跟踪请求。

OpenTracing 是分布式跟踪的规范和 API 集。在上一篇文章中,我们展示了如何使用 OpenTracing 社区创建的开源模块 (nginx-opentracing),为由 NGINX Open Source 和 NGINX Plus 代理和负载平衡的应用程序启用分布式跟踪。在撰写本文时,开放跟踪提供了九种编程语言的库。

没有w,当使用 Kubernetes 的 NGINX 和 NGINX Plus 入口控制器来平衡集群中的流量时,我们还添加了对 Kubernetes 集群中 HTTP 和 gRPC 请求的 OpenTracing 的本机支持。

使用 OpenTracing 有多种用例,这里我们重点关注通过请求上下文传播来跟踪服务器端点。在分布式环境中,集群内的每个应用程序都被视为不同的服务器。想象一下两个应用程序或服务都参与处理来自客户端的请求。例如,在下图所示的拓扑中,App1 是处理 HTTP 请求并将其重定向到 App2 的 Web 服务器。这两个应用程序都在由 NGINX Ingress Controller 进行负载平衡的 Kubernetes 集群内运行,并且启用了 OpenTracing,因此我们可以跟踪来自 Ingress Controller 的请求通过 App1 并到达 App2。

有关组件 i 执行的每个操作的信息系统(例如服务)在 OpenTracing 所谓的跨度中捕获,将跨度链接在一起使我们能够在请求通过集群中的微服务的过程中识别和跟踪请求。

注意:在撰写本文时,OpenTracing 仅在 NGINX Ingress Controller 的边缘版本中可用。

将 OpenTracing 构建到 NGINX 入口控制器映像中

要将 OpenTracing 与我们的 Ingress Controller 结合使用,您需要将 OpenTracing 模块合并到 NGINX 或 NGINX Plus Ingress Controller 的 Docker 映像中,并指定您正在使用的跟踪器。

在 Ingress Controller 的 GitHub 存储库中,我们为 NGINX 和 NGINX Plus 提供单独的 Dockerfile。它们都将开源 OpenTracing 模块合并到 Docker 镜像中,但方式不同:

  • 对于NGINX,DockerfileWithOpentracing从GitHub下载OpenTracing模块并在第一阶段手动编译它Docker 构建的一部分。
  • 对于 NGINX Plus,DockerfileWithOpentracingForPlus 使用包管理器检索 NGINX 从开源 OpenTracing 模块构建并维护的动态模块。

执行以下步骤:

  • (可选。)指定除默认 Jaeger 之外的跟踪器。插件还适用于 Datadog、LightStep 和 Zipkin。要使用不同的跟踪器,请按照启用 OpenTracing 的说明的先决条件部分中指定的方式修改 Dockerfile。
  • 使用 Ingress Controller 存储库中的说明构建 Docker 映像。在步骤 3 中,指定适当的 Dockerfile。

    对于 NGINX:

    $ 清理干净
    $ make DOCKERFILE=DockerfileWithOpentracing PREFIX=您的私有注册表/nginx-ingress

    对于 NGINX Plus:

    $ 清理干净
    $ make DOCKERFILE=DockerfileWithOpentracingForPlus PREFIX=您的私人注册表/nginx-plus-ingress

  • 使用 Ingre 中的说明安装映像ss 控制器存储库。

    在运行说明第 3 部分中的 kubectl apply 命令之前,请记住更新 YAML 文件以指定包含 OpenTracing 的新建映像:

    容器:
    – 图片:IMAGE_WITH_OPENTRACING

  • 部署 Jaeger Tracer

    在本博客中,为了简单起见,我们使用默认的跟踪器 Jaeger,并将其部署在集群内部,但它也可以部署在外部。 Ingress Controller pod 和使用 OpenTracing 的应用程序 pod 必须有权访问跟踪器。

    同样为了简单起见,我们使用 Jaeger 提供的一体化模板在集群中设置一个非生产 Jaeger 实例。最终的部署(适合开发环境)创建一个 Jaeger Pod 以及访问该 Pod 所需的一组服务;它在默认命名空间中设置最新的 Jaeger 版本,具有内存存储和有限的功能y。

    $ kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml

    在生产中,我们建议使用 Jaeger Operator 进行安装。有关 Jaeger 的更多信息,请参阅 Jaeger 网站。

    启用 OpenTracing

    NGINX Ingress Controller 的以下 ConfigMap (nginx-config.yaml) 在全局范围内启用 OpenTracing。它在数据部分添加了三个新的 ConfigMap 键:

    • opentracing 密钥为集群中创建的所有 Ingress 资源启用 OpenTracing。
    • opentracing-tracer 键指定跟踪器库的路径,该库会在您构建 Ingress Controller 映像时下载并复制到该映像中。
    • opentracing-tracer-config 键嵌入跟踪器配置。 service_name 字段定义与实际跨度关联的服务,reporter 字段指定跟踪器的地址和端口(在我们的例子中,是跟踪器的地址和端口)Jaeger 服务由上一节中的一体化模板部署)。 Sampler字段指定客户端采样配置;为简单起见,我们配置“常量”采样器 (const),它对所有轨迹进行采样。

    种类:ConfigMap
    api版本:v1
    元数据:
    名称:nginx-config
    命名空间:nginx-ingress
    数据:
    开放跟踪:“真实”
    opentracing-tracer:“/usr/local/lib/libjaegertracing_plugin.so”
    opentracing-tracer-config: |
    {
    “service_name”: “nginx-ingress”,
    “采样器”:{
    “类型”:“常量”,
    “参数”:1
    },
    “记者”:{
    “localAgentHostPort”:“jaeger-agent.default.svc.cluster.local:6831”
    }
    }

    要应用配置,只需运行:

    $ kubectl apply –f nginx-config.yaml

    部署示例应用程序

    为了简单起见,我们使用 NGINX 实例作为后端应用程序。我们有两个不同的应用程序,其中 App1 配置为将所有 HTTP 流量重定向到 App2。

    这两个应用程序都使用 ConfigMap 和卷来配置在 Pod 内运行的 NGINX 实例。其中一个 ConfigMap 具有 NGINX 配置。另一个用于指定每个 NGINX 实例的跟踪器配置(我们将配置包含在每个应用程序中,因为如前所述,应用程序 Pod 需要访问跟踪器才能发送有关请求的信息)。

    部署 App1

    这是第一个应用程序 (app1.yaml) 的 YAML 清单:

    api版本:v1
    种类:ConfigMap
    元数据:
    名称:app1-config
    数据:
    nginx.conf: |-
    用户 nginx;
    工作进程 1;
    load_module 模块/ngx_http_opentracing_module.so;
    error_log /var/log/nginx/error.log 警告;
    pid /var/run/nginx.pid;
    事件{
    工人连接1024;
    }
    http{
    opentracing_load_tracer /usr/local/lib/libjaegertracing_plugin.so
    /etc/jaeger-config.json;
    打开跟踪;
    服务器{
    听80;
    服务器名称 example.com;
    地点 / {
    opentracing_propagate_context;
    proxy_set_header 主机 $host;
    proxy_pass http://app2-svc:80;
    }
    }
    }

    api版本:v1
    种类:ConfigMap
    元数据:
    名称: jaeger-config-app1
    数据:
    jaeger-config.json: |-
    {
    “服务名称”:“应用程序1”,
    “采样器”:{
    “类型”:“常量”,
    “参数”:1
    },
    “记者”:{
    “localAgentHostPort”:“jaeger-agent.default.svc.cluster.local:6831”
    }
    }

    api版本:apps/v1
    种类:部署
    元数据:
    名称:应用程序1
    规格:
    副本:1
    选择器:
    匹配标签:
    应用程序:应用程序1
    模板:
    元数据:
    标签:
    应用程序:应用程序1
    规格:
    容器:
    – 名称:app1
    图片:opentracing/nginx-opentracing
    端口:
    – 集装箱端口:80
    体积安装:
    – 名称:配置-app1
    挂载路径:/etc/nginx/nginx.conf子路径:nginx.conf
    只读:真
    – 名称:config-jaeger
    挂载路径:/etc/jaeger-config.json
    子路径:jaeger-config.json
    只读:真
    卷:
    – 名称:配置-app1
    配置映射:
    名称:app1-config
    – 名称:config-jaeger
    配置映射:
    名称: jaeger-config-app1

    api版本:v1
    种类: 服务
    元数据:
    名称:app1-svc
    规格:
    端口:
    – 端口:80
    目标端口:80
    选择器:
    应用程序:应用程序1

    要部署第一个应用程序,请运行以下命令:

    $ kubectl apply –f app1.yaml

    部署App2

    这是第二个应用程序 (app2.yaml) 的 YAML 清单:

    api版本:v1
    种类:ConfigMap
    元数据:
    名称:app2-config
    数据:
    nginx.conf: |-
    用户 nginx;
    工作进程 1;
    load_module 模块/ngx_http_opentracing_module.so;
    error_log /var/log/nginx/error.log 警告;
    pid /var/run/nginx.pid;
    事件{
    工人连接1024;}
    http{
    opentracing_load_tracer /usr/local/lib/libjaegertracing_plugin.so
    /etc/jaeger-config.json;
    打开跟踪;
    服务器 {
    听80;
    服务器名称 example.com;
    地点 / {
    opentracing_propagate_context;
    opentracing_tag应用程序app2;
    return 200 “成功!\n”;
    }
    }
    }

    api版本:v1
    种类:ConfigMap
    元数据:
    名称: jaeger-config-app2
    数据:
    jaeger-config.json: |-
    {
    “服务名称”:“应用程序2”,
    “采样器”:{
    “类型”:“常量”,
    “参数”:1
    },
    “记者”:{
    “localAgentHostPort”:“jaeger-agent.default.svc.cluster.local:6831”
    }
    }

    api版本:apps/v1
    种类:部署
    元数据:
    名称:应用程序2
    规格:
    副本:1
    选择器:
    匹配标签:
    应用程序:应用程序2
    模板:
    元数据:
    标签:
    应用程序:应用程序2
    规格:
    容器:
    – 名称:app2图片:opentracing/nginx-opentracing
    端口:
    – 集装箱端口:80
    体积安装:
    – 名称:配置-app2
    挂载路径:/etc/nginx/nginx.conf
    子路径:nginx.conf
    只读:真
    – 名称:config-jaeger
    挂载路径:/etc/jaeger-config.json
    子路径:jaeger-config.json
    只读:真
    卷:
    – 名称:配置-app2
    配置映射:
    名称:app2-config
    – 名称:config-jaeger
    配置映射:
    名称: jaeger-config-app2

    api版本:v1
    种类: 服务
    元数据:
    名称:app2-svc
    规格:
    端口:
    – 端口:80
    目标端口:80
    选择器:
    应用程序:应用程序2

    要部署第二个应用程序,请运行以下命令:

    $ kubectl apply -f app2.yaml

    部署入口资源

    为了能够从集群外部访问 App1,我们创建以下 Ingress 资源 (opentracing-ingress.yaml):

    api版本:扩展/v1beta1
    种类: 入口
    元数据:
    娜我:opentracing-ingress
    注释:
    nginx.org/location-snippets:|
    opentracing_propagate_context;
    规格:
    规则:
    – 主机:example.com
    http:
    路径:
    – 小路: /
    后端:
    服务名称:app1-svc
    服务端口:80

    请注意我们如何使用 nginx.org/location-snippets 注释在入口控制器级别启用跟踪上下文传播。片段注释是一种将自定义代码添加到 Ingress Controller 中的最终 NGINX 配置的方法。

    最后,我们通过运行以下命令来应用 Ingress 资源:

    $ kubectl apply -f opentracing-ingress.yaml

    我们验证 App1 和 App2 都在运行:

    $ kubectl 获取 Pod
    名称就绪状态重新开始年龄
    app1-68fd9db45c-szqpr 1/1 运行 0 53m
    app2-67c7788789-lvbgw 1/1 运行 0 53m

    跟踪请求

    现在,我们只需通过 Ingress Controller 向 App1 发出请求,其中

    • 我C_HTTP_PORT 是 Ingress Controller Pod 中的 HTTP 端口(默认为 80)
    • IC_IP_ADDRESS 是 Ingress Controller Pod 的 IP 地址。如果您使用 minikube,这是 minikube IP 地址。

    $curl –resolve example.com:IC_HTTP_PORT:IC_IP_ADDRESS http://example.com:IC_HTTP_PORT/ –insecure
    成功!

    查看跟踪

    我们运行以下命令来启用对 Jaeger UI 的访问,其中 JAEGER_POD 是我们根据部署 Jaeger Tracer 中的一体化模板创建的 pod 的“类型/名称”值:

    $ kubectl 端口转发 JAEGER_POD 16686:16686

    每个请求都会创建一个新的跟踪。要查看我们刚刚发出的请求的跟踪,我们在浏览器中打开 Jaeger UI(网址为 http://localhost:16686),在左列的“服务”字段中输入 nginx-egress,然后单击底部的“查找跟踪”按钮列的。

    单击搜索窗口右栏中的 nginx-ingress 以选择跟踪。橱窗里打开(如下),我们可以看到请求的三个跨度:棕色代表 Ingress 控制器,蓝色代表 App1,黄色代表 App2。

    单击某个范围可显示有关它的更多详细信息,包括 HTTP 状态代码、主机名、IP 地址和 Jaeger 版本。

    结论

    在 Kubernetes 中为您的服务启用 OpenTracing 可帮助您和您的团队了解应用程序中发生的情况并更快地调试问题。

    此外,能够跟踪从 Ingress Controller Pod 开始的请求,让您可以全面了解从集群外部发送的请求在通过每个服务时的情况。

    了解 NGINX Plus 中的增强功能如何促进您的 Kubernetes 部署 – 立即开始 30 天免费试用或联系我们讨论您的使用案例。


    评论

    发表回复

    您的电子邮箱地址不会被公开。 必填项已用 * 标注