<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>HPA on 文艺技术笔记</title><link>https://wenyiblog.top/tags/hpa/</link><description>Recent content in HPA on 文艺技术笔记</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>文艺技术笔记 | 软件工程师文艺</copyright><lastBuildDate>Fri, 19 Jun 2026 22:30:00 +0800</lastBuildDate><atom:link href="https://wenyiblog.top/tags/hpa/index.xml" rel="self" type="application/rss+xml"/><item><title>Kubernetes 垂直扩展（VPA）深度解读：Pod 资源动态调整终于来了</title><link>https://wenyiblog.top/2026/06/k8s-vpa-vertical-scaling/</link><pubDate>Fri, 19 Jun 2026 22:30:00 +0800</pubDate><guid>https://wenyiblog.top/2026/06/k8s-vpa-vertical-scaling/</guid><description>&lt;h2 id="hpa-解决了水平扩展但垂直扩展一直是痛点"&gt;&lt;a href="#hpa-%e8%a7%a3%e5%86%b3%e4%ba%86%e6%b0%b4%e5%b9%b3%e6%89%a9%e5%b1%95%e4%bd%86%e5%9e%82%e7%9b%b4%e6%89%a9%e5%b1%95%e4%b8%80%e7%9b%b4%e6%98%af%e7%97%9b%e7%82%b9" class="header-anchor"&gt;&lt;/a&gt;HPA 解决了水平扩展，但垂直扩展一直是痛点
&lt;/h2&gt;&lt;p&gt;做过 K8s 运维的人都有体感：&lt;strong&gt;大多数性能问题不是靠加 Pod 能解决的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;水平扩展（HPA）解决的是&amp;quot;请求量大了，多开几个 Pod 分担&amp;quot;的问题。但对于单线程计算密集型任务、大内存缓存服务、数据库连接池这类场景，瓶颈不在请求并发量，而在&lt;strong&gt;单个 Pod 的 CPU 和内存不够用&lt;/strong&gt;。这时候你需要的是垂直扩展——给现有的 Pod 分配更多的 CPU 或内存。&lt;/p&gt;
&lt;p&gt;长期以来，K8s 对垂直扩展的支持一直是个半成品。VPA（Vertical Pod Autoscaler）作为 incubator 项目存在了好几年，但生产环境中用的人不多，原因有几个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VPA 调整资源需要重启 Pod（修改 requests/limits 必须重建容器）&lt;/li&gt;
&lt;li&gt;跟 HPA 同时使用可能冲突（一个调副本数，一个调资源量）&lt;/li&gt;
&lt;li&gt;推荐值更新有延迟，不能应对突发流量&lt;/li&gt;
&lt;li&gt;社区关注度远不如 HPA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但 K8s 1.35 带来了重要变化——**In-place Pod Vertical Scaling（原地垂直扩展）**进入了 Beta 阶段。这个特性允许在不重启容器的情况下动态调整 Pod 的 CPU 和内存资源。虽然 VPA 本身还不是 K8s 内置组件，但这个底层能力的成熟意味着垂直扩展终于可以在生产环境中认真使用了。&lt;/p&gt;
&lt;h2 id="vpa-vs-hpa不是替代关系是互补关系"&gt;&lt;a href="#vpa-vs-hpa%e4%b8%8d%e6%98%af%e6%9b%bf%e4%bb%a3%e5%85%b3%e7%b3%bb%e6%98%af%e4%ba%92%e8%a1%a5%e5%85%b3%e7%b3%bb" class="header-anchor"&gt;&lt;/a&gt;VPA vs HPA：不是替代关系，是互补关系
&lt;/h2&gt;&lt;p&gt;先把两个概念的区别理清楚，很多人搞混了。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;维度&lt;/th&gt;
&lt;th&gt;HPA（水平扩展）&lt;/th&gt;
&lt;th&gt;VPA（垂直扩展）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;扩展方向&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;增减 Pod 副本数&lt;/td&gt;
&lt;td&gt;调整单个 Pod 的 CPU/内存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;触发条件&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CPU/内存利用率、自定义指标&lt;/td&gt;
&lt;td&gt;历史资源使用数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;生效方式&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;创建/销毁 Pod（秒级）&lt;/td&gt;
&lt;td&gt;需要重启 Pod（Off 模式）或原地调整（In-place）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适用场景&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;无状态服务、可水平扩展的服务&lt;/td&gt;
&lt;td&gt;单线程任务、大内存缓存、数据库&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;对业务影响&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;新 Pod 需要启动和预热时间&lt;/td&gt;
&lt;td&gt;重启模式有短暂中断，原地模式几乎无感&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;资源效率&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;可能产生资源碎片&lt;/td&gt;
&lt;td&gt;精确匹配实际需求&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;配置复杂度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;中（需要调优推荐算法参数）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;核心原则：能用 HPA 的场景优先用 HPA，VPA 解决的是 HPA 解决不了的问题。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;典型的 VPA 适用场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;批处理任务&lt;/strong&gt;：一个 Pod 跑一个大数据处理 Job，CPU 需求波动大，但不能水平扩展（任务不可拆分）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存密集型服务&lt;/strong&gt;：Redis 集群的单个节点、Elasticsearch 的单个分片、Java 应用的 JVM 堆&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开发/测试环境&lt;/strong&gt;：不想为每个服务手动调资源，让 VPA 自动推荐合适的 requests/limits&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;资源浪费严重的集群&lt;/strong&gt;：大量 Pod 的 requests 设得过高（怕 OOM），实际使用率不到 30%&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vpa-的工作原理"&gt;&lt;a href="#vpa-%e7%9a%84%e5%b7%a5%e4%bd%9c%e5%8e%9f%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;VPA 的工作原理
&lt;/h2&gt;&lt;p&gt;VPA 由三个组件组成：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Recommender（推荐器）&lt;/strong&gt;
监控 Pod 的历史资源使用数据（从 Metrics Server 获取），基于统计算法计算推荐的 CPU/内存值。核心算法考虑了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;历史使用量的分位数（默认取 95% 分位数作为推荐值）&lt;/li&gt;
&lt;li&gt;使用趋势（增长/稳定/下降）&lt;/li&gt;
&lt;li&gt;最小资源限制（避免推荐过低的值）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. Updater（更新器）&lt;/strong&gt;
检查当前 Pod 的资源配置和 Recommender 的推荐值之间的差异。如果差异超过阈值，标记 Pod 需要更新。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Admission Controller（准入控制器）&lt;/strong&gt;
当 Pod 被重建时（由 Updater 触发或正常滚动更新），拦截 Pod 创建请求，自动将 resources.requests 修改为 Recommender 的推荐值。&lt;/p&gt;
&lt;p&gt;这三个组件的协作流程：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Metrics Server → Recommender（计算推荐值）→ Updater（检测差异）→ 标记 Pod 需要更新 → Pod 重建时 → Admission Controller（注入推荐值）
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;注意一个关键点：&lt;strong&gt;在 Off 和 Auto 模式下，VPA 需要 Pod 重启才能生效。&lt;/strong&gt; 这是 VPA 在生产环境中被吐槽最多的地方。In-place 扩展解决了这个问题，但目前还在 Beta 阶段。&lt;/p&gt;
&lt;h2 id="vpa-的三种模式"&gt;&lt;a href="#vpa-%e7%9a%84%e4%b8%89%e7%a7%8d%e6%a8%a1%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;VPA 的三种模式
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;行为&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Off&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;只计算推荐值，不自动执行&lt;/td&gt;
&lt;td&gt;资源规划、容量评估&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;仅在 Pod 首次创建时注入推荐值&lt;/td&gt;
&lt;td&gt;不希望运行时被中断的服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auto&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;自动更新 Pod 资源（通过重建）&lt;/td&gt;
&lt;td&gt;可以容忍短暂中断的服务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;生产环境中，&lt;strong&gt;Off 模式用得最多&lt;/strong&gt;。原因是：你让 VPA 算出推荐值，然后人工审核后手动调整，比让 VPA 自动重启你的 Pod 安全得多。&lt;/p&gt;
&lt;h2 id="配置实操"&gt;&lt;a href="#%e9%85%8d%e7%bd%ae%e5%ae%9e%e6%93%8d" class="header-anchor"&gt;&lt;/a&gt;配置实操
&lt;/h2&gt;&lt;h3 id="安装-vpa"&gt;&lt;a href="#%e5%ae%89%e8%a3%85-vpa" class="header-anchor"&gt;&lt;/a&gt;安装 VPA
&lt;/h3&gt;&lt;p&gt;VPA 不是 K8s 内置组件，需要单独安装：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 克隆 VPA 仓库&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/kubernetes/autoscaler.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; autoscaler/vertical-pod-autoscaler
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 安装（会自动创建 namespace、部署三个组件）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./hack/vpa-up.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;安装完成后验证：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get pods -n kube-system &lt;span class="p"&gt;|&lt;/span&gt; grep vpa
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 应该看到 vpa-recommender、vpa-updater、vpa-admission-controller 三个 Pod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="创建-vpa-资源"&gt;&lt;a href="#%e5%88%9b%e5%bb%ba-vpa-%e8%b5%84%e6%ba%90" class="header-anchor"&gt;&lt;/a&gt;创建 VPA 资源
&lt;/h3&gt;&lt;p&gt;以一个 Java Web 服务为例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;autoscaling.k8s.io/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;VerticalPodAutoscaler&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service-vpa&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;production&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;targetRef&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;apps/v1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Deployment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;updatePolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;updateMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Off&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 只推荐，不自动执行&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;resourcePolicy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerPolicies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;minAllowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;100m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;256Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;maxAllowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;8Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controlledResources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cpu&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;memory&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;controlledValues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;RequestsAndLimits&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;关键参数解释：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;updateMode: &amp;ldquo;Off&amp;rdquo;&lt;/strong&gt;：只计算推荐值，不自动重启 Pod。生产环境建议先用 Off 模式观察一段时间。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;minAllowed / maxAllowed&lt;/strong&gt;：推荐值的上下限。防止 VPA 推荐过低的值导致 OOM，或推荐过高的值浪费资源。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;controlledResources&lt;/strong&gt;：控制哪些资源类型。如果只想让 VPA 调 CPU 不动内存，设为 &lt;code&gt;[&amp;quot;cpu&amp;quot;]&lt;/code&gt; 即可。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;controlledValues&lt;/strong&gt;：&lt;code&gt;RequestsAndLimits&lt;/code&gt; 表示同时调整 requests 和 limits，&lt;code&gt;RequestsOnly&lt;/code&gt; 只调整 requests。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="查看推荐值"&gt;&lt;a href="#%e6%9f%a5%e7%9c%8b%e6%8e%a8%e8%8d%90%e5%80%bc" class="header-anchor"&gt;&lt;/a&gt;查看推荐值
&lt;/h3&gt;&lt;p&gt;VPA 创建后，Recommender 需要几分钟收集数据才会给出推荐值：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get vpa order-service-vpa -n production -o yaml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在 status 里会看到类似这样的输出：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;recommendation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;containerRecommendations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;containerName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-service&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;lowerBound&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;200m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;512Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;500m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;1Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;upperBound&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;800m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;2Gi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uncappedTarget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;cpu&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;450m&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;900Mi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;target&lt;/strong&gt;：推荐的目标值（考虑了 minAllowed/maxAllowed 约束）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lowerBound&lt;/strong&gt;：资源使用量的下界（低于这个值服务可能不稳定）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;upperBound&lt;/strong&gt;：资源使用量的上界（历史峰值加上安全余量）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;uncappedTarget&lt;/strong&gt;：不考虑约束的原始推荐值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根据这些推荐值，你可以手动调整 Deployment 的 resources 配置。&lt;/p&gt;
&lt;h2 id="in-place-垂直扩展不重启容器就能调资源"&gt;&lt;a href="#in-place-%e5%9e%82%e7%9b%b4%e6%89%a9%e5%b1%95%e4%b8%8d%e9%87%8d%e5%90%af%e5%ae%b9%e5%99%a8%e5%b0%b1%e8%83%bd%e8%b0%83%e8%b5%84%e6%ba%90" class="header-anchor"&gt;&lt;/a&gt;In-place 垂直扩展：不重启容器就能调资源
&lt;/h2&gt;&lt;p&gt;K8s 1.35 的 In-place Pod Vertical Scaling 是一个底层能力突破。它允许通过 &lt;code&gt;kubectl patch&lt;/code&gt; 直接修改运行中 Pod 的资源配置，而不需要重建容器。&lt;/p&gt;
&lt;p&gt;使用方式：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 原地调整 Pod 的 CPU 和内存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl patch pod order-service-abc123 --subresource&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;resize&amp;#39;&lt;/span&gt; --type&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;merge&amp;#39;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -p &lt;span class="s1"&gt;&amp;#39;{&amp;#34;spec&amp;#34;:{&amp;#34;containers&amp;#34;:[{&amp;#34;name&amp;#34;:&amp;#34;order-service&amp;#34;,&amp;#34;resources&amp;#34;:{&amp;#34;requests&amp;#34;:{&amp;#34;cpu&amp;#34;:&amp;#34;500m&amp;#34;,&amp;#34;memory&amp;#34;:&amp;#34;1Gi&amp;#34;}}}]}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;限制条件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CPU 可以原地调整&lt;/strong&gt;，因为 CFS（Completely Fair Scheduler）支持动态修改 CPU 配额&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内存原地调整有限制&lt;/strong&gt;：只能调整 requests（用于调度决策），limits 的修改可能仍需要重启（因为涉及 cgroup 内存限制）&lt;/li&gt;
&lt;li&gt;需要 kubelet 和容器运行时支持（containerd 1.7+ 已支持）&lt;/li&gt;
&lt;li&gt;需要开启 &lt;code&gt;InPlacePodVerticalScaling&lt;/code&gt; feature gate&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;In-place 扩展和 VPA 的结合&lt;/strong&gt;：理论上，未来的 VPA 可以利用 In-place 能力来避免 Pod 重启。但目前 VPA 还没有内置对 In-place 的支持，需要等后续版本。&lt;/p&gt;
&lt;h2 id="生产环境的注意事项"&gt;&lt;a href="#%e7%94%9f%e4%ba%a7%e7%8e%af%e5%a2%83%e7%9a%84%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9" class="header-anchor"&gt;&lt;/a&gt;生产环境的注意事项
&lt;/h2&gt;&lt;h3 id="vpa-和-hpa-不能同时用在同一个指标上"&gt;&lt;a href="#vpa-%e5%92%8c-hpa-%e4%b8%8d%e8%83%bd%e5%90%8c%e6%97%b6%e7%94%a8%e5%9c%a8%e5%90%8c%e4%b8%80%e4%b8%aa%e6%8c%87%e6%a0%87%e4%b8%8a" class="header-anchor"&gt;&lt;/a&gt;VPA 和 HPA 不能同时用在同一个指标上
&lt;/h3&gt;&lt;p&gt;如果 HPA 基于 CPU 利用率扩展副本数，VPA 也在调整 CPU requests，两者会互相干扰。VPA 调大了 requests，CPU 利用率下降，HPA 缩容；HPA 缩容后单 Pod 负载上升，VPA 又调大 requests……形成振荡。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VPA 和 HPA 使用不同的指标维度（VPA 管内存，HPA 管 CPU 副本数）&lt;/li&gt;
&lt;li&gt;或者 VPA 用 Off 模式，只做资源规划参考&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="java-应用的特殊处理"&gt;&lt;a href="#java-%e5%ba%94%e7%94%a8%e7%9a%84%e7%89%b9%e6%ae%8a%e5%a4%84%e7%90%86" class="header-anchor"&gt;&lt;/a&gt;Java 应用的特殊处理
&lt;/h3&gt;&lt;p&gt;Java 应用的 JVM 堆大小是启动时确定的，VPA 调整了 Pod 的内存 limits 但 JVM 不知道。如果 VPA 推荐了更大的内存但 JVM 堆没变，等于白调。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;-XX:+UseContainerSupport&lt;/code&gt;（JDK 8u191+），JVM 会自动感知容器的内存限制&lt;/li&gt;
&lt;li&gt;配合 &lt;code&gt;-XX:MaxRAMPercentage=75.0&lt;/code&gt;，让 JVM 堆占容器内存的 75%&lt;/li&gt;
&lt;li&gt;VPA 调整内存后需要重启 Pod 才能生效（除非 In-place 成熟）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="不要对关键服务开-auto-模式"&gt;&lt;a href="#%e4%b8%8d%e8%a6%81%e5%af%b9%e5%85%b3%e9%94%ae%e6%9c%8d%e5%8a%a1%e5%bc%80-auto-%e6%a8%a1%e5%bc%8f" class="header-anchor"&gt;&lt;/a&gt;不要对关键服务开 Auto 模式
&lt;/h3&gt;&lt;p&gt;VPA 的 Auto 模式会在&amp;quot;合适的时候&amp;quot;重启 Pod 来应用新资源。但&amp;quot;合适的时候&amp;quot;是 VPA 自己判断的，可能在你的业务高峰期触发。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最佳实践&lt;/strong&gt;：生产环境用 Off 模式，开发/测试环境用 Auto 模式。&lt;/p&gt;
&lt;h3 id="推荐值的滞后性"&gt;&lt;a href="#%e6%8e%a8%e8%8d%90%e5%80%bc%e7%9a%84%e6%bb%9e%e5%90%8e%e6%80%a7" class="header-anchor"&gt;&lt;/a&gt;推荐值的滞后性
&lt;/h3&gt;&lt;p&gt;VPA 的 Recommender 基于历史数据计算推荐值，默认取过去 8 天的数据。如果你的服务有周期性负载波动（比如工作日和周末差异很大），推荐值可能不准确。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;调优参数：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--memory-saver&lt;/code&gt;：减少内存使用，但推荐值精度降低&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--history-length&lt;/code&gt;：调整历史数据窗口长度（默认 8 天）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--pod-label-selector&lt;/code&gt;：只对特定标签的 Pod 计算推荐值&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vpa-在集群资源优化中的价值"&gt;&lt;a href="#vpa-%e5%9c%a8%e9%9b%86%e7%be%a4%e8%b5%84%e6%ba%90%e4%bc%98%e5%8c%96%e4%b8%ad%e7%9a%84%e4%bb%b7%e5%80%bc" class="header-anchor"&gt;&lt;/a&gt;VPA 在集群资源优化中的价值
&lt;/h2&gt;&lt;p&gt;很多企业的 K8s 集群存在严重的**资源超额分配（Over-provisioning）**问题。开发者在申请资源时总是&amp;quot;多要一点&amp;quot;以防万一，导致：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pod 的 CPU requests 总和远超节点实际 CPU 能力&lt;/li&gt;
&lt;li&gt;内存 requests 设置过高，大量内存被预留但从未使用&lt;/li&gt;
&lt;li&gt;集群利用率只有 20-30%，但管理层觉得&amp;quot;资源不够&amp;quot;要买更多机器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;VPA 的 Off 模式配合一个简单的脚本，就能生成&lt;strong&gt;资源优化报告&lt;/strong&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 获取所有 VPA 推荐值和当前配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl get vpa --all-namespaces -o json &lt;span class="p"&gt;|&lt;/span&gt; jq -r &lt;span class="s1"&gt;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; .items[] |
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; .metadata.name as $name |
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; .status.recommendation.containerRecommendations[]? |
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; [$name, .containerName, .target.cpu, .target.memory] | @tsv
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;把推荐值和当前 requests 做个对比，就能发现哪些服务超额分配了、浪费了多少资源。这个报告拿给管理层看，比任何 PPT 都有说服力。&lt;/p&gt;
&lt;h2 id="写在最后"&gt;&lt;a href="#%e5%86%99%e5%9c%a8%e6%9c%80%e5%90%8e" class="header-anchor"&gt;&lt;/a&gt;写在最后
&lt;/h2&gt;&lt;p&gt;K8s 的垂直扩展能力正在走向成熟。VPA 虽然不是新东西，但配合 In-place 扩展的底层能力，它终于有机会在生产环境中发挥真正的价值。&lt;/p&gt;
&lt;p&gt;几个核心建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;先用 Off 模式&lt;/strong&gt;：让 VPA 跑几周收集推荐数据，人工审核后手动调整&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VPA 和 HPA 分开管&lt;/strong&gt;：一个管资源量，一个管副本数，别混在一起&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关注 In-place 扩展的进展&lt;/strong&gt;：等 In-place 稳定后，VPA 的 Auto 模式才真正适合生产环境&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VPA 最大的价值是资源规划&lt;/strong&gt;：帮你发现超额分配、优化集群利用率，这比自动扩展更实际&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;工具的价值不在于自动化程度有多高，而在于它帮你看到了之前看不到的东西。VPA 让你看到了每个 Pod 到底需要多少资源——这个信息本身就值回票价。&lt;/p&gt;
&lt;/blockquote&gt;</description></item></channel></rss>