news 2026/1/17 5:57:40

Helm 自定义 Chart 开发与版本管控(适配 K8s 1.33)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Helm 自定义 Chart 开发与版本管控(适配 K8s 1.33)

作为 10 年运维专家,先把核心逻辑捋清楚,再给落地步骤和可直接跑的案例 —— 全程说人话,不堆砌术语,适配 K8s 1.33 的特性(比如废弃的 API 都规避掉)。

一、核心技术逻辑:先搞懂 Helm 到底在干嘛

1. Helm 的本质

Helm 是 K8s 的包管理器,把 K8s 的 YAML 配置(Deployment、Service、Ingress 等)打包成一个「Chart」(相当于 Linux 的 rpm/deb 包),解决:

  • 零散 YAML 不好管理的问题;
  • 环境差异化配置(开发 / 测试 / 生产);
  • 版本追溯、回滚、升级的管控;
  • 一键部署 / 卸载,不用手动改 YAML。

2. Chart 的核心逻辑

一个 Chart 就是一个目录结构,核心是「模板 + 配置」:

  • 模板(templates):带变量的 K8s YAML 文件(比如镜像版本、副本数用变量 {{.Values.xxx}} 代替);
  • 配置(values.yaml):模板变量的默认值,部署时可通过-f--set覆盖;
  • 元数据(Chart.yaml):Chart 的版本、名称、依赖、适配 K8s 版本等核心信息(关键:要适配 1.33)。

3. 版本管控的核心逻辑

Helm 的版本管控分两层:

  • Chart 版本:Chart.yaml 里的version(语义化版本,比如 1.0.0、1.0.1),对应 Chart 包的迭代;
  • Release 版本:Helm 部署 Chart 后生成的 Release(比如部署 myapp-1.0.0 生成 release myapp-v1),Helm 会记录每个 Release 的配置,支持回滚(helm rollback);
  • 配合仓库(Chart Repository):把打好的 Chart 包推到仓库(比如 Harbor、ChartMuseum),实现版本归档和团队共享。

4. K8s 1.33 适配要点

1.33 版本主要废弃 / 变更的 API 要规避:

  • Ingress:必须用networking.k8s.io/v1(v1beta1 早已废弃);
  • StatefulSet/Deployment:用apps/v1(没问题,1.33 仍支持);
  • PodSecurityPolicy(PSP)已完全移除,改用 Pod Security Standards(PSS)+ Pod Security Admission(PSA);
  • 其他核心 API(Service、ConfigMap、Secret)无变更,正常用v1

二、自定义 Chart 开发:详细操作步骤

步骤 1:环境准备(适配 1.33)

先确认 Helm 版本(建议 3.14+,适配 1.33):

# 安装Helm 3.14+(Linux示例) curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash # 验证版本 helm version # 输出v3.14.x即可 # 验证K8s集群(1.33) kubectl version --short # 确保Server Version是v1.33.x

步骤 2:初始化 Chart 骨架

Helm 提供create命令生成标准目录结构,不用手动建:

# 创建名为myapp的Chart(自定义Chart的核心目录) helm create myapp

生成的目录结构(重点标★):

myapp/ ├── Chart.yaml ★ Chart元数据(版本、名称、K8s适配) ├── values.yaml ★ 模板默认配置(镜像、副本数、端口等) ├── charts/ ★ 依赖的其他Chart(比如redis、mysql) ├── templates/ ★ 核心模板目录(K8s资源YAML) │ ├── deployment.yaml ★ 部署模板 │ ├── service.yaml ★ 服务模板 │ ├── ingress.yaml ★ 入口模板(适配1.33) │ ├── _helpers.tpl ★ 辅助函数(变量复用) │ ├── NOTES.txt ★ 部署后提示信息 └── .helmignore ★ 忽略文件(类似.gitignore)

步骤 3:定制 Chart 元数据(Chart.yaml)

核心是适配 K8s 1.33,示例如下(注释讲清楚每一项):

