乌克兰国旗 我们与乌克兰的朋友和同事站在一起。为了支持乌克兰度过难关 访问此页面.

Kubernetes 的运营商

版本  1.62 最新

了解运营商

Jaeger 运营商是 Kubernetes 运营商外部链接 的实现。运营商是简化运行其他软件的运营复杂性的软件。更准确地说,运营商是一种在 Kubernetes 上打包、部署和管理应用程序的方法。

Kubernetes 应用程序是在 Kubernetes 上部署并使用 Kubernetes API 和 kubectl(Kubernetes)或 oc(OKD)工具管理的应用程序。为了充分利用 Kubernetes,您需要一组一致的 API 来扩展,以服务和管理在 Kubernetes 上运行的应用程序。将运营商视为在 Kubernetes 上管理此类应用程序的运行时。

安装运营商

Jaeger 运营商可以安装在基于 Kubernetes 的集群中,能够监视特定命名空间或整个集群中新的 Jaeger 自定义资源 (CR)。通常每个集群只有一个 Jaeger 运营商,但在多租户场景中,每个命名空间最多可能有一个 Jaeger 运营商。当检测到新的 Jaeger CR 时,运营商将尝试将自身设置为资源的所有者,并将标签 jaegertracing.io/operated-by 设置为新 CR,并将运营商的命名空间和名称作为标签的值。

虽然我们希望 Jaeger 运营商能够适用于尽可能多的 Kubernetes 版本,但我们只能预期修复可以在 Kubernetes 的最后三个次要版本(currentcurrent-1current-2)中重现的错误。

虽然多个运营商可能共存并监视同一组命名空间,但哪个运营商会成功将自身设置为 CR 的所有者是未定义的行为。自动注入 sidecar 也可能导致未定义的行为。因此,强烈建议每个命名空间最多有一个运营商进行监视。请注意,命名空间可能包含任意数量的 Jaeger 实例 (CR)。

Jaeger 运营商版本跟踪一个版本的 Jaeger 组件(jaeger-queryjaeger-collectorjaeger-agent)。当发布新的 Jaeger 组件版本时,将发布一个新的运营商版本,它了解如何将先前版本的运行实例升级到新版本。

先决条件

从 1.31 版开始,Jaeger 运营商使用 Webhook 验证 Jaeger 自定义资源 (CR)。这需要安装 cert-manager外部链接 的版本。支持版本的更详细列表可以在 兼容性矩阵外部链接 中找到。安装指南可以在 此处外部链接 中找到。

必须安装 cert-manager 版本 1.6.1 或更高版本。

安装模式

Jaeger 运营商可以安装以监视整个集群或特定命名空间中的新的 Jaeger 自定义资源 (CR)。在为集群模式配置时,运营商可以

  • 监视与所有命名空间中的 Jaeger 资源相关的事件
  • 监视命名空间本身,查找 sidecar.jaegertracing.io/inject 注释
  • 监视所有部署,根据 sidecar.jaegertracing.io/inject 注释注入或删除 sidecar
  • 在必要时创建集群角色绑定

如果未使用集群范围的资源(ClusterRoleClusterRoleBinding),请将 WATCH_NAMESPACE 设置为 Jaeger 运营商应监视与 Jaeger 资源相关的事件的命名空间的逗号分隔列表。Jaeger 运营商可以在给定命名空间(如 observability)中运行,并在另一个命名空间(如 myproject)中管理 Jaeger 资源。为此,请为运营商应监视资源的每个命名空间使用以下 RoleBinding

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jaeger-operator-in-myproject
  namespace: myproject
subjects:
- kind: ServiceAccount
  name: jaeger-operator
  namespace: observability
roleRef:
  kind: Role
  name: jaeger-operator
  apiGroup: rbac.authorization.k8s.io

在 Kubernetes 上安装运营商

以下说明将创建 observability 命名空间并在其中安装 Jaeger 运营商。默认情况下,运营商将监视所有命名空间。

确保您的 kubectl 命令已正确配置为与有效的 Kubernetes 集群通信。如果您没有集群,可以使用 minikube外部链接 在本地创建一个。

要安装运营商,请运行

kubectl create namespace observability # <1>
kubectl create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.62.0.0/jaeger-operator.yaml -n observability # <2>

<1> 这将创建部署文件默认使用的命名空间。如果您想在不同的命名空间中安装 Jaeger 运营商,则必须编辑部署文件以将 observability 更改为所需的命名空间值。

<2> 这将安装 apiVersion: jaegertracing.io/v1 的“自定义资源定义”。

如果要将操作员安装在集群范围模式下,如果您只想监控特定命名空间,则需要将操作员清单中的ClusterRoleClusterRoleBinding更改为RoleRoleBinding,并在Jaeger操作员部署中设置WATCH_NAMESPACE环境变量。

此时,应该有一个jaeger-operator部署可用。您可以通过运行以下命令来查看它

$ kubectl get deployment jaeger-operator -n observability

NAME              DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
jaeger-operator   1         1         1            1           48s

操作员现在已准备好创建Jaeger实例。

在OKD/OpenShift上安装操作员

上一节中的说明也适用于在OKD或OpenShift上安装操作员。确保您以特权用户身份登录,当您安装基于角色的访问控制(RBAC)规则、自定义资源定义和操作员时。

oc login -u <privileged user>

oc new-project observability # <1>
oc create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.62.0.0/jaeger-operator.yaml -n observability # <2>

<1> 这将创建部署文件默认使用的命名空间。如果您想在不同的命名空间中安装 Jaeger 运营商,则必须编辑部署文件以将 observability 更改为所需的命名空间值。

<2> 这将安装 apiVersion: jaegertracing.io/v1 的“自定义资源定义”。

如果要将操作员安装在集群范围模式下,如果您只想监控特定命名空间,则需要将操作员清单中的ClusterRoleClusterRoleBinding更改为RoleRoleBinding,并在Jaeger操作员部署中设置WATCH_NAMESPACE环境变量。

操作员安装完成后,将角色jaeger-operator授予应能够安装单个Jaeger实例的用户。以下示例创建一个角色绑定,允许用户developer创建Jaeger实例

oc create \
  rolebinding developer-jaeger-operator \
  --role=jaeger-operator \
  --user=developer

角色授予后,切换回非特权用户。

快速入门 - 部署AllInOne镜像

