将 Jaeger Collector 暴露给集群外的客户端

Expose Jaeger Collector to clients outside of cluster

我正在使用 Jaeger Operator 将 Jaeger 查询和收集器服务部署到 Kubernetes(实际上是 K3S)以及用于存储后端的 ElasticSearch 实例。

Jaeger Operator 为 Jaeger 查询服务创建了一个 Ingress 实例,但它假定您的所有 Jaeger Agent 也将 运行在 Kubernetes 集群中。不幸的是,我的情况并非如此,因为我正在跟踪的某些应用程序不在集群中 运行,因此我需要可以从外部访问我的 Jaeger Collector。

This Jaeger GitHub issue discusses a potential enhancement to the Jaeger Operator for this functionality 它建议在 Operator 之外创建您自己的 Ingress 以公开 Jaeger Collector,但没有详细说明。

我还想利用 gRPC 来实现集群外的 Agent 和集群中的 Collector 之间的通信,this article describes how to set up an Ingress for gRPC (though it is not specific to Jaeger). I used the example ingress spec there,针对我的场景做了一些调整,并将其部署到我的集群中:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
  name: simple-prod-collector
  namespace: monitoring
spec:
  rules:
  - host: jaeger-collector.my-container-dev
    http:
      paths:
      - backend:
          serviceName: simple-prod-collector
          servicePort: 14250

这会为我创建一个 Ingress 以及由 Jaeger Operator 创建的 simple-prod-query ingress:

NAMESPACE      NAME                    CLASS    HOSTS                               ADDRESS          PORTS   AGE
monitoring    simple-prod-query       <none>   jaeger-query.my-container-dev       10.128.107.220   80      6h56m
monitoring    simple-prod-collector   <none>   jaeger-collector.my-container-dev                    80      4h33m

以下是入口背后的服务:

NAMESPACE        NAME                             TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                                  AGE
monitoring       simple-prod-collector            ClusterIP      10.43.20.131    <none>           9411/TCP,14250/TCP,14267/TCP,14268/TCP   7h5m
monitoring       simple-prod-query                ClusterIP      10.43.141.211   <none>           16686/TCP                                7h5m
monitoring       simple-prod-collector-headless   ClusterIP      None            <none>           9411/TCP,14250/TCP,14267/TCP,14268/TCP   7h5m

不幸的是,我的 Jaeger Agent 似乎仍然无法与其对话......我实际上是通过 docker-compose 部署我的 Jaeger Agent,正如你在这里看到的,我正在配置它以连接到 jaeger-collector.my-container-dev:80:

version: "3"

services:

  jaeger-agent:
    image: jaegertracing/jaeger-agent
    hostname: jaeger-agent
    command: ["--reporter.grpc.host-port=jaeger-collector.my-container-dev:80"]
    ports:
      - "6831:6831/udp"  # UDP | accept jaeger.thrift in compact Thrift protocol used by most current Jaeger clients
      - "5778:5778"      # HTTP | serve configs, sampling strategies
      - "14271:14271"    # HTTP | admin port: health check at / and metrics at /metrics
    restart: on-failure

我可以看到连接有问题,因为当我使用 HTTP GET to http://localhost:5778/sampling?service=myservice 访问 Jaeger Agent 的采样策略服务时,我收到一条错误消息,内容如下:

collector error: rpc error: code = Unimplemented desc = Not Found: HTTP status code 404; transport: received the unexpected content-type "text/plain; charset=utf-8"

我的 Ingress 规格有问题吗?似乎没有跟踪数据从我的代理发送到收集器,并且在访问 Jaeger 代理采样服务时出现错误。另外,我觉得有点奇怪 kubectl get ing 输出中没有列出 IP 地址,但也许这是一个转移注意力的问题。

如上所述,我正在使用 K3S,它似乎使用 traefik 作为其入口控制器(与 nginx 相反)。我检查了 traefik 控制器的日志,也没有看到任何有用的信息。

好的,我在这里弄清楚了这个问题,这对于那些拥有更多专业知识的人来说可能是显而易见的。 The guide I linked to above that describes how to make an Ingress spec for gRPC 特定于 NGINX。同时,我正在使用 K3S,它与 Traefik 一起作为入口控制器开箱即用。因此,我在 Ingress 规范中使用的注释没有影响:

metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "GRPC"

所以我找到了 并修改了上面的原始 Ingress 规范以包含那里提到的注释:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-prod-collector
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: traefik
    ingress.kubernetes.io/protocol: h2c
    traefik.protocol: h2c
spec:
  rules:
  - host: jaeger-collector.my-container-dev
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: simple-prod-collector
            port:
              number: 14250

这些是我所做的更改:

  1. 更改了 metadata/annotations(我确信这是实际需要的更改)
  2. 我还更新了规范版本以使用 networking.k8s.io/v1 而不是 networking.k8s.io/v1beta1 因此有一些结构上的变化但是 none 的实际内容改变了 AFAIK。

希望这可以帮助其他人 运行 陷入同样的​​困惑。