Helm Chart 编写

Helm Chart 是 Kubernetes 应用的打包格式,包含描述应用所需资源的模板文件。编写高质量的 Helm Chart 是实现应用标准化部署的关键。

Chart 项目结构
graph TD
    A[Helm Chart]
    A --> B[Chart.yaml]
    A --> C[values.yaml]
    A --> D[templates/]
    A --> E[charts/]
    A --> F[README.md]
    
    D --> G[deployment.yaml]
    D --> H[service.yaml]
    D --> I[_helpers.tpl]
    D --> J[ingress.yaml]
    D --> K[NOTES.txt]
    
    E --> L[依赖 Chart]
    
    B --> M[元数据]
    C --> N[默认值]
    G --> O[应用部署]
    H --> P[服务暴露]
                                
创建 Chart 示例
# 创建新的 Chart
helm create my-app
# Chart.yaml 示例
apiVersion: v2
name: my-app
description: A Helm chart for my application
type: application
version: 0.1.0
appVersion: "1.0.0"
home: https://example.com
sources:
  - https://github.com/my-org/my-app
maintainers:
  - name: maintainer
    email: maintainer@example.com
dependencies:
  - name: redis
    version: "15.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled
模板语法与函数

Helm 使用 Go 模板语言和 Sprig 库函数来动态生成 Kubernetes 资源清单。

# 模板函数示例
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
  labels:
    {{- include "my-app.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "my-app.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "my-app.selectorLabels" . | nindent 8 }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - name: http
          containerPort: {{ .Values.service.port }}
          protocol: TCP
_helpers.tpl 命名模板

使用命名模板来定义可重用的模板片段,提高代码复用性。

# _helpers.tpl 示例
{{/*
Expand the name of the chart.
*/}}
{{- define "my-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "my-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "my-app.labels" -}}
helm.sh/chart: {{ include "my-app.chart" . }}
{{ include "my-app.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
Chart 最佳实践
结构与组织
  • 使用语义化版本控制
  • 提供清晰的 README.md
  • 合理组织模板文件
  • 使用命名模板提高复用性
配置与测试
  • 提供合理的默认值
  • 支持条件部署
  • 包含测试模板
  • 验证 Chart 质量
常用 Chart 开发命令
# 验证 Chart
helm lint
# 查看渲染后的模板
helm template .
# 安装开发版本
helm install my-test . --dry-run
# 打包 Chart
helm package .
# 测试 Chart
helm test <release-name>