Kubernetes 官方 examples 仓库:6.6K stars 装着的 K8s 实战样本
💬 评论Kubernetes 官方 examples 仓库(SIG Apps 维护,6.6K stars)的全栈式拆解。vLLM 推理 + GPU HPA + TF Serving + Cassandra StatefulSet 四个真生产级案例——为什么它既能装应用又能装 AI 平台
“Welcome to the official Kubernetes Examples repository! This curated collection, stewarded by SIG Apps, provides high-quality, educational examples for running a diverse range of applications and workloads on Kubernetes.” ——
kubernetes/examplesREADME 第一行
一、为什么我会去翻这个仓库#
起因是我在 GKE 上跑 vLLM 想加 GPU 弹性扩缩容,搜出来一篇 Google Cloud 博客引到一个示例仓库:kubernetes/examples ↗。
我点进去一看——6.6K stars、Shell 主语言、17MB。比起 OpenViking 100MB 和 TencentDB Agent Memory 44MB 算是轻量,但 40 个 YAML + 11 个 README + 32 个 archived 历史目录 的密度很高。
最让我在意的是 README 第一段不写 “What is X” 而写 “How do you reduce repetitive work”——它故意把”例子”和”模板”区分开。
读完之后我给的判断:这是一个”Kubernetes 实战手册”,不是”Kubernetes 教程”。它的工作不是解释每个 API 字段,而是给你看 4-5 个真实生产场景怎么跑通。
二、目录长得很稀疏,但每个目录都是”完整场景”#
kubernetes/examples/
├── AI/ # AI/ML 推理场景
│ ├── vllm-deployment/ # vLLM + GPU HPA + Prometheus
│ └── model-serving-tensorflow/ # TF Serving + PV + Ingress
├── databases/ # 有状态数据库
│ ├── cassandra/ # StatefulSet 经典案例
│ └── mysql-cinder-pd/ # OpenStack 块存储
├── web/ # Web 应用
│ ├── guestbook/ # PHP 多层应用
│ └── guestbook-go/ # Go 版 controller 模式
├── nginx-platform-app/ # 单 nginx 演示
├── _archived/ # 32 个已归档历史示例
├── guidelines.md # 贡献者必读
└── README.mdtext一共 4 个活跃类别 + 1 个 nginx 演示 + 32 个 archived 目录。表面看很小,但每个活跃目录都做”完整”:
- vLLM 不是只给个
Deployment,而是从 Deployment → Service → Prometheus → ServiceMonitor → PrometheusRule → PrometheusAdapter → HPA 8 个 YAML 全套 - Cassandra 不只给 StatefulSet,而是带 Go/Java/image 三种语言 client + 完整测试
- Guestbook 提供 PHP 版 + Go controller 版两个完整对照
这是”examples”和”snippets”的根本区别——snippets 给你看一个 yaml 字段,examples 给你看一个能跑通的生产场景。
三、vLLM 部署:把”AI 推理 + GPU 弹性”做成 Kubernetes 一等公民#
这是仓库里最值得拆的一个例子。AI/vllm-deployment/ 包含两个子案例:
- 基础部署:
vllm-deployment.yaml+vllm-service.yaml - GPU 弹性扩缩:
hpa/子目录 8 个 YAML + 2 个 MD 完成完整监控回路
3.1 基础部署#
vllm-deployment.yaml 是个典型 AI 推理 Pod 模板,但有 4 个关键设计值得看:
# vllm-deployment.yaml 关键参数
resources:
requests:
nvidia.com/gpu: "1"
limits:
nvidia.com/gpu: "1"yaml注意:GPU 资源是 requests/limits 都设 1——这是 Kubernetes GPU 调度的硬约束,少一个 pod 就不能调度。
command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
args:
- --model=$(MODEL_ID)
- --tensor-parallel-size=1
- --gpu-memory-utilization=0.85
- --max-num-seqs=64yaml--gpu-memory-utilization=0.85 不是默认——这是为了防 OOM 的”内存保留”。注释里写”添加这行修复可能 OOM 错误”。
volumes:
- name: dshm
emptyDir:
medium: MemoryyamlemptyDir.medium: Memory 走 tmpfs——vLLM 用 /dev/shm 做 PyTorch 多进程通信,磁盘会慢 10 倍。
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-secret
key: hf_tokenyamlHF token 从 K8s Secret 注入——不是 bake 进镜像。这避免了”镜像泄漏 token”。
3.2 GPU HPA:用”业务指标”驱动弹性#
这是真正精彩的部分。AI/vllm-deployment/hpa/ 给了两个 HPA 案例:
Case A:基于 DCGM GPU 利用率(gpu-horizontal-pod-autoscaler.yaml)
metrics:
- type: Pods
pods:
metric:
name: gpu_utilization_percent
target:
type: AverageValue
averageValue: 20yaml但 HPA 不直接接 DCGM Exporter,中间需要 3 层翻译:
DCGM Prometheus Exporter
↓ 暴露 DCGM_FI_DEV_GPU_UTIL
Prometheus
↓ 抓 + PrometheusRule 用 label_replace 重打标签
dcgm_fi_dev_gpu_util_relabelled
↓ Prometheus Adapter 翻译成 Kubernetes API
gpu_utilization_percent
↓ HPA 读取
按平均 GPU 利用率 20% 扩缩text这个链路在 prometheus-rule.yaml 顶部注释里写得很清楚:
“The raw ‘DCGM_FI_DEV_GPU_UTIL’ metric scraped by Prometheus does not have the standard ‘pod’ and ‘namespace’ labels that the Prometheus Adapter needs to associate the metric with a specific workload pod.”
这是一个被低估的 K8s 知识点:DCGM exporter 直接出来的 metric 没有 pod / namespace 标签,Prometheus Adapter 没法做关联。必须用 label_replace() 把标签重打。
Case B:基于 vLLM 业务指标(vllm-hpa.md)
vllm:num_requests_running{model_name="google/gemma-3-1b-it"}plaintext直接用 vLLM 自己暴露的 /metrics,按”并发请求数”扩缩。这比 GPU 利用率更准——GPU 利用率 100% 可能是正常 batch 跑满,扩缩毫无意义;并发请求数才是真的”用户压力”。
这两个案例并列放在 hpa/ 下的意义是 “给你两个选择,看你的业务是什么”:
- GPU 利用率:硬件资源视角(适合算力贵场景)
- 业务指标:负载视角(适合用户体验优先场景)
3.3 HPA 的 stabilizationWindow 写得也很到位#
behavior:
scaleUp:
stabilizationWindowSeconds: 0 # 立即扩
policies:
- type: Pods
value: 4
periodSeconds: 15
- type: Percent
value: 100
periodSeconds: 15
selectPolicy: Max # 两者取大
scaleDown:
stabilizationWindowSeconds: 30 # 30s 稳定窗口防抖
policies:
- type: Percent
value: 100
periodSeconds: 15
selectPolicy: MaxyamlscaleUp 立即扩 + scaleDown 30s 稳定——这是”宁可浪费 GPU 也不能让用户等”的弹性策略。注释里写明 trade-off:
“A non-zero value would make the scaling less sensitive to short-lived spikes, but could introduce latency if the load persists.”
policies 写 Pods: 4 + Percent: 100 + selectPolicy: Max ——两个策略取最大,15 秒内最多扩 1 倍或 4 个 Pod。这是”激进 + 保守”的双保险。
四、TensorFlow Serving:把”模型仓库”的标准范式落到 K8s#
AI/model-serving-tensorflow/ 是个对照案例——同样做 AI 推理,用完全不同的方式:
vllm-deployment/ # 模型从 HF 拉,Pod 启动时下载
model-serving-tensorflow/ # 模型用 PV 挂载到 Podtextdeployment.yaml 关键片段:
volumes:
- name: model-storage
persistentVolumeClaim:
claimName: model-pvc
containers:
- name: tensorflow-serving
image: tensorflow/serving:latest
args:
- --model_name=resnet
- --model_base_path=/models/resnet
volumeMounts:
- name: model-storage
mountPath: /modelsyaml配套文件 pvc.yaml + pv.yaml + service.yaml + ingress.yaml 完整一条龙。这是 K8s 传统做法:模型和 Pod 分离,PV 持久化。
两种方式的对比:
| 维度 | vLLM (HF 拉) | TF Serving (PV 挂) |
|---|---|---|
| 启动时间 | 慢(首次下载 5GB+ 模型) | 快(PV 已就绪) |
| 存储成本 | 高(每 Pod 缓存) | 低(一份共享) |
| 模型更新 | 改 env 重启 | 改 PV 内容 |
| 适合 | 临时实验 / 单租户 | 生产 / 多 Pod 共享 |
README.md 写明:
“Use a PersistentVolume to mount your model directory.”
这是 K8s 1.0 时代就有的范式,但放在 TF Serving 上下文里依然是最优解。
五、Cassandra StatefulSet:K8s 早期教科书写过的”作业正确性”#
databases/cassandra/ 是仓库里最”老派”的一个例子——完整 Go/Java 客户端 + 镜像构建,但核心是 cassandra-statefulset.yaml 的 9 个设计决策。
5.1 经典 StatefulSet 写法#
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cassandra
spec:
serviceName: cassandra
replicas: 3yamlserviceName: cassandra 是 StatefulSet 强制的——必须先有 headless Service,Pod 才有 stable DNS 解析。
5.2 4 个端口和它们的历史#
ports:
- containerPort: 7000
name: intra-node
- containerPort: 7001
name: tls-intra-node
- containerPort: 7199
name: jmx
- containerPort: 9042
name: cqlyaml7000/7001 节点间通信、7199 JMX 监控、9042 CQL 业务端口。这是 Cassandra 4 端口的”祖传”配置——10 年没变。
5.3 优雅关闭#
terminationGracePeriodSeconds: 1800 # 30 分钟
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- nodetool drainyamlterminationGracePeriodSeconds: 1800 + preStop: nodetool drain——这是 Cassandra 关闭时”先把数据 flush 到磁盘再退出”的标准操作。30 分钟是因为有状态数据库关闭就是慢。
securityContext:
capabilities:
add:
- IPC_LOCKyamlIPC_LOCK capability——Cassandra mmap 文件需要锁内存,不加这个 capability 会被内核 swap。
5.4 节点发现写得很”毒”#
env:
- name: CASSANDRA_SEEDS
value: "cassandra-0.cassandra.default.svc.cluster.local"yamlcassandra-0.cassandra.default.svc.cluster.local——这是 K8s StatefulSet 给 Pod 分配的稳定 DNS:
<POD_NAME>.<SERVICE_NAME>.<NAMESPACE>.svc.cluster.localtext第一个 Pod 永远是 cassandra-0,第二个是 cassandra-1……用 Pod 序号做种子节点发现,这是 K8s StatefulSet 最经典的设计。
cassandra.yaml 里还写明 MAX_HEAP_SIZE=512M + HEAP_NEWSIZE=100M——JVM 调优显然不是 K8s 知识点,但这个 examples 教了:Stack 与 Heap 比例要预先设好。
六、MySQL + OpenStack Cinder:展示”云原生存储插件”怎么工作#
databases/mysql-cinder-pd/ 是仓库里最”小众”的例子——演示如何用 OpenStack Cinder 做 Kubernetes PersistentVolume。
volumes:
- name: mysql-persistent-storage
cinder:
volumeID: 9a461d06-...-f8c5b8d33
fsType: ext4yamlcinder 是 OpenStack 块存储的 volume 类型——Kubernetes 通过 cloud-provider 集成,调用 Cinder API 把 volume 挂到 Pod 所在的虚拟机。
README 列了 4 个 kubelet 依赖:
/bin/lsblk # 找 fs type
/sbin/mkfs.ext3, mkfs.ext4 # 必要时格式
/usr/bin/udevadm # 探测设备挂载text这是 K8s 1.0 时代的 PV 写法——现在已经被 StorageClass + Dynamic Provisioning 替代。
这个 examples 留它不是因为它”现在还实用”,而是因为它演示了”云提供商的存储插件怎么和 K8s 集成”——这是理解 K8s 存储子系统的最好教材。
七、Guestbook Classic:K8s 教程的”Hello World”#
web/guestbook/ 是 K8s 官网教程的原始配套——PHP + Redis Master + Redis Replica + Frontend 的 4 层应用。
7.1 历史演化#
guestbook/ # PHP 版 + 多 deployment + service
├── legacy/ # 旧版 controller 模式(archived)
└── all-in-one/ # 单文件版本(学习用)
guestbook-go/ # Go 版 + controller 模式
├── main.go
└── guestbook-controller.yamltextlegacy/ 留了旧 controller 模式的 deployment——这是 K8s 早期 kubectl run 命令生成的 YAML,后来被 kubectl create deployment 替代。
all-in-one/ 提供单文件运行版——所有 deployment + service 塞一个 YAML,方便速跑。
7.2 多语言版本的对照价值#
guestbook-go/ 给了一个完整 Go 实现 + Dockerfile + Makefile + controller.yaml。这是”用 Deployment vs 用 Controller”两种写法的对比——新人看 Deployment,老 K8s 用户看 Controller。
两面读,5 分钟就能理解 K8s workload 模型的演化。
八、guidelines.md:隐藏在仓库里的”教学哲学”#
guidelines.md 不长,但每条都值得读。我抽几条最关键的:
8.1 “An example is NOT…”#
- Minimalistic Feature Snippets: 应展示"完整应用",不是单个 YAML 字段
- Pure Kubernetes Feature Demonstrations: 应展示"应用运行在 K8s 上",不是"展示 K8s 某个功能"markdown第二条特别重要——这不是”教集群管理员怎么用 HPA”的仓库,是”教应用开发者怎么把自己应用跑在 K8s”的仓库。
8.2 README 强制结构#
- Purpose / What You'll Learn
- Prerequisites
- Quick Start / TL;DR
- Detailed Steps & Explanation
- Verification / Seeing it Work
- Configuration Customization
- Cleanup
- Troubleshooting (Optional)
- Further Reading / Next Steps
- Maintainer(s) (Optional)
- Last Validated Kubernetes Version (Recommended)markdown“Last Validated Kubernetes Version” 是非常工程化的要求——因为 K8s API 一直在变(apps/v1beta2 → apps/v1),不验证版本就是埋雷。
8.3 Manifest 的硬要求#
- Each example should use standard kubectl apply or kustomize, not be tied to a specific tool
- Use namespaces for resource isolation
- Pin image versions (no:latest)
- Include resource requests/limitsmarkdown“no:latest”——一个 examples 仓库如果用 latest 标签,今天能跑明天可能挂。必须 pin 版本。
九、_archived/:32 个”样本库”是 K8s 生态的化石#
_archived/ 目录下有 32 个历史例子:
cockroachdb, elasticsearch, javaee, meteor, newrelic, oms,
openshift-origin, persistent-volume-provisioning, phabricator,
pod, podsecuritypolicy, scheduler-policy, selenium, sharing-clusters,
spark, storm, ...text这是 K8s 生态的”考古层”——phabricator(Meta 的 code review 工具)、openshift-origin(红帽 K8s 发行版)、javaee(Java 企业版)——这些例子记录了 2014-2020 年 K8s 生态的演化。
最有考古价值的:
pod/:K8s 早期连 Deployment 都没有,只有裸 Podscheduler-policy/:早期自定义调度器范式podsecuritypolicy/:PSP 已于 1.25 移除,是 K8s 安全模型演化的活标本sharing-clusters/:多租户 K8s 早期实践
这是 90% 的 K8s 教程不会告诉你的”黑暗历史”。
十、为什么这个仓库只有 6.6K stars?#
仔细看 README 的贡献者:
kubernetes-sigs contributors
SIG Apps maintainerstext它是 SIG Apps 维护的”教学仓库”,不是产品仓库。教学方法的价值往往不被 star 数量反映。
但它给的价值是:
- 每个 example 都是”完整生产场景”——不是 snippet
- README 强制 11 节结构——质量保证
- 附带历史归档——生态演化的时间轴
- AI/ML 案例占快速增长的 50%——vLLM + TF Serving
和 OpenViking、TencentDB Agent Memory 相比:
| 维度 | OpenViking | TencentDB Agent Memory | kubernetes/examples |
|---|---|---|---|
| 类型 | 框架 | 框架 | 示例库 |
| 受众 | Agent 开发者 | Agent 团队 | K8s 应用开发者 |
| 抽象层 | 上下文数据库 | 记忆资产 | 实际部署 |
| 语言 | Python + Rust | TypeScript | Shell + YAML |
| 教学价值 | 中(架构) | 中(设计) | 极高(手把手) |
| 生产可用性 | 高 | 高 | 高(直接 copy) |
kubernetes/examples 的教学价值我认为是三者最高的——因为它不跟你讲架构,直接给你能跑的 YAML。
十一、5 个 “我读完才发现” 的隐藏细节#
11.1 Image Pull Policy 写 Always#
imagePullPolicy: AlwaysyamlYAML 里写 Always 而不是默认——刻意防止 image 缓存导致更新不生效。
11.2 Headless Service 必要性#
Cassandra StatefulSet 配套的 cassandra-service.yaml 是 headless(clusterIP: None),没有 headless service 设不出 cassandra-0.cassandra.default.svc.cluster.local 这种 DNS。
11.3 README 里的 Last Validated#
README.md 末尾要求标注:
- Last Validated Kubernetes Version (Recommended)markdown这是工程化最佳实践——例子能跑不能只靠”现在能跑”,要标记”在 X.Y 版本验证过”。
11.4 平台兼容性注释#
vllm-deployment.yaml 顶部注释:
# Node selectors are the main difference among the cloud providers,
# making sure vLLM pods land on Nodes with the correct GPU. The
# following are node selector examples for three cloud providers.yaml不同云厂商的 GPU 标签都不一样——GKE cloud.google.com/gke-accelerator / EKS node.kubernetes.io/instance-type / AKS agentpiscasi.com/gpu。这是 K8s 生态最痛的问题。
11.5 CPU Manager 隐含的硬件要求#
archived/cpu-manager/ 留了一整个目录讲 CPU Manager(K8s 静态绑核)——这个功能只有少数工作负载真需要(NFV、低延迟交易),普通应用忽略。
十二、复制这个仓库的方式#
仓库 README 的 Quick Start 模式极简:
# 找一个例子
cd AI/vllm-deployment
# 跟着 README TL;DR 跑
kubectl create namespace vllm-example
kubectl apply -f vllm-deployment.yaml -n vllm-example
kubectl wait --for=condition=Available --timeout=900s deployment/vllm-gemma-deployment -n vllm-examplebash克隆到本地都不需要——直接 kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/AI/vllm-deployment/vllm-deployment.yaml。
这种”例子即 URL”的设计哲学,是 SIG Apps 的精髓:例子不是私有模板,是公共契约。
十三、读完之后我换了一个角度看”examples”#
我之前看 examples 仓库默认思路是:
examples = 给新手看的入门教程text读完之后我换了个角度:
examples = 维护者用贡献门槛筛选出来的高质量实战案例text注意 guidelines.md 的措辞:
“An example demonstrates running an application… must be: Meaningful, Educational, Illustrative of Best Practices, Focused.”
这四条不仅是给贡献者的要求,也是给所有”想给项目写 examples”的工程师的清单——
- Meaningful:解决真实问题,不是技术 demo
- Educational:解释为什么这么写,不只是”这是什么”
- Best Practices:用当前推荐做法,不用旧的 deprecated API
- Focused:聚焦一个具体场景,不过度扩展
这是 Kubernetes 社区给我示范的”软件工程美学”——例子不是免费的,每一个例子都要回答”为什么我存在”。
我下一篇博客可能会写怎么用这个仓库的范式给我自己的 K8s 项目写 examples(一篇博客可能写不完,会分系列)。如果你想先动手,最短路径:
# 直接看 vLLM 那个例子
git clone https://github.com/kubernetes/examples.git
cd examples/AI/vllm-deployment
# 跟着 README 的 TL;DR 跑bash或者直接看 官方教程列表 ↗——examples 仓库 + 官方教程是配对的。
附录:关键源码定位速查#
| 模块 | 路径 |
|---|---|
| README 自我介绍 | README.md:1-5 |
| 贡献指南 | guidelines.md |
| vLLM 部署 | AI/vllm-deployment/vllm-deployment.yaml |
| vLLM Service | AI/vllm-deployment/vllm-service.yaml |
| GPU HPA | AI/vllm-deployment/hpa/gpu-horizontal-pod-autoscaler.yaml |
| vLLM HPA(业务指标) | AI/vllm-deployment/hpa/vllm-hpa.md |
| PrometheusRule | AI/vllm-deployment/hpa/prometheus-rule.yaml |
| Prometheus Adapter | AI/vllm-deployment/hpa/prometheus-adapter.yaml |
| TF Serving 部署 | AI/model-serving-tensorflow/deployment.yaml |
| TF Serving PV | AI/model-serving-tensorflow/pv.yaml |
| Cassandra StatefulSet | databases/cassandra/cassandra-statefulset.yaml |
| Cassandra Service | databases/cassandra/cassandra-service.yaml |
| Cassandra Go client | databases/cassandra/go/ |
| MySQL + Cinder | databases/mysql-cinder-pd/mysql.yaml |
| Guestbook PHP | web/guestbook/redis-master-deployment.yaml |
| Guestbook Go | web/guestbook-go/main.go |
| AI 目录愿景 | AI/README.md |
| Archived 演进 | _archived/(32 个目录) |
📘 项目信息
- 仓库:kubernetes/examples ↗
- 维护者:Kubernetes SIG Apps
- License:Apache 2.0
- Stars:6.6K
- 例子数量:4 个活跃类别 + 1 个 nginx 演示 + 32 个 archived 历史
- 官方教程:https://kubernetes.io/docs/tutorials/ ↗