创建Jaeger实例的最简单方法是创建类似以下示例的YAML文件。这将安装默认的AllInOne策略,该策略默认情况下将all-in-one镜像(将jaeger-agentjaeger-collectorjaeger-query和Jaeger UI组合在一起)部署在一个Pod中,使用内存存储。

此默认策略适用于开发、测试和演示目的,不适用于生产环境。
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simplest

然后,可以使用kubectl使用YAML文件

kubectl apply -f simplest.yaml

几秒钟后,将提供一个新的内存中all-in-one Jaeger实例,适用于快速演示和开发目的。要检查创建的实例,列出jaeger对象

$ kubectl get jaegers
NAME        CREATED AT
simplest    28s

要获取Pod名称,查询属于simplest Jaeger实例的Pod

$ kubectl get pods -l app.kubernetes.io/instance=simplest
NAME                        READY     STATUS    RESTARTS   AGE
simplest-6499bb6cdd-kqx75   1/1       Running   0          2m

类似地,日志可以从Pod本身直接查询(使用从前一个示例中获得的Pod名称),也可以从属于我们实例的所有Pod查询

$ kubectl logs -l app.kubernetes.io/instance=simplest
...
{"level":"info","ts":1535385688.0951214,"caller":"healthcheck/handler.go:133","msg":"Health Check state change","status":"ready"}
在OKD/OpenShift上,必须指定容器名称。
$ kubectl logs -l app.kubernetes.io/instance=simplest -c jaeger
...
{"level":"info","ts":1535385688.0951214,"caller":"healthcheck/handler.go:133","msg":"Health Check state change","status":"ready"}

配置操作员

Jaeger操作员可以通过命令行界面参数、环境变量或配置文件进行配置。当在不同级别指定相同变量时,优先级顺序为

  1. 命令行参数(标志)
  2. 环境变量
  3. 配置文件

每个项目优先于其下面的项目。可以通过使用--help标志运行操作员来查看可用选项,例如

$ podman run jaegertracing/jaeger-operator:master start --help

示例

通过给定Jaeger操作员部署的标志设置log-level参数(摘录)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger-operator
spec:
  template:
    spec:
      containers:
      - name: jaeger-operator
        image: jaegertracing/jaeger-operator:master
        args: ["start", "--log-level=debug"]

通过给定Jaeger操作员部署的环境变量设置log-level参数(摘录)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger-operator
spec:
  template:
    spec:
      containers:
      - name: jaeger-operator
        image: jaegertracing/jaeger-operator:master
        args: ["start"]
        env:
        - name: LOG-LEVEL
          value: debug

在配置文件中设置log-level参数

log-level: debug

要使用配置文件,请在${HOME}/.jaeger-operator.yaml处创建一个文件,或通过--config指定位置。

部署策略

创建Jaeger实例时,它与策略相关联。该策略在自定义资源文件中定义,并确定用于Jaeger后端的架构。默认策略为allInOne。其他可能的值是productionstreaming

以下部分介绍了可用的策略。

AllInOne(默认)策略

此策略适用于开发、测试和演示目的。

主要的后端组件jaeger-agentjaeger-collectorjaeger-query服务都打包在一个可执行文件中,该文件配置(默认情况下)为使用内存存储。此策略无法扩展到超过一个副本。

生产策略

production策略适用于(顾名思义)生产环境,在生产环境中,跟踪数据的长期存储很重要,并且需要更可扩展、高可用的架构。因此,每个后端组件都是单独部署的。

jaeger-agent可以作为侧车注入到已检测的应用程序中,也可以作为DaemonSet注入。

jaeger-collector可以配置为按需自动扩展。默认情况下,当没有为.Spec.Collector.Replicas提供值时,Jaeger操作员将为jaeger-collector创建一个水平Pod自动扩展器(HPA)配置。我们建议设置.Spec.Collector.MaxReplicas的显式值,以及jaeger-collector的Pod预计要消耗的资源的合理值。当没有设置.Spec.Collector.MaxReplicas时,操作员将设置100作为其值。有关HPA的更多信息,请阅读Kubernetes网站external link 。可以通过将.Spec.Collector.Autoscale设置为false来显式禁用此功能。以下是一个示例,设置jaeger-collector的限制以及最大副本数

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  collector:
    maxReplicas: 5
    resources:
      limits:
        cpu: 100m
        memory: 128Mi

jaeger-queryjaeger-collector服务配置了支持的存储类型 - 目前是Cassandra或Elasticsearch。可以根据性能和弹性要求配置每个组件的多个实例。

主要的其他要求是提供存储类型和选项的详细信息,例如

    storage:
      type: elasticsearch
      options:
        es:
          server-urls: http://elasticsearch:9200

流策略

streaming策略旨在通过提供一种流功能来增强production策略,该功能实际上位于收集器和后端存储(Cassandra或Elasticsearch)之间。这提供了在高负载情况下减轻后端存储压力的益处,并使其他跟踪后处理功能能够直接从流平台(Kafka)获取实时跨度数据。

jaeger-collector可以配置为按需自动扩展,如“生产策略”部分所述。

jaeger-ingester也可以配置为按需自动扩展。默认情况下,当没有为.Spec.Ingester.Replicas提供值时,Jaeger操作员将为jaeger-ingester创建一个水平Pod自动扩展器(HPA)配置。我们建议设置.Spec.Ingester.MaxReplicas的显式值,以及jaeger-ingester的Pod预计要消耗的资源的合理值。当没有设置.Spec.Ingester.MaxReplicas时,操作员将设置100作为其值。有关HPA的更多信息,请阅读Kubernetes网站external link 。可以通过将.Spec.Ingester.Autoscale设置为false来显式禁用此功能。以下是一个示例,设置jaeger-ingester的限制以及最大副本数

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-streaming
spec:
  strategy: streaming
  ingester:
    maxReplicas: 8
    resources:
      limits:
        cpu: 100m
        memory: 128Mi

现有Kafka集群

唯一需要的信息是提供访问Kafka平台的详细信息,这些详细信息在collector组件(作为生产者)和ingester组件(作为消费者)中配置

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-streaming
spec:
  strategy: streaming
  collector:
    options:
      kafka: # <1>
        producer:
          topic: jaeger-spans
          brokers: my-cluster-kafka-brokers.kafka:9092
  ingester:
    options:
      kafka: # <1>
        consumer:
          topic: jaeger-spans
          brokers: my-cluster-kafka-brokers.kafka:9092
      ingester:
        deadlockInterval: 5s # <2>
  storage:
    type: elasticsearch
    options:
      es:
        server-urls: http://elasticsearch:9200

