介绍
之前的部署实验直接使用了原始的 Kubernetes 清单(manifests)。Helm 在这些清单之上增加了一个打包层。Helm chart 将相关的 Kubernetes 模板存储在一起,通过 values.yaml 暴露可重用的设置,并将渲染后的对象安装为一个命名的发布版本(release)。
在本实验中,你将构建一个小型本地 chart,而不是从仓库下载。你将编写 chart 元数据、配置值、Deployment 模板和 Service 模板,在安装前渲染 chart,然后通过更改配置值来升级发布版本。这有助于你专注于 CKAD 的核心技能:理解本地 chart 如何转化为普通的 Kubernetes 对象。
准备 Helm 工作空间
在此步骤中,你将准备一个命名空间,并确认本地 Helm chart 工作流所需的工具。
从 /home/labex/project 开始。本实验将 chart 目录、生成的清单以及所有命令都保存在此工作空间中。
mkdir -p /home/labex/project
cd /home/labex/project
检查 Kubernetes API 服务器是否可达。如果虚拟机刚启动且节点尚未就绪,请等待几秒钟后再次运行该命令。
kubectl get nodes --request-timeout=5s
预期输出包括:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
等待集群网络 Pod 变为就绪状态。由于 chart 将创建一个 Service,因此在进行流量测试之前,应用程序 Pod 需要集群网络支持。
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
预期输出:
pod/calico-node-... condition met
创建一个名为 ckad-prep-helm 的命名空间,并将其设置为当前命名空间:
kubectl create namespace ckad-prep-helm
kubectl config set-context --current --namespace=ckad-prep-helm
确认当前命名空间和 Helm 客户端。Helm 3 使用当前的 kubeconfig 直接与 Kubernetes 交互;不再有独立的服务器端 Tiller 组件。
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
helm version --short
预期输出包括:
ckad-prep-helm
v...
创建并渲染本地 Chart
在此步骤中,你将创建一个最小化的本地 Helm chart,并在安装前对其进行渲染。
chart 目录包含几个重要部分。Chart.yaml 描述了 chart 本身。values.yaml 包含默认设置。templates/ 下的文件是带有模板表达式(如 {{ .Values.replicaCount }})的 Kubernetes 清单。当 Helm 渲染或安装 chart 时,它会将这些表达式替换为具体的值。
创建 chart 目录:
mkdir -p local-web-chart/templates
编写 Chart.yaml。chart 名称与发布名称不同;发布名称是在安装 chart 时选择的。
cat > local-web-chart/Chart.yaml <<'EOF'
apiVersion: v2
name: local-web
description: A small local chart for CKAD deployment practice
type: application
version: 0.1.0
appVersion: "1.0"
EOF
编写 values.yaml。这些默认值控制 Pod 数量、容器镜像、Service 端口以及应用程序提供的消息。
cat > local-web-chart/values.yaml <<'EOF'
replicaCount: 2
image:
repository: busybox
tag: "1.36"
service:
port: 80
targetPort: 8080
message: helm-v1
EOF
创建 Deployment 模板。该模板在对象名称和标签中使用发布名称,因此同一个 chart 可以以不同的发布名称安装多次。
cat > local-web-chart/templates/deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-web
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- |
mkdir -p /www
echo {{ .Values.message | quote }} > /www/index.html
httpd -f -p {{ .Values.service.targetPort }} -h /www
ports:
- containerPort: {{ .Values.service.targetPort }}
readinessProbe:
httpGet:
path: /
port: {{ .Values.service.targetPort }}
initialDelaySeconds: 1
periodSeconds: 2
EOF
创建 Service 模板。注意,Service 选择器使用了与 Pod 模板相同的标签。
cat > local-web-chart/templates/service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
selector:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
EOF
运行 helm lint 来检查 chart 结构和模板问题:
helm lint ./local-web-chart
预期输出包括:
1 chart(s) linted, 0 chart(s) failed
在本地渲染 chart。helm template 会打印出 Helm 将发送给 API 服务器的 Kubernetes YAML,但不会创建任何对象。
helm template local-web ./local-web-chart | sed -n '1,120p'
预期输出包括一个名为 local-web 的 Service 和一个名为 local-web-web 的 Deployment。
将 Chart 安装为发布版本
在此步骤中,你将把本地 chart 安装到 ckad-prep-helm 命名空间中。
安装 chart 会创建一个 Helm 发布版本。在本实验中,发布名称为 local-web。Helm 会记录发布元数据,而 Kubernetes 会接收到普通的 Deployment 和 Service 等对象。
安装 chart:
helm install local-web ./local-web-chart
预期输出包括:
NAME: local-web
STATUS: deployed
等待 chart 创建的 Deployment 就绪:
kubectl rollout status deployment/local-web-web --timeout=120s
预期输出:
deployment "local-web-web" successfully rolled out
检查发布版本及其创建的 Kubernetes 对象:
helm list
kubectl get deployment,service -l app.kubernetes.io/instance=local-web
预期输出包括:
local-web
deployment.apps/local-web-web
service/local-web
创建一个客户端 Pod 并向 Service 发送请求。这证实了 chart 不仅创建了对象,而且安装的应用程序确实是可访问的。
kubectl run chart-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/chart-client --timeout=120s
kubectl exec chart-client -- wget -qO- http://local-web
预期输出:
helm-v1
使用新配置值升级发布版本
在此步骤中,你将通过覆盖 chart 的配置值来升级现有的发布版本。
该 chart 已经包含了可重用的模板。你无需编辑模板文件即可更改消息或副本数量。helm upgrade 会使用新的配置值重新渲染同一个 chart,更新 Kubernetes 对象,并记录一个新的发布修订版本。
升级发布版本,使其通过 3 个副本提供 helm-v2 消息:
helm upgrade local-web ./local-web-chart --set message=helm-v2 --set replicaCount=3
预期输出包括:
Release "local-web" has been upgraded.
STATUS: deployed
等待升级后的 Deployment 就绪:
kubectl rollout status deployment/local-web-web --timeout=120s
预期输出:
deployment "local-web-web" successfully rolled out
检查发布历史记录以及当前随发布版本存储的配置值:
helm history local-web
helm get values local-web
预期输出包括两个修订版本以及被覆盖的配置值:
REVISION
1
2
message: helm-v2
replicaCount: 3
检查正在运行的 Deployment 和应用程序响应:
kubectl get deployment local-web-web
kubectl exec chart-client -- wget -qO- http://local-web
预期输出包括:
3/3
helm-v2
总结
你通过 chart 元数据、默认配置值和 Kubernetes 模板创建了一个本地 Helm chart。你在安装前渲染了 chart,将其安装为发布版本,测试了 Service,并通过覆盖配置值升级了发布版本。核心思想是:Helm 将可重复的应用程序部署工作打包,同时仍然生成你可以使用 kubectl 检查的普通 Kubernetes 对象。


