使用 ConfigMap 配置应用程序

KubernetesBeginner
立即练习

介绍

ConfigMap 将非敏感配置与容器镜像分离开来。这使你能够使用相同的应用程序镜像,但通过不同的设置(如开发模式、日志级别、功能开关或端点名称)来运行。

在本实验中,你将创建一个 ConfigMap,检查其数据,使用它来配置 Pod,更新 ConfigMap,并重新创建 Pod 以获取新值。后续实验将深入探讨具体的环境变量注入和挂载配置文件的方法;本实验重点在于 ConfigMap 对象本身以及核心的应用程序配置工作流程。

准备 ConfigMap 命名空间

在此步骤中,你将为 ConfigMap 的练习准备一个干净的命名空间。

从 /home/labex/project 开始。你将在此目录中编写一个 Pod 清单。

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 就绪。

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

预期输出:

pod/calico-node-... condition met

创建一个名为 ckad-prep-configmaps 的命名空间:

kubectl create namespace ckad-prep-configmaps

将此命名空间设置为当前上下文的命名空间:

kubectl config set-context --current --namespace=ckad-prep-configmaps

确认当前命名空间:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

预期输出:

ckad-prep-configmaps

创建并检查 ConfigMap

在此步骤中,你将创建一个包含简单应用程序设置的 ConfigMap。

kubectl create configmap 命令可以直接从字面量键值对创建 ConfigMap。每个 --from-literal 标志都会在 ConfigMap 的 data 字段下添加一个条目。

kubectl create configmap app-settings \
  --from-literal=APP_MODE=dev \
  --from-literal=LOG_LEVEL=debug \
  --from-literal=FEATURE_BANNER=enabled

预期输出:

configmap/app-settings created

检查 ConfigMap 摘要:

kubectl get configmap app-settings

预期输出:

NAME           DATA   AGE
app-settings   3      ...

读取存储的值。jsonpath 可以打印选定的字段,而无需显示整个对象。

kubectl get configmap app-settings -o 'jsonpath={.data.APP_MODE}{" "}{.data.LOG_LEVEL}{" "}{.data.FEATURE_BANNER}{"\n"}'

预期输出:

dev debug enabled

你也可以将 ConfigMap 以 YAML 格式查看,以了解键在对象中的位置。

kubectl get configmap app-settings -o yaml

预期输出包括:

data:
  APP_MODE: dev
  FEATURE_BANNER: enabled
  LOG_LEVEL: debug

从 ConfigMap 配置 Pod

在此步骤中,你将启动一个 Pod,将 ConfigMap 的值读取为环境变量。

envFrom.configMapRef 字段会将 ConfigMap 中的所有键导入到容器环境中。这是一种将少量非敏感设置连接到应用程序的简洁方法。

创建 config-reader-pod.yaml:

cat > config-reader-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: config-reader
  labels:
    app: config-reader
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: reader
    image: busybox:1.36
    command:
    - /bin/sh
    - -c
    - 'echo mode=${APP_MODE}; echo level=${LOG_LEVEL}; echo banner=${FEATURE_BANNER}; sleep 3600'
    envFrom:
    - configMapRef:
        name: app-settings
EOF

应用 Pod 清单:

kubectl apply -f config-reader-pod.yaml

预期输出:

pod/config-reader created

等待 Pod 就绪:

kubectl wait --for=condition=Ready pod/config-reader --timeout=120s

预期输出:

pod/config-reader condition met

读取 Pod 日志。应用程序会打印来自 ConfigMap 的值。

kubectl logs config-reader -c reader

预期输出:

mode=dev
level=debug
banner=enabled

更新 ConfigMap 并重新创建 Pod

在此步骤中,你将更新 ConfigMap 并重新创建 Pod,以便容器接收新值。

当 ConfigMap 用作环境变量时,正在运行的容器不会自动更改其环境。必须启动一个新容器才能读取更新后的值。这是 CKAD 考试中的一个重要细节,因为你可能需要更新配置,然后重启或重新创建工作负载。

修补(Patch)ConfigMap:

kubectl patch configmap app-settings --type merge --patch '{"data":{"APP_MODE":"prod","LOG_LEVEL":"warn","FEATURE_BANNER":"disabled"}}'

预期输出:

configmap/app-settings patched

确认新的 ConfigMap 值:

kubectl get configmap app-settings -o 'jsonpath={.data.APP_MODE}{" "}{.data.LOG_LEVEL}{" "}{.data.FEATURE_BANNER}{"\n"}'

预期输出:

prod warn disabled

删除旧的 Pod:

kubectl delete pod config-reader

预期输出包括:

pod "config-reader" deleted

使用相同的清单重新创建 Pod 并等待其就绪:

kubectl apply -f config-reader-pod.yaml
kubectl wait --for=condition=Ready pod/config-reader --timeout=120s

预期输出:

pod/config-reader created
pod/config-reader condition met

再次读取日志。新的 Pod 现在可以看到更新后的 ConfigMap 值。

kubectl logs config-reader -c reader

预期输出:

mode=prod
level=warn
banner=disabled

总结

你创建了一个 ConfigMap,检查了其数据,将其连接到应用程序 Pod,更新了 ConfigMap,并重新创建了 Pod 以便容器获取新值。这为你掌握核心的 ConfigMap 工作流程打下了基础,后续实验将进一步探讨更详细的环境变量和文件挂载模式。