前言
在 Kubernetes 集群中,应用往往需要处理一些敏感信息,例如数据库密码、API 密钥、TLS 证书或 OAuth Token。如果将这些机密数据直接写入 Pod 定义或容器镜像中,不仅存在泄露风险,而且不利于配置的集中管理和版本控制。为了解决这一问题,Kubernetes 提供了 Secret 资源,用于以密文形式存储敏感信息,并通过 Volume 或环境变量安全地注入到 Pod 中。同时,对于一些非敏感的配置信息(如应用配置文件、命令行参数等),K8s 提供了 ConfigMap 资源,以明文形式管理配置数据。本文将详细介绍 Secret 和 ConfigMap 的创建方法、在 Pod 中的使用方式,以及动态更新等实用技巧。
一、K8s 资源 Secret
Secret 是 Kubernetes 中用于保存敏感数据的资源对象。它通过 Base64 编码(非加密)的方式存储数据,降低了敏感信息在 YAML 文件或命令行中直接暴露的风险。用户可以创建自己的 Secret,系统也会为服务账号自动创建 Secret。
Pod 使用 Secret 的常见方式有两种:
-
以 Volume 的形式挂载到 Pod,容器通过读取文件的方式获取敏感数据(支持动态更新)。
-
通过 环境变量 注入(不支持动态更新,且可能被调试信息暴露)。
官方更推荐使用 Volume 挂载方式,因为当 Secret 内容更新后,Pod 内的文件也会同步更新(有一定延迟)。
二、创建 Secret 的方式
方式一:使用 kubectl create secret 命令(--from-literal)
[root@master secret]# kubectl create secret generic mysecret \
--from-literal=username=admin \
--from-literal=password=123456
每个 --from-literal 对应一个键值对。generic 表示普通类型(还有 docker-registry 和 tls 类型)。
方式二:通过 YAML 配置文件
首先将敏感数据编码为 Base64:
[root@master secret]# echo -n "admin" | base64
YWRtaW4=
[root@master secret]# echo -n "12345678" | base64
MTIzNDU2Nzg=
编写 secret.yml:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
data:
username: YWRtaW4=
password: MTIzNDU2Nzg=
注意:echo -n 避免换行符也被编码。创建 Secret:
[root@master secret]# kubectl apply -f secret.yml
查看 Secret
[root@master secret]# kubectl get secret mysecret
NAME TYPE DATA AGE
mysecret Opaque 2 10s
[root@master secret]# kubectl describe secret mysecret
Name: mysecret
Namespace: default
Data
====
username: 5 bytes
password: 8 bytes
若想查看具体的值,可以使用 kubectl edit secret mysecret 或 kubectl get secret mysecret -o yaml,然后将 Base64 值解码:
[root@master secret]# echo "YWRtaW4=" | base64 --decode
admin
三、在 Pod 中使用 Secret(Volume 方式)
通过 Volume 挂载 Secret,Kubernetes 会在指定挂载路径下为每个键创建一个文件,文件名为键名,内容为明文值。这种方式支持 Secret 动态更新。
示例 secret-pod.yml:
apiVersion: v1
kind: Pod
metadata:
name: pod-test
spec:
containers:
- name: app-pod
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/check; sleep 30000
volumeMounts:
- name: secrets
mountPath: /etc/secret
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
创建 Pod 并验证:
[root@master secret]# kubectl apply -f secret-pod.yml
[root@master secret]# kubectl exec -it pod-test -- sh
/ # ls /etc/secret
password username
/ # cat /etc/secret/username
admin
/ # cat /etc/secret/password
12345678
动态更新测试
修改 Secret 中的 password 为 xyz123,重新编码(echo -n "xyz123" | base64 得 eHl6MTIz)。更新 Secret YAML 文件并重新 apply:
[root@master secret]# kubectl apply -f secret.yml
稍等片刻,在 Pod 内再次查看密码文件:
/ # cat /etc/secret/password
xyz123
可见数据已自动同步(Kubelet 会定期刷新挂载的 Secret 内容)。
四、ConfigMap 的使用与配置
与 Secret 类似,ConfigMap 用于保存非敏感的配置数据,例如应用环境变量、配置文件内容等。区别在于 ConfigMap 的数据以明文形式存储,不进行 Base64 编码。ConfigMap 同样支持通过 Volume 或环境变量注入 Pod。
4.1 创建 ConfigMap
方式一:使用 --from-literal
[root@master secret]# kubectl create configmap myconfigmap1 \
--from-literal=config1=abc \
--from-literal=config2=def
方式二:通过 YAML 文件
configmap.yml:
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap-test
data:
config1: ABC123
config2: XXYYY
创建并查看:
[root@master secret]# kubectl apply -f configmap.yml
[root@master secret]# kubectl describe configmap configmap-test
Name: configmap-test
Namespace: default
Data
====
config1: ABC123
config2: XXYYY
4.2 在 Pod 中使用 ConfigMap(Volume 方式)
与 Secret 几乎相同,只需将 secret 替换为 configMap。
configmap-pod.yml:
apiVersion: v1
kind: Pod
metadata:
name: configmap-test
spec:
containers:
- name: app-pod
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/check; sleep 30000
volumeMounts:
- name: myconfigmap
mountPath: /etc/config
readOnly: true
volumes:
- name: myconfigmap
configMap:
name: configmap-test
验证:
[root@master secret]# kubectl apply -f configmap-pod.yml
[root@master secret]# kubectl exec -it configmap-test -- sh
/ # ls /etc/config
config1 config2
/ # cat /etc/config/config1
ABC123
4.3 ConfigMap 的典型应用场景
-
环境变量注入:通过
envFrom或env.valueFrom.configMapKeyRef将 ConfigMap 键值对作为容器环境变量。 -
挂载配置文件:使用
--from-file创建 ConfigMap,然后将整个配置文件挂载到 Pod 中,替代默认配置。 -
命令行参数:结合环境变量或文件内容设置启动参数。
五、注意事项与最佳实践
-
Secret 的 Base64 不是加密:Base64 仅编码,并非加密。要真正加密敏感数据,可结合外部密钥管理服务(如 HashiCorp Vault)或开启 Kubernetes 的静态加密(EncryptionConfiguration)。
-
Secret 大小限制:单个 Secret 默认最大大小为 1 MiB,以减轻 API Server 压力。
-
动态更新延迟:使用 Volume 挂载时,Secret/ConfigMap 更新后,Pod 内文件刷新有约 1-2 分钟的延迟(取决于 Kubelet 同步周期)。对于需要立即生效的场景,可考虑重启 Pod 或使用外部工具。
-
命名规范:建议为 Secret 和 ConfigMap 名称添加明确前缀(如
db-credential、app-config),便于管理。 -
访问控制:通过 RBAC 限制对 Secret 资源的访问权限,防止未授权用户查看敏感数据。
-
优先使用 Volume 挂载而非环境变量:环境变量方式无法动态更新,且某些调试工具可能打印环境变量内容,增加泄露风险。
结尾
本文详细介绍了 Kubernetes 中两种核心的配置与机密管理资源——Secret 和 ConfigMap。Secret 专门用于存储密码、Token 等敏感信息,以 Base64 编码形式存放在集群中;ConfigMap 则用于管理普通配置数据。通过实际的命令和 YAML 示例,我们演示了如何创建它们,并将其以 Volume 形式挂载到 Pod 中,同时验证了 Secret 的动态更新能力。
合理使用 Secret 和 ConfigMap 可以显著提升应用配置的安全性和灵活性,避免将敏感数据硬编码到镜像或启动脚本中。在实际生产环境中,建议结合 RBAC、网络策略、静态加密等安全措施,进一步加强对机密信息的保护。希望本文能帮助你更好地在 Kubernetes 中管理和使用配置信息。
2444

被折叠的 条评论
为什么被折叠?



