ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Kubernetes 垂直扩缩容 VPA Helm Chart 部署完全指南:Webhook 证书管理与参数详解

Kubernetes 垂直扩缩容 VPA Helm Chart 部署完全指南:Webhook 证书管理与参数详解 Kubernetes 垂直扩缩容 VPA Helm Chart 部署完全指南Webhook 证书管理与参数详解【免费下载链接】autoscalerAutoscaling components for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/au/autoscalerVertical Pod AutoscalerVPA是 Kubernetes Autoscaler 项目中负责自动调整 Pod CPU 与内存资源请求的核心组件而vertical-pod-autoscalerHelm Chart当前 Chart 版本 0.11.0对应 VPA AppVersion 1.7.1是将其一键部署到集群的标准途径。本文以该 Chart 的官方文档为主体结合仓库内values.yaml与全部模板源码系统讲解 Helm 安装/升级、三种 Webhook 证书管理模式Helm-managed、Application-managed、cert-manager-managed的取舍与迁移并逐项解读 Admission Controller、Recommender、Updater 三大组件的全部可配置参数帮助你在生产环境中正确、安全地落地 VPA。提示Chart 官方文档在标题处即标注当前仍处于开发阶段尚未做好生产环境使用准备WARNING: This chart is currently under development and is not ready for production use部署前请结合自身集群版本与 VPA 项目发布状态评估风险。一、Chart 概览与核心组件vertical-pod-autoscaler是一个 Helm v2 格式的 application 类型 Chart其元数据定义在 Chart.yamlChart 版本0.11.0应用版本AppVersion1.7.1即 Chart 打包的 VPA 镜像版本未显式设置image.tag时默认使用该版本类型application维护者adrianmoisey、omerap12均为 SIG Autoscaling 成员联系邮箱 kubernetes-sig-autoscalinggooglegroups.comChart 默认部署三个相互协作的 VPA 组件三者均可通过xxx.enabled独立开关组件默认镜像默认副本数职责Admission Controllerregistry.k8s.io/autoscaling/vpa-admission-controller2作为 MutatingWebhook 拦截 Pod 创建/更新将 VPA 推荐值写入 Pod 资源请求Recommenderregistry.k8s.io/autoscaling/vpa-recommender2基于历史与实时用量数据计算 CPU/内存推荐值写入 VPA 对象状态Updaterregistry.k8s.io/autoscaling/vpa-updater2对比推荐值与实际请求对需要更新的 Pod 执行原地更新或驱逐重建组件清单与安装后提示信息由 NOTES.txt 模板在helm install/upgrade结束时输出可用于快速确认当前 Webhook 管理模式。二、Helm 安装与升级官方文档给出的安装与升级命令upgrade -i兼具安装与幂等升级能力helm repo add autoscalers https://kubernetes.github.io/autoscaler helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler如果希望使用当前仓库内的 Chart 源码而非远端仓库可直接指向本地 Chart 目录helm upgrade -i vertical-pod-autoscaler ./vertical-pod-autoscaler/charts/vertical-pod-autoscaler \ -n vpa --create-namespace安装时 Chart 会依次完成安装 VPA CRD位于 crds/vpa-v1-crd-gen.yaml→ 创建 RBAC、ServiceAccount → 按所选模式创建 Webhook 证书与 MutatingWebhookConfiguration → 部署三个组件 Deployment 及其 PodDisruptionBudget。三、Webhook 证书管理三种互斥模式Admission Controller 依赖一个MutatingWebhookConfiguration与一套 TLS 证书工作证书来源决定了整个 VPA 的注册方式。Chart 支持三种互斥模式同一时刻只能启用其中一种模式registerWebhookcertGen.enabledcertManager.enabled谁创建 Webhook谁管理证书Helm-managed默认推荐falsetruefalseHelmcertgen Jobkube-webhook-certgenApplication-managedtruefalsefalseVPA 应用自身用户自行准备 TLS Secretcert-manager managedfalsefalsetrueHelmcert-manager自动签发与续期模式冲突会在渲染阶段被模板 admission-controller-validations.yaml 中的fail断言直接拦截例如registerWebhook与certGen.enabled同时为 true 会安装失败避免部署出错误配置。3.1 Helm-managed默认模式推荐admissionController: registerWebhook: false certGen: enabled: true工作流程Helm 创建 MutatingWebhookConfiguration模板 admission-controller-webhook.yaml 渲染出名为vpa.k8s.io的 webhook拦截pods的 CREATE 操作以及autoscaling.k8s.io组下verticalpodautoscalers资源的 CREATE/UPDATE 操作两个 certgen Job 生成并注入证书pre-install,pre-upgrade钩子上的createJob见 admission-controller-certgen.yaml执行kube-webhook-certgen create为 Service 主机名vpa-webhook、vpa-webhook.namespace.svc生成自签名证书并存入 Secret默认名vpa-tls-certspost-install,post-upgrade钩子上的patchJob见 admission-controller-certgen-patch.yaml执行kube-webhook-certgen patch将证书 CA 注入到MutatingWebhookConfiguration的clientConfig.caBundle字段证书自动挂载Deployment 通过 admission-controller-deployment.yaml 将 Secret 以tls-certs卷只读挂载到/etc/tls-certs并默认追加--reload-certtrue参数以便证书更新后热加载。默认使用的 certgen 镜像为registry.k8s.io/ingress-nginx/kube-webhook-certgen标签v20231011-8b53cabe0拉取策略IfNotPresent官方建议不要更改该策略。两个 Job 都设置了ttlSecondsAfterFinished: 300任务完成后 5 分钟自动清理。3.2 Application-managed 模式admissionController: registerWebhook: true certGen: enabled: false该模式下部署模板会为 Admission Controller 追加--register-webhooktrue参数由 VPA 应用自身创建并管理MutatingWebhookConfigurationTLS Secret 必须由你自行提前创建可用admissionController.tls.create: true让 Helm 用内置genCA/genSignedCert能力生成或预置自定义 Secret。Admission Controller 只有在 Secret 存在后才会注册 Webhook若 Secret 是在 Helm 安装之后才创建必须重启 Admission Controller Pod才能触发 Webhook 注册kubectl rollout restart deployment/vpa-admission-controller -n namespace安全提醒该模式需要授予 Admission Controllerdeletemutatingwebhookconfigurations的权限见 admission-controller-clusterrole.yaml这意味着它具备删除集群内任意 Webhook 配置的潜在能力存在安全风险官方明确提示应谨慎权衡。3.3 cert-manager managed 模式admissionController: registerWebhook: false certGen: enabled: false certManager: enabled: true前提集群中必须已安装 cert-manager。该模式下Helm 创建MutatingWebhookConfigurationcert-manager 负责证书的自动签发与续期其 cainjector 组件自动将 CA 注入 Webhook 配置模板在 webhook 的 annotations 中写入cert-manager.io/inject-ca-from见 admission-controller-webhook.yaml证书的私钥算法默认为 RSA 2048Webhook 证书有效期默认168h7 天、续期提前量24hTLS 证书的 DNS 名称覆盖vpa-webhook、vpa-webhook.ns、ns.svc、ns.svc.cluster.local四个地址见 admission-controller-certmanager.yaml。Issuer 的两种提供方式二选一引用集群中已有的Issuer/ClusterIssuer默认issuerRef.kind: ClusterIssuer、group: cert-manager.io需设置issuerRef.name若未设置名称且未开启自签名 Issuer渲染会直接失败开启自签名 Issuer由 Chart 在 VPA 命名空间内自动创建一套完整的证书链admissionController: certManager: createSelfSignedIssuer: enabled: true # 创建 namespaced SelfSigned Issuer 与中间 CA duration: 8760h # 中间 CA 证书有效期默认 1 年 renewBefore: 720h # CA 到期前提前续期时间默认 30 天开启后Chart 依次创建SelfSignedIssuer→ 中间 CACertificateisCA: true→ 以该 CA 为签发源的ca类型Issuer→ Webhook TLSCertificate实现完全由 cert-manager 驱动的自动化证书生命周期。注意cert-manager 模式下Deployment 的 volumes/volumeMounts 由 Chart 接管直接使用 Secret 中ca.crt/tls.crt/tls.key三个 key任何自定义的admissionController.volumes/volumeMounts都将被忽略同时由于证书会周期性续期不能传--reload-certfalse模板会校验并报错。3.4 四种模式的互斥校验总结由 admission-controller-validations.yaml 可见以下组合都会被helm拒绝渲染registerWebhook: true与certGen.enabled: true并存certManager.enabled: true与certGen.enabled: true并存certManager.enabled: true与registerWebhook: true并存certManager.enabled: true与tls.create: true并存certManager.enabled: true且createSelfSignedIssuer.enabled: false但issuerRef.name为空certManager.enabled: true但extraArgs中包含--reload-certfalse。四、Custom Resource DefinitionsCRD升级注意事项按 Helm 设计chart/crds目录下的 CRD不会随helm upgrade自动升级。因此升级 Chart 后VPA 的 CRD 依旧停留在旧版本需要手动用kubectl应用新版本。官方文档建议从上游项目仓库的发布分支拉取生成好的 CRD 文件# 将 appVersion 替换为 Chart 的 appVersion例如 1.7.1 kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes/autoscaler/vertical-pod-autoscaler-appVersion/vertical-pod-autoscaler/deploy/vpa-v1-crd-gen.yaml # 以 v1.7.1 为例 kubectl apply --server-side -f https://raw.githubusercontent.com/kubernetes/autoscaler/vertical-pod-autoscaler-1.7.1/vertical-pod-autoscaler/deploy/vpa-v1-crd-gen.yaml在当前仓库中该 CRD 清单的本地副本位于 vertical-pod-autoscaler/deploy/vpa-v1-crd-gen.yamlChart 包内副本位于 vertical-pod-autoscaler/charts/vertical-pod-autoscaler/crds/vpa-v1-crd-gen.yaml需要升级 CRD 时也可直接对本地文件执行kubectl apply --server-side -f。使用--server-side可以避免kubectl.kubernetes.io/last-applied-configuration注解带来的冲突问题。五、迁移指南5.1 从 vpa-up.sh 脚本迁移官方文档目前将该小节标记为TBD待补充。仓库中传统部署方式是vertical-pod-autoscaler/deploy目录下的 YAML 清单与vpa-up.sh等脚本见 vertical-pod-autoscaler/hack/vpa-up.sh迁移到 Helm Chart 时需注意脚本部署的 Webhook 采用应用自注册模式而 Chart 默认采用 Helm-managed 模式迁移时应按 5.2 节完成 Webhook 归属的切换。5.2 从 Application-managed 切换到 Helm-managed Webhook如果你之前使用registerWebhook: true部署希望切换到 Helm 托管按以下三步操作1. 删除旧的 Webhook 配置kubectl delete mutatingwebhookconfiguration vpa-webhook-config2. 删除旧证书 Secret让 certgen 重新生成证书kubectl delete secret -n namespace vpa-tls-certs3. 以新 values 执行升级helm upgrade release-name chart \ --set admissionController.registerWebhookfalse \ --set admissionController.certGen.enabledtrue六、Values 参数全解基于 values.yaml6.1 全局公共参数Key默认值说明imagePullSecrets[]拉取私有镜像仓库时的 Secret 列表nameOverride/fullnameOverridenil覆盖 Chart 生成的对象名称commonLabels{}添加到所有 Chart 资源上的公共标签rbac.createtrue是否创建访问 Kubernetes API 所需的 ClusterRole 与 ClusterRoleBindingrbac.extraRules[]追加到 ClusterRole 的额外规则podSecurityContextrunAsNonRoot: true, runAsUser: 65534所有组件 Pod 的安全上下文以非 root 用户运行containerSecurityContext{}容器级安全上下文可在其上追加allowPrivilegeEscalation、capabilities、seccompProfile等6.2 admissionController准入控制器镜像与运行Key默认值说明admissionController.enabledtrue是否部署 Admission ControlleradmissionController.image.repositoryregistry.k8s.io/autoscaling/vpa-admission-controller镜像仓库admissionController.image.tagnil未设置时默认取.Chart.AppVersion即 1.7.1admissionController.image.pullPolicyIfNotPresent拉取策略admissionController.replicas2副本数admissionController.revisionHistoryLimit10Deployment 保留的历史版本数admissionController.logLevel4klog 日志级别--vadmissionController.extraArgs/extraEnv[]追加命令行参数与环境变量admissionController.hostNetworkfalse是否启用宿主机网络启用会绕过 Kubernetes 网络隔离多副本同节点时可能产生端口冲突admissionController.priorityClassNamenil调度优先级类调度与高可用Key默认值说明admissionController.affinity基于app.kubernetes.io/component: admission-controller的podAntiAffinitypreferredDuringSchedulingIgnoredDuringExecutionweight 100topologyKeykubernetes.io/hostname默认将副本分散到不同节点admissionController.nodeSelector/tolerations/podAnnotations/podLabels{}/[]调度与元数据定制admissionController.resources{}容器资源请求与限制官方注释示例limits cpu 200m / memory 500Mirequests cpu 50m / memory 200MiadmissionController.podDisruptionBudget.enabledtrue启用 PDBadmissionController.podDisruptionBudget.minAvailable1驱逐后最小可用 Pod 数与 maxUnavailable 二选一不可同时设置admissionController.podDisruptionBudget.maxUnavailablenil驱逐后最大不可用 Pod 数/百分比与 minAvailable 二选一Webhook 与证书与第三节对应Key默认值说明admissionController.registerWebhookfalse是否由应用自身注册 Webhook设为 false 表示由 Helm 托管。授予 delete mutatingwebhookconfigurations 权限存在安全风险admissionController.certGen.enabledtrue使用 certgen Job 生成证书admissionController.certGen.image.repository/.tag/.pullPolicyregistry.k8s.io/ingress-nginx/kube-webhook-certgen/v20231011-8b53cabe0/IfNotPresentcertgen 镜像官方建议不改 pullPolicyadmissionController.certGen.env{}追加到 certgen 容器的环境变量格式为KEY: ValueadmissionController.certGen.resources{}certgen Pod 资源admissionController.certGen.podSecurityContextrunAsNonRoot: true, runAsUser: 65534, seccompProfile: {type: RuntimeDefault}certgen Pod 安全上下文admissionController.certGen.securityContextreadOnlyRootFilesystem: true, allowPrivilegeEscalation: false, capabilities.drop: [ALL]certgen 容器安全上下文admissionController.certGen.nodeSelector/tolerations/affinity{}/[]/{}certgen Job 调度定制admissionController.certManager.enabledfalse使用 cert-manager 管理证书生命周期需集群已安装 cert-manager与 certGen/registerWebhook/tls.create 互斥admissionController.certManager.issuerRef{group: cert-manager.io, kind: ClusterIssuer, name: }签发 Webhook 证书的已有 Issuer 引用createSelfSignedIssuer.enabled: false时必填admissionController.certManager.createSelfSignedIssuer{enabled: false, duration: 8760h, renewBefore: 720h}自动创建 namespaced SelfSigned Issuer 与中间 CA 的开关及生命周期参数admissionController.certManager.duration168hWebhook TLS 证书有效期admissionController.certManager.renewBefore24h证书到期前续期时间admissionController.certManager.privateKey{algorithm: RSA, size: 2048}证书私钥算法RSA/ECDSA/Ed25519与密钥大小Ed25519 忽略 sizeadmissionController.certManager.annotations{}添加到所有 cert-manager 资源的注解MutatingWebhookConfiguration 细节Key默认值说明admissionController.mutatingWebhookConfiguration.annotations{}附加注解admissionController.mutatingWebhookConfiguration.failurePolicyIgnoreWebhook 失败策略可选Ignore/Fail生产环境可按需改为Fail强制校验admissionController.mutatingWebhookConfiguration.namespaceSelector{}控制哪些命名空间的 Pod 受 Webhook 影响admissionController.mutatingWebhookConfiguration.objectSelector{}按对象标签如 Pod 标签过滤admissionController.mutatingWebhookConfiguration.timeoutSeconds5API Server 等待 Webhook 响应的超时时间模板 admission-controller-webhook.yaml 显示该 Webhook 的完整属性matchPolicy: Equivalent、reinvocationPolicy: Never、sideEffects: None且只有当certGen.enabled或certManager.enabled为 true 时才会创建即 Application-managed 模式下 Webhook 由应用自行注册Chart 不渲染。TLS Secret 与挂载Key默认值说明admissionController.tls.createfalse为 true 时由 Helm 内建能力生成证书并创建 Secret见 admission-controller-tls-secret.yaml包含ca/cert/key三个字段admissionController.tls.secretNamevpa-tls-certsTLS Secret 名称admissionController.tls.caCert/.cert/.keytls.create: true时使用的证书内容admissionController.service.namevpa-webhookWebhook Service 名称admissionController.service.ports443 → targetPort 8000 (TCP)Service 端口映射admissionController.volumes/volumeMountsSecretvpa-tls-certs的ca/cert/key映射为caCert.pem/serverCert.pem/serverKey.pem挂载至/etc/tls-certs只读证书卷配置cert-manager 模式下由 Chart 接管Admission Controller 的 Deploymentadmission-controller-deployment.yaml还内置了健康检查liveness 与 readiness 均探测/health-check端口 8944/prometheusinitialDelaySeconds: 5、periodSeconds: 10、failureThreshold: 3容器暴露 8000webhook与 8944metrics两个端口。6.3 recommender推荐器Key默认值说明recommender.enabledtrue是否部署 Recommenderrecommender.image.repositoryregistry.k8s.io/autoscaling/vpa-recommender镜像仓库tag 默认取 AppVersionrecommender.replicas2副本数recommender.logLevel4klog 日志级别recommender.extraArgs/extraEnv[]追加参数与环境变量recommender.resources{}资源限制注释示例limits cpu 200m / memory 1000Mirecommender.affinity基于component: recommender的 podAntiAffinityweight 100hostname默认跨节点分布recommender.nodeSelector/tolerations/podAnnotations/podLabels/priorityClassName{}/[]/{}/{}/nil调度与元数据recommender.podDisruptionBudgetenabled: true, minAvailable: 1同 Admission Controller 规则recommender.leaderElection.enablednil未设置null时若replicas 1自动启用选主多副本运行时保证同一时刻仅一个实例处理推荐计算recommender.leaderElection.resourceNamespaceLease 所在命名空间未设置默认用 Release 命名空间recommender.leaderElection.resourceNamevpa-recommender-leaseLease 资源名recommender.leaderElection.leaseDuration15s非 Leader 等待观测领导续期的时长recommender.leaderElection.renewDeadline10s当前 Leader 续期的间隔上限recommender.leaderElection.retryPeriod2s客户端尝试获取/续期领导的间隔模板 recommender-deployment.yaml 实现了智能自动选主逻辑当leaderElection.enabled为 nil 时通过gt (int .Values.recommender.replicas) 1判断副本数超过 1 即自动追加--leader-electtrue及配套参数无需手动配置。Recommender 暴露 8942 端口prometheus用于健康检查/health-check与指标采集。6.4 updater更新器Key默认值说明updater.enabledtrue是否部署 Updaterupdater.image.repositoryregistry.k8s.io/autoscaling/vpa-updater镜像仓库tag 默认取 AppVersionupdater.replicas2副本数updater.logLevel4klog 日志级别updater.extraArgs[--in-place-skip-disruption-budgettrue]默认追加参数启用原地更新时跳过 Disruption Budget 校验updater.extraEnv[]追加环境变量updater.resources{}资源限制注释示例limits cpu 200m / memory 500Miupdater.affinity基于component: updater的 podAntiAffinityweight 100hostname默认跨节点分布updater.nodeSelector/tolerations/podAnnotations/podLabels/priorityClassName{}/[]/{}/{}/nil调度与元数据updater.podDisruptionBudgetenabled: true, minAvailable: 1同前updater.leaderElection.*与 recommender 相同的默认结构resourceName 为vpa-updater-lease多副本选主配置同样支持自动启用三个组件的 Deployment 模板均引用了vertical-pod-autoscaler.component.selectorLabels等 helper见 templates/_helpers.tpl并统一注入NAMESPACE环境变量metadata.namespacefieldRef供组件感知自身命名空间。七、安装后验证与排障确认组件就绪kubectl -n vpa get deploy,svc,pdb kubectl -n vpa get pods -w确认 Webhook 与证书kubectl get mutatingwebhookconfiguration | grep vpa kubectl -n vpa get secret vpa-tls-certs若为 Application-managed 模式且 Secret 创建于安装之后需重启 Admission Controllerkubectl rollout restart deployment/vpa-admission-controller -n vpa。确认 CRD 版本升级 Chart 后检查verticalpodautoscalers.autoscaling.k8s.io是否仍为期望版本若否按第四节手动升级 CRD。模式自检helm upgrade输出NOTES会明确提示当前 Webhook 模式若出现未配置任何 TLS 证书来源的警告说明三种模式均未启用Admission Controller 可能无法启动需按 NOTES.txt 提示补配certGen.enabled、tls.create、registerWebhook、certManager.enabled之一。八、总结模式选型建议常规生产部署优先使用默认的 Helm-managedcertgen模式证书自动生成、自动注入 CA全程无需手动干预已有 cert-manager 基础设施的团队选用 cert-manager 模式证书自动续期更符合长期运行需求配合createSelfSignedIssuer可完全自举需要最大程度控制 Webhook 注册逻辑的场景选用 Application-managed 模式但必须接受自行管理 TLS Secret 与额外的 RBAC 安全风险无论选择哪种模式都应在升级 Chart 后检查 CRD 是否需要手动升级并依据 values.yaml 中的参数说明结合集群容量为三个组件设置合理的resources与 PDB 策略。本文所有结论均可在仓库对应文件中验证Chart 元数据见 Chart.yaml默认参数见 values.yamlWebhook/证书/部署逻辑见 templates 目录 下的模板文件CRD 清单见 crds/vpa-v1-crd-gen.yaml。【免费下载链接】autoscalerAutoscaling components for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/au/autoscaler创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进