欢迎点击下方👇关注我,记得星标哟~
文末会有重磅福利赠送
K8S实战系列:所有案例均源自笔者在SRE实际工作中遇到的真实任务,欢迎大家一同讨论学习。
引言:一个普遍的痛点
在使用社区或厂商提供的 Helm Chart 部署应用时,我们常常会遇到一个尴尬的场景:Chart 的 values.yaml并没有暴露所有我们想调整的字段。接着上篇文章优化 Linkerd 指标在 Prometheus 的实践指南,Linkerd 的监控配置就是一个典型例子。为了优化 Prometheus 的性能,我们需要为 PodMonitor资源添加精细的 metricRelabelings规则来剔除高基数标签,但 Linkerd 的 Helm Chart 并未直接提供注入这些规则的入口。
传统的解决方案,如 Fork Chart 或使用复杂的 postRenderer,都存在维护成本高、易出错的问题。本文将介绍另一种更有意思的解决方案:使用 Kyverno 策略在资源应用到集群时对其进行动态修改(Mutate)。

为什么选择 Kyverno?
Kyverno 是一个为 Kubernetes 设计的策略引擎,它能以原生方式运行在你的集群中,通过声明式的策略来验证(validate)、修改(mutate)、生成(generate)和清理(cleanup)资源。
使用 Kyverno 的优势:
-
1. 非侵入式:无需修改上游 Helm Chart,保持了 Chart 的纯净性,升级更方便。 -
2. 声明式:策略本身就是 Kubernetes 资源( ClusterPolicy或Policy),易于通过 GitOps 管理。 -
3. 动态生效:策略在资源创建或更新时自动应用,无需手动干预。 -
4. 功能强大:支持 JSON Patch、Strategic Merge Patch 等多种修改方式,能应对复杂的修改场景。
场景分析:为 Linkerd 的 PodMonitor添加 metricRelabelings
我们的目标是为 Linkerd 代理(data plane)的 PodMonitor资源(例如 linkerd-proxy)添加 metricRelabelings,以实现以下优化:
-
• 丢弃高基数标签:如 pod_template_hash,authority,route_*等。 -
• 优化直方图桶:丢弃不必要的高延迟桶,减少存储。
由于 Linkerd Helm Chart 未在 values.yaml中提供直接配置 metricRelabelings的字段,我们将编写一条 Kyverno ClusterPolicy来实现这一目标。
实战代码:编写 Kyverno ClusterPolicy
以下策略将匹配名为 linkerd-proxy、位于 linkerd命名空间的 PodMonitor资源,并使用 patchesJson6902为其 podMetricsEndpoints数组的第一个元素添加 metricRelabelings字段。
# 文件路径: kyverno/policies/linkerd-podmonitor-relabel.yaml
{{- if .Values.kyvernoPolicies.enabled -}}
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: linkerd-proxy-podmonitor-metricrelabelings
annotations:
argocd.argoproj.io/sync-wave: "-10" # 确保策略在 PodMonitor 之前应用
policies.kyverno.io/title: Add metricRelabelings to Linkerd Proxy PodMonitor
policies.kyverno.io/category: Observability
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: PodMonitor, Linkerd
policies.kyverno.io/description: >-
Adds metricRelabelings to the PodMonitor for the Linkerd data plane to
drop high-cardinality labels and high-latency histogram buckets,
optimizing Prometheus performance.
spec:
# background: false # 仅在资源创建/更新时生效
# background: true # 也会对已存在的资源生效
background: false
webhookConfiguration:
failurePolicy: Fail # 如果策略应用失败,则拒绝资源创建
rules:
- name: add-metricrelabelings-to-linkerd-proxy-podmonitor
match:
any:
- resources:
kinds:
- PodMonitor
names:
- linkerd-proxy
namespaces:
- linkerd
mutate:
# patchesJson6902 必须是字符串格式,因此使用 YAML 块标量 `|-`
patchesJson6902: |-
- op: add
path: "/spec/podMetricsEndpoints/0/metricRelabelings"
value:
- action: labeldrop
regex: ^(pod_template_hash|dst_pod_template_hash)$
- action: labeldrop
regex: ^(parent_|route_|backend_).*
- action: labeldrop
regex: ^authority$
- action: labeldrop
regex: ^client_id$
# 优化直方图桶,仅保留关键部分
- action: drop
sourceLabels: [le]
regex: "^(20000|30000|40000|50000)$"
{{- end -}}
关键点解析
-
1. {{- if .Values.kyvernoPolicies.enabled -}}:这是一个 Helm 模板的条件判断。通过在values.yaml中设置kyvernoPolicies.enabled: true,我们可以控制是否启用这条策略,增加了灵活性。 -
2. match块:精确地锁定了我们要修改的目标资源:kind: PodMonitor、name: linkerd-proxy、namespace: linkerd。 -
3. mutate.patchesJson6902:这是 Kyverno 的一个强大功能,允许我们使用 JSON Patch RFC 6902 格式来修改资源。 -
• |-语法:patchesJson6902字段要求其值为一个字符串。YAML 的块标量|-让我们能够以多行、易读的方式编写这个字符串。这是导致许多初学者策略失效的常见错误点。 -
• op: add:我们使用add操作。如果metricRelabelings字段不存在,它会创建该字段;如果已存在,它会替换整个字段的内容。 -
• path: "/spec/podMetricsEndpoints/0/metricRelabelings":我们硬编码了路径,指向podMetricsEndpoints数组的第一个元素。这基于我们对 Linkerd Chart 输出的了解,通常该数组只有一个元素。 -
4. background: falsevstrue: -
• false(默认):策略只在资源创建或更新时通过 Admission Webhook 生效。对于已经存在的资源,它不会起作用。 -
• true:策略不仅在 Admission 时生效,还会通过一个后台控制器扫描并修改已存在的、符合match条件的资源。如果你希望策略能追溯性地修复存量资源,应设置为true。
部署与验证
-
1. 部署策略:将上述 YAML 文件作为 Helm Chart 的一部分,通过 Argo CD 或其他 GitOps 工具部署到集群中。确保 Kyverno 已经安装在你的集群里。 -
2. 触发修改: -
• 如果 background: false,你需要触发一次资源的更新。最简单的方法是删除PodMonitor,让 Argo CD 重新创建它:kubectl -n linkerd delete podmonitor linkerd-proxy -
• 如果 background: true,等待几秒钟,Kyverno 的后台控制器会自动完成修改。 -
3. 验证结果:检查 PodMonitor资源,确认metricRelabelings字段已被成功添加。kubectl -n linkerd get podmonitor linkerd-proxy -o yaml | yq '.spec.podMetricsEndpoints[0].metricRelabelings'
-
你应该能看到我们定义的metricRelabelings下
labeldrop和drop规则。
总结
当面对不够灵活的 Helm Chart 时,我们不必陷入 Fork 维护或编写复杂脚本的困境。Kyverno 提供了一种强大、声明式且与 Kubernetes 生态系统深度集成的方式,来动态地“修正”不符合我们预期的资源。
通过一条简单的 ClusterPolicy,我们成功地为 Linkerd 的 PodMonitor注入了关键的性能优化配置,同时保持了上游 Chart 的完整性。这种模式可以广泛应用于各种需要“最后一公里”定制化的场景,是现代云原生运维工具箱中不可或缺的一项利器。
更多云架构、K8S学习资料以及CKA、Azure考试认证资料,星球内可免费领取哦!
往期回顾
K8S工具推荐,Kargo:下一代 GitOps 持续交付工具
K8S工具推荐:Bufstream-唯一通过 Jepsen 验证的云原生 Kafka 实现
K8S工具推荐: 使用 Kubemark 进行 Kubernetes 大规模集群模拟实践
K8S工具推荐:使用Argo Rollouts实现GitOps自动化测试与回滚
K8S工具推荐:告别复杂认证!Kubernetes登录神器kubelogin指南
K8S工具推荐:Kubernetes资源优化神器KRR:一键诊断集群资源浪费
Kubernetes工具推荐:使用 k8s-pod-restart-info-collector简化故障排查
K8S工具推荐:动态无缝的Kubernetes多集群解决方案-Liqo
𝙺̲𝚞̲𝚋̲𝚎̲𝚛̲𝚗̲𝚎̲𝚝̲𝚎̲𝚜̲ 管理的最佳实践(2025)
如何落地一个企业级PaaS容器云平台:从规划到实施全流程指南