<1> 标识jaeger-collector用于生产消息的Kafka配置,以及jaeger-ingester用于消费消息的Kafka配置。

<2> 死锁间隔默认情况下被禁用(设置为0),以防止jaeger-ingester在没有消息到达时终止。它可以配置为指定在终止之前等待消息的分钟数。

自备Kafka集群

要使用自备方法,不应定义生产者/消费者代理属性。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: auto-provision-kafka
spec:
  strategy: streaming
  storage:
    type: elasticsearch
    options:
      es:
        # Note: This assumes elasticsearch is running in the "default" namespace.
        server-urls: http://elasticsearch.default.svc:9200

可以通过将标志--kafka-provision设置为false来禁用Kafka集群的自备。默认值为auto,这将使Jaeger操作员查询Kubernetes集群,以了解它是否能够处理Kafka自定义资源。这通常由Kafka操作员在安装过程中设置,因此,如果预期Kafka操作员在Jaeger操作员之后运行,则可以将标志设置为true

了解自定义资源定义

在Kubernetes API中,资源是一个存储特定类型API对象的集合的端点。例如,内置的Pods资源包含Pod对象的集合。自定义资源定义(CRD)对象在集群中定义一个新的、唯一的对象Kind,并允许Kubernetes API服务器处理它的整个生命周期。

要创建自定义资源(CR)对象,集群管理员必须首先创建一个自定义资源定义(CRD)。CRD允许集群用户创建CR,以将新的资源类型添加到他们的项目中。操作员监视自定义资源对象的创建,当它看到自定义资源被创建时,它根据自定义资源对象中定义的参数创建应用程序。

虽然只有集群管理员可以创建CRD,但如果开发人员对CRD具有读写权限,则他们可以从现有CRD创建CR。

作为参考,以下是您如何创建更复杂的all-in-one实例的方法

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: my-jaeger
spec:
  strategy: allInOne # <1>
  allInOne:
    image: jaegertracing/all-in-one:latest # <2>
    options: # <3>
      log-level: debug # <4>
  storage:
    type: memory # <5>
    options: # <6>
      memory: # <7>
        max-traces: 100000
  ingress:
    enabled: false # <8>
  agent:
    strategy: DaemonSet # <9>
  annotations:
    scheduler.alpha.kubernetes.io/critical-pod: "" # <10>

<1> 默认策略为allInOne。其他可能的值是productionstreaming

<2> 要使用的镜像,使用常规的Docker语法。

<3> 要逐字传递给底层二进制文件的(与存储无关的)选项。有关所有可用选项,请参阅Jaeger文档和/或相关二进制文件的--help选项。

<4> 该选项是一个简单的key: value映射。在这种情况下,我们要将选项--log-level=debug传递给二进制文件。

<5> 要使用的存储类型。默认情况下,它将是memory,但可以是任何其他支持的存储类型(Cassandra、Elasticsearch、Kafka)。

<6> 所有与存储相关的选项都应放置在此处,而不是放在‘allInOne’或其他组件选项下。

<7> 一些选项是命名空间的,我们可以选择将它们分解为嵌套对象。我们可以指定memory.max-traces: 100000

<8> 默认情况下,将为jaeger-query服务创建一个入口对象。可以通过将其enabled选项设置为false来禁用它。如果在OpenShift上部署,它将由一个路由对象表示。

<9> 默认情况下,操作员假设jaeger-agent作为侧车部署在目标Pod中。将策略指定为“DaemonSet”会更改这一点,并使操作员将jaeger-agent作为DaemonSet部署。请注意,您的跟踪器客户端可能必须覆盖“JAEGER_AGENT_HOST”环境变量以使用节点的IP。

<10> 定义要应用于所有部署(而不是服务)的注释。这些注释可以被定义在各个组件上的注释覆盖。

您可以在 GitHub 上查看不同 Jaeger 配置的示例自定义资源 GitHub外部链接

配置自定义资源

您可以使用最简单的示例(如上所示)并使用默认值创建 Jaeger 实例,或者您可以创建自己的自定义资源文件。

Span 存储选项

Cassandra 存储

当存储类型设置为 Cassandra 时,操作员将自动创建一个批处理作业,该作业创建 Jaeger 运行所需的模式。此批处理作业将阻止 Jaeger 安装,以便它仅在模式成功创建后才启动。可以通过将 enabled 属性设置为 false 来禁用此批处理作业的创建。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: cassandra-without-create-schema
spec:
  strategy: allInOne
  storage:
    type: cassandra
    cassandraCreateSchema:
      enabled: false # <1>

<1> 默认值为 true

还可以配置批处理作业的其他方面。下面显示了包含所有可能选项的示例。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: cassandra-with-create-schema
spec:
  strategy: allInOne # <1>
  storage:
    type: cassandra
    options: # <2>
      cassandra:
        servers: cassandra
        keyspace: jaeger_v1_datacenter3
    cassandraCreateSchema: # <3>
      datacenter: "datacenter3"
      mode: "test"

<1> productionstreaming 也一样。

<2> 这些选项用于常规 Jaeger 组件,如 collectorquery

<3> create-schema 作业的选项。

默认的 create-schema 作业使用 MODE=prod,这意味着使用 NetworkTopologyStrategy 作为类,复制因子为 2,实际上意味着 Cassandra 集群中至少需要 3 个节点。如果需要 SimpleStrategy,请将模式设置为 test,这将设置复制因子为 1。请参考 create-schema 脚本外部链接 以了解更多详细信息。

Elasticsearch 存储

默认情况下,Elasticsearch 存储不需要运行任何初始化作业。但是,Elasticsearch 存储需要运行一个 cron 作业来清理存储中的旧数据。

当启用滚动(es.use-aliases)时,Jaeger 操作员还会部署一个作业来初始化 Elasticsearch 存储,以及另外两个 cron 作业来执行必要的索引管理操作。

外部 Elasticsearch

