Kubernetes Operator
v1.69.0
版本已发布,但实际情况可能并非如此,因为 Operator 的发布与主 Jaeger 版本的发布并不同步。请查看 jaeger-operator 仓库以获取可用版本,并相应调整安装命令。了解 Operators
Jaeger Operator 是 Kubernetes Operator 的实现。Operators 是一种软件,用于简化运行其他软件的操作复杂性。更技术地说,Operators 是一种打包、部署和管理 Kubernetes 应用的方法。
Kubernetes 应用是既部署在 Kubernetes 上,又使用 Kubernetes API 和 kubectl
(Kubernetes) 或 oc
(OKD) 工具进行管理的应用。为了充分利用 Kubernetes,您需要一套一致的 API 来扩展,以便服务和管理运行在 Kubernetes 上的应用。将 Operators 视为在 Kubernetes 上管理此类应用的运行时。
安装 Operator
Jaeger Operator 可以安装在基于 Kubernetes 的集群中,并能够监控特定命名空间或整个集群中的新 Jaeger Custom Resources (CR)。每个集群通常只有一个 Jaeger Operator,但在多租户场景下,每个命名空间最多可以有一个 Jaeger Operator。当检测到新的 Jaeger CR 时,Operator 将尝试将自身设置为该资源的所有者,为新的 CR 设置一个标签 jaegertracing.io/operated-by
,标签的值为 Operator 的命名空间和名称。
current
、current-1
和 current-2
)中可重现的错误。虽然多个 Operator 可能同时监控同一组命名空间,但哪个 Operator 会成功将自身设置为 CR 的所有者是未定义行为。sidecar 的自动注入也可能导致未定义行为。因此,强烈建议每个命名空间最多只有一个 Operator 监控。请注意,命名空间可以包含任意数量的 Jaeger 实例 (CR)。
前提条件
自版本 1.31 起,Jaeger Operator 使用 webhook 来验证 Jaeger custom resources (CR)。这需要安装 cert-manager 的某个版本。可以在 兼容性矩阵 中找到受支持版本的更详细列表。安装指南可以在 这里 找到。
安装模式
Jaeger Operator 可以安装在整个集群中或特定命名空间中,以监控新的 Jaeger custom resources (CR)。当配置为集群模式时,Operator 可以
- 监控所有命名空间中与 Jaeger 资源相关的事件
- 监控命名空间本身,查找
sidecar.jaegertracing.io/inject
注解 - 监控所有 Deployment,根据
sidecar.jaegertracing.io/inject
注解注入或移除 sidecar - 在必要时创建集群角色绑定
当不使用集群范围资源(ClusterRole
和 ClusterRoleBinding
)时,将 WATCH_NAMESPACE
设置为 Jaeger Operator 应监控与 Jaeger 资源相关的事件的命名空间的逗号分隔列表。可以将 Jaeger Operator 运行在给定的命名空间(例如 observability
),并管理另一个命名空间(例如 myproject
)中的 Jaeger 资源。为此,对于 Operator 应监控资源的每个命名空间,请使用如下所示的 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 上安装 Operator
以下说明将创建 observability
命名空间并将 Jaeger Operator 安装到其中。默认情况下,Operator 将监控所有命名空间。
kubectl
命令已正确配置,可以与有效的 Kubernetes 集群通信。如果您没有集群,可以使用 minikube
在本地创建一个。要安装 Operator,请运行
kubectl create namespace observability # <1>
kubectl create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.69.0/jaeger-operator.yaml -n observability # <2>
<1> 这将创建部署文件中默认使用的命名空间。如果您想将 Jaeger Operator 安装到不同的命名空间,则必须编辑部署文件,将 observability
更改为所需的命名空间值。
<2> 这将安装适用于 apiVersion: jaegertracing.io/v1
的“Custom Resource Definition”。
Operator 将以集群范围模式安装,如果您只想监控特定的命名空间,则需要将 Operator 清单中的 ClusterRole
和 ClusterRoleBinding
更改为 Role
和 RoleBinding
,同时在 Jaeger Operator Deployment 上设置 WATCH_NAMESPACE
环境变量。
此时,应该有一个可用的 jaeger-operator
Deployment。您可以通过运行以下命令查看它
$ kubectl get deployment jaeger-operator -n observability
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
jaeger-operator 1 1 1 1 48s
Operator 现在可以创建 Jaeger 实例了。
在 OKD/OpenShift 上安装 Operator
{{ /* TODO: Add instructions for installing via the operatorhub? */ }}
上一节的说明也适用于在 OKD 或 OpenShift 上安装 Operator。安装基于角色的访问控制 (RBAC) 规则、custom resource definition 和 Operator 时,请确保您已以特权用户身份登录。
oc login -u <privileged user>
oc new-project observability # <1>
oc create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.69.0/jaeger-operator.yaml -n observability # <2>
<1> 这将创建部署文件中默认使用的命名空间。如果您想将 Jaeger Operator 安装到不同的命名空间,则必须编辑部署文件,将 observability
更改为所需的命名空间值。
<2> 这将安装适用于 apiVersion: jaegertracing.io/v1
的“Custom Resource Definition”。
Operator 将以集群范围模式安装,如果您只想监控特定的命名空间,则需要将 Operator 清单中的 ClusterRole
和 ClusterRoleBinding
更改为 Role
和 RoleBinding
,同时在 Jaeger Operator Deployment 上设置 WATCH_NAMESPACE
环境变量。
Operator 安装完成后,将角色 jaeger-operator
授予应能够安装单个 Jaeger 实例的用户。以下示例创建了一个角色绑定,允许用户 developer
创建 Jaeger 实例
oc create \
rolebinding developer-jaeger-operator \
--role=jaeger-operator \
--user=developer
授予角色后,切换回非特权用户。
快速开始 - 部署 AllInOne 镜像
创建 Jaeger 实例最简单的方法是创建一个如下示例所示的 YAML 文件。这将安装默认的 AllInOne 策略,该策略将 all-in-one 镜像(结合了 jaeger-collector、jaeger-query 和 Jaeger UI)部署到单个 Pod 中,默认使用内存存储。
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: simplest
然后可以将 YAML 文件与 kubectl
一起使用:{{ /* TODO - Add OKD commands and tabs shortcode. */}}
kubectl apply -f simplest.yaml
几秒钟后,将创建一个新的内存版 Jaeger all-in-one 实例,适用于快速演示和开发用途。要检查已创建的实例,请列出 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"}
$ 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"}
配置 Operator
Jaeger Operator 可以通过命令行参数、环境变量或配置文件进行配置。当在不同级别指定同一变量时,优先级顺序为
- 命令行参数 (flag)
- 环境变量
- 配置文件
每个项目优先于其下方的项目。可以通过使用 --help
标志运行 Operator 查看可用选项,例如
$ podman run jaegertracing/jaeger-operator:master start --help
示例
通过给定 Jaeger Operator Deployment 的标志设置 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 Operator Deployment 的环境变量设置 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 实例时,会与其关联一个策略。该策略在 custom resource 文件中定义,并决定了用于 Jaeger 后端的架构。默认策略是 allInOne
。其他可能的值是 production
和 streaming
。
可用策略在以下章节中描述。
AllInOne(默认)策略
此策略适用于开发、测试和演示用途。
主要后端组件 jaeger-collector 和 jaeger-query 服务都打包到一个可执行文件中,该文件(默认)配置为使用内存存储。此策略无法扩展到超过一个副本。
生产策略
production
策略(顾名思义)适用于生产环境,在这些环境中,追踪数据的长期存储以及更具可扩展性和高可用性的架构至关重要。因此,每个后端组件都是单独部署的。
jaeger-agent 可以作为 sidecar 注入到被检测应用中,或作为 DaemonSet 部署。
jaeger-collector 可以配置为按需自动伸缩。默认情况下,当没有为 .Spec.Collector.Replicas
提供值时,Jaeger Operator 将为 jaeger-collector 创建 Horizontal Pod Autoscaler (HPA) 配置。我们建议为 .Spec.Collector.MaxReplicas
设置一个明确的值,同时为 jaeger-collector 的 Pod 预期消耗的资源设置一个合理的值。当没有设置 .Spec.Collector.MaxReplicas
时,Operator 将其值设置为 100
。在 Kubernetes 网站 上阅读更多关于 HPA 的信息。可以通过将 .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-query 和 jaeger-collector 服务配置了支持的存储类型 - 当前是 Cassandra 或 Elasticsearch。可以根据性能和弹性需求配置这些组件的多个实例。
主要额外要求是提供存储类型和选项的详细信息,例如
storage:
type: elasticsearch
options:
es:
server-urls: http://elasticsearch:9200
流式策略
streaming
策略旨在增强 production
策略,通过提供流式能力,该能力有效地介于 collector 和后端存储(Cassandra 或 Elasticsearch)之间。这提供了在高负载情况下减轻后端存储压力的好处,并使其他追踪后处理能力能够直接从流式平台 (Kafka) 获取实时 span 数据。
jaeger-collector 可以配置为按需自动伸缩,如“生产策略”章节所述。
jaeger-ingester 也可以配置为按需自动伸缩。默认情况下,当没有为 .Spec.Ingester.Replicas
提供值时,Jaeger Operator 将为 jaeger-ingester 创建 Horizontal Pod Autoscaler (HPA) 配置。我们建议为 .Spec.Ingester.MaxReplicas
设置一个明确的值,同时为 jaeger-ingester 的 Pod 预期消耗的资源设置一个合理的值。当没有设置 .Spec.Ingester.MaxReplicas
时,Operator 将其值设置为 100
。在 Kubernetes 网站 上阅读更多关于 HPA 的信息。可以通过将 .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 用于生成消息以及 jaeger-ingester 用于消费消息的 Kafka 配置。
<2> 默认情况下,死锁间隔已禁用(设置为 0),以防止在没有消息到达时 jaeger-ingester 被终止。可以配置它来指定在终止之前等待消息的分钟数。
自备 Kafka 集群
要使用自备方法,不应定义 producer/consumer brokers 属性。
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 Operator 查询 Kubernetes 集群是否具备处理 Kafka
custom resource 的能力。这通常由 Kafka Operator 在其安装过程中设置,因此,如果 Kafka Operator 预计在 Jaeger Operator 之后运行,则可以将该标志设置为 true
。
理解 Custom Resource Definitions
在 Kubernetes API 中,资源是一个存储特定类型 API 对象集合的端点。例如,内置的 Pods 资源包含一组 Pod 对象。一个 Custom Resource Definition (CRD) 对象在集群中定义了一种新的、独特的对象 Kind
,并让 Kubernetes API Server 处理其整个生命周期。
要创建 Custom Resource (CR) 对象,集群管理员必须首先创建一个 Custom Resource Definition (CRD)。CRD 允许集群用户创建 CR,将新的资源类型添加到他们的项目中。Operator 监控 custom resource 对象的创建,当它看到 custom resource 被创建时,它会根据 custom resource 对象中定义的参数创建应用。
{{ /*
Jaeger Custom Resource 参数
TODO 创建一个包含所有参数、描述/注意事项、有效值和默认值的表格。弄清楚我们是否可以生成选项?我们能否以任何方式过滤它们? https://github.com/jaegertracing/jaeger/issues/1537 https://github.com/jaegertracing/documentation/issues/250 */ }}
供参考,以下是如何创建更复杂的 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
。其他可能的值是 production
和 streaming
。
<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 服务创建一个 ingress 对象。通过将其 enabled
选项设置为 false
可以禁用它。如果部署在 OpenShift 上,这将由一个 Route object 表示。
<9> 默认情况下,Operator 假定 jaeger-agents 作为 sidecar 部署在目标 Pod 中。将策略指定为“DaemonSet”会改变这一点,并使 Operator 将 jaeger-agent 部署为 DaemonSet。请注意,您的 tracer 客户端可能需要覆盖“JAEGER_AGENT_HOST”环境变量才能使用节点的 IP。
<10> 定义要应用于所有 Deployment(而非 Service)的注解。这些可以被单个组件上定义的注解覆盖。
您可以在 GitHub 上查看不同 Jaeger 配置的示例 custom resources。
配置 Custom Resource
{{ /* TODO esIndexCleaner Spark dependencies */ }}
您可以使用最简单的示例(如上所示),并使用默认值创建 Jaeger 实例,或者您可以创建自己的 custom resource 文件。
Span 存储选项
Cassandra 存储
当存储类型设置为 Cassandra 时,Operator 将自动创建一个批处理作业,该作业创建 Jaeger 运行所需的 schema。该批处理作业将阻塞 Jaeger 的安装,使其仅在 schema 成功创建后才启动。可以通过将 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> 这也适用于 production
和 streaming
。
<2> 这些选项适用于常规 Jaeger 组件,例如 collector
和 query
。
<3> create-schema
作业的选项。
MODE=prod
,这意味着使用 NetworkTopologyStrategy
作为类,复制因子为 2
,实际意味着 Cassandra 集群中至少需要 3 个节点。如果需要 SimpleStrategy
,请将模式设置为 test
,它将复制因子设置为 1
。有关更多详细信息,请参阅 create-schema 脚本 。Elasticsearch 存储
默认情况下,Elasticsearch 存储不需要运行任何初始化作业。但是,Elasticsearch 存储需要运行一个 cron 作业来清理存储中的旧数据。
启用 rollover (es.use-aliases
) 后,Jaeger operator 还会部署一个作业来初始化 Elasticsearch 存储,以及另外两个 cron 作业来执行所需的索引管理操作。
外部 Elasticsearch
Jaeger 可以与外部 Elasticsearch 集群一起使用。以下示例展示了一个 Jaeger CR,它使用了一个外部 Elasticsearch 集群(由 Elasticsearch Operator 创建),其 TLS CA 证书从卷中挂载,用户/密码存储在 secret 中。
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 证书,但在使用双向 TLS 时也可以包含 es.tls.key
和 es.tls.cert
。
<4> 定义环境变量 ES_PASSWORD
和 ES_USERNAME
的 Secret。通过 kubectl create secret generic jaeger-secret --from-literal=ES_PASSWORD=password --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 实例。
以下是带有 AWS gp2
持久存储的单节点 Elasticsearch 集群的 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> 持久存储配置。在此示例中,使用大小为 5Gi
的 AWS gp2
。如果省略,则使用 emptyDir
。Elasticsearch operator 会配置 PersistentVolumeClaim
和 PersistentVolume
,它们不会随 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 索引清理作业
使用 elasticsearch
存储时,默认会创建一个 cron 作业来清理旧的 trace,以下是其选项,您可以根据您的用例进行配置。连接配置派生自存储选项。
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 滚动更新 (rollover)
这种索引管理策略比使用默认的每日索引更复杂,它需要一个初始化作业来准备存储和两个 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-query 和 jaeger-collector 使用读写索引别名。
<2> 禁用默认索引模板的创建。
存储插件
指标存储选项
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
映射。所有可用选项都记录在带有 Prometheus CLI 部分的 Jaeger All-In-One 中
<2> 将默认的 http://localhost:9090
prometheus 服务器 URL 覆盖为 http://prometheus:9090
。
<3> 用于启用指标查询功能的部分。
<4> 选择 prometheus
作为指标存储后端。
派生依赖项
派生依赖项的处理将从存储中收集跨度,分析服务之间的链接并存储它们以便稍后在 UI 中展示。此作业只能与 production
策略和存储类型 cassandra
或 elasticsearch
一起使用。
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
与存储的连接配置派生自存储选项。
自动注入 Jaeger Agent Sidecar
目前,仅支持为 Deployments
自动注入 jaeger-agent sidecar。
对于其他控制器类型,请参阅下面的手动定义 Jaeger Agent Sidecar。
正在跟踪对自动注入其他控制器类型的支持,参见问题 #750 。
operator 可以在 Deployment
工作负载中注入 jaeger-agent sidecar,前提是 deployment 或其命名空间带有 annotation sidecar.jaegertracing.io/inject
且值合适。值可以是 "true"
(字符串),也可以是 kubectl get jaegers
返回的 Jaeger 实例名称。使用 "true"
时,对于与 deployment 相同的命名空间,应该恰好有一个 Jaeger 实例,否则 operator 无法自动确定使用哪个 Jaeger 实例。deployment 上指定的特定 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 的 Deployment 级别配置
由于 sidecar 可能注入到不受 jaeger-operator 管理的 Deployment 中,因此许多适用于 Deployment 级别的配置不会应用于 sidecar 的 Deployment,*除非*它们在 jaeger-agent 节点下指定。以下配置支持 sidecar 的 Deployment
- 卷 (& 卷挂载)
- ImagePullSecrets
例如,以下 Jaeger 配置将把 agent-volume
和 agent-imagePullSecrets
添加到 sidecar 的 deployment 中。
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
以外的控制器类型(例如 StatefulSets
、DaemonSets
等),可以在您的规范中手动定义 jaeger-agent sidecar。
以下片段显示了可以在 jaeger-agent sidecar 的 containers
部分中包含的手动定义
- 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
获取。
然后可以在 localhost
的默认位置访问 jaeger-agent。
将 Agent 安装为 DaemonSet
默认情况下,Operator 期望 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
,因为 agent 需要绑定到节点上众所周知的端口。因此,第二个 daemon set 将无法绑定到这些端口。然后,您的 tracer 客户端很可能需要被告知 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 中,只有在设置特殊安全上下文时才能设置 HostPort
。jaeger-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 实例
DaemonSet
的创建:Warning 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
在 AWS EKS(或 Fargate)上运行指向服务的自定义 Calico CNI webhook 无法访问。
当请求 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
deployment 上设置hostNetwork:true
- 将
/healthz
和/readyz
端口从 8081 更改为其他值 - 将
kube-rbac-proxy
安全端口从 8443 更改为其他值 - 将
webhook-server
端口从 9443 更改为其他值- 此设置由
webhook-bind-port
标志控制
- 此设置由
Jaeger operator 配置示例
---
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 节点上暴露它。Secrets 支持
Operator 支持将 secrets 传递给 jaeger-collector、jaeger-query 和 all-in-one deployment。例如,这可以用于传递凭据(用户名/密码)来访问底层存储后端(例如:Elasticsearch)。secrets 在 (Collector/Query/All-In-One) 节点中作为环境变量提供。
storage:
type: elasticsearch
options:
es:
server-urls: http://elasticsearch:9200
secretName: jaeger-secrets
secret 本身将在 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}"
定义采样策略
operator 可用于定义将提供给已配置为使用远程采样器的 tracer 的采样策略
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: with-sampling
spec:
strategy: allInOne
sampling:
options:
default_strategy:
type: probabilistic
param: 0.5
此示例定义了一个默认的概率采样策略,trace 实例有 50% 的机会被采样。
请参阅 Jaeger 文档中关于收集器采样配置 的部分,了解如何配置服务和端点采样。该文档中描述的 JSON 表示可以通过转换为 YAML 在 operator 中使用。
更精细的配置
自定义资源可用于定义更精细的 Kubernetes 配置,该配置应用于所有 Jaeger 组件或单个组件级别。
需要通用定义(适用于所有 Jaeger 组件)时,它在 spec
节点下定义。当定义与单个组件相关时,它放在 spec/<component>
节点下。
支持的配置类型包括
亲和性 (affinity) ,用于确定 Pod 可以分配到哪些节点
资源 (resources) ,用于限制 CPU 和内存
容忍度 (tolerations) ,与
taints
结合使用,使 Pod 不受节点排斥卷 (volumes) 和卷挂载
ServiceAccount ,用于以独立身份运行每个组件
安全上下文 (securityContext) ,用于定义运行组件的权限
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
注意:如果需要,可以通过 serviceAccounts 为组件配置 imagePullSecrets(请参阅 https://kubernetes.ac.cn/docs/tasks/configure-pod-container/configure-service-account/#add-image-pull-secret-to-service-account) 。对于 sidecar,请参阅注入 Sidecar 的 Deployment 级别配置部分。
访问 Jaeger 控制台 (UI)
{{ /* TODO Add tabs shortcode */ }}
Kubernetes
operator 创建一个 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
当 Operator 在 OpenShift 上运行时,Operator 将自动为查询服务创建一个 Route
对象。使用以下命令检查主机名/端口
oc get routes
https
,否则您会看到类似“Application is not available”的消息。默认情况下,Jaeger UI 受 OpenShift 的 OAuth 服务保护,任何有效用户都可以登录。要禁用此功能并使 Jaeger UI 不受保护,请在自定义资源文件中将 Ingress 属性 security
设置为 none
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: disable-oauth-proxy
spec:
ingress:
security: none
可以将自定义 SAR
和 Delegate 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 Operator 需要在 UI Proxy 使用的服务帐户 ({InstanceName}-ui-proxy
) 和 system:auth-delegator
角色之间创建一个新的 ClusterRoleBinding
,这是 OpenShift OAuth Proxy 所要求的。因此,operator 本身使用的服务帐户也需要具有相同的 cluster role binding。为此,必须创建类似于以下的 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 实例的集群管理员可以不向 operator 的服务帐户添加此集群角色。在这种情况下,Operator 将自动检测到所需的权限缺失,并记录一条类似于以下的消息:the requested instance specifies the delegateUrls option for the OAuth Proxy, but this operator cannot assign the proper cluster role to it (system:auth-delegator). Create a cluster role binding between the operator's service account and the cluster role 'system:auth-delegator' in order to allow instances to use 'delegateUrls'
。
Jaeger Operator 还支持通过 OpenShift OAuth Proxy 使用 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
创建 secret 后,可以在 Jaeger CR 中将其指定为 volume/volume mount
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
升级 Operator 及其管理的实例
Jaeger Operator 的每个版本都遵循一个 Jaeger 版本。每当安装新版本的 Jaeger Operator 时,Operator 管理的所有 Jaeger 实例都将升级到 Operator 支持的版本。例如,使用 Jaeger Operator 1.12.0 创建的名为 simplest
的实例将运行 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) )进行升级。
更新 Jaeger 实例(实验性)
可以通过更改 CustomResource
来更新 Jaeger 实例,方法可以是使用 kubectl edit jaeger simplest
(其中 simplest
是 Jaeger 实例的名称),或者通过 kubectl apply -f simplest.yaml
应用更新后的 YAML 文件。
更改副本数等较简单的修改可以放心应用,而策略上的更改则需要密切关注,并可能导致单个组件(collector/query/agent)中断。
虽然支持更改后端存储,但不支持数据的迁移。
移除 Jaeger 实例
{{ /* TODO Add OKD/OpenShift commands and tabs shortcode */ }}
要移除实例,请使用 delete
命令并指定创建实例时使用的自定义资源文件
kubectl delete -f simplest.yaml
或者,您也可以通过运行以下命令来移除 Jaeger 实例
kubectl delete jaeger simplest
跟踪和调试 Operator
从 1.16.0 版本开始,Jaeger Operator 能够生成与其自身操作相关的 Span。要利用此功能,必须配置 operator.yaml
以通过将 --tracing-enabled=true
标志添加到容器的 args
中来启用跟踪,并为 Pod 添加一个 Jaeger Agent 作为 Sidecar。以下是启用了跟踪并假定 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 的 Span 保存在内部缓冲区中。可以使用以下 Jaeger CR 来配置一个适合非生产环境的 Jaeger 实例
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: jaeger
当将 --log-level
标志设置为 debug
时,Jaeger Operator 还会提供详细的日志记录。以下是已将日志级别设置为 debug 的 operator.yaml
摘录
# .Spec.Template.Spec.Containers[0].Args
args: ["start", "--log-level=debug"]
请注意,跟踪和调试级别的日志记录可以同时启用。
使用 OLM 时,可以通过更改 Subscription
的 config
属性来配置 Jaeger Operator。要设置 log-level
参数,Subscription 将如下所示(摘录)
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"}
增加的时间大致相同时。
卸载 Operator
{{ /* TODO Add OKD/OpenShift commands and tabs shortcode */ }}
要卸载 Operator,请运行以下命令
kubectl delete -n observability -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.69.0/jaeger-operator.yaml