helm-chart-scaffolding

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Helm Chart Scaffolding

Helm Chart 脚手架搭建

Comprehensive guidance for creating, organizing, and managing Helm charts for packaging and deploying Kubernetes applications.
本文为创建、组织和管理用于打包与部署Kubernetes应用的Helm Charts提供全面指导。

Purpose

用途

This skill provides step-by-step instructions for building production-ready Helm charts, including chart structure, templating patterns, values management, and validation strategies.
本技能提供构建生产级Helm Charts的分步说明,包括Chart结构、模板化模式、配置值管理和验证策略。

When to Use This Skill

适用场景

Use this skill when you need to:
  • Create new Helm charts from scratch
  • Package Kubernetes applications for distribution
  • Manage multi-environment deployments with Helm
  • Implement templating for reusable Kubernetes manifests
  • Set up Helm chart repositories
  • Follow Helm best practices and conventions
在以下场景中使用本技能:
  • 从零开始创建新的Helm Charts
  • 打包Kubernetes应用以进行分发
  • 使用Helm管理多环境部署
  • 为可复用的Kubernetes清单实现模板化
  • 搭建Helm Chart仓库
  • 遵循Helm最佳实践与规范

Helm Overview

Helm 概述

Helm is the package manager for Kubernetes that:
  • Templates Kubernetes manifests for reusability
  • Manages application releases and rollbacks
  • Handles dependencies between charts
  • Provides version control for deployments
  • Simplifies configuration management across environments
Helm是Kubernetes的包管理器,具备以下功能:
  • 为Kubernetes清单提供模板化以实现复用
  • 管理应用版本发布与回滚
  • 处理Chart之间的依赖关系
  • 为部署提供版本控制
  • 简化跨环境的配置管理

Step-by-Step Workflow

分步工作流

1. Initialize Chart Structure

1. 初始化Chart结构

Create new chart:
bash
helm create my-app
Standard chart structure:
my-app/
├── Chart.yaml           # Chart metadata
├── values.yaml          # Default configuration values
├── charts/              # Chart dependencies
├── templates/           # Kubernetes manifest templates
│   ├── NOTES.txt       # Post-install notes
│   ├── _helpers.tpl    # Template helpers
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── serviceaccount.yaml
│   ├── hpa.yaml
│   └── tests/
│       └── test-connection.yaml
└── .helmignore         # Files to ignore
创建新Chart:
bash
helm create my-app
标准Chart结构:
my-app/
├── Chart.yaml           # Chart元数据
├── values.yaml          # 默认配置值
├── charts/              # Chart依赖
├── templates/           # Kubernetes清单模板
│   ├── NOTES.txt       # 安装后说明
│   ├── _helpers.tpl    # 模板助手
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── serviceaccount.yaml
│   ├── hpa.yaml
│   └── tests/
│       └── test-connection.yaml
└── .helmignore         # 需忽略的文件

2. Configure Chart.yaml

2. 配置Chart.yaml

Chart metadata defines the package:
yaml
apiVersion: v2
name: my-app
description: A Helm chart for My Application
type: application
version: 1.0.0 # Chart version
appVersion: "2.1.0" # Application version
Chart元数据定义包信息:
yaml
apiVersion: v2
name: my-app
description: A Helm chart for My Application
type: application
version: 1.0.0 # Chart version
appVersion: "2.1.0" # Application version

Keywords for chart discovery

Keywords for chart discovery

keywords:
  • web
  • api
  • backend
keywords:
  • web
  • api
  • backend

Maintainer information

Maintainer information

maintainers:
maintainers:

Source code repository

Source code repository

Homepage

Homepage

Chart icon

Chart icon

Dependencies

Dependencies

dependencies:

**Reference:** See `assets/Chart.yaml.template` for complete example
dependencies:

**参考:** 完整示例请查看 `assets/Chart.yaml.template`

3. Design values.yaml Structure

3. 设计values.yaml结构

Organize values hierarchically:
yaml
undefined
按层级组织配置值:
yaml
undefined

Image configuration

Image configuration

image: repository: myapp tag: "1.0.0" pullPolicy: IfNotPresent
image: repository: myapp tag: "1.0.0" pullPolicy: IfNotPresent

