Helm是Kubernetes生态中的应用包管理工具,通过Chart模板将应用部署配置参数化。相比裸YAML清单,Helm Chart支持版本管理、依赖声明、配置覆盖和一键回滚,已成为GitOps流水线的标准交付格式。本文从Chart结构设计、模板函数编写、子Chart依赖管理到CI/CD集成完整展开。
Helm Chart目录结构与Chart.yaml配置
Chart是Helm的打包单元,包含模板文件、默认值、依赖声明等。通过helm create命令初始化标准结构后进行定制。
# 创建Chart骨架
helm create webapp
# 目录结构:
# webapp/
# ├── Chart.yaml # Chart元数据
# ├── values.yaml # 默认配置值
# ├── templates/ # 模板文件目录
# │ ├── deployment.yaml
# │ ├── service.yaml
# │ ├── ingress.yaml
# │ ├── _helpers.tpl # 模板辅助函数
# │ └── NOTES.txt # 安装后提示信息
# ├── charts/ # 子Chart依赖
# └── .helmignore
# Chart.yaml
apiVersion: v2
name: webapp
description: Web应用Helm Chart
type: application
version: 1.2.3
appVersion: "3.1.0"
keywords:
- web
- nginx
maintainers:
- name: devops-team
email: devops@example.com
dependencies:
- name: redis
version: "18.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
import-values:
- child: service.port
parent: redisPort
模板变量与Go Template函数实战
Helm模板使用Go template语法,内置Sprig函数库提供字符串、集合、编码等60+函数。_helpers.tpl文件定义可复用的命名模板,通过include调用。
# templates/_helpers.tpl
{{- define "webapp.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "webapp.fullname" -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- printf "%s-%s" $name .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "webapp.labels" -}}
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version }}
{{ include "webapp.selectorLabels" . }}
{{- if .Chart.AppVersion -}}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end -}}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- define "webapp.selectorLabels" -}}
app.kubernetes.io/name: {{ include "webapp.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "webapp.fullname" . }}
labels:
{{- include "webapp.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
{{- with .Values.strategy }}
strategy:
{{- toYaml . | nindent 4 }}
{{- end }}
selector:
matchLabels:
{{- include "webapp.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
labels:
{{- include "webapp.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
{{- if .Values.probes.enabled }}
livenessProbe:
httpGet:
path: {{ .Values.probes.liveness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
readinessProbe:
httpGet:
path: {{ .Values.probes.readiness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
env:
{{- range $key, $val := .Values.env }}
- name: {{ $key }}
value: {{ $val | quote }}
{{- end }}
values.yaml分层配置与环境覆盖
# values.yaml - 默认配置
replicaCount: 2
image:
repository: registry.example.com/webapp
tag: ""
pullPolicy: IfNotPresent
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
service:
type: ClusterIP
port: 8080
resources:
limits:
cpu: 1000m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
env:
LOG_LEVEL: info
DB_HOST: postgres.internal
probes:
enabled: true
liveness:
path: /health
initialDelaySeconds: 15
readiness:
path: /ready
initialDelaySeconds: 5
# 环境覆盖:生产环境
# helm install webapp ./webapp -f values-prod.yaml
# values-prod.yaml
replicaCount: 5
image:
tag: "3.1.0-prod"
resources:
limits:
cpu: 2000m
memory: 1Gi
requests:
cpu: 500m
memory: 512Mi
env:
LOG_LEVEL: warn
DB_HOST: pg-cluster.internal
Chart依赖管理与子Chart值传递
复杂应用拆分为主Chart和子Chart,子Chart的值通过主Chart的values.yaml中以其名称为键的节点覆盖。import-values实现子Chart数据引用到父Chart。
# 父Chart values.yaml中配置子Chart
redis:
enabled: true
auth:
enabled: true
password: "SecurePass123"
architecture: replication
master:
persistence:
size: 8Gi
replica:
replicaCount: 2
# 更新依赖
helm dependency update
helm dependency build
# 安装时传递子Chart配置
helm install webapp ./webapp \n --set redis.auth.password="NewPass456" \n --set redis.master.persistence.size=16Gi
Helm CI/CD流水线集成与版本管理
# GitLab CI 中自动化Lint、测试、打包
stages:
- lint
- test
- package
helm-lint:
stage: lint
image: alpine/helm:3.14
script:
- helm lint ./webapp
- helm template ./webapp --validate > /dev/null
helm-test:
stage: test
image: alpine/helm:3.14
services:
- docker:24.0-dind
script:
- helm install test-release ./webapp -f values-test.yaml
- helm test test-release
- helm uninstall test-release
helm-package:
stage: package
image: alpine/helm:3.14
script:
- helm package ./webapp --version $CI_COMMIT_TAG
- helm push webapp-*.tgz oci://registry.example.com/charts
only:
- tags
# 回滚操作
# helm history webapp --namespace prod
# helm rollback webapp 3 --namespace prod
checksum/config注解确保ConfigMap变更时Pod自动滚动更新。生产环境建议maxUnavailable设为0、maxSurge设为1,保证滚动更新期间零停机。Chart版本号遵循SemVer规范,CI管线中用Git Tag触发自动打包推送。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/helmchart-mu-ban-kai-fa-shi-zhan-yu-kubernetes-ying-yong/