3. Helm Chart 基础回顾:Chart 结构、Values 文件、模板渲染、Release 管理
在深入 DNS 故障场景的架构适配之前,必须牢固掌握 Helm 的核心基础。Helm 是 Kubernetes 的包管理工具,它将应用定义、配置和部署逻辑封装为 Chart。本节将系统回顾 Chart 的目录结构、Values 文件的参数化机制、Go 模板渲染引擎的工作原理,以及 Release 的生命周期管理。
3.1 Chart 标准目录结构
一个标准的 Helm Chart 遵循固定的目录布局,每个文件和文件夹都有明确的职责。理解这一结构是编写可维护 Chart 的前提。
| 路径 / 文件 | 必需 | 说明 |
|---|---|---|
Chart.yaml |
是 | Chart 的元数据文件,包含名称、版本、API 版本、描述等。 |
values.yaml |
是 | 默认配置值文件,用户可通过 --set 或自定义 values 文件覆盖。 |
templates/ |
是 | 存放 Kubernetes 资源模板(YAML + Go 模板语法),Helm 渲染后生成最终清单。 |
charts/ |
否 | 存放子 Chart(依赖),用于构建复合应用。 |
crds/ |
否 | 自定义资源定义(CRD),在模板渲染前安装。 |
templates/NOTES.txt |
否 | 安装成功后打印的使用说明文本。 |
templates/_helpers.tpl |
否 | 存放可复用的模板片段(命名模板),通过 include 调用。 |
templates/_helpers.tpl 常用于生成统一的 DNS 后缀或服务发现名称,确保模板复用性。
3.2 Values 文件与参数化
Values 文件是 Helm 实现配置与代码分离的核心机制。通过 values.yaml 定义默认值,用户可以在部署时通过 -f custom-values.yaml 或 --set key=value 进行覆盖。
Values 支持嵌套结构、列表和类型约束。以下是一个典型示例:
# values.yaml
replicaCount: 3
image:
repository: nginx
tag: "1.25"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
dnsConfig:
nameservers:
- 8.8.8.8
- 1.1.1.1
searches:
- svc.cluster.local
- default.svc.cluster.local
dnsConfig 字段应作为 Values 中的一等公民暴露,允许运维人员快速切换 nameservers 或调整搜索域,而无需修改模板代码。
3.3 模板渲染引擎
Helm 使用 Go 的 text/template 引擎,并扩展了 sprig 函数库。模板文件位于 templates/ 目录,以 .yaml 或 .tpl 结尾。渲染过程将 Values 对象注入模板,生成最终的 Kubernetes 资源清单。
核心语法包括:
- 变量引用:
{{ .Values.replicaCount }}—— 点号.代表根作用域。 - 流程控制:
{{- if .Values.service.enabled }} ... {{- end }}—— 支持条件判断、循环range。 - 命名模板:在
_helpers.tpl中定义{{- define "myapp.labels" -}} ... {{- end }},在模板中通过{{ include "myapp.labels" . }}调用。 - 管道与函数:
{{ .Values.image.tag | default "latest" | quote }}—— 支持链式处理。
以下是一个 Deployment 模板的简化示例:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
labels:
{{- include "myapp.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "myapp.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "myapp.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.dnsConfig }}
dnsConfig:
nameservers:
{{- toYaml .nameservers | nindent 10 }}
searches:
{{- toYaml .searches | nindent 10 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
toYaml 时,必须配合 nindent 控制缩进,否则生成的 YAML 缩进错误会导致 Kubernetes API 拒绝资源。尤其在 DNS 配置等嵌套结构中,缩进错误是高频故障点。
3.4 Release 管理
Release 是 Helm Chart 的一次部署实例。每次 helm install 或 helm upgrade 都会创建一个新的 Release 版本,并记录在集群的 Secret 中。Release 管理是回滚、升级和故障恢复的基础。
| 命令 | 作用 | DNS 故障场景下的关键行为 |
|---|---|---|
helm install |
首次部署 Chart,创建 Release | 如果集群 DNS 不可用,Pod 可能无法解析服务名,导致启动探针失败。 |
helm upgrade |
升级 Release 到新版本 | 支持 --recreate-pods 强制重建;DNS 故障时需确保新 Pod 能获取正确 DNS 配置。 |
helm rollback |
回滚到指定 Release 版本 | 回滚操作依赖 Secret 中的历史记录;DNS 故障不影响回滚本身,但回滚后的 Pod 仍需 DNS 就绪。 |
helm list |
列出所有 Release | 仅查询集群内 Secret,不依赖 DNS。 |
helm uninstall |
删除 Release | 删除操作不依赖 DNS,但需注意清理关联的 Service 和 Endpoint。 |
helm upgrade --install 的原子性尤为重要。建议在 Values 中预置 dnsConfig 的 fallback 策略,确保新部署的 Pod 即使 DNS 解析失败,也能通过硬编码的 IP 或备用 nameserver 完成初始化。
3.5 Chart 渲染与 Release 生命周期流程图
下图展示了从 Chart 源文件到最终 Release 的完整渲染与部署流程,重点标注了 Values 注入和模板渲染的关键步骤。
3.6 模板渲染与 Values 合并机制
为了进一步理解 Values 的优先级和合并规则,下图展示了 Helm 在渲染前如何合并多个 Values 来源。
dnsConfig.nameservers 和 dnsConfig.searches 设计为列表类型,并通过 --set 在 CI/CD 流水线中动态注入。利用 Helm 的 --set-json 可以完整替换整个 DNS 配置块,避免列表合并带来的意外行为。