k8s(七)pod的配置资源管理
文章目录
- 前言
- 一、配置资源管理
- 1. Secret(密钥管理)
- 1.1 概念
- 1.2 Secret 类型
- 1.3 创建 Secret
- 1.3.1 方法一:命令行创建
- 1.3.2 方法二:YAML 文件(Base64 编码)
- 1.4 使用 Secret
- 1.4.1 方式一:挂载为文件
- 1.4.2 方式二:导入环境变量
- 2. ConfigMap(配置管理)
- 2.1 概念
- 2.2 创建 ConfigMap
- 2.2.1 方法一:从目录创建
- 2.2.2 方法二:从文件创建
- 2.2.3 方法三:使用字面值
- 2.3 Pod 中使用 ConfigMap
- 2.3.1 方式一:作为环境变量注入
- 2.3.2 方式二:命令行参数使用
- 2.3.3 方式三:以 Volume 形式挂载
- 2.4 ConfigMap 热更新机制
- 2.5 触发滚动更新
- 3. 总结对比表
- 总结
前言
在 Kubernetes 集群中,应用的配置管理是保障服务稳定运行的核心环节。无论是数据库密码、API 令牌等敏感信息,还是应用程序的参数配置、环境变量等非敏感数据,都需要一套规范的管理机制来实现配置与代码的解耦、提升安全性,并简化配置的维护与更新流程。本文将聚焦 Kubernetes 中两种关键的配置资源 ——Secret 和 ConfigMap,详细解析它们的概念、创建方式、使用场景及核心特性,帮助开发者高效管理应用配置,构建更灵活、安全的容器化应用。
一、配置资源管理
在 Kubernetes 集群中,配置资源管理是保障应用的重要组成部分,它主要用于管理应用程序运行所需的配置信息和敏感数据,以实现配置与应用的解耦,提高配置的可维护性和安全性。下面将详细介绍 Kubernetes 中两种主要的配置资源:Secret 和 ConfigMap。
1. Secret(密钥管理)
1.1 概念
Secret 主要用于保存敏感数据,例如密码、Token、密钥等。
其作用在于将敏感信息与 Pod 分离,这样做既方便对敏感信息的访问进行控制,又能降低敏感信息泄露的风险。
1.2 Secret 类型
类型 | 说明 |
---|---|
kubernetes.io/service-account-token | Kubernetes 会自动创建,用于访问 APIServer。Pod 默认会将其挂载在 /run/secrets/kubernetes.io/serviceaccount 路径下。 |
Opaque | 默认类型,可用于存储用户自定义的密码、密钥等信息(这些信息会经过 Base64 编码)。 |
kubernetes.io/dockerconfigjson | 用于存储私有 Docker Registry 的认证信息。 |
kubernetes.io/tls | 用于存储 SSL/TLS 证书与私钥。 |
📌 使用前提:Pod 必须显式引用 Secret 才能使用其中存储的敏感信息。
Secret 的使用方式主要有以下几种:
- 作为 Volume 文件 挂载到 Pod 中。
- 作为 环境变量 注入到 Pod 的容器中。
- 在 kubelet 拉取镜像时作为认证信息使用。
应用场景:主要用于凭据管理。
官方文档:https://kubernetes.io/docs/concepts/configuration/secret/
1.3 创建 Secret
1.3.1 方法一:命令行创建
echo -n 'zhangsan' > username.txt
echo -n 'abc1234' > password.txtkubectl create secret generic mysecret --from-file=username.txt --from-file=password.txt
命令行创建的方式是将username.txt这个文件名作为键录入了secret中,因此当需要使用用户名或密码时,--from-file=username.txt --from-file=password.txt
这一格式创建的secret只用username.txt
、password.txt
这两个键和它们对应的文本内容作为值,而当使用--from-file=username=username.txt --from-file=password=password.txt
这样的格式创建时,直接将username.txt
指向了键username
,将password.txt
指向了password
,直接可以使用键名username
、password
进行引用。
apiVersion: v1
kind: Pod
metadata:name: secret-env-pod
spec:containers:- name: mycontainerimage: busyboxcommand: [ "sh", "-c", "echo Username: $USERNAME && echo Password: $PASSWORD && sleep 3600" ]env:- name: USERNAME # 环境变量名valueFrom:secretKeyRef:name: mysecret # 关联的 Secret 名称key: username.txt # Secret 中的键(如果用了--from-file=username=xxx.txt,这里就是username)- name: PASSWORDvalueFrom:secretKeyRef:name: mysecretkey: password.txt # 对应 Secret 中的键restartPolicy: Never
查看创建的 Secret:
kubectl get secrets
kubectl describe secret mysecret
注意:为保护数据安全,查看 Secret 时不会展示实际的敏感内容。
1.3.2 方法二:YAML 文件(Base64 编码)
首先对需要存储的敏感信息进行 Base64 编码:
echo -n zhangsan | base64 # 输出:emhhbmdzYW4=
echo -n abc1234 | base64 # 输出:YWJjMTIzNA==
然后创建 Secret 的 YAML 文件:
apiVersion: v1
kind: Secret
metadata:name: mysecret1
type: Opaque
data:password: 'YWJjMTIzNA=='username: 'emhhbmdzYW4='
创建 Secret:
kubectl apply -f secret.yaml
kubectl get secret mysecret1 -o yaml
1.4 使用 Secret
1.4.1 方式一:挂载为文件
# 将 Secret 挂载到 Volume 中,以 Volume 的形式挂载到 Pod 的某个目录下
vim secret-test.yaml
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: nginximage: nginxvolumeMounts:- name: secretsmountPath: "/etc/secrets"readOnly: truevolumes:- name: secretssecret:secretName: mysecret
验证 Secret 是否挂载成功:
kubectl exec -it mypod -- ls /etc/secrets
使用挂载的方式挂载secret时,密码和账号的键值对会变成文件放在指定的文件夹下。
1.4.2 方式二:导入环境变量
vim secret-test1.yaml
apiVersion: v1
kind: Pod
metadata:name: mypod1
spec:containers:- name: nginximage: nginxenv:- name: TEST_USERvalueFrom:secretKeyRef:name: mysecret1key: username- name: TEST_PASSWORDvalueFrom:secretKeyRef:name: mysecret1key: password
验证环境变量是否导入成功:
kubectl exec -it mypod1 -- printenv | grep TEST
- 环境变量方式:使用简单,但安全性较低,Secret 值易通过命令暴露,且更新需要重启 Pod。
- 文件挂载方式:安全性更高,更新无需重启 Pod(需应用配合),但需要应用支持读取文件获取配置。
因此,对于敏感信息(如密码、令牌),推荐使用文件挂载方式;只有在应用架构限制必须使用环境变量时,才考虑环境变量方式,且需格外注意容器内的进程安全和权限控制。
2. ConfigMap(配置管理)
2.1 概念
ConfigMap 与 Secret 类似,但它主要用于存储非敏感配置数据。ConfigMap 可以供应用程序读取配置文件、命令行参数或环境变量等。
应用场景:主要用于应用配置管理。
2.2 创建 ConfigMap
2.2.1 方法一:从目录创建
mkdir /opt/configmap/
vim /opt/configmap/game.propertiesenemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30vim /opt/configmap/ui.propertiescolor.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNicekubectl create configmap game-config --from-file=/opt/configmap/
# --from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容
2.2.2 方法二:从文件创建
kubectl create configmap game-config-2 \--from-file=/opt/configmap/game.properties \--from-file=/opt/configmap/ui.properties
2.2.3 方法三:使用字面值
kubectl create configmap special-config \--from-literal=special.how=very \--from-literal=special.type=good
2.3 Pod 中使用 ConfigMap
2.3.1 方式一:作为环境变量注入
首先创建 ConfigMap 的 YAML 文件:
vim env.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: special-confignamespace: default
data:special.how: veryspecial.type: good
---
apiVersion: v1
kind: ConfigMap
metadata:name: env-confignamespace: default
data: #log_level: INFO
在 Kubernetes 中,ConfigMap 的 data
字段是其核心部分,用于存储非敏感的配置数据,这些数据可以被 Pod 中的容器挂载和使用。
data
字段的主要作用:
-
存储配置信息
以键值对(key-value)的形式存储配置数据,例如:- 应用程序的配置文件(如
app.conf
、database.properties
) - 环境变量的值
- 命令行参数
- 其他需要动态调整的配置参数
- 应用程序的配置文件(如
-
与 Pod 共享配置
Pod 可以通过以下方式使用 ConfigMap 中的data
数据:- 作为环境变量:直接将
data
中的键值对映射为容器的环境变量 - 作为文件挂载:将
data
中的内容挂载为容器内的文件(在指定路径下) - 作为命令行参数:通过环境变量间接引用
data
中的值
- 作为环境变量:直接将
-
解耦配置与代码
将配置数据从应用程序镜像中分离出来,使得:- 无需重新构建镜像即可修改配置
- 同一镜像可在不同环境(开发、测试、生产)中使用不同配置
- 便于集中管理和版本控制配置
Pod 可以通过挂载或环境变量的方式使用这些配置,实现配置与应用的解耦。
注意:data
适用于非敏感数据,如果需要存储密码、令牌等敏感信息,应使用 Secret 资源。
创建 ConfigMap:
kubectl create -f env.yaml kubectl get cm
# 输出结果应显示 env-config 和 special-config 已创建
然后创建使用这些 ConfigMap 的 Pod:
vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod
spec:containers:- name: busyboximage: busybox:1.28.4command: ["/bin/sh", "-c", "env"]env:- name: SPECIAL_HOW_KEY #pod内的键名valueFrom: #键对应的值的来源configMapKeyRef:name: special-config #cm中预先导入的config的文件名key: special.how #文件中的对应的键的名字- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef:name: env-configrestartPolicy: Never
验证环境变量是否注入成功:
kubectl logs test-pod
2.3.2 方式二:命令行参数使用
vim test-pod2.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod2
spec:containers:- name: busyboximage: busybox:1.28.4command: - /bin/sh- -c- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY)"env:- name: SPECIAL_HOW_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typeenvFrom:- configMapRef: name: env-configrestartPolicy: Never
创建 Pod 并查看输出:
kubectl create -f test-pod2.yamlkubectl get pods
# 查看 Pod 状态,等待其变为 Completedkubectl logs test-pod2
# 输出结果应为:very good
2.3.3 方式三:以 Volume 形式挂载
# 在数据卷里面使用 ConfigMap,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容
vim test-pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: test-pod3
spec:containers:- name: busyboximage: busybox:1.28.4command: [ "/bin/sh", "-c", "sleep 36000" ] #这是一个会在36000秒后完成的podvolumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: special-configrestartPolicy: Never
创建 Pod 并验证挂载是否成功:
kubectl create -f test-pod3.yaml kubectl get pods
# 查看 Pod 状态,等待其变为 Runningkubectl exec -it test-pod3 sh
# 进入容器后执行以下命令
cd /etc/config/
ls
# 应显示 special.how 和 special.type 文件
vi special.how
vi special.type
# 可查看文件内容是否与 ConfigMap 中存储的数据一致
2.4 ConfigMap 热更新机制
vim test-pod4.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: log-confignamespace: default
data:log_level: INFO
---
apiVersion: apps/v1
kind: Deployment
metadata:name: my-nginx
spec:replicas: 1selector:matchLabels:app: my-nginxtemplate:metadata:labels:app: my-nginxspec:containers:- name: my-nginximage: nginxports:- containerPort: 80volumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: log-config
部署应用并验证初始配置:
kubectl apply -f test-pod4.yaml
kubectl exec -it my-nginx-c6df7db54-4zknb -- cat /etc/config/log_level
# 输出应为:INFO
修改 ConfigMap:
kubectl edit configmap log-config
# 将 log_level 的值从 INFO 修改为 DEBUG
验证配置是否更新:
# 等待约 10 秒左右,使用该 ConfigMap 挂载的 Volume 中的数据会同步更新
kubectl exec -it my-nginx-c6df7db54-4zknb -- cat /etc/config/log_level
# 输出应为:DEBUG
注意:以 Volume 挂载的 ConfigMap 数据约 10 秒后会同步更新,但以环境变量形式注入的 ConfigMap 数据不会自动更新。
2.5 触发滚动更新
更新 ConfigMap 不会自动触发相关 Pod 的滚动更新,可通过以下方式手动触发:
# 在 .spec.template.metadata.annotations 中添加 version/config ,每次通过修改 version/config 来触发滚动更新
kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20210525" }}}}}'kubectl get pods
# 可以看到旧的 Pod 被终止,新的 Pod 被创建kubectl get pods
# 确认新的 Pod 处于 Running 状态
PS:更新 ConfigMap 后:
- 使用该 ConfigMap 挂载的 Env 不会同步更新。
- 使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。
3. 总结对比表
项目 | Secret | ConfigMap |
---|---|---|
存储内容 | 敏感信息(密码、密钥) | 普通配置信息 |
数据编码 | Base64 | 纯文本 |
使用方式 | Volume、Env、镜像拉取凭证 | Volume、Env、命令参数 |
是否自动更新 | Volume 延迟更新,Env 不会 | Volume 延迟更新,Env 不会 |
安全性 | 高(需 RBAC 控制) | 普通 |
总结
综上所述,Secret 和 ConfigMap 作为 Kubernetes 中配置管理的核心工具,分别承担着敏感信息与非敏感配置的管理职责。通过将配置与应用解耦,它们不仅简化了配置的维护流程,还提升了系统的安全性和可扩展性。在实际应用中,需根据数据的敏感性选择合适的资源类型:敏感信息优先使用 Secret 并通过文件挂载增强安全性,非敏感配置则可通过 ConfigMap 灵活注入。同时,理解两者的更新机制(如 Volume 挂载的延迟更新、Env 变量的静态特性),并结合滚动更新策略,能进一步保障配置变更的平滑性。掌握这些配置资源的使用技巧,是构建可靠、可维护的 Kubernetes 应用的重要基础。