apiVersion: v2 # Helm Chart的API版本(v2是通用版,v1是旧版) name: myapp # Chart名称(全局唯一) description: A simple web app Chart for K8s 1.33 # 描述 type: application # 类型(application/库chart) # Chart版本(语义化:主版本.次版本.补丁,比如1.0.0) # 迭代规则:主版本(大改)、次版本(新增功能)、补丁(bug修复) version: 1.0.0 # App版本(对应业务应用的版本,比如v1.0.0) appVersion: "v1.0.0" # 适配的K8s版本(1.33.x),避免部署到不兼容的集群 kubeVersion: ">=1.33.0 <1.34.0" # 可选:依赖(比如需要redis) dependencies: - name: redis version: 17.3.1 repository: https://charts.bitnami.com/bitnami condition: redis.enabled # 条件启用

步骤 4:定制默认配置(values.yaml)

核心是「默认值 + 可覆盖」,适配 1.33 的 Ingress,示例如下:

# 全局配置(可被依赖Chart继承) global: namespace: myapp # 默认命名空间 # 部署配置 deployment: replicas: 2 # 默认副本数 strategy: type: RollingUpdate # 滚动更新(1.33支持) rollingUpdate: maxSurge: 1 maxUnavailable: 0 pod: # 容器配置 containers: name: myapp-web image: nginx:1.25-alpine # 基础镜像(1.33兼容) imagePullPolicy: IfNotPresent ports: - containerPort: 80 name: http # 资源限制(避免资源抢占) resources: limits: cpu: 500m memory: 512Mi requests: cpu: 100m memory: 256Mi # 健康检查(1.33推荐配置) livenessProbe: httpGet: path: / port: http initialDelaySeconds: 10 periodSeconds: 10 readinessProbe: httpGet: path: / port: http initialDelaySeconds: 5 periodSeconds: 5 # PSS适配(替代PSP,1.33必用) securityContext: runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 # Service配置 service: type: ClusterIP # 类型(ClusterIP/NodePort/LoadBalancer) port: 80 targetPort: http # Ingress配置(适配1.33的networking.k8s.io/v1) ingress: enabled: true className: nginx # Ingress Controller类名(需提前部署nginx-ingress) annotations: nginx.ingress.kubernetes.io/rewrite-target: / hosts: - host: myapp.example.com paths: - path: / pathType: Prefix # 1.33必填(Prefix/Exact/ImplementationSpecific) tls: false # 暂时关闭TLS,生产可开启 # 依赖配置(redis) redis: enabled: false # 默认不启用 auth: enabled: true

步骤 5:定制模板(templates/)

模板是「带变量的 K8s YAML」,核心是复用 values.yaml 的配置,适配 1.33:

5.1 Deployment 模板(deployment.yaml)
apiVersion: apps/v1 # 1.33支持 kind: Deployment metadata: name: {{ .Release.Name }}-myapp # Release名称+固定后缀(避免冲突) namespace: {{ .Values.global.namespace }} labels: app: {{ .Chart.Name }} version: {{ .Chart.AppVersion }} spec: replicas: {{ .Values.deployment.replicas }} strategy: {{- toYaml .Values.deployment.strategy | nindent 4 }} # 复用values的更新策略 selector: matchLabels: app: {{ .Chart.Name }} template: metadata: labels: app: {{ .Chart.Name }} spec: securityContext: {{- toYaml .Values.deployment.pod.securityContext | nindent 8 }} containers: - name: {{ .Values.deployment.pod.containers.name }} image: {{ .Values.deployment.pod.containers.image }} imagePullPolicy: {{ .Values.deployment.pod.containers.imagePullPolicy }} ports: {{- toYaml .Values.deployment.pod.containers.ports | nindent 12 }} resources: {{- toYaml .Values.deployment.pod.containers.resources | nindent 12 }} livenessProbe: {{- toYaml .Values.deployment.pod.containers.livenessProbe | nindent 12 }} readinessProbe: {{- toYaml .Values.deployment.pod.containers.readinessProbe | nindent 12 }}
5.2 Service 模板(service.yaml)
apiVersion: v1 # 1.33支持 kind: Service metadata: name: {{ .Release.Name }}-myapp-service namespace: {{ .Values.global.namespace }} labels: app: {{ .Chart.Name }} spec: type: {{ .Values.service.type }} selector: app: {{ .Chart.Name }} ports: - port: {{ .Values.service.port }} targetPort: {{ .Values.service.targetPort }} protocol: TCP name: http
5.3 Ingress 模板(ingress.yaml,适配 1.33)

