使用 OpenTelemetry Collector 采集 Kubernetes 指标数据
batch 处理器
批处理器接受追踪、指标或日志,并将它们分批处理。批处理有助于更好地压缩数据,并减少传输数据所需的外部连接数量。该处理器支持基于大小和时间的批处理。
强烈建议在每个采集器上配置批处理器。批处理器应该在内存限制器(memory_limiter
)以及任何其他采样处理器之后的管道中定义。这是因为批处理应该在任何数据采样之后再发生。
批处理器中可以配置如下所示的一些参数:
-
send_batch_size
(默认值=8192):无论超时如何,达到此数量的追踪、指标数据或日志记录后,都将立即发送批处理。send_batch_size
起到触发器的作用,不影响批处理的大小。如果需要强制限制发送到管道中下一个组件的批处理大小,可以配置send_batch_max_size
。 -
timeout
(默认值=200ms):无论批处理大小如何,在经过一定时间后,将立即发送批处理。如果设置为零,则忽略send_batch_size
,因为数据将立即发送,只受send_batch_max_size
的限制。 -
send_batch_max_size
(默认值=0):批处理大小的上限。0 表示批处理大小无上限,此属性确保较大的批处理被拆分为较小的单位。它必须大于或等于send_batch_size
。 -
metadata_keys
(默认值=空):当设置时,此处理器将为client.Metadata
中值的每个不同组合创建一个批处理程序实例。 -
metadata_cardinality_limit
(默认值=1000):当metadata_keys
不为空时,此设置限制将在进程的生命周期内处理的元数据键值的唯一组合的数量。
比如如下配置包含一个默认的批处理器和一个具有自定义设置的第二个批处理器。批处理器 batch/2
将在 10 秒内缓冲最多 10000 个 span、指标数据点或日志记录,而不会分割数据项以强制执行最大批处理大小。
processors:
batch:
batch/2:
send_batch_size: 10000
timeout: 10s
下面的配置将强制执行最大批处理大小限制,即 10000 个 span、指标数据点或日志记录,而不引入任何人为的延迟。
processors:
batch:
send_batch_max_size: 10000
timeout: 0s
memory_limiter 处理器
内存限制处理器用于防止收集器的内存不足情况。考虑到收集器处理的数据的数量和类型是环境特定的,并且收集器的资源利用率也取决于配置的处理器,因此对内存使用情况进行检查非常重要。
memory_limiter
处理器允许定期检查内存使用情况,如果超过定义的限制,将开始拒绝数据并强制 GC 减少内存消耗。memory_limiter
使用软内存限制和硬内存限制,硬限制始终高于或等于软限制。
内存使用量随时间变化,硬限制是进程堆分配的最大内存量,超过此限制将触发内存限制操作。软限制是内存使用量下降到硬限制以下的阈值,恢复正常操作。
比如定义硬限制 limit_mib
为 100 MiB,软限制是 80 MiB,那么 spike_limit_mib
则为 20 MiB。当内存使用量超过硬限制时,处理器将拒绝接收数据,并强制执行垃圾收集以尝试释放内存。当内存使用量超过软限制时,处理器将进入内存限制模式,如果内存使用量下降到软限制以下,则恢复正常操作,数据将不再被拒绝,并且不会执行强制垃圾收集。
在内存限制模式下,处理器返回的错误是非永久性错误。当接收器方看到此错误时,他们会重试发送相同的数据。
强烈建议在每个收集器上配置 ballast 扩展以及 memory_limiter 处理器。ballast 扩展应配置为分配给收集器的内存的 1/3 到 1/2。 memory_limiter 处理器应该是管道中定义的第一个处理器(紧接在接收器之后)。这是为了确保可以将背压发送到适用的接收器,并在触发 memory_limiter 时将数据丢失的可能性降到最低。
内存限制器主要的配置选项包括下面这些:
-
check_interval
(默认 = 0s):用于指定检查内存使用情况的时间间隔。比如设置为 5s,表示每 5 秒检查一次内存使用情况。 -
limit_mib
(默认 = 0):进程堆分配的最大内存量(以 MiB 为单位)。请注意,通常进程的总内存使用量将比该值高出约 50MiB,这定义了硬限制。 -
spike_limit_mib
(默认 =limit_mib
的 20%):内存使用测量之间预期的最大峰值。该值必须小于limit_mib
。软限制值将等于limit_mib - spike_limit_mib
。spike_limit_mib
的建议值约为limit_mib
的 20%。 -
limit_percentage
(默认值 = 0):进程堆要分配的最大总内存量。此配置在具有 cgroup 的 Linux 系统上受支持,旨在用于像 docker 这样的动态平台。此选项用于根据可用总内存计算内存限制。例如,设置为 75%,总内存为 1GiB,将限制为 750 MiB。固定内存设置 (limit_mib
) 优先于百分比配置。 -
spike_limit_percentage
(默认 = 0):内存使用测量之间预期的最大峰值。该值必须小于limit_percentage
。该选项用于根据总可用内存计算spike_limit_mib
。例如,如果总内存为 1GiB,则设置为 25% 将峰值限制为 250MiB。此选项仅与limit_percentage
一起使用。
k8sattributes 处理器
Kubernetes 属性处理器允许使用 K8s 元数据自动设置追踪、指标和日志资源属性。当 k8sattributes 处理器被应用于一个 Kubernetes 集群中的 Pod 时,它会从 Pod 的元数据中提取一些属性,例如 Pod 的名称、UID、启动时间等其他元数据。这些属性将与遥测数据一起发送到后端,以便在分析和调试遥测数据时可以更好地了解它们来自哪个 Pod。
在 k8sattributes 处理器中,pod_association
属性定义了如何将遥测数据与 Pod 相关联。例如,如果一个 Pod 发送了多个遥测数据,那么这些遥测数据将被关联到同一个 Pod 上,以便在后续的分析和调试中可以更好地了解它们来自哪个 Pod。
比如我们这里定义的处理器如下所示:
k8sattributes:
extract:
metadata: # 列出要从k8s中提取的元数据属性
- k8s.namespace.name
- k8s.deployment.name
- k8s.statefulset.name
- k8s.daemonset.name
- k8s.cronjob.name
- k8s.job.name
- k8s.node.name
- k8s.pod.name
- k8s.pod.uid
- k8s.pod.start_time
filter: # 只有来自与该值匹配的节点的数据将被考虑。
node_from_env_var: K8S_NODE_NAME
passthrough: false # 表示处理器不会传递任何不符合过滤条件的数据。
pod_association:
- sources:
- from: resource_attribute # from 表示规则类型
name: k8s.pod.ip
- sources:
- from: resource_attribute # resource_attribute 表示从接收到的资源的属性列表中查找的属性名称
name: k8s.pod.uid
- sources:
- from: connection
其中 extract
选项列出要从 Kubernetes 中提取的元数据属性,我们这里包括命名空间、Deployment、StatefulSet、DaemonSet、CronJob、Job、Node、Pod 名称、Pod UID 和 Pod 启动时间。 filter
属性指定仅考虑名称与 K8S_NODE_NAME
环境变量的值匹配的节点的数据。passthrough
选项设置为 false,这意味着处理器不会传递任何不符合过滤条件的数据。
最后,pod_association
选项定义了如何将从 Kubernetes 中提取的 Pod 元数据与遥测数据关联起来。在这个配置文件中,pod_association
属性定义了三个关联源,分别是 k8s.pod.ip
、k8s.pod.uid
和 connection
。
- 第一个关联源是
k8s.pod.ip
,它使用 Pod IP 作为关联的来源。这意味着从同一个 Pod IP 发送的所有遥测数据都将与同一个 Pod 关联起来。 - 第二个关联源是
k8s.pod.uid
,它使用 Pod UID 作为关联的来源。这意味着从同一个 Pod UID 发送的所有遥测数据都将与同一个 Pod 关联起来。 - 第三个关联源是
connection
,它使用连接信息作为关联的来源。这意味着从同一个连接发送的所有遥测数据都将与同一个 Pod 关联起来。
如果未配置 Pod 关联规则,则资源仅通过连接的 IP 地址与元数据关联。
通过这些关联源,pod_association
属性可以确保遥测数据与正确的 Pod 相关联,从而使得在分析和调试遥测数据时更加方便和准确。
要收集的元数据由定义的元数据配置确定,该配置定义了要添加的资源属性列表。列表中的项与将要添加的资源属性名称完全相同。默认情况下添加以下属性:
-
k8s.namespace.name
-
k8s.pod.name
-
k8s.pod.uid
-
k8s.pod.start_time
-
k8s.deployment.name
-
k8s.node.name
你可以使用 metadata
配置更改此列表。并非所有属性都能够被添加。只有来自 metadata
的属性名称应该用于 pod_association
的 resource_attribute
,空值或不存在的值将会被忽略。
此外 k8sattributesprocessor
还可以通过 pod 和命名空间的标签和注解来设置资源属性。
metricstransform 处理器
指标转换处理器可用于重命名指标,以及添加、重命名或删除标签键和值。它还可用于跨标签或标签值对指标执行缩放和聚合。下表提供了可应用于一个或多个指标的受支持操作的完整列表。
操作 | 示例 (基于指标 |
Rename metrics | 重命名 |
Add labels | 添加一个新的标签 |
Rename label keys | 重命名标签 |
Rename label values | 对于标签 |
Delete data points | 删除标签为 |
Toggle data type | 从 |
Scale value | 将值乘以 1000,从秒转换为毫秒。 |
Aggregate across label sets | 仅保留标签 |
Aggregate across label values | 对于标签 |
我们这里的添加的配置如下:
metricstransform:
transforms:
action: update
include: .+
match_type: regexp
operations:
- action: add_label
new_label: k8s.cluster.id
new_value: abcd1234
- action: add_label
new_label: k8s.cluster.name
new_value: youdian-k8s
表示我们会对所有的指标添加 k8s.cluster.id
和 k8s.cluster.name
两个标签。
logging 导出器
日志导出器,用于将数据导出到标准输出,主要用于调试阶段。
prometheus 导出器
Prometheus 导出器,该导出器可以指定一个端点,将从接收器接收到的指标数据通过这个端点进行导出,这样 Prometheus 只需要从这个端点拉取数据即可。而 prometheusremotewrite
导出器则是将指标数据直接远程写入到指定的地址,这个地址是支持 Prometheus 远程写入协议的地址。(经测试当前版本远程写入的导出器有一定问题)
我们这里的配置如下:
prometheus:
endpoint: 0.0.0.0:9090
metric_expiration: 180m
resource_to_telemetry_conversion:
enabled: true
-
endpoint
:指标将通过路径/metrics
暴露的地址,也就是我们想通过上面地址来访问指标数据,我们这里表示想在 9090 端口来暴露指标数据。 -
metric_expiration
(默认值= 5m):定义了在没有更新的情况下暴露的指标的时间长度。 -
resource_to_telemetry_conversion
(默认为 false):如果启用为 true,则所有资源属性将默认转换为指标标签。
所以最后我们可以在 Prometheus 中去采集 OpenTelemetry Collector 在 9090 端口暴露的指标数据,只需要创建一个如下所示的 ServiceMonitor
对象即可:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: otel-prom
namespace: kube-otel
labels:
release: prometheus
spec:
endpoints:
- interval: 10s
port: prom # 我们在helm values 中定义了一个 prom 的 Service 端口
path: metrics
selector:
matchLabels:
component: agent-collector
app.kubernetes.io/instance: opentelemetry-collector
创建后我们就可以在 Prometheus 中找到 OpenTelemetry Collector 暴露的指标数据了。
采集到的指标里面包含了很多的标签,这些标签都是通过我们前面定义的处理器添加的,比如:
同样我们也可以通过 Grafana 来查询这些指标数据:
此外我们还可以部署 OpenTelemetry Collector 的 Deployment 模式来采集其他指标数据。
文章转载自公众号:k8s技术圈