Number of replicas

Number of replicas

replicaCount: 3
replicaCount: 3

Service configuration

Service configuration

service: type: ClusterIP port: 80 targetPort: 8080
service: type: ClusterIP port: 80 targetPort: 8080

Ingress configuration

Ingress configuration

ingress: enabled: false className: nginx hosts: - host: app.example.com paths: - path: / pathType: Prefix
ingress: enabled: false className: nginx hosts: - host: app.example.com paths: - path: / pathType: Prefix

Resources

Resources

resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m"
resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m"

Autoscaling

Autoscaling

autoscaling: enabled: false minReplicas: 2 maxReplicas: 10 targetCPUUtilizationPercentage: 80
autoscaling: enabled: false minReplicas: 2 maxReplicas: 10 targetCPUUtilizationPercentage: 80

Environment variables

Environment variables

env:
  • name: LOG_LEVEL value: "info"
env:
  • name: LOG_LEVEL value: "info"

ConfigMap data

ConfigMap data

configMap: data: APP_MODE: production
configMap: data: APP_MODE: production

Dependencies

Dependencies

postgresql: enabled: true auth: database: myapp username: myapp
redis: enabled: false

**Reference:** See `assets/values.yaml.template` for complete structure
postgresql: enabled: true auth: database: myapp username: myapp
redis: enabled: false

**参考:** 完整结构请查看 `assets/values.yaml.template`

4. Create Template Files

4. 创建模板文件