重点:必须用networking.k8s.io/v1,pathType 必填:

{{- if .Values.ingress.enabled }} # 条件渲染(enabled为true才生成) apiVersion: networking.k8s.io/v1 # 1.33唯一支持的版本 kind: Ingress metadata: name: {{ .Release.Name }}-myapp-ingress namespace: {{ .Values.global.namespace }} annotations: {{- toYaml .Values.ingress.annotations | nindent 4 }} spec: ingressClassName: {{ .Values.ingress.className }} rules: {{- range .Values.ingress.hosts }} # 循环渲染多个host - host: {{ .host }} http: paths: {{- range .paths }} - path: {{ .path }} pathType: {{ .pathType }} # 1.33必填 backend: service: name: {{ $.Release.Name }}-myapp-service # 引用Service名称 port: number: {{ $.Values.service.port }} {{- end }} {{- end }} {{- if .Values.ingress.tls }} # TLS配置 tls: {{- toYaml .Values.ingress.tls | nindent 4 }} {{- end }} {{- end }}

步骤 6:模板校验(避免语法错误)

开发完模板后,先校验语法和适配性:

# 1. 检查Chart语法(核心) helm lint myapp/ # 2. 渲染模板(看最终生成的YAML,不部署) helm template myapp/ --namespace myapp # 3. 模拟部署(dry-run,检查K8s 1.33兼容性) helm install myapp-test myapp/ --namespace myapp --create-namespace --dry-run

如果报错,优先看:

  • API 版本是否正确(比如 Ingress 用 networking.k8s.io/v1);
  • 变量是否存在(比如 {{.Values.xxx}} 有没有在 values.yaml 定义);
  • K8s 1.33 的特性是否兼容(比如 pathType 必填)。

三、版本管控:从打包到仓库全流程

步骤 1:Chart 打包(版本固化)

把 Chart 目录打成 tgz 包,版本对应 Chart.yaml 里的 version:

# 打包(生成myapp-1.0.0.tgz) helm package myapp/ # 查看包信息 helm show chart myapp-1.0.0.tgz

步骤 2:搭建 Chart 仓库(团队共享)

推荐用 Harbor(自带 Chart 仓库)或 ChartMuseum,这里用 ChartMuseum 快速搭建(适配 1.33):

# 1. 部署ChartMuseum(用Helm本身部署) helm repo add chartmuseum https://chartmuseum.github.io/charts helm install chartmuseum chartmuseum/chartmuseum \ --namespace chartmuseum \ --create-namespace \ --set env.open.DISABLE_API=false # 开启API(允许推送) # 2. 获取ChartMuseum地址 kubectl get svc -n chartmuseum chartmuseum-chartmuseum -o jsonpath='{.spec.clusterIP}' # 假设地址是10.96.0.100:8080

步骤 3:推送 Chart 到仓库(版本归档)

cm-push插件推送(需先安装):

# 安装cm-push插件 helm plugin install https://github.com/chartmuseum/helm-push.git # 添加仓库到Helm helm repo add myrepo http://10.96.0.100:8080 # 推送包到仓库(版本1.0.0) helm cm-push myapp-1.0.0.tgz myrepo # 刷新仓库 helm repo update myrepo # 查看仓库里的Chart版本 helm search repo myrepo/myapp

步骤 4:部署指定版本(版本管控核心)

部署时指定版本,避免随意升级:

# 部署1.0.0版本 helm install myapp vmyrepo/myapp --version 1.0.0 \ --namespace myapp \ --create-namespace \ # 覆盖默认配置(比如生产环境副本数3) --set deployment.replicas=3 \ --set ingress.hosts[0].host=myapp.prod.example.com # 查看Release版本 helm list -n myapp # 输出示例:NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION # myapp myapp 1 2025-12-15 10:00:00 deployed myapp-1.0.0 v1.0.0