Jaeger 可以与外部 Elasticsearch 集群一起使用。以下示例展示了使用外部 Elasticsearch 集群(由 Elasticsearch Operator外部链接 创建)的 Jaeger CR,该集群使用从卷中挂载的 TLS CA 证书,以及存储在秘密中的用户名和密码。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  storage:
    type: elasticsearch # <1>
    options:
      es:
        server-urls: https://quickstart-es-http.default.svc:9200 # <2>
        index-prefix: my-prefix
        tls: # <3>
          ca: /es/certificates/ca.crt
    secretName: jaeger-secret # <4>
  volumeMounts: # <5>
    - name: certificates
      mountPath: /es/certificates/
      readOnly: true
  volumes:
    - name: certificates
      secret:
        secretName: quickstart-es-http-certs-public

<1> 存储类型 Elasticsearch。

<2> 运行在默认命名空间中的 Elasticsearch 服务的 URL。

<3> TLS 配置。在这种情况下,只有 CA 证书,但它还可以包含 es.tls.keyes.tls.cert(当使用双向 TLS 时)。

<4> 定义环境变量 ES_PASSWORDES_USERNAME 的秘密。通过 kubectl create secret generic jaeger-secret --from-literal=ES_PASSWORD=changeme --from-literal=ES_USERNAME=elastic 创建。

<5> 挂载到所有存储组件的卷挂载和卷。

自我配置

在某些情况下,Jaeger Operator 可以使用 Elasticsearch Operator外部链接 来配置合适的 Elasticsearch 集群。Jaeger CR 公开了与 OpenShift 集群日志记录外部链接 相同的配置。

当 Jaeger production 实例中没有 es.server-urls 选项,并且 elasticsearch 设置为存储类型时,Jaeger Operator 通过根据存储部分中提供的配置创建自定义资源,通过 Elasticsearch Operator 创建一个 Elasticsearch 集群。Elasticsearch 集群旨在专用于单个 Jaeger 实例。

以下是使用单个节点 Elasticsearch 集群(具有 AWS gp2 持久存储)的 Jaeger 示例。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  storage:
    type: elasticsearch
    elasticsearch:
      nodeCount: 1 # <1>
      storage: # <2>
        storageClassName: gp2
        size: 5Gi
      resources: # <3>
        requests:
          cpu: 200m
          memory: 4Gi
        limits:
          memory: 4Gi
      redundancyPolicy: ZeroRedundancy # <4>

<1> Elasticsearch 节点的数量。要实现高可用性,请至少使用 3 个节点。不要使用 2 个节点,因为可能会出现“脑裂”问题。

<2> 持久存储配置。在这种情况下,AWS gp2,大小为 5Gi。省略时使用 emptyDir。Elasticsearch 操作员配置 PersistentVolumeClaimPersistentVolume,它们不会随着 Jaeger 实例一起删除。如果创建具有相同名称和命名空间的 Jaeger,则可以挂载相同的卷。由于 OpenShift SCC 策略,某些存储可能会在 default 命名空间中失败。

<3> Elasticsearch 节点的资源。在这种情况下,为 4Gi,这会导致默认情况下需要 2Gi 的堆空间。请参考 Elasticsearch 文档外部链接 以获取内存建议。

<4> 数据复制策略定义了 Elasticsearch 分片如何在集群中的数据节点之间进行复制。如果未指定,Jaeger Operator 会根据节点数量自动确定最合适的复制策略。

  • FullRedundancy Elasticsearch 将每个索引的主分片完全复制到每个数据节点。这提供了最高的安全性,但代价是需要最多的磁盘空间,并且性能最差。
  • MultipleRedundancy Elasticsearch 将每个索引的主分片完全复制到一半的数据节点。这在安全性与性能之间提供了良好的权衡。
  • SingleRedundancy Elasticsearch 为每个索引创建主分片的副本。只要存在至少两个数据节点,数据始终可用且可恢复。与使用 5 个或更多节点时的 MultipleRedundancy 相比,性能更好。您不能在单个 Elasticsearch 节点部署中应用此策略。
  • ZeroRedundancy Elasticsearch 不会创建主分片的副本。如果节点出现故障或失败,数据可能不可用或丢失。当您更关心性能而不是安全性,或者已实施了自己的磁盘/PVC 备份/恢复策略时,使用此模式。

可以通过将标志 --es-provision 设置为 false 来禁用 Elasticsearch 集群的自我配置。默认值为 auto,这将使 Jaeger Operator 查询 Kubernetes 集群以确定其处理 Elasticsearch 自定义资源的能力。这通常由 Elasticsearch Operator 在安装过程中设置,因此,如果预计 Elasticsearch Operator 在 Jaeger Operator 之后 运行,则可以将标志设置为 true

目前,每个命名空间只能有一个具有自我配置的 Elasticsearch 实例的 Jaeger。

Elasticsearch 索引清理作业

当使用 elasticsearch 存储时,默认情况下会创建一个 cron 作业来清理其中的旧跟踪,下面列出了该作业的选项,以便您可以根据自己的用例对其进行配置。连接配置是从存储选项中获取的。

storage:
  type: elasticsearch
  esIndexCleaner:
    enabled: true                                 // turn the cron job deployment on and off
    numberOfDays: 7                               // number of days to wait before deleting a record
    schedule: "55 23 * * *"                       // cron expression for it to run

连接到存储的配置是从存储选项中获取的。

Elasticsearch 滚动

这种索引管理策略比使用默认的每日索引更复杂,它需要一个初始化作业来准备存储,以及两个 cron 作业来管理索引。第一个 cron 作业用于滚动到新的索引,第二个 cron 作业用于从读取别名中删除索引。当存储选项 es.use-aliases 启用时,使用滚动功能。

要详细了解 Jaeger 中的滚动索引管理,请参考此 文章外部链接

storage:
  type: elasticsearch
  options:
    es:
      use-aliases: true
  esRollover:
    conditions: "{\"max_age\": \"2d\"}"          // conditions when to rollover to a new index
    readTTL: 168h                                // how long should be old data available for reading (7 days)
    schedule: "55 23 * * *"                      // cron expression for it to run

连接到存储的配置是从存储选项中获取的。

Elasticsearch 索引生命周期管理

索引生命周期管理外部链接 (ILM) 是 X-Pack 插件中的一个 Elasticsearch 功能,用于管理索引的生命周期。在 Operator 上下文中,这意味着可以将 ILM 用于代替滚动 cron 作业。Jaeger 项目没有提供与 ILM 的直接集成,但是 Jaeger 实例可以配置为使用索引别名(ILM 所需)并禁用索引模板创建和滚动 cron 作业。这允许用户在部署 Jaeger 之前在自定义索引模板中配置 ILM。

