介绍
Helm 通过将 Kubernetes 模板打包为发布版本来管理应用。Kustomize 则采用了不同的方法:它从普通的 Kubernetes YAML 文件开始,通过分层的方式应用变更,而无需使用模板表达式。当你需要一个共享的基础配置,并针对不同环境进行微小的差异化调整(如名称、命名空间、副本数或补丁)时,这种方式非常有用。
在本实验中,你将创建一个基础的 Deployment 和 Service,使用 Kustomize 渲染该基础配置,然后创建一个生产环境的覆盖层(Overlay),用于修改名称、命名空间、副本数和应用程序消息。最后,你将使用 kubectl apply -k 部署该覆盖层并测试生成的 Service。
准备 Kustomize 工作空间
在此步骤中,你将准备一个命名空间,并确认 kubectl 已支持 Kustomize 功能。
从 /home/labex/project 开始。本实验将基础清单文件和覆盖层文件保存在此工作空间中。
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 变为就绪状态。你将在实验结束时测试 Service,因此集群网络必须处于健康状态。
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
预期输出:
pod/calico-node-... condition met
创建一个名为 ckad-prep-kustomize 的命名空间,并将其设置为当前命名空间:
kubectl create namespace ckad-prep-kustomize
kubectl config set-context --current --namespace=ckad-prep-kustomize
确认命名空间并检查 kubectl kustomize 是否可用。kubectl kustomize 可以在不应用的情况下渲染 Kustomize 目录。
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
kubectl kustomize --help | sed -n '1,3p'
预期输出包含:
ckad-prep-kustomize
Build a set of KRM resources...
创建可重用的基础配置
在此步骤中,你将从普通的 Kubernetes YAML 文件创建一个 Kustomize 基础配置(Base)。
基础配置是共享的起点。在添加任何特定于环境的自定义之前,它应该包含完整、有效的 Kubernetes 对象。在这里,基础配置包含一个 Deployment 和一个 Service。该应用程序会将 MESSAGE 环境变量的值写入一个小网页中。
创建基础目录:
mkdir -p kustomize-demo/base
编写基础 Deployment:
cat > kustomize-demo/base/deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: kustomize-web
labels:
app: kustomize-web
spec:
replicas: 1
selector:
matchLabels:
app: kustomize-web
template:
metadata:
labels:
app: kustomize-web
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: busybox:1.36
env:
- name: MESSAGE
value: base-v1
command:
- /bin/sh
- -c
- |
mkdir -p /www
echo "$MESSAGE" > /www/index.html
httpd -f -p 8080 -h /www
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
EOF
编写基础 Service。其选择器(selector)与 Deployment 中的 Pod 标签匹配。
cat > kustomize-demo/base/service.yaml <<'EOF'
apiVersion: v1
kind: Service
metadata:
name: kustomize-web
spec:
selector:
app: kustomize-web
ports:
- port: 80
targetPort: 8080
EOF
创建基础 kustomization.yaml。此文件告诉 Kustomize 哪些资源属于该基础配置。
cat > kustomize-demo/base/kustomization.yaml <<'EOF'
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
EOF
在不应用的情况下渲染基础配置:
kubectl kustomize kustomize-demo/base | sed -n '1,120p'
预期输出包含一个名为 kustomize-web 的 Service、一个名为 kustomize-web 的 Deployment、replicas: 1 以及 value: base-v1。
添加生产环境覆盖层
在此步骤中,你将创建一个覆盖层(Overlay),用于为生产环境部署自定义基础配置。
覆盖层指向一个基础配置并添加变更。此覆盖层会将对象放入 ckad-prep-kustomize 命名空间,添加 prod- 名称前缀,将 Deployment 扩展为三个副本,并将 MESSAGE 的值修补(patch)为 prod-v2。
创建覆盖层目录:
mkdir -p kustomize-demo/overlays/prod
编写 Deployment 补丁。补丁指定了原始基础对象 kustomize-web。Kustomize 会在添加 prod- 前缀之前匹配该补丁。
cat > kustomize-demo/overlays/prod/deployment-patch.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: kustomize-web
spec:
replicas: 3
template:
spec:
containers:
- name: web
env:
- name: MESSAGE
value: prod-v2
EOF
创建覆盖层 kustomization.yaml。resources 条目指向基础配置,而 namespace、namePrefix 和 patches 则描述了自定义内容。
cat > kustomize-demo/overlays/prod/kustomization.yaml <<'EOF'
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: ckad-prep-kustomize
namePrefix: prod-
resources:
- ../../base
patches:
- path: deployment-patch.yaml
EOF
渲染生产环境覆盖层:
kubectl kustomize kustomize-demo/overlays/prod | sed -n '1,160p'
预期输出包含:
name: prod-kustomize-web
namespace: ckad-prep-kustomize
replicas: 3
value: prod-v2
部署并测试自定义应用程序
在此步骤中,你将应用生产环境覆盖层并测试它创建的 Service。
命令 kubectl apply -k 会渲染 Kustomize 目录并将渲染后的对象发送到 Kubernetes API 服务器。你无需创建临时的 YAML 文件。
应用生产环境覆盖层:
kubectl apply -k kustomize-demo/overlays/prod
预期输出包含:
service/prod-kustomize-web created
deployment.apps/prod-kustomize-web created
等待自定义 Deployment 就绪:
kubectl rollout status deployment/prod-kustomize-web --timeout=120s
预期输出:
deployment "prod-kustomize-web" successfully rolled out
检查从覆盖层创建的对象:
kubectl get deployment,service prod-kustomize-web
预期输出包含:
deployment.apps/prod-kustomize-web 3/3
service/prod-kustomize-web
创建一个客户端 Pod 并测试 Service。响应应该是 prod-v2,这证明了覆盖层补丁成功修改了正在运行的应用程序配置。
kubectl run kustomize-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/kustomize-client --timeout=120s
kubectl exec kustomize-client -- wget -qO- http://prod-kustomize-web
预期输出:
prod-v2
总结
你通过普通的 Deployment 和 Service YAML 构建了一个 Kustomize 基础配置,然后创建了一个生产环境覆盖层,修改了命名空间、对象名称、副本数和应用程序消息。你在使用 kubectl apply -k 应用覆盖层之前渲染了基础配置和覆盖层,并通过其 Service 验证了自定义后的应用程序。