步骤 5:版本升级 / 回滚(运维核心操作)

5.1 版本升级(比如迭代到 1.0.1)
  1. 修改 Chart.yaml 的 version 为 1.0.1,更新功能(比如增加资源限制);
  2. 重新打包:helm package myapp/
  3. 推送新版本:helm cm-push myapp-1.0.1.tgz myrepo
  4. 升级 Release:
helm upgrade myapp myrepo/myapp --version 1.0.1 -n myapp \ --set deployment.replicas=4 # 同时覆盖配置
5.2 版本回滚(升级出问题时)

Helm 会记录每个 Release 的版本(REVISION),回滚到上一版本:

# 查看Release历史 helm history myapp -n myapp # 输出示例:REVISION UPDATED STATUS CHART DESCRIPTION # 1 2025-12-15 10:00:00 superseded myapp-1.0.0 Install complete # 2 2025-12-15 10:10:00 deployed myapp-1.0.1 Upgrade complete # 回滚到REVISION 1(1.0.0版本) helm rollback myapp 1 -n myapp # 验证回滚结果 helm status myapp -n myapp

步骤 6:版本清理(避免冗余)

# 卸载Release(保留Chart版本) helm uninstall myapp -n myapp # 从仓库删除指定Chart版本(1.0.0) curl -X DELETE http://10.96.0.100:8080/api/charts/myapp/1.0.0 # 清理本地Chart缓存 helm repo remove myrepo rm -rf myapp-1.0.0.tgz myapp-1.0.1.tgz

四、完整案例:部署一个 Nginx Web 应用(适配 1.33)

案例目标

开发一个 myapp Chart,部署 Nginx 应用,支持:

  • 自定义副本数、镜像版本;
  • Ingress 访问(myapp.example.com);
  • 版本升级(1.0.0→1.0.1);
  • 版本回滚。

前置条件

  1. K8s 1.33 集群已部署 nginx-ingress Controller(Ingress 需要);
  2. Helm 3.14 + 已安装;
  3. 本地 hosts 配置:集群节点IP myapp.example.com

步骤 1:创建并定制 Chart

# 1. 创建Chart helm create myapp # 2. 修改Chart.yaml(按前面的示例,version=1.0.0,kubeVersion=>=1.33.0) # 3. 修改values.yaml(按前面的示例,镜像用nginx:1.25-alpine,副本数2) # 4. 校验模板 helm lint myapp/ helm template myapp/ --namespace myapp

步骤 2:部署 1.0.0 版本

# 1. 创建命名空间 kubectl create namespace myapp # 2. 部署Release helm install myapp myapp/ -n myapp \ --set ingress.hosts[0].host=myapp.example.com \ --set deployment.replicas=2 # 3. 验证部署 helm status myapp -n myapp kubectl get pods -n myapp # 应该有2个nginx pod kubectl get ingress -n myapp # Ingress已创建 curl myapp.example.com # 应该返回Nginx默认页面

步骤 3:升级到 1.0.1 版本

# 1. 修改Chart.yaml,version改为1.0.1,appVersion改为v1.0.1 # 2. 修改values.yaml,镜像改为nginx:1.26-alpine,副本数3 # 3. 打包并推送(这里用本地测试,不用仓库) helm package myapp/ # 4. 升级Release helm upgrade myapp myapp-1.0.1.tgz -n myapp \ --set deployment.replicas=3 # 5. 验证升级 helm status myapp -n myapp # 显示REVISION=2,CHART=myapp-1.0.1 kubectl get pods -n myapp # 3个pod,镜像为1.26-alpine curl myapp.example.com # 仍返回Nginx页面

步骤 4:回滚到 1.0.0 版本

# 1. 查看Release历史 helm history myapp -n myapp # 2. 回滚到REVISION=1 helm rollback myapp 1 -n myapp # 3. 验证回滚 helm status myapp -n myapp # 显示REVISION=3,CHART=myapp-1.0.0 kubectl get pods -n myapp # 2个pod,镜像为1.25-alpine

