Goldilocks 资源推荐权威手册
Goldilocks 把 VPA recommendation 汇总成便于审核的容器级资源建议,但不会自动判断生产 request 是否安全。简单下调 request 可能把静态预留转化为启动长尾、CPU 竞争、HPA 提前扩容与节点供给抖动;仪表盘上的 target 只是模型输出,不是容量承诺。
建议对象还会同时包含业务容器、service mesh sidecar、短期异常样本和历史不足的 VPA。每项 recommendation 都要结合业务峰值、SLO、HPA 耦合、发布余量与中断风险复核。Goldilocks 负责提高建议的可读性,生产字段仍应由明确的 owner 和变更流程控制。
Goldilocks 展示建议,VPA 才生成 recommendation
Goldilocks 不是独立的自动扩缩器。它的 controller 为选择的工作负载创建或维护 VerticalPodAutoscaler 对象,dashboard 读取这些对象的 recommendation 并提供适合审核的视图。默认思路是让 VPA 保持 Off,只输出建议,不自动驱逐或修改生产 Pod。Goldilocks 当前稳定应用发行线为 v4.15.1;VPA 当前正式版为 1.7.0,API 使用 autoscaling.k8s.io/v1。实施时仍应锁定镜像摘要与 chart 版本,并在升级前核对目标 Kubernetes 兼容性。
运行链路可以拆成五步:工作负载声明 requests;kubelet 与指标流水线产生资源使用样本;VPA Recommender 聚合容器历史并写入 VPA status.recommendation;Goldilocks controller 发现已启用命名空间并管理 VPA;dashboard 读取推荐。任何一段缺失,页面都可能空白或陈旧。
官方的 Goldilocks 安装说明给出 Helm 与组件配置入口,Goldilocks FAQ解释了常见推荐与工作负载行为,VPA Quick Start则展示 VPA 对象和 recommendation 的真实字段。遇到版本行为差异时,应先查看锁定发行版的文档,而不是从仪表盘颜色猜测含义。
安装前先确认指标、CRD 与读取权限
实验至少需要一个非生产 Kubernetes 集群、可工作的资源指标流水线、Helm、创建 CRD 和集群级 RBAC 的管理员,以及一个只供实验使用的命名空间。VPA 安装会增加 CRD、Recommender、Updater 和 Admission Controller 等组件;Goldilocks 会增加 controller、dashboard、Service 和 RBAC。即使只做 recommendation,也不能把这些组件当作零成本页面。
先检查已有安装,避免两个 release 同时写同一类 VPA:
kubectl version
helm version
kubectl api-resources | grep -i verticalpodautoscaler
kubectl get deployment -A | grep -E 'vpa-|goldilocks'
kubectl top nodes
kubectl auth can-i create customresourcedefinitions.apiextensions.k8s.io
kubectl auth can-i create clusterroles.rbac.authorization.k8s.iokubectl top 成功只证明 Resource Metrics API 的当前样本可读,不证明 VPA 已有足够推荐历史。若 VPA 已由平台统一提供,应用团队不应再安装第二套;只需让 Goldilocks 连接受支持的 VPA API。生产环境的 CRD、ClusterRole 与 webhook 变更应由平台 owner 审核,业务账号只获得指定命名空间的 VPA 只读权限。
VPA 1.7.0 的 Auto 模式已弃用,应显式选择 Off、Initial、Recreate、InPlaceOrRecreate 或 InPlace。Goldilocks 做审核时使用 Off 最容易保持字段所有权清晰;它也不兼容 Kubernetes Pod 级 spec.resources,若集群使用该能力,必须先通过VPA 发行说明核对限制。
用锁定版本安装 VPA 与 Goldilocks
先从组织允许的来源取得 VPA 1.7.0 清单或制品,审查 CRD、webhook、镜像与 RBAC 后安装。官方仓库提供按 tag 固定的部署入口;生产环境应镜像到受控仓库并锁定摘要。安装后验证 API 与三个核心组件,而不是只看 Helm release:
kubectl get crd verticalpodautoscalers.autoscaling.k8s.io
kubectl api-resources --api-group=autoscaling.k8s.io
kubectl get deploy -n kube-system | grep vpa
kubectl get pods -n kube-system | grep vpaGoldilocks 官方 chart 仓库可按下面方式加入。chart 版本与应用版本不是同一个编号,先搜索并选择 APP VERSION 为 4.15.1 的 chart,把解析出的 chart 版本写进环境锁定文件,再安装:
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm repo update fairwinds-stable
helm search repo fairwinds-stable/goldilocks --versions
helm upgrade --install goldilocks fairwinds-stable/goldilocks \
--namespace goldilocks --create-namespace \
--version <approved-chart-version> \
--set controller.enabled=true \
--set dashboard.enabled=true \
--wait --timeout 5m预期看到 controller 与 dashboard Deployment Available,Service 存在,controller 日志没有 VPA discovery、RBAC 或 webhook 错误:
helm status goldilocks -n goldilocks
kubectl get deploy,pod,svc -n goldilocks
kubectl logs -n goldilocks deploy/goldilocks-controller --tail=100安装命令中的组件键以锁定 chart 的 values 为准,升级前应执行 helm show values fairwinds-stable/goldilocks --version <approved-chart-version> 并纳入评审。公网仓库不可达时,使用已校验的内部 OCI/chart 镜像,不应临时关闭 TLS 验证。
命名空间标签决定哪些工作负载进入观察
Goldilocks 通常通过命名空间标签 goldilocks.fairwinds.com/enabled=true 发现工作负载。这个字段会扩大 controller 创建 VPA 和 dashboard 展示容量事实的范围;给全体命名空间批量打标,既增加 Recommender 计算与 API 对象数量,也可能把敏感工作负载名称和 requests 暴露给页面访问者。
先建立小范围实验:
kubectl create namespace rightsizing-lab
kubectl label namespace rightsizing-lab goldilocks.fairwinds.com/enabled=true
kubectl get namespace rightsizing-lab --show-labels创建一个稳定、可持续产生轻量 CPU 与内存使用的 Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: steady-worker
namespace: rightsizing-lab
spec:
replicas: 2
selector:
matchLabels: {app: steady-worker}
template:
metadata:
labels: {app: steady-worker}
spec:
containers:
- name: worker
image: registry.k8s.io/e2e-test-images/resource-consumer:1.13
args: ["-port", "8080", "-consume-cpu", "20", "-consume-mem", "32"]
ports:
- containerPort: 8080
resources:
requests: {cpu: 100m, memory: 96Mi}
limits: {cpu: 500m, memory: 256Mi}kubectl apply -f steady-worker.yaml
kubectl rollout status deployment/steady-worker -n rightsizing-lab --timeout=120s
kubectl get vpa -n rightsizing-lab镜像参数属于实验发行版接口,受限网络应先同步到内部仓库。若镜像拉取失败,Pod 已经调度但不 Ready,这不是 Goldilocks 或 VPA 推荐故障;应先修复镜像来源,再开始累计样本。
recommendation 四组数值必须按容器解释
VPA recommendation 位于状态而不是 spec。每个容器分别给出 lowerBound、target、upperBound 与 uncappedTarget:
kubectl get vpa -n rightsizing-lab -o yaml
kubectl get vpa -n rightsizing-lab \
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{range .status.recommendation.containerRecommendations[*]} {.containerName}{" target="}{.target}{" lower="}{.lowerBound}{" upper="}{.upperBound}{" uncapped="}{.uncappedTarget}{"\n"}{end}{end}'target 是 Recommender 在当前策略与边界下建议的 request;lowerBound 与 upperBound 是推荐区间信号,不是 guaranteed QoS 或硬性安全上下限;uncappedTarget 展示未受 VPA policy 上限约束的目标。当 uncappedTarget 明显高于 target,说明策略上限正在截断建议,不能把较低 target 当作负载天然只需要这么多资源。
推荐按容器拆分,所以 sidecar、代理、日志 agent 都会独立出现。业务容器的峰值模式与 sidecar 的连接数、配置推送或证书轮换峰值不同,不能把所有容器按同一个比例缩放。初始化容器、短任务和生命周期不稳定的工作负载也要单独判断;仪表盘中的总量适合发现候选对象,真正变更必须回到容器字段。
VPA policy 可以通过 resourcePolicy.containerPolicies 约束受控资源、最小值、最大值和容器模式。字段改变会直接改变 recommendation 的裁剪结果。使用 policy 时,应把“为什么设置边界、谁批准、何时复审”留在配置评审记录中,避免永久上限把业务增长隐藏掉。
正向实验:从建议产生到审核候选
等待多个采样周期后,检查 Deployment 使用、VPA 状态、controller 日志与 dashboard。页面可通过本地端口转发访问,不要默认创建公网 LoadBalancer 或匿名 Ingress:
kubectl top pod -n rightsizing-lab --containers
kubectl get vpa -n rightsizing-lab -o yaml
kubectl logs -n goldilocks deploy/goldilocks-controller --tail=100
kubectl port-forward -n goldilocks svc/goldilocks-dashboard 8080:80预期结果不是某个固定 request,而是 steady-worker 对应的 VPA 出现非空 status.recommendation.containerRecommendations,其中 containerName=worker 与真实容器一致;Goldilocks 页面展示同一对象,且 controller 无持续 reconcile 错误。推荐值受样本历史、负载和发行版算法影响,文章中的演示负载不能转换成生产阈值。
把建议转成审核候选时,先记录原 request、target、区间、负载版本、样本窗口内的吞吐与延迟,再在 Git 中只改一个工作负载。比如 target 比当前 request 低很多,也不要一步降到 target;选择一个保留发布与冷启动余量的候选值,在预发布或少量副本上验证。通过 kubectl diff 或 GitOps diff 确认只改变目标容器的 requests:
kubectl get deployment steady-worker -n rightsizing-lab -o yaml
kubectl diff -f steady-worker-candidate.yaml
kubectl apply -f steady-worker-candidate.yaml
kubectl rollout status deployment/steady-worker -n rightsizing-lab --timeout=120s
kubectl top pod -n rightsizing-lab --containers验收应观察一段具有代表性的业务周期:Pod Ready 长尾不恶化,CPU throttling、OOM、重启、延迟和错误率不增长,HPA 与节点伸缩没有异常放大,VPA target 不因样本不足持续单向漂移。生产阈值由 SLO、压测、历史峰值与容量预算决定。
反向实验:用短时尖峰暴露自动照抄的风险
对实验容器制造短时 CPU 峰值,再观察即时使用与 VPA recommendation 的变化。资源消费者镜像支持通过 HTTP 请求改变消耗;先转发端口,然后发送受控请求,具体接口以镜像发行版为准:
kubectl port-forward -n rightsizing-lab deploy/steady-worker 18080:8080
curl -X POST 'http://localhost:18080/ConsumeCPU' -d 'millicores=350&durationSec=120'
kubectl top pod -n rightsizing-lab --containers
kubectl get vpa -n rightsizing-lab -o yaml若镜像接口与锁定版本不同,可以改用组织已有的压测工作负载;关键是同时保存峰值开始、结束和推荐变化的相对时间线。预期现象是 kubectl top 较快看到使用变化,而 VPA recommendation 经过聚合后才变化,且不会等同于某一瞬时值。短峰若反复出现,target 或 upperBound 可能上移;只有一次异常并不自动等于长期 request 应提升。
更危险的反例是把 VPA 更新模式切成会修改 Pod 的模式,再与 HPA 同时基于 CPU 利用率运行。VPA 改小 CPU request 后,即使 CPU 使用量不变,usage/request 也会升高,HPA 可能扩副本;两条控制环互相影响。实验不需要真的在生产启用,只要检查对象所有权即可:
kubectl get hpa -n rightsizing-lab
kubectl get vpa -n rightsizing-lab -o jsonpath='{range .items[*]}{.metadata.name}{" mode="}{.spec.updatePolicy.updateMode}{"\n"}{end}'发现 HPA 使用 CPU/内存利用率时,VPA 应保持 Off,或明确排除 HPA 所依赖的资源维度。任何自动更新模式都需要单独评估驱逐、原地调整支持、PDB、启动时间和回滚路径,不能由 Goldilocks 页面按钮替代架构决策。
样本不足、异常峰值和 sidecar 要分别审查
新部署、低频任务和周期性批作业最容易产生“看起来很精确”的不可靠建议。推荐对象存在不代表样本覆盖了周峰、发布峰、缓存冷启动、故障恢复或批处理窗口。审核时应把 recommendation 与工作负载版本、replicas、吞吐、延迟、重启、HPA、节点类型放在同一时间线上。
建议长期不出现时,按链路分层:
kubectl top pod -n rightsizing-lab --containers
kubectl get vpa -n rightsizing-lab -o yaml
kubectl logs -n kube-system deploy/vpa-recommender --tail=200
kubectl logs -n goldilocks deploy/goldilocks-controller --tail=200
kubectl get events -n rightsizing-lab --sort-by=.metadata.creationTimestampMetrics API 不可用、VPA Recommender 无法读取历史、selector 没有匹配 Pod、容器刚改名、RBAC 拒绝、Goldilocks 未发现标签命名空间,都会造成不同失败。先确认 VPA status 是否为空:status 有推荐而 dashboard 没有,是 Goldilocks 展示或读取路径;status 本身为空,则应回到 VPA 与指标链路。
sidecar 必须单独建立责任。service mesh 代理的资源可能随连接数和遥测配置增长,日志 agent 可能随日志风暴增长。应用 owner 不能擅自把平台 sidecar request 改小,平台 owner 也不能用 sidecar 总量掩盖业务容器浪费。建议导出时保留 containerName,并为注入容器建立独立策略和升级复测。
推荐写回会同时影响调度、HPA 与节点成本
requests 是多个控制环共享的事实。调低 CPU 或内存 request,单个节点表面可容纳更多 Pod,但更容易发生运行时争用;HPA 的资源利用率分母会改变;Cluster Autoscaler 或 Karpenter 看到的待调度需求也会改变。调高 request 则可能改善隔离,却增加 Pending、节点数和碎片。
因此 rightsizing 的成本不能只看“request 降低多少”。至少同时比较:工作负载可用副本、节点数与实例类型、空闲碎片、扩缩容次数、启动长尾、CPU throttling、OOM/eviction、HPA 副本曲线以及真实业务 SLO。Goldilocks dashboard 本身还会增加 API list/watch、VPA 对象、Recommender 内存与遥测存储成本;大集群应分批启用命名空间,观察控制器队列、API 限流和推荐延迟。
对于稳定在线服务,Goldilocks 适合持续发现明显 over-request 或 under-request 的候选项;对于短时 Job、强周期业务、GPU/扩展资源、需要 Pod 级资源语义或极端峰值保护的工作负载,单靠历史推荐不足。批任务还可能更适合队列与配额治理;Goldilocks 不决定作业何时准入,也不负责 Pod 放置。
Dashboard 是敏感容量入口,不应匿名暴露
Goldilocks 页面会显示 namespace、workload、container、当前 requests 与建议区间,这些信息能够推断业务拓扑、规模和容量弱点。默认使用 kubectl port-forward 做受控访问;需要团队共享时,应放在已有身份代理后,限制 namespace 读取范围,启用访问日志和会话过期,不直接开放公网 Service。
controller 通常需要跨命名空间观察 workload 并管理 VPA,dashboard 需要读取 VPA 与工作负载。安装后审查实际 ClusterRole,而不是假设 chart 已经最小化:
kubectl get clusterrole,clusterrolebinding | grep goldilocks
kubectl describe clusterrole <goldilocks-controller-role>
kubectl auth can-i list verticalpodautoscalers.autoscaling.k8s.io \
--as=system:serviceaccount:goldilocks:<dashboard-service-account> --all-namespaces若使用外部身份代理,客户端 Secret、TLS 私钥和 OIDC 配置进入现有密钥系统,按服务账号轮换,不写进 values 文件或提示词。卸载时不仅删除 Pod,还要撤销 ClusterRoleBinding、Ingress/DNS、证书、监控抓取和临时管理员凭证。审计应能回答谁查看了哪些容量数据、谁批准了 request 变更、变更对应哪次压测和回滚。
从人工建议走向自动更新要设置更高门槛
最稳妥的起点是 Goldilocks + VPA Off + Git 审核:推荐只产生候选,资源字段仍由应用仓库的单一 owner 写入。团队成熟后,可以对启动成本低、无 HPA 资源利用率耦合、PDB 与回滚完善的工作负载评估 Initial、Recreate、InPlaceOrRecreate 或 InPlace。不同模式改变的是何时、以何种中断语义应用推荐,不能统一开启。
自动化若把 dashboard recommendation 直接生成 PR,也必须保留策略:样本年龄、最小变化幅度、单次变化上限、容器白名单、发布冻结、SLO 回归、双人审核与自动回滚。PR 机器人只能写指定 requests 字段,不能同时控制 replicas、limits、HPA target 或 VPA update mode。推荐缺失或异常时应 fail closed,不生成“清空 request”的变更。
长期 owner 至少分三层:应用团队对业务峰值、SLO 和最终 request 负责;平台团队对 VPA/Goldilocks 版本、RBAC、性能和策略模板负责;FinOps 或容量团队用成本事实提出候选,但不越权批准可靠性风险。没有人对建议正确性承担责任时,仪表盘越漂亮,批量误改反而越快。
升级、回退与安全卸载要按依赖逆序执行
升级前导出 Helm values、VPA CRD schema、现有 VPA 对象、RBAC 与镜像摘要,在隔离命名空间验证新版本能读取旧 recommendation,controller 不会批量重建或删除非本 release 的 VPA。Goldilocks、chart 和 VPA 是三条版本线,不能只升级页面;先升级 CRD 所需兼容项,再升级 VPA 组件,最后升级 Goldilocks,并在每一步比较对象数量、recommendation 非空比例和 reconcile 错误。
若新版本推荐明显漂移,先停止把建议写回 Git,冻结命名空间扩展,回退 Goldilocks 或 VPA 组件;不要立即删除 CRD,因为删除 CRD 会连同所有 VPA 自定义资源一起删除。回退后确认旧组件能读取保留对象,dashboard 与 kubectl get vpa 一致,再恢复审核流程。
完全退出时,先移除命名空间启用标签,确认 Goldilocks 不再创建新对象;保留一段只读观察窗口并导出必要的审核记录;然后卸载 Goldilocks,删除由它拥有且已确认无其他消费者的 VPA,再卸载 VPA 组件。CRD 只有在集群中没有其他 VPA 使用者、对象已核对、回滚窗口结束后才可删除。
kubectl label namespace rightsizing-lab goldilocks.fairwinds.com/enabled-
kubectl get vpa -A
helm uninstall goldilocks -n goldilocks
kubectl delete namespace goldilocks --wait=trueVPA 的卸载命令取决于组织采用的安装方式,应执行对应锁定发行版的卸载流程,并复核 webhook configuration、CRD、ClusterRoleBinding 与 API discovery 残留。强行删除 namespace 或 CRD 可能留下 webhook 故障或误删其他团队对象。
清理实验并把 recommendation 变成可审计证据
实验结束先删除工作负载和 VPA,再移除标签与命名空间;如果集群中的 Goldilocks/VPA 是共享平台,不卸载共享组件:
kubectl delete deployment steady-worker -n rightsizing-lab --wait=true
kubectl delete vpa --all -n rightsizing-lab
kubectl label namespace rightsizing-lab goldilocks.fairwinds.com/enabled-
kubectl delete namespace rightsizing-lab --wait=true
kubectl get vpa -A同时停止 port-forward,删除临时 YAML、导出的容量数据和测试镜像缓存;若实验创建了 LoadBalancer、Ingress、证书或额外节点,逐项核销。推荐历史与截图同样属于敏感容量记录,应按审计需求设保留期,不长期散落在工单和聊天工具里。
成熟的治理记录不会只保存“Goldilocks 建议 200m”。它会关联工作负载 revision、容器名、原 request、四组 recommendation、样本覆盖、峰值解释、候选值、压测与灰度证据、HPA/节点影响、批准人和回滚值。这样 recommendation 才从一张易读页面变成可以复核、可以拒绝、也可以安全撤销的工程证据。