spec:
  strategy: production
  collector:
    options:
      es:
        use-aliases: true # <1>
  query:
    options:
      es:
        use-aliases: true  # <1>
  storage:
    type: elasticsearch
    options:
      es:
        create-index-templates: false  # <2>
        server-urls: http://elasticsearch:9200

<1> 配置 jaeger-queryjaeger-collector 以使用读写索引别名。

<2> 禁用默认索引模板的创建。

存储插件

从 v1.58 开始将不再支持 Sidecar 插件。自定义存储后端应迁移到远程存储 API。

指标存储选项

Prometheus

spec.metricsStorage.type 设置为 prometheus 可以使 Jaeger 使用与 PromQL 兼容的存储实现来存储 服务性能监控 功能的 jaeger-query R.E.D 指标。

以下是一个使用 allInOne 部署策略、内存中跨度存储和 Prometheus 指标存储的 Jaeger CR 示例。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: jaeger-spm
spec:
  strategy: allInOne
  allInOne:
    image: jaegertracing/all-in-one:latest
    options:
      log-level: debug
      query:
        base-path: /jaeger
      prometheus: # <1>
        server-url: "http://prometheus:9090" # <2>
    metricsStorage: # <3>
      type: prometheus # <4>
  storage:
    options:
      memory:
        max-traces: 100000

<1> prometheus 命名空间配置的开头,定义为一个简单的 key: value 映射。所有可用选项都在 Jaeger All-In-One with Prometheus CLI 部分 中有文档说明。

<2> 用 http://prometheus:9090 覆盖默认的 https://127.0.0.1:9090 Prometheus 服务器 URL。

<3> 用于启用指标查询功能的部分。

<4> 选择 prometheus 作为指标存储后端。

推断依赖关系

推断依赖关系的处理过程将从存储中收集跨度,分析服务之间的链接并将它们存储起来,以便稍后在 UI 中呈现。此作业只能与 production 策略和 cassandraelasticsearch 存储类型一起使用。

storage:
  type: elasticsearch
  dependencies:
    enabled: true                                 # turn the job deployment on and off
    schedule: "55 23 * * *"                       # cron expression for it to run
    sparkMaster:                                  # spark master connection string, when empty spark runs in embedded local mode
    resources:
      requests:
        memory: 4096Mi
      limits:
        memory: 4096Mi

连接到存储的配置是从存储选项中获取的。

确保分配足够的内存资源。Spark 文档外部链接 建议至少使用 8Gi 的内存。但是,该作业可以使用至少 2Gi 的内存启动。正确的内存设置将取决于正在处理的数据量。请注意,该作业将当前日期的所有数据加载到内存中。

自动注入 Jaeger Agent Sidecar

只要部署或其命名空间具有带有适当值的 sidecar.jaegertracing.io/inject 注释,操作员就可以在 Deployment 工作负载中注入 jaeger-agent sidecar。这些值可以是 "true"(作为字符串),也可以是 kubectl get jaegers 返回的 Jaeger 实例名称。如果使用 "true",则应该存在与部署相同的命名空间的 一个 Jaeger 实例,否则,操作员无法自动确定要使用哪个 Jaeger 实例。部署上的特定 Jaeger 实例名称优先于应用于其命名空间的 true

以下代码段显示了一个将注入 sidecar 的简单应用程序,其中 jaeger-agent 指向同一命名空间中可用的单个 Jaeger 实例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  annotations:
    "sidecar.jaegertracing.io/inject": "true" # <1>
spec:
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: acme/myapp:myversion

<1> "true"(作为字符串)或 Jaeger 实例名称。

完整的示例部署位于 deploy/examples/business-application-injected-sidecar.yaml外部链接

注入 sidecar 后,jaeger-agent 可以在其默认位置 localhost 上访问。

注入 Sidecar 的部署级配置

由于 sidecar 可能被注入到未由 jaeger-operator 管理的部署中,因此许多应用于部署级的配置都不会应用于 sidecar 的部署,除非它们在 jaeger-agent 节点下指定。以下配置适用于 sidecar 的部署

  • 卷(和卷挂载)
  • ImagePullSecrets

例如,以下 Jaeger 配置将 agent-volumeagent-imagePullSecrets 添加到 sidecar 的部署中。

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: my-jaeger
spec:
  agent:
    volumeMounts:
    - name: agent-volume
      mountPath: /tmp/agent
      readOnly: true
    volumes:
      - name: agent-volume
        secret:
          secretName: agent-secret
    imagePullSecrets:
    - name: agent-imagePullSecret

手动定义 Jaeger Agent Sidecar

对于 Deployments 以外的控制器类型(例如 StatefulSetsDaemonSets 等),可以在您的规范中手动定义 jaeger-agent sidecar。

以下代码段显示了可以在您的 containers 部分中包含的 jaeger-agent sidecar 的手动定义

- name: jaeger-agent
  image: jaegertracing/jaeger-agent:latest
  imagePullPolicy: IfNotPresent
  ports:
    - containerPort: 5775
      name: zk-compact-thrift
      protocol: UDP
    - containerPort: 5778
      name: config-rest
      protocol: TCP
    - containerPort: 6831
      name: jg-compact-thrift
      protocol: UDP
    - containerPort: 6832
      name: jg-binary-thrift
      protocol: UDP
    - containerPort: 14271
      name: admin-http
      protocol: TCP
  args:
    - --reporter.grpc.host-port=dns:///jaeger-collector-headless.observability:14250
    - --reporter.type=grpc

完整的示例 StatefulSet 位于 deploy/examples/statefulset-manual-sidecar.yaml外部链接

jaeger-agent 可以在其默认位置 localhost 上访问。

将 Agent 安装为 DaemonSet

默认情况下,操作员期望 jaeger-agent 被部署为目标应用程序的 sidecar。这对多种目的都很方便,例如在多租户场景中或为了获得更好的负载平衡,但在某些情况下,您可能希望将 jaeger-agent 安装为 DaemonSet。在这种情况下,请将 jaeger-agent 的策略指定为 DaemonSet,如下所示

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: my-jaeger
spec:
  agent:
    strategy: DaemonSet