步骤 5:卸载 Release

helm uninstall myapp -n myapp kubectl delete namespace myapp

五、核心总结(运维视角)

  1. Chart 开发核心:模板 + 配置分离,适配 K8s 1.33 的 API 版本(尤其是 Ingress);
  2. 版本管控核心:Chart 版本(包迭代)+ Release 版本(部署迭代),通过仓库归档,支持升级 / 回滚;
  3. 避坑点
    • 不要硬编码 K8s 资源名称,用 {{.Release.Name}} 避免冲突;
    • 必须校验模板(helm lint/helm template),避免部署时出错;
    • K8s 1.33 的 Ingress 必须用 networking.k8s.io/v1,pathType 必填;
    • 版本号严格遵循语义化,便于团队协作和追溯。

可以基于这个框架,扩展到更复杂的场景(比如 StatefulSet、ConfigMap/Secret、多环境配置),核心逻辑不变 —— 模板复用、配置可覆盖、版本可管控。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/13 3:54:01

16、GTK+ 样式定制全解析

GTK+ 样式定制全解析 1. GTK+ 样式定制概述 GTK+ 提供了多种定制小部件样式的方法。大部分小部件样式的定制是通过样式属性和资源(RC)文件来完成的。除了常见的背景、前景、基础和文本颜色样式外,还需要为许多样式指定小部件的状态。小部件有五种状态: - NORMAL :小部…

作者头像 李华
网站建设 2026/1/13 2:40:52

LobeChat是否支持Service Worker?离线访问能力构建

LobeChat 与离线能力&#xff1a;Service Worker 的实践路径 在移动设备普及、网络环境复杂多变的今天&#xff0c;用户对 Web 应用的期待早已超越“能打开”这一基本要求。他们希望应用加载迅速、响应及时&#xff0c;即便在地铁隧道或电梯间这类弱网甚至断网场景下&#xff0…

作者头像 李华
网站建设 2026/1/12 6:29:04

重学计算机基础013:减法运算的底层逻辑——为什么没有“减法器”?

上一章我们拆解了加法运算的完整链路&#xff0c;知道高级语言里的“”号最终会落地为全加器的晶体管通断动作。但随之而来的是一个更有意思的疑问&#xff1a;既然有加法就必然有减法&#xff08;比如a - b&#xff09;&#xff0c;为什么计算机硬件里从来没有“减法器”这个部…

作者头像 李华
网站建设 2026/1/11 20:06:54

apk pure安全性争议下,本地大模型成新趋势

apk pure安全性争议下&#xff0c;本地大模型成新趋势 在智能应用生态快速扩张的今天&#xff0c;一个不容忽视的问题正日益凸显&#xff1a;用户数据到底去了哪里&#xff1f;当我们在第三方安卓市场如APK Pure下载一款“AI助手”类应用时&#xff0c;看似便捷的服务背后&…

作者头像 李华
网站建设 2026/1/15 18:00:32

LobeChat能否支持NFT头像展示?个性化形象设定

LobeChat 与 NFT 头像&#xff1a;如何为 AI 聊天界面注入数字身份灵魂&#xff1f; 在今天的数字世界里&#xff0c;用户不再满足于“匿名对话”或千篇一律的默认头像。随着 Web3 概念深入人心&#xff0c;越来越多的人开始用 NFT 来表达自己的数字身份——一张 CryptoPunk 是…

作者头像 李华
网站建设 2026/1/16 19:43:18

LobeChat + Kubernetes:大规模部署AI前端界面的可行路径

LobeChat Kubernetes&#xff1a;大规模部署AI前端界面的可行路径 在企业加速拥抱大模型的今天&#xff0c;一个普遍却容易被忽视的问题浮出水面&#xff1a;我们有了强大的AI引擎&#xff0c;但用户“看得见、摸得着”的入口却依然粗糙。 命令行交互对普通员工不友好&#xf…

作者头像 李华