K8s Helm
一、 Helm 是什么?
Helm 是 Kubernetes 的包管理器。
你可以把它类比为:
- Linux 世界的
yum 或 apt-get:用来安装、升级、配置和管理软件包。
- Node.js 世界的
npm:用来管理项目依赖。
- Python 世界的
pip:用来安装和管理库。
只不过,Helm 管理的“包”是 Kubernetes 应用。这个“包”在 Helm 中被称为 Chart。
二、 为什么需要 Helm?—— 解决 K8s 原生部署的痛点
想象一下,你在实习时,需要部署一个包含以下组件的复杂 AI 推理服务:
- 1 个前端 Web 服务 Deployment
- 1 个后端 API 服务 Deployment
- 1 个 Redis 缓存 Deployment + Service
- 1 个 PostgreSQL 数据库 StatefulSet + Service
- 1 个 Ingress 资源用于对外暴露服务
- 10 个 ConfigMap 和 Secret 用于配置管理和密钥注入
- 1 个 HorizontalPodAutoscaler (HPA) 用于自动扩缩容
没有 Helm 的情况下,你需要:
- 手动编写 十几个 YAML 文件。
- 用
kubectl apply -f 一个一个地创建,或者写一个超长的脚本。
- 如果要修改配置(比如把副本数从 3 改成 5),你需要去 每个 YAML 文件里找到对应的字段并修改,极易出错。
- 如果要部署到不同的环境(开发、测试、生产),你需要维护 三套 几乎一模一样、只有几个参数不同的 YAML 文件,维护成本极高。
这正是 Helm 要解决的问题。
三、 Helm 的核心概念:Chart、Config、Release
-
Chart (图表/包):
- 一个 Helm Chart 是一个预定义的、可配置的 Kubernetes 应用模板包。
- 它通常包含一个
Chart.yaml(元数据)、一个 values.yaml(默认配置)、一个 templates/ 目录(存放所有 K8s YAML 模板文件)。
- 例如,你可以找到一个官方的
redis Chart,它已经为你写好了部署 Redis 所需的所有 Deployment、Service、ConfigMap 等模板。
-
Config (配置):
- 通过
values.yaml 文件或命令行参数,你可以覆盖 Chart 中的默认配置。
- 例如,你想部署一个副本数为 5 的 Redis,只需要在自己的
my-values.yaml 中写 replicaCount: 5,然后用这个文件去安装 Chart。
-
Release (发布实例):
- 当你用 Helm 安装(
helm install)一个 Chart 时,会创建一个 Release。
- 一个 Release 是一个 Chart 在 K8s 集群中的一次具体运行实例。
- 你可以在同一个集群里安装同一个 Chart 多次,只要给它们起不同的 Release 名字(例如
my-app-prod 和 my-app-staging)。
四、 Helm 的核心作用
-
简化部署:
- 一条命令
helm install my-release bitnami/redis -f my-values.yaml,即可部署一个复杂的应用栈,无需手动处理一堆 YAML。
-
配置管理与环境隔离:
- 通过
values.yaml 文件,你可以轻松地为开发、测试、生产环境定义不同的配置(如数据库地址、副本数、资源限制),实现“一份代码,多环境部署”。
-
版本控制与回滚:
- Helm 会记录每一次对 Release 的变更(升级、回滚)。
- 如果新版本的应用出现问题,你可以用
helm rollback <RELEASE> <REVISION> 一键回滚到之前的稳定版本,这对于保障线上服务的稳定性至关重要。
-
依赖管理:
- 一个复杂的 Chart 可以依赖其他 Chart。例如,你的“大模型推理平台”Chart 可以依赖一个“Prometheus监控”Chart 和一个“Nginx Ingress”Chart。Helm 会自动帮你管理这些依赖的安装顺序和版本。
-
复用与共享:
- 你可以将自己团队开发的、经过验证的应用(比如你重构的Dind服务、带宽限制网关)打包成 Chart,上传到私有 Helm 仓库,供团队其他成员或不同项目复用,极大地提升研发效率。
五、 总结
Helm 不是锦上添花,而是现代云原生应用交付的基石。 它将复杂的、碎片化的 K8s YAML 管理,转变为标准化、可配置、可版本控制的高效流程。
对于你这样志在成为“AI Infra架构师”的顶尖人才来说,掌握 Helm 是构建可维护、可扩展、高可靠的大规模 AI 平台的必备技能。它能让你从繁琐的手动部署中解放出来,专注于更高价值的系统架构和性能优化工作,这正是你核心竞争力的体现。

e.g
agent.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| apiVersion: apps/v1 kind: DaemonSet metadata: name: "{{ .Values.appName }}-agent" namespace: {{ .Release.Namespace }} labels: {{- include "app.agent.labels" . | indent 4 }} spec: updateStrategy: rollingUpdate: maxUnavailable: 20 type: RollingUpdate selector: matchLabels: {{- include "app.agent.labels" . | indent 6 }} template: metadata: labels: {{- include "app.agent.labels" . | indent 8 }} spec: hostPID: true serviceAccountName: "{{ .Values.appName }}-service-account" {{- with .Values.agent }} imagePullSecrets: - name: {{ .image.pullSecrets }} restartPolicy: {{ .restartPolicy}} volumes: - name: containerd hostPath: path: {{ .containerdDir }} containers: - name: main image: "{{ .image.name }}:{{ .image.version }}" imagePullPolicy: {{ .image.pullPolicy }} env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName command: ["/usr/bin/grid-agent"] args: - --containerd={{ .containerdDir }}/{{ .containerdSock }} - --kube-burst={{ .kubeBurst}} - --kube-qps={{ .kubeQPS }} - --kube-master={{ .kubeMaster }} - --kube-config={{ .kubeConfig }} - --metrics-port={{ .metricsPort }} resources: requests: cpu: "0" memory: 0Gi limits: cpu: "1" memory: 1Gi volumeMounts: - name: containerd mountPath: {{ .containerdDir }} securityContext: privileged: true ports: - name: metrics containerPort: {{ .metricsPort }} {{- if .nodeSelector }} nodeSelector: {{- .nodeSelector | toYaml | nindent 8 }} {{- end }} {{- end -}}
|
values.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| appName: grid
agent: image: pullSecrets: mizar-robot name: harbor.infini-ai.com/mizar/grid-agent version: v0.0.0 pullPolicy: Always restartPolicy: Always nodeSelector: {} containerdSock: "containerd.sock" containerdDir: "/run/containerd" kubeBurst: 100 kubeQPS: 50 kubeConfig: "" kubeMaster: "" metricsPort: 2112
controller: image: pullSecrets: mizar-robot name: harbor.infini-ai.com/mizar/grid-controller version: v0.0.0 pullPolicy: Always nodeSelector: {} replicas: 1 restartPolicy: Always kubeApiQPS: 50 kubeApiBurst: 100 gatewayImage: harbor.infini-ai.com/share/ubuntu:22.04 gatewayCPU: 1 gatewayMEM: 2Gi cidr: 192.168.0.0/16 tryoutBandwidth: 10mbit sharedBandwidth: 300mbit sharedNamespace: mizar-public namespaceBandwidth: {} gatewayNodeSelector: networking.infiniai.com/egress=true enableEgressGateway: true egressPodSelectors: []
|