如果您尝试在同一个集群上安装两个使用 DaemonSet 作为策略的 Jaeger 实例,则最终只会部署 一个 DaemonSet,因为代理需要绑定到节点上的知名端口。因此,第二个守护进程集将无法绑定到这些端口。

然后,您的跟踪器客户端可能需要告知 jaeger-agent 的位置。这通常通过将环境变量 JAEGER_AGENT_HOST 设置为 Kubernetes 节点的 IP 值来完成,例如

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: acme/myapp:myversion
        env:
        - name: JAEGER_AGENT_HOST
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP

OpenShift

在 OpenShift 中,只有在设置了特殊的安全上下文时才能设置 HostPortjaeger-agent 可以使用单独的服务帐户,该帐户具有绑定到 HostPort 的权限,如下所示

oc create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/examples/openshift/hostport-scc-daemonset.yaml # <1>
oc new-project myproject
oc create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/examples/openshift/service_account_jaeger-agent-daemonset.yaml # <2>
oc adm policy add-scc-to-user daemonset-with-hostport -z jaeger-agent-daemonset # <3>
oc apply -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/main/examples/openshift/agent-as-daemonset.yaml # <4>

<1> 具有 allowHostPorts 策略的 SecurityContextConstraints

<2> jaeger-agent 要使用的 ServiceAccount

<3> 将安全策略添加到服务帐户

<4> 使用在上述步骤中创建的 serviceAccount 创建 Jaeger 实例

