大数跨境
0
0

K8S实战案例分享:当 Helm不够灵活,如何用 Kyverno 优雅地“魔改”Helm Chart 部署应用

K8S实战案例分享:当 Helm不够灵活,如何用 Kyverno 优雅地“魔改”Helm Chart 部署应用 云原生SRE
2025-10-10
0
导读:所有案例均源自笔者在SRE实际工作中遇到的真实任务,欢迎大家一同讨论学习

欢迎点击下方👇关注我,记得星标哟~

文末会有重磅福利赠送


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. 1. 非侵入式:无需修改上游 Helm Chart,保持了 Chart 的纯净性,升级更方便。
  2. 2. 声明式:策略本身就是 Kubernetes 资源(ClusterPolicy或 Policy),易于通过 GitOps 管理。
  3. 3. 动态生效:策略在资源创建或更新时自动应用,无需手动干预。
  4. 4. 功能强大:支持 JSON Patch、Strategic Merge Patch 等多种修改方式,能应对复杂的修改场景。

场景分析:为 Linkerd 的 PodMonitor添加 metricRelabelings

我们的目标是为 Linkerd 代理(data plane)的 PodMonitor资源(例如 linkerd-proxy)添加 metricRelabelings,以实现以下优化:

  • • 丢弃高基数标签:如 pod_template_hashauthorityroute_*等。
  • • 优化直方图桶:丢弃不必要的高延迟桶,减少存储。

由于 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. 1. {{- if .Values.kyvernoPolicies.enabled -}}:这是一个 Helm 模板的条件判断。通过在 values.yaml中设置 kyvernoPolicies.enabled: true,我们可以控制是否启用这条策略,增加了灵活性。
  2. 2. match:精确地锁定了我们要修改的目标资源:kind: PodMonitorname: linkerd-proxynamespace: linkerd
  3. 3. mutate.patchesJson6902:这是 Kyverno 的一个强大功能,允许我们使用 JSON Patch RFC 6902 格式来修改资源。
    • • |-语法patchesJson6902字段要求其值为一个字符串。YAML 的块标量 |-让我们能够以多行、易读的方式编写这个字符串。这是导致许多初学者策略失效的常见错误点。
    • • op: add:我们使用 add操作。如果 metricRelabelings字段不存在,它会创建该字段;如果已存在,它会替换整个字段的内容。
    • • path: "/spec/podMetricsEndpoints/0/metricRelabelings":我们硬编码了路径,指向 podMetricsEndpoints数组的第一个元素。这基于我们对 Linkerd Chart 输出的了解,通常该数组只有一个元素。
  4. 4. background: falsevs true
    • • false(默认):策略只在资源创建或更新时通过 Admission Webhook 生效。对于已经存在的资源,它不会起作用。
    • • true:策略不仅在 Admission 时生效,还会通过一个后台控制器扫描并修改已存在的、符合 match条件的资源。如果你希望策略能追溯性地修复存量资源,应设置为 true

部署与验证

  1. 1. 部署策略:将上述 YAML 文件作为 Helm Chart 的一部分,通过 Argo CD 或其他 GitOps 工具部署到集群中。确保 Kyverno 已经安装在你的集群里。
  2. 2. 触发修改
    • • 如果 background: false,你需要触发一次资源的更新。最简单的方法是删除 PodMonitor,让 Argo CD 重新创建它:
      
            
             
            kubectl -n linkerd delete podmonitor linkerd-proxy
    • • 如果 background: true,等待几秒钟,Kyverno 的后台控制器会自动完成修改。
  3. 3. 验证结果:检查 PodMonitor资源,确认 metricRelabelings字段已被成功添加。
    
         
          
         kubectl -n linkerd get podmonitor linkerd-proxy -o yaml | yq '.spec.podMetricsEndpoints[0].metricRelabelings'
  4. 你应该能看到我们定义的metricRelabelings下 labeldrop和 drop规则。

总结

当面对不够灵活的 Helm Chart 时,我们不必陷入 Fork 维护或编写复杂脚本的困境。Kyverno 提供了一种强大、声明式且与 Kubernetes 生态系统深度集成的方式,来动态地“修正”不符合我们预期的资源。

通过一条简单的 ClusterPolicy,我们成功地为 Linkerd 的 PodMonitor注入了关键的性能优化配置,同时保持了上游 Chart 的完整性。这种模式可以广泛应用于各种需要“最后一公里”定制化的场景,是现代云原生运维工具箱中不可或缺的一项利器。


 

入知识星球,共同探索云原生学习之旅!

更多云架构、K8S学习资料以及CKA、Azure考试认证资料,星球内可免费领取哦!

云原生、K8S等相关实战教程系列持续更新中。。
往期回顾

K8S工具推荐,Kargo:下一代 GitOps 持续交付工具

K8S工具推荐:Bufstream-唯一通过 Jepsen 验证的云原生 Kafka 实现

K8S工具推荐: 使用 Kubemark 进行 Kubernetes 大规模集群模拟实践

K8S工具推荐:使用Argo Rollouts实现GitOps自动化测试与回滚

K8S工具推荐:资源编排新利器:三大云厂商联合推出 KRO

K8S工具推荐:告别复杂认证!Kubernetes登录神器kubelogin指南

K8S工具推荐:Kubernetes资源优化神器KRR:一键诊断集群资源浪费

Kubernetes工具推荐:使用 k8s-pod-restart-info-collector简化故障排查

K8S工具推荐:动态无缝的Kubernetes多集群解决方案-Liqo

K8S学习路线2025

𝙺̲𝚞̲𝚋̲𝚎̲𝚛̲𝚗̲𝚎̲𝚝̲𝚎̲𝚜̲ 管理的最佳实践(2025)

如何落地一个企业级PaaS容器云平台:从规划到实施全流程指南


【声明】内容源于网络
0
0
云原生SRE
懂点K8S的SRE,关注云原生、DevOps、AI&ChatGPT等技术热点
内容 313
粉丝 0
云原生SRE 懂点K8S的SRE,关注云原生、DevOps、AI&ChatGPT等技术热点
总阅读58
粉丝0
内容313