使用 Kustomize 自定义应用程序

KubernetesBeginner
立即练习

介绍

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 验证了自定义后的应用程序。