如果没有此策略,以下错误将阻止创建 DaemonSetWarning FailedCreate 4s (x14 over 45s) daemonset-controller Error creating: pods "agent-as-daemonset-agent-daemonset-" is forbidden: unable to validate against any security context constraint: [spec.containers[0].securityContext.containers[0].hostPort: Invalid value: 5775: Host ports are not allowed to be used

几秒钟后,DaemonSet 应该启动并运行

$ oc get daemonset agent-as-daemonset-agent-daemonset
NAME                                 DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE
agent-as-daemonset-agent-daemonset   1         1         1         1            1

Calico CNI

在运行指向服务的自定义 Calico CNI Webhook 的 AWS EKS(或 Fargate)中,无法访问服务。

请求 jaeger 资源时,将显示以下错误。

Error from server (InternalError): Internal error occurred: failed calling webhook "myservice.mynamespace.svc": Post "https://myservice.mynamespace.svc:443/mutate?timeout=30s": Address is not allowed

为了解决这个问题

  • jaeger-operator 部署中设置 hostNetwork:true
  • /healtz/readyz 端口从 8081 更改为其他值
  • kube-rbac-proxy 安全端口从 8443 更改为其他值
  • webhook-server 端口从 9443 更改为其他值
    • 此设置由 webhook-bind-port 标志控制

Jaeger 操作员配置示例

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
  name: jaeger-operator-webhook-service
  namespace: monitoring
spec:
  ports:
  - port: 443
    protocol: TCP
    targetPort: 10290
  selector:
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
---
...
    spec:
      hostNetwork: true
      containers:
      - args:
        - start
        - --health-probe-bind-address=:10280
        - --webhook-bind-port=10290
        - --leader-elect
        command:
        - /jaeger-operator
      ...
      ports:
        - containerPort: 10290
          name: webhook-server
          protocol: TCP
      ...
      readinessProbe:
          httpGet:
            path: /readyz
            port: 10280
      ...
      livenessProbe:
          httpGet:
            path: /healthz
            port: 10280

Kube-rbac-proxy 配置示例

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: metrics
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
  name: jaeger-operator-metrics
  namespace: monitoring
spec:
  ports:
  - name: https
    port: 10270
    protocol: TCP
    targetPort: https
  selector:
    app.kubernetes.io/name: jaeger-operator
    name: jaeger-operator
---
...
    spec:
      hostNetwork: true
      containers:
      - args:
        - --secure-listen-address=0.0.0.0:10270
        - --upstream=http://127.0.0.1:8383/
        - --logtostderr=true
        - --v=0
      ...
      ports:
        - containerPort: 10270
          name: https
          protocol: TCP
上述端口值必须在全局范围内唯一,因此 jaeger-operator 端口可以在每个 k8s 节点上公开它。

秘密支持

操作员支持将秘密传递给 jaeger-collectorjaeger-queryall-in-one 部署。这可用于例如将凭据(用户名/密码)传递给访问基础存储后端(例如:Elasticsearch)。这些秘密作为环境变量在(收集器/查询/全部合一)节点中可用。

    storage:
      type: elasticsearch
      options:
        es:
          server-urls: http://elasticsearch:9200
      secretName: jaeger-secrets

秘密本身将在 jaeger-operator 自定义资源之外进行管理。

配置 UI

有关 UI 的各种配置选项的信息可以在 此处 找到,以 json 格式定义。

要在自定义资源中应用 UI 配置更改,可以将相同信息以 yaml 格式包含在其中,如下所示

    ui:
      options:
        dependencies:
          menuEnabled: false
        tracking:
          gaID: UA-000000-2
        menu:
        - label: "About Jaeger"
          items:
            - label: "Documentation"
              url: "https://jaeger.golang.ac.cn/docs/latest"
        linkPatterns:
        - type: "logs"
          key: "customer_id"
          url: /search?limit=20&lookback=1h&service=frontend&tags=%7B%22customer_id%22%3A%22#{customer_id}%22%7D
          text: "Search for other traces for customer_id=#{customer_id}"

定义采样策略

如果跟踪是由 Istio 代理启动的,则这并不相关,因为采样决策是在那里做出的。当您使用 Jaeger 跟踪器(客户端)时,Jaeger 采样决策才相关。

操作员可用于定义采样策略,这些策略将提供给已配置为使用远程采样器的跟踪器

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: with-sampling
spec:
  strategy: allInOne
  sampling:
    options:
      default_strategy:
        type: probabilistic
        param: 0.5

此示例定义了一个默认采样策略,该策略是概率性的,有 50% 的机会采样跟踪实例。

请参阅 Jaeger 文档中的 Collector 采样配置外部链接,了解如何配置服务和端点采样。该文档中描述的 JSON 表示形式可通过转换为 YAML 在操作符中使用。

更细粒度的配置

自定义资源可用于定义应用于所有 Jaeger 组件或单个组件级别的更细粒度的 Kubernetes 配置。

当需要通用定义(针对所有 Jaeger 组件)时,它在 spec 节点下定义。当定义与单个组件相关时,它放在 spec/<component> 节点下。

支持的配置类型包括

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: simple-prod
spec:
  strategy: production
  storage:
    type: elasticsearch
    options:
      es:
        server-urls: http://elasticsearch:9200
  annotations:
    key1: value1
  labels:
    key2: value2
  resources:
    requests:
      memory: "64Mi"
      cpu: "250m"
    limits:
      memory: "128Mi"
      cpu: "500m"
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  tolerations:
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoSchedule"
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoExecute"
  serviceAccount: nameOfServiceAccount
  securityContext:
    runAsUser: 1000
  volumeMounts:
    - name: config-vol
      mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level

注意:如果需要,可以通过其服务账户为组件配置 imagePullSecrets(请参阅 https://kubernetes.ac.cn/docs/tasks/configure-pod-container/configure-service-account/#add-image-pull-secret-to-service-account)外部链接。对于 sidecar,请参阅 为注入的 sidecar 进行部署级别配置 部分。

访问 Jaeger 控制台(UI)

Kubernetes

操作符创建一个 Kubernetes ingress外部链接 路由,这是 Kubernetes 将服务公开到外部世界的标准方式,但默认情况下它不包含 Ingress 提供程序。查看 Kubernetes 文档外部链接,了解为您的平台实现 Ingress 提供程序的最合适方法。以下命令在 minikube 上启用 Ingress 提供程序

minikube addons enable ingress

启用 Ingress 后,可以通过查询 Ingress 对象找到 Jaeger 控制台的地址

$ kubectl get ingress
NAME             HOSTS     ADDRESS          PORTS     AGE
simplest-query   *         192.168.122.34   80        3m

在此示例中,Jaeger UI 可在 http://192.168.122.34 上访问。

要在 Ingress 中启用 TLS,请传递一个 secretName,其中包含包含 TLS 证书的 Secret外部链接 的名称

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: ingress-with-tls
spec:
  ingress:
    secretName: my-tls-secret

OpenShift

当操作符在 OpenShift 上运行时,操作符将自动为查询服务创建 Route 对象。使用以下命令检查主机名/端口

oc get routes
确保使用从上述命令获取的主机名/端口使用 https,否则您将看到类似以下消息:“应用程序不可用”。

默认情况下,Jaeger UI 受 OpenShift 的 OAuth 服务保护,任何有效用户都可以登录。要禁用此功能并使 Jaeger UI 不安全,请在自定义资源文件中将 Ingress 属性 security 设置为 none

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: disable-oauth-proxy
spec:
  ingress:
    security: none

自定义 SARDelegate URL 值可以作为 .Spec.Ingress.OpenShift.SAR.Spec.Ingress.Openshift.DelegateURLs 的一部分指定,如下所示

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: custom-sar-oauth-proxy
spec:
  ingress:
    openshift:
      sar: '{"namespace": "default", "resource": "pods", "verb": "get"}'
      delegateUrls: '{"/":{"namespace": "default", "resource": "pods", "verb": "get"}}'

当设置 delegateUrls 时,Jaeger 操作符需要在 UI 代理使用的服务帐户({InstanceName}-ui-proxy)和角色 system:auth-delegator 之间创建一个新的 ClusterRoleBinding,这是 OpenShift OAuth 代理所需的。因此,操作符本身使用的服务帐户需要具有相同的集群角色绑定。为了实现这一点,必须创建一个类似于以下内容的 ClusterRoleBinding

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jaeger-operator-with-auth-delegator
  namespace: observability
subjects:
- kind: ServiceAccount
  name: jaeger-operator
  namespace: observability
roleRef:
  kind: ClusterRole
  name: system:auth-delegator
  apiGroup: rbac.authorization.k8s.io

如果集群管理员不希望用户使用此集群角色部署 Jaeger 实例,则可以不将此集群角色添加到操作符的服务帐户。在这种情况下,操作符将自动检测到缺少必要的权限,并记录类似以下内容的消息:请求的实例指定了 OAuth 代理的 delegateUrls 选项,但此操作符无法为此分配适当的集群角色(system:auth-delegator)。创建操作符服务帐户与集群角色“system:auth-delegator”之间的集群角色绑定,以允许实例使用“delegateUrls”。

Jaeger 操作符还支持通过 OpenShift OAuth 代理使用 htpasswd 文件进行身份验证。要使用它,请在 OpenShift 特定条目中指定 htpasswdFile 选项,并指向本地磁盘中 htpasswd 文件的位置。htpasswd 文件可以使用 htpasswd 实用程序创建

$ htpasswd -cs /tmp/htpasswd jdoe
New password:
Re-type new password:
Adding password for user jdoe

然后可以使用此文件作为 kubectl create secret 命令的输入

$ kubectl create secret generic htpasswd --from-file=htpasswd=/tmp/htpasswd
secret/htpasswd created

创建秘密后,可以在 Jaeger CR 中将其指定为卷/卷挂载

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: with-htpasswd
spec:
  ingress:
    openshift:
      sar: '{"namespace": "default", "resource": "pods", "verb": "get"}'
      htpasswdFile: /usr/local/data/htpasswd
  volumeMounts:
  - name: htpasswd-volume
    mountPath: /usr/local/data
  volumes:
  - name: htpasswd-volume
    secret:
      secretName: htpasswd

升级操作符及其管理的实例

Jaeger Operator 的每个版本都对应一个 Jaeger 版本。每当安装新版本的 Jaeger Operator 时,由该 Operator 管理的所有 Jaeger 实例都会升级到 Operator 支持的版本。例如,名为 simplest 的实例是在 Jaeger Operator 1.12.0 中创建的,它将运行 Jaeger 1.12.0。一旦 Jaeger Operator 升级到 1.13.0,实例 simplest 将升级到 1.13.0 版本,遵循 Jaeger 项目的官方升级说明。

Jaeger Operator 可以通过更改部署(kubectl edit deployment jaeger-operator)手动升级,也可以通过专门的工具(如 Operator Lifecycle Manager (OLM)external link )进行升级。

更新 Jaeger 实例(实验性)

可以通过更改 CustomResource 来更新 Jaeger 实例,可以通过 kubectl edit jaeger simplest(其中 simplest 是 Jaeger 实例名称)或通过 kubectl apply -f simplest.yaml 应用更新的 YAML 文件来实现。

Jaeger 实例的名称无法更新,因为它属于资源识别信息的一部分。

更改副本大小等简单的更改可以毫不费力地应用,而对策略的更改则需要密切关注,并可能导致单个组件(收集器/查询/代理)出现故障。

虽然支持更改后端存储,但数据迁移不支持。

删除 Jaeger 实例

要删除实例,请使用 delete 命令以及创建实例时使用的自定义资源文件

kubectl delete -f simplest.yaml

或者,您可以通过运行以下命令删除 Jaeger 实例

kubectl delete jaeger simplest
删除实例不会删除与该实例一起使用的任何永久存储中的数据。但是,内存实例中的数据将丢失。

跟踪和调试 Operator

从 1.16.0 版本开始,Jaeger Operator 能够生成与其自身操作相关的跨度。为了利用这一点,operator.yaml 必须配置为通过将标志 --tracing-enabled=true 设置为容器的 args 并将 Jaeger Agent 作为 sidecar 添加到 pod 来启用跟踪。以下是启用跟踪并假设 Jaeger 实例与 Jaeger Operator 位于同一命名空间的 operator.yaml 的摘录

...
        # .Spec.Template.Spec.Containers[0].Args
        args: ["start", "--tracing-enabled=true"]
...
      # add as a second container to .Spec.Template.Spec.Containers
      - name: jaeger-agent
        image: jaegertracing/jaeger-agent:latest # it's best to keep this version in sync with the operator's
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        args:
        - --reporter.grpc.host-port=dns:///jaeger-collector-headless.$(POD_NAMESPACE).svc.cluster.local:14250
        ports:
        - containerPort: 6831
          name: jg-compact-thrift
          protocol: UDP

请注意,您还必须手动配置 Jaeger 实例。您可以在 Jaeger Operator 初始化后执行此操作。jaeger-agent 将在与 Jaeger 实例建立连接之前将 Operator 跨度保存在内部缓冲区中。以下 Jaeger CR 可用于配置适用于非生产环境的 Jaeger 实例

apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
  name: jaeger

当标志 --log-level 设置为 debug 时,Jaeger Operator 还提供详细的日志记录。以下是将日志级别设置为调试的 operator.yaml 的摘录

        # .Spec.Template.Spec.Containers[0].Args
        args: ["start", "--log-level=debug"]

请注意,跟踪和调试级别的日志记录可以同时启用。

使用 OLM 时,可以通过更改 Subscriptionconfig 属性来配置 Jaeger Operator。要设置 log-level 参数,订阅的格式如下(摘录)

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: jaeger
  namespace: openshift-operators
spec:
  channel: stable
  config:
    env:
      - name: LOG-LEVEL
        value: debug
  installPlanApproval: Automatic
  name: jaeger
  source: community-operators
  sourceNamespace: openshift-marketplace

监控 Operator

Jaeger Operator 在 0.0.0.0:8383/metrics 上启动一个与 Prometheus 兼容的端点,该端点包含可用于监控进程的内部指标。值得关注的指标是

# Total number of reconciliations and their outcomes (cumulative)
controller_runtime_reconcile_total{controller="jaeger-controller",result="error"}
controller_runtime_reconcile_total{controller="jaeger-controller",result="success"}

# Total number of retries (cumulative)
workqueue_retries_total{name="jaeger-controller"}

# Current number of reconciliation loops in progress (gauge)
workqueue_depth{name="jaeger-controller"}

# How long (in seconds) the oldest reconciliation loop is taking. (gauge)
workqueue_unfinished_work_seconds{name="jaeger-controller"}

# How long (in seconds) it takes to process an item from the workqueue. (bucket)
workqueue_work_duration_seconds_bucket{name="jaeger-controller"}

很少的协调错误是正常的(controller_runtime_reconcile_total{controller="jaeger-controller",result="error"}),因为可能有多个进程出于不同的原因同时更改资源。每当出现故障时,Operator 都会尝试重新协调,从而增加 workqueue_retries_total{name="jaeger-controller"} 指标。但是,如果随着时间的推移错误率持续增加或超过合理阈值,则可能需要进行调查。合理的阈值可能会因集群而异,具体取决于集群中发生的情况,但 10% 是一个好的起点。

从 v1.17.0 版本开始,Jaeger Operator 仅当自定义资源发生变化或前一次协调失败时才会触发协调循环。因此,这个指标(controller_runtime_reconcile_total{controller="jaeger-controller"})在很长一段时间内保持相同的值是正常的:它仅表示自定义资源没有发生变化。如果这个数字每秒都在变化,则表明集群中的某个东西在周期性地更改自定义资源,或者 Jaeger Operator 正在撤消其他组件正在进行的更改。未来版本的 Jaeger Operator 可能会触发周期性的协调循环。

工作队列深度(workqueue_depth{name="jaeger-controller"})表示当前活动的协调循环数量。对于小型集群或 Jaeger 实例配置不频繁的集群,此数字在大多数情况下应保持接近零。任何长时间高于 0 的值都表明协调循环卡住了。如果发生这种情况,指标 workqueue_unfinished_work_seconds{name="jaeger-controller"} 也会不断增加。这种情况表明 Jaeger Operator 中存在错误。经验法则:协调必须在几分钟内完成,除非涉及 Elasticsearch 或 Kafka 的配置。超过 10 分钟的协调循环可以被视为“卡住”。Elasticsearch 或 Kafka 的配置可能需要几分钟。通常情况下,协调循环将在不到一分钟的时间内完成。

工作队列桶(workqueue_unfinished_work_seconds{name="jaeger-controller"}workqueue_work_duration_seconds_bucket{name="jaeger-controller"})与处理每个协调循环所花费的时间直接相关。新 Jaeger 实例的前 3 个循环之一花费的时间远远超过后续循环是正常的,尤其是当底层组件的容器映像尚未被集群缓存时。使用自动配置功能创建 Elasticsearch 和/或 Kafka 集群也会影响此指标。一般规则是:几个长时间运行的协调循环是正常的,尤其是在指标 controller_runtime_reconcile_total{controller="jaeger-controller"} 增加的同时出现这些循环。

Jaeger Operator 尚未发布自己的指标。相反,它提供了其使用的组件(例如 Operator SDK)报告的指标。

卸载 Operator

要卸载 Operator,请运行以下命令

kubectl delete -n observability -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.62.0.0/jaeger-operator.yaml