Use Go templating with Helm functions:
templates/deployment.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
  labels:
    {{- include "my-app.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  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 | default .Chart.AppVersion }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - name: http
          containerPort: {{ .Values.service.targetPort }}
        resources:
          {{- toYaml .Values.resources | nindent 12 }}
        env:
          {{- toYaml .Values.env | nindent 12 }}
结合Helm函数使用Go模板:
templates/deployment.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
  labels:
    {{- include "my-app.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  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 | default .Chart.AppVersion }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - name: http
          containerPort: {{ .Values.service.targetPort }}
        resources:
          {{- toYaml .Values.resources | nindent 12 }}
        env:
          {{- toYaml .Values.env | nindent 12 }}

5. Create Template Helpers

5. 创建模板助手

templates/_helpers.tpl:
yaml
{{/*
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.
*/}}
{{- 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 }}

{{/*
Selector labels
*/}}
{{- define "my-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
templates/_helpers.tpl:
yaml
{{/*
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.
*/}}
{{- 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 }}

{{/*
Selector labels
*/}}
{{- define "my-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

6. Manage Dependencies

6. 管理依赖

Add dependencies in Chart.yaml:
yaml
dependencies:
  - name: postgresql
    version: "12.0.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
Update dependencies:
bash
helm dependency update
helm dependency build
Override dependency values:
yaml
undefined
在Chart.yaml中添加依赖:
yaml
dependencies:
  - name: postgresql
    version: "12.0.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled
更新依赖:
bash
helm dependency update
helm dependency build
覆盖依赖配置值:
yaml
undefined

values.yaml

values.yaml

postgresql: enabled: true auth: database: myapp username: myapp password: changeme primary: persistence: enabled: true size: 10Gi
undefined
postgresql: enabled: true auth: database: myapp username: myapp password: changeme primary: persistence: enabled: true size: 10Gi
undefined

7. Test and Validate

7. 测试与验证

Validation commands:
bash
undefined
验证命令:
bash
undefined

Lint the chart

Lint the chart

helm lint my-app/
helm lint my-app/

Dry-run installation

Dry-run installation

helm install my-app ./my-app --dry-run --debug
helm install my-app ./my-app --dry-run --debug

Template rendering

Template rendering

helm template my-app ./my-app
helm template my-app ./my-app

Template with values

Template with values

helm template my-app ./my-app -f values-prod.yaml
helm template my-app ./my-app -f values-prod.yaml

Show computed values

Show computed values

helm show values ./my-app

**Validation script:**

```bash
#!/bin/bash
set -e

echo "Linting chart..."
helm lint .

echo "Testing template rendering..."
helm template test-release . --dry-run

echo "Checking for required values..."
helm template test-release . --validate

echo "All validations passed!"
Reference: See
scripts/validate-chart.sh
helm show values ./my-app

**验证脚本:**

```bash
#!/bin/bash
set -e

echo "Linting chart..."
helm lint .

echo "Testing template rendering..."
helm template test-release . --dry-run

echo "Checking for required values..."
helm template test-release . --validate

echo "All validations passed!"
参考: 请查看
scripts/validate-chart.sh

8. Package and Distribute

8. 打包与分发

Package the chart:
bash
helm package my-app/
打包Chart:
bash
helm package my-app/

Creates: my-app-1.0.0.tgz

Creates: my-app-1.0.0.tgz


**Create chart repository:**

```bash

**创建Chart仓库:**

```bash

Create index

Create index

helm repo index .
helm repo index .

Upload to repository

Upload to repository

AWS S3 example

AWS S3 example

aws s3 sync . s3://my-helm-charts/ --exclude "" --include ".tgz" --include "index.yaml"

**Use the chart:**

```bash
helm repo add my-repo https://charts.example.com
helm repo update
helm install my-app my-repo/my-app
aws s3 sync . s3://my-helm-charts/ --exclude "" --include ".tgz" --include "index.yaml"

**使用Chart:**

```bash
helm repo add my-repo https://charts.example.com
helm repo update
helm install my-app my-repo/my-app

9. Multi-Environment Configuration

9. 多环境配置

Environment-specific values files:
my-app/
├── values.yaml          # Defaults
├── values-dev.yaml      # Development
├── values-staging.yaml  # Staging
└── values-prod.yaml     # Production
values-prod.yaml:
yaml
replicaCount: 5

image:
  tag: "2.1.0"

resources:
  requests:
    memory: "512Mi"
    cpu: "500m"
  limits:
    memory: "1Gi"
    cpu: "1000m"

autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 20

ingress:
  enabled: true
  hosts:
    - host: app.example.com
      paths:
        - path: /
          pathType: Prefix

postgresql:
  enabled: true
  primary:
    persistence:
      size: 100Gi
Install with environment:
bash
helm install my-app ./my-app -f values-prod.yaml --namespace production
环境专属配置值文件:
my-app/
├── values.yaml          # 默认配置
├── values-dev.yaml      # 开发环境
├── values-staging.yaml  # 预发布环境
└── values-prod.yaml     # 生产环境
values-prod.yaml:
yaml
replicaCount: 5

image:
  tag: "2.1.0"

resources:
  requests:
    memory: "512Mi"
    cpu: "500m"
  limits:
    memory: "1Gi"
    cpu: "1000m"

autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 20

ingress:
  enabled: true
  hosts:
    - host: app.example.com
      paths:
        - path: /
          pathType: Prefix

postgresql:
  enabled: true
  primary:
    persistence:
      size: 100Gi
按环境安装:
bash
helm install my-app ./my-app -f values-prod.yaml --namespace production

10. Implement Hooks and Tests

10. 实现钩子与测试

Pre-install hook:
yaml
undefined
安装前钩子:
yaml
undefined

templates/pre-install-job.yaml

templates/pre-install-job.yaml

apiVersion: batch/v1 kind: Job metadata: name: {{ include "my-app.fullname" . }}-db-setup annotations: "helm.sh/hook": pre-install "helm.sh/hook-weight": "-5" "helm.sh/hook-delete-policy": hook-succeeded spec: template: spec: containers: - name: db-setup image: postgres:15 command: ["psql", "-c", "CREATE DATABASE myapp"] restartPolicy: Never

**Test connection:**

```yaml
apiVersion: batch/v1 kind: Job metadata: name: {{ include "my-app.fullname" . }}-db-setup annotations: "helm.sh/hook": pre-install "helm.sh/hook-weight": "-5" "helm.sh/hook-delete-policy": hook-succeeded spec: template: spec: containers: - name: db-setup image: postgres:15 command: ["psql", "-c", "CREATE DATABASE myapp"] restartPolicy: Never

**连接测试:**

```yaml

templates/tests/test-connection.yaml

templates/tests/test-connection.yaml

apiVersion: v1 kind: Pod metadata: name: "{{ include "my-app.fullname" . }}-test-connection" annotations: "helm.sh/hook": test spec: containers:
  • name: wget image: busybox command: ['wget'] args: ['{{ include "my-app.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never

**Run tests:**

```bash
helm test my-app
apiVersion: v1 kind: Pod metadata: name: "{{ include "my-app.fullname" . }}-test-connection" annotations: "helm.sh/hook": test spec: containers:
  • name: wget image: busybox command: ['wget'] args: ['{{ include "my-app.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never

**运行测试:**

```bash
helm test my-app

Common Patterns

常见模式

Pattern 1: Conditional Resources

模式1:条件化资源

yaml
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "my-app.fullname" . }}
spec:
  # ...
{{- end }}
yaml
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "my-app.fullname" . }}
spec:
  # ...
{{- end }}

Pattern 2: Iterating Over Lists

模式2:遍历列表

yaml
env:
{{- range .Values.env }}
- name: {{ .name }}
  value: {{ .value | quote }}
{{- end }}
yaml
env:
{{- range .Values.env }}
- name: {{ .name }}
  value: {{ .value | quote }}
{{- end }}

Pattern 3: Including Files

模式3:引入文件

yaml
data:
  config.yaml: |
    {{- .Files.Get "config/application.yaml" | nindent 4 }}
yaml
data:
  config.yaml: |
    {{- .Files.Get "config/application.yaml" | nindent 4 }}

Pattern 4: Global Values

模式4:全局配置值

yaml
global:
  imageRegistry: docker.io
  imagePullSecrets:
    - name: regcred
yaml
global:
  imageRegistry: docker.io
  imagePullSecrets:
    - name: regcred

Use in templates:

Use in templates:

image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}
undefined
image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}
undefined

Best Practices

最佳实践

  1. Use semantic versioning for chart and app versions
  2. Document all values in values.yaml with comments
  3. Use template helpers for repeated logic
  4. Validate charts before packaging
  5. Pin dependency versions explicitly
  6. Use conditions for optional resources
  7. Follow naming conventions (lowercase, hyphens)
  8. Include NOTES.txt with usage instructions
  9. Add labels consistently using helpers
  10. Test installations in all environments
  1. 为Chart和应用版本使用语义化版本控制
  2. 在values.yaml中为所有配置值添加注释说明
  3. 使用模板助手处理重复逻辑
  4. 打包前验证Chart
  5. 显式固定依赖版本
  6. 为可选资源使用条件判断
  7. 遵循命名规范(小写、连字符分隔)
  8. 包含NOTES.txt提供使用说明
  9. 通过助手统一添加标签
  10. 在所有环境中测试安装流程

Troubleshooting

故障排查

Template rendering errors:
bash
helm template my-app ./my-app --debug
Dependency issues:
bash
helm dependency update
helm dependency list
Installation failures:
bash
helm install my-app ./my-app --dry-run --debug
kubectl get events --sort-by='.lastTimestamp'
模板渲染错误:
bash
helm template my-app ./my-app --debug
依赖问题:
bash
helm dependency update
helm dependency list
安装失败:
bash
helm install my-app ./my-app --dry-run --debug
kubectl get events --sort-by='.lastTimestamp'

Reference Files

参考文件

  • assets/Chart.yaml.template
    - Chart metadata template
  • assets/values.yaml.template
    - Values structure template
  • scripts/validate-chart.sh
    - Validation script
  • references/chart-structure.md
    - Detailed chart organization
  • assets/Chart.yaml.template
    - Chart元数据模板
  • assets/values.yaml.template
    - 配置值结构模板
  • scripts/validate-chart.sh
    - 验证脚本
  • references/chart-structure.md
    - 详细Chart组织说明

Related Skills

相关技能

  • k8s-manifest-generator
    - For creating base Kubernetes manifests
  • gitops-workflow
    - For automated Helm chart deployments
  • k8s-manifest-generator
    - 用于创建基础Kubernetes清单
  • gitops-workflow
    - 用于Helm Chart自动化部署