Kubernetes Operator
v1.71.0
版本已发布,但实际情况可能并非如此,因为 Operator 的发布与 Jaeger 主发布**不同步**。请查看 jaeger-operator 仓库以获取可用版本并相应调整安装命令。理解 Operator
Jaeger Operator 是 Kubernetes Operator 的一种实现。Operator 是简化运行其他软件的操作复杂度的软件。更确切地说,*Operator* 是一种打包、部署和管理 Kubernetes 应用程序的方法。
Kubernetes 应用程序是指部署在 Kubernetes 上并使用 Kubernetes API 和 kubectl
(Kubernetes) 或 oc
(OKD) 工具进行管理的应用程序。为了充分利用 Kubernetes,您需要一套内聚的 API 来扩展,以便服务和管理在 Kubernetes 上运行的应用程序。可以将 Operator 视为在 Kubernetes 上管理此类应用程序的运行时。
安装 Operator
Jaeger Operator 可以安装在基于 Kubernetes 的集群中,并且能够监视特定命名空间或整个集群中的新 Jaeger 自定义资源 (CR)。通常每个集群只有一个 Jaeger Operator,但在多租户场景中,每个命名空间最多可以有一个 Jaeger Operator。当检测到新的 Jaeger CR 时,Operator 将尝试将自己设置为资源的拥有者,将标签 jaegertracing.io/operated-by
设置到新的 CR,其中标签值为 Operator 的命名空间和名称。
current
、current-1
和 current-2
)中可重现的错误。尽管多个 Operator 可能共存并监视同一组命名空间,但哪个 Operator 能成功将自己设置为 CR 的拥有者是未定义的行为。Sidecar 的自动注入也可能导致未定义的行为。因此,强烈建议每个命名空间最多只有一个 Operator 监视。请注意,命名空间可以包含任意数量的 Jaeger 实例 (CR)。
先决条件
自 1.31 版本以来,Jaeger Operator 使用 webhook 来验证 Jaeger 自定义资源 (CR)。这需要安装 cert-manager 。受支持版本的详细列表可在兼容性矩阵 中找到。安装指南可在此处 找到。
安装模式
Jaeger Operator 可以安装为监视整个集群或特定命名空间中的新 Jaeger 自定义资源 (CR)。当配置为集群模式时,Operator 可以
- 监视所有命名空间中与 Jaeger 资源相关的事件
- 监视命名空间本身,查找
sidecar.jaegertracing.io/inject
注解 - 监视所有部署,根据
sidecar.jaegertracing.io/inject
注解注入或移除 sidecar - 在必要时创建集群角色绑定
当不使用集群范围资源(ClusterRole
和 ClusterRoleBinding
)时,将 WATCH_NAMESPACE
设置为 Jaeger Operator 应监视与 Jaeger 资源相关的事件的命名空间列表(以逗号分隔)。可以在给定命名空间(如 observability
)中运行 Jaeger Operator,并在另一个命名空间(如 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.71.0/jaeger-operator.yaml -n observability # <2>
<1> 这将创建部署文件中默认使用的命名空间。如果您想将 Jaeger Operator 安装到不同的命名空间,则必须编辑部署文件,将 observability
更改为所需的命名空间值。
<2> 这将安装 apiVersion: jaegertracing.io/v1
的“自定义资源定义”
Operator 将以集群范围模式安装,如果您只想监视特定命名空间,则需要将 Operator 清单的 ClusterRole
和 ClusterRoleBinding
更改为 Role
和 RoleBinding
,并在 Jaeger Operator 部署上设置 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
Operator 现在已准备好创建 Jaeger 实例。
在 OKD/OpenShift 上安装 Operator
{{ /* TODO: Add instructions for installing via the operatorhub? */ }}
上一节中的说明也适用于在 OKD 或 OpenShift 上安装 Operator。在安装基于角色的访问控制 (RBAC) 规则、自定义资源定义和 Operator 时,请确保您以特权用户身份登录。
oc login -u <privileged user>
oc new-project observability # <1>
oc create -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.71.0/jaeger-operator.yaml -n observability # <2>
<1> 这将创建部署文件中默认使用的命名空间。如果您想将 Jaeger Operator 安装到不同的命名空间,则必须编辑部署文件,将 observability
更改为所需的命名空间值。
<2> 这将安装 apiVersion: jaegertracing.io/v1
的“自定义资源定义”
Operator 将以集群范围模式安装,如果您只想监视特定命名空间,则需要将 Operator 清单的 ClusterRole
和 ClusterRoleBinding
更改为 Role
和 RoleBinding
,并在 Jaeger Operator 部署上设置 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 查询
$ 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 部署的标志设置 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 部署的环境变量设置 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
。其他可能的值是 production
和 streaming
。
可用策略在以下部分中描述。
AllInOne (默认) 策略
此策略适用于开发、测试和演示目的。
主要的后端组件 **jaeger-collector** 和 **jaeger-query** 服务都打包到一个可执行文件中,该文件(默认)配置为使用内存存储。此策略无法扩展到单个副本以上。
生产策略
正如其名,production
策略适用于生产环境,在该环境中,跟踪数据的长期存储以及更具可伸缩性和高可用性的架构是必需的。因此,每个后端组件都单独部署。
**jaeger-agent** 可以作为 sidecar 注入到已检测的应用程序中,或作为 daemonset 部署。
**jaeger-collector** 可以配置为按需自动伸缩。默认情况下,当未提供 .Spec.Collector.Replicas
的值时,Jaeger Operator 将为 **jaeger-collector** 创建一个水平 Pod 自动伸缩器 (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
策略,该能力有效地位于收集器和后端存储(Cassandra 或 Elasticsearch)之间。这带来了在高负载情况下减少后端存储压力的好处,并使其他跟踪后处理功能能够直接从流式平台 (Kafka) 获取实时 span 数据。
**jaeger-collector** 可以配置为按需自动伸缩,如“生产策略”一节所述。
**jaeger-ingester** 也可以配置为按需自动伸缩。默认情况下,当未提供 .Spec.Ingester.Replicas
的值时,Jaeger Operator 将为 **jaeger-ingester** 创建一个水平 Pod 自动伸缩器 (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 集群
要使用自管理方法,不应定义生产者/消费者 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
自定义资源。这通常由 Kafka Operator 在其安装过程中设置,因此,如果 Kafka Operator 预计在 Jaeger Operator *之后*运行,则可以将该标志设置为 true
。
理解自定义资源定义
在 Kubernetes API 中,资源是一个端点,存储特定类型的 API 对象集合。例如,内置的 Pods 资源包含 Pod 对象的集合。*自定义资源定义* (CRD) 对象在集群中定义了一种新的、独特的对象 Kind
,并让 Kubernetes API 服务器处理其整个生命周期。
要创建*自定义资源* (CR) 对象,集群管理员必须首先创建自定义资源定义 (CRD)。CRD 允许集群用户创建 CR 以将新资源类型添加到其项目中。Operator 监视自定义资源的创建,当它看到自定义资源被创建时,它会根据自定义资源对象中定义的参数创建应用程序。
{{ /*
Jaeger 自定义资源参数
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 对象表示。
<9> 默认情况下,Operator 假定 **jaeger-agent** 作为 sidecar 部署在目标 Pod 中。将策略指定为“DaemonSet”会改变这一点,并使 Operator 将 **jaeger-agent** 部署为 DaemonSet。请注意,您的跟踪器客户端可能必须覆盖“JAEGER_AGENT_HOST”环境变量以使用节点的 IP。
<10> 定义要应用于所有部署(而非服务)的注解。这些注解可以被单个组件上定义的注解覆盖。
您可以在 GitHub 上查看不同 Jaeger 配置的自定义资源示例。
配置自定义资源
{{ /* TODO esIndexCleaner Spark dependencies */ }}
您可以使用最简单的示例(如上所示)并使用默认设置创建 Jaeger 实例,或者创建自己的自定义资源文件。
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
,这意味着复制因子为 2
,使用 NetworkTopologyStrategy
作为类,实际上意味着 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 Cluster Logging 相同。
当 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> 持久存储配置。在这种情况下,AWS gp2
具有 5Gi
大小。省略时使用 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 作业来清理其中的旧跟踪数据,其选项如下所示,您可以根据自己的用例进行配置。连接配置来源于存储选项。
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 作业用于滚动更新到新索引,第二个用于从读取别名中删除索引。当存储选项 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 指标。
以下是一个 Jaeger CR 示例,它使用 allInOne
部署策略、内存 span 存储和 Prometheus 指标存储。
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> 将默认的 https://:9090
Prometheus 服务器 URL 覆盖为 http://prometheus:9090
。
<3> 启用指标查询能力的部分。
<4> 选择 prometheus
作为指标存储后端。
推导依赖关系
推导依赖关系的处理将从存储中收集 span,分析服务之间的链接并存储它们,以便稍后在 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。
对其他控制器类型自动注入的支持正在通过 Issue #750 进行跟踪。
Operator 可以在 Deployment
工作负载中注入 **jaeger-agent** sidecar,前提是部署或其命名空间具有带有合适值的 sidecar.jaegertracing.io/inject
注解。该值可以是 “true”
(字符串形式),也可以是 Jaeger 实例的名称,由 kubectl get jaegers
返回。当使用 “true”
时,同一命名空间中应只有一个 Jaeger 实例,否则 Operator 无法自动确定要使用哪个 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-volume
和 agent-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
之外的其他控制器类型(例如 StatefulSets
、DaemonSets
等),可以在您的规范中手动定义 **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
默认情况下,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 将无法绑定到这些端口。您的跟踪器客户端届时很可能需要知道 **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
部署上设置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 节点上暴露它。Secret 支持
Operator 支持将 Secret 传递给 **jaeger-collector**、**jaeger-query** 和 **all-in-one** 部署。例如,这可以用于传递凭据(用户名/密码)以访问底层存储后端(例如:Elasticsearch)。Secret 在(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 可用于定义采样策略,这些策略将提供给已配置为使用远程采样器的跟踪器
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: with-sampling
spec:
strategy: allInOne
sampling:
options:
default_strategy:
type: probabilistic
param: 0.5
此示例定义了一个默认的概率采样策略,跟踪实例有 50% 的几率被采样。
请参阅 Jaeger 文档中的采样配置,了解如何配置服务和端点采样。该文档中描述的 JSON 表示形式可以通过转换为 YAML 在 Operator 中使用。
更精细的配置
自定义资源可用于定义应用于所有 Jaeger 组件或单个组件级别的更精细的 Kubernetes 配置。
当需要通用定义(适用于所有 Jaeger 组件)时,它在 spec
节点下定义。当定义与单个组件相关时,它放在 spec/<component>
节点下。
支持的配置类型包括
亲和性 以确定 Pod 可以分配到哪些节点
资源 以限制 CPU 和内存
容忍度 与
taints
结合使用,以使 Pod 避免被节点排斥卷 和卷挂载
服务账户 以独立身份运行每个组件
安全上下文 以定义运行组件的权限
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)
{{ /* 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 上运行时,它将自动为查询服务创建一个 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
自定义 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 代理 ({InstanceName}-ui-proxy
) 使用的服务账户与 system:auth-delegator
角色之间创建一个新的 ClusterRoleBinding
,这是 OpenShift OAuth 代理所要求的。因此,Operator 本身使用的服务账户需要具有相同的集群角色绑定。为实现此目的,必须创建如下所示的 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 实例的集群管理员,可以自由选择不将此集群角色添加到操作员的服务账户。在这种情况下,操作员将自动检测到所需权限缺失,并记录一条类似以下内容的消息: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 代理使用 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 时,操作员管理的所有 Jaeger 实例都将升级到该操作员支持的版本。例如,使用 Jaeger Operator 1.12.0 创建的名为 simplest
的实例将运行 Jaeger 1.12.0。一旦 Jaeger Operator 升级到 1.13.0,simplest
实例将根据 Jaeger 项目的官方升级说明升级到 1.13.0 版本。
Jaeger Operator 可以通过修改部署 (kubectl edit deployment jaeger-operator
) 手动升级,或者通过专门的工具(例如 Operator 生命周期管理器 (OLM) )进行升级。
更新 Jaeger 实例(实验性)
Jaeger 实例可以通过更改 CustomResource
来更新,可以通过 kubectl edit jaeger simplest
命令(其中 simplest
是 Jaeger 实例的名称),或者通过 kubectl apply -f simplest.yaml
命令应用更新后的 YAML 文件。
诸如更改副本大小等较简单的更改可以放心地应用,而对策略的更改应密切关注,并可能导致个别组件(收集器/查询器/代理)中断。
尽管支持更改后端存储,但不支持数据迁移。
移除 Jaeger 实例
{{ /* TODO Add OKD/OpenShift commands and tabs shortcode */ }}
要移除实例,请使用创建实例时所用的自定义资源文件,配合 delete
命令。
kubectl delete -f simplest.yaml
另外,您可以通过运行以下命令移除 Jaeger 实例:
kubectl delete jaeger simplest
追踪和调试操作员
从 1.16.0 版本开始,Jaeger Operator 能够生成与其自身操作相关的 Span。为了利用此功能,必须配置 operator.yaml
以启用追踪,方法是将 --tracing-enabled=true
标志添加到容器的 args
中,并添加一个 Jaeger Agent 作为 Pod 的 Sidecar。以下是 operator.yaml
的一个片段,其中启用了追踪,并假定 Jaeger 实例与 Jaeger Operator 位于同一命名空间:
...
# .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 将把操作员的 Span 保留在内部缓冲区中,直到它连接到 Jaeger 实例。以下 Jaeger CR 可用于配置一个适合非生产环境使用的 Jaeger 实例:
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: jaeger
当 --log-level
标志设置为 debug
时,Jaeger Operator 还会提供详细的日志记录。以下是 operator.yaml
的一个片段,其中日志级别设置为 debug:
# .Spec.Template.Spec.Containers[0].Args
args: ["start", "--log-level=debug"]
请注意,追踪和调试级别的日志记录可以同时启用。
使用 OLM 时,可以通过更改 Subscription
的 config
属性来配置 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
监控操作员
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"}
),因为可能存在多个进程因不同原因同时更改资源。每当发生故障时,操作员将尝试再次协调,从而增加 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"}
增加的时间大致相同。
卸载操作员
{{ /* TODO Add OKD/OpenShift commands and tabs shortcode */ }}
要卸载操作员,请运行以下命令:
kubectl delete -n observability -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.71.0/jaeger-operator.yaml