Kubernetes 的运营商
了解运营商
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,并将运营商的命名空间和名称作为标签的值。
current
、current-1
和 current-2
)中重现的错误。虽然多个运营商可能共存并监视同一组命名空间,但哪个运营商会成功将自身设置为 CR 的所有者是未定义的行为。自动注入 sidecar 也可能导致未定义的行为。因此,强烈建议每个命名空间最多有一个运营商进行监视。请注意,命名空间可能包含任意数量的 Jaeger 实例 (CR)。
先决条件
从 1.31 版开始,Jaeger 运营商使用 Webhook 验证 Jaeger 自定义资源 (CR)。这需要安装 cert-manager 的版本。支持版本的更详细列表可以在 兼容性矩阵 中找到。安装指南可以在 此处 中找到。
安装模式
Jaeger 运营商可以安装以监视整个集群或特定命名空间中的新的 Jaeger 自定义资源 (CR)。在为集群模式配置时,运营商可以
- 监视与所有命名空间中的 Jaeger 资源相关的事件
- 监视命名空间本身,查找
sidecar.jaegertracing.io/inject
注释 - 监视所有部署,根据
sidecar.jaegertracing.io/inject
注释注入或删除 sidecar - 在必要时创建集群角色绑定
如果未使用集群范围的资源(ClusterRole
和 ClusterRoleBinding
),请将 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
的“自定义资源定义”。
如果要将操作员安装在集群范围模式下,如果您只想监控特定命名空间,则需要将操作员清单中的ClusterRole
和ClusterRoleBinding
更改为Role
和RoleBinding
,并在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
的“自定义资源定义”。
如果要将操作员安装在集群范围模式下,如果您只想监控特定命名空间,则需要将操作员清单中的ClusterRole
和ClusterRoleBinding
更改为Role
和RoleBinding
,并在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-agent、jaeger-collector、jaeger-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"}
$ 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操作员可以通过命令行界面参数、环境变量或配置文件进行配置。当在不同级别指定相同变量时,优先级顺序为
- 命令行参数(标志)
- 环境变量
- 配置文件
每个项目优先于其下面的项目。可以通过使用--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
。其他可能的值是production
和streaming
。
以下部分介绍了可用的策略。
AllInOne(默认)策略
此策略适用于开发、测试和演示目的。
主要的后端组件jaeger-agent、jaeger-collector和jaeger-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网站 。可以通过将.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)获取实时跨度数据。
jaeger-collector可以配置为按需自动扩展,如“生产策略”部分所述。
jaeger-ingester也可以配置为按需自动扩展。默认情况下,当没有为.Spec.Ingester.Replicas
提供值时,Jaeger操作员将为jaeger-ingester创建一个水平Pod自动扩展器(HPA)配置。我们建议设置.Spec.Ingester.MaxReplicas
的显式值,以及jaeger-ingester的Pod预计要消耗的资源的合理值。当没有设置.Spec.Ingester.MaxReplicas
时,操作员将设置100
作为其值。有关HPA的更多信息,请阅读Kubernetes网站 。可以通过将.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,以将新的资源类型添加到他们的项目中。操作员监视自定义资源对象的创建,当它看到自定义资源被创建时,它根据自定义资源对象中定义的参数创建应用程序。
作为参考,以下是您如何创建更复杂的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服务创建一个入口对象。可以通过将其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> production
和 streaming
也一样。
<2> 这些选项用于常规 Jaeger 组件,如 collector
和 query
。
<3> 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.key
和 es.tls.cert
(当使用双向 TLS 时)。
<4> 定义环境变量 ES_PASSWORD
和 ES_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 操作员配置 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 作业用于滚动到新的索引,第二个 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
映射。所有可用选项都在 Jaeger All-In-One with Prometheus CLI 部分 中有文档说明。
<2> 用 http://prometheus:9090
覆盖默认的 https://127.0.0.1:9090
Prometheus 服务器 URL。
<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
连接到存储的配置是从存储选项中获取的。
8Gi
的内存。但是,该作业可以使用至少 2Gi
的内存启动。正确的内存设置将取决于正在处理的数据量。请注意,该作业将当前日期的所有数据加载到内存中。自动注入 Jaeger Agent Sidecar
目前,仅支持将 jaeger-agent sidecar 自动注入 Deployments
中。
对于其他控制器类型,请参阅下面的 手动定义 Jaeger Agent Sidecar。
自动注入其他控制器类型的支持正在使用 问题 #750 跟踪。
只要部署或其命名空间具有带有适当值的 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-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
默认情况下,操作员期望 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 中,只有在设置了特殊的安全上下文时才能设置 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
在运行指向服务的自定义 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-collector、jaeger-query 和 all-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}"
定义采样策略
操作员可用于定义采样策略,这些策略将提供给已配置为使用远程采样器的跟踪器
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>
节点下。
支持的配置类型包括
亲和性 ,以确定 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)
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
自定义 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 操作符需要在 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) )进行升级。
更新 Jaeger 实例(实验性)
可以通过更改 CustomResource
来更新 Jaeger 实例,可以通过 kubectl edit jaeger simplest
(其中 simplest
是 Jaeger 实例名称)或通过 kubectl apply -f simplest.yaml
应用更新的 YAML 文件来实现。
更改副本大小等简单的更改可以毫不费力地应用,而对策略的更改则需要密切关注,并可能导致单个组件(收集器/查询/代理)出现故障。
虽然支持更改后端存储,但数据迁移不支持。
删除 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 时,可以通过更改 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
监控 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
要卸载 Operator,请运行以下命令
kubectl delete -n observability -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.62.0.0/jaeger-operator.yaml