(一) Kubernetes ConfigMap
ConfigMap 是 Kubernetes 中用于存储非敏感配置数据的对象,它允许你将配置信息与容器镜像解耦,实现配置的动态管理。ConfigMap 可以被 Pod 以多种方式挂载和使用。
一、ConfigMap 的核心作用
- 存储配置数据:
- 存储应用程序的配置文件、环境变量、命令行参数等。
- 支持存储键值对(Key-Value)或文件内容。
- 解耦配置与镜像:
- 避免将配置硬编码到容器镜像中,提高灵活性。
- 动态更新配置:
- 修改 ConfigMap 后,可以重新加载 Pod 的配置(需应用支持)。
- 共享配置:
- 多个 Pod 或应用可以共享同一个 ConfigMap。
二、ConfigMap 的创建方式
1. 通过命令行创建
# 创建一个简单的 ConfigMap(键值对形式)
kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2
# 从文件创建 ConfigMap(将文件内容作为配置)
kubectl create configmap my-config --from-file=config-file.txt
# 从目录创建 ConfigMap(将目录下所有文件作为配置)
kubectl create configmap my-config --from-file=./config-dir/
2. 通过 YAML 文件创建
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
# 键值对形式
key1: value1
key2: value2
# 文件内容形式(文件名作为键,内容作为值)
config-file.txt: |
line1
line2
说明:
data
字段用于存储键值对或文件内容。- 文件内容会以 Base64 编码存储(但 YAML 中直接写明文即可,Kubernetes 会自动处理)。
三、ConfigMap 的使用方式
1. 挂载为环境变量
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: MY_ENV_VAR # 环境变量名
valueFrom:
configMapKeyRef:
name: my-config # ConfigMap 名称
key: key1 # ConfigMap 中的键名
说明:
- 将 ConfigMap 中的
key1
挂载为 Pod 的环境变量MY_ENV_VAR
。
2. 挂载为文件(Volume 挂载)
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/config # 挂载到容器内的路径
volumes:
- name: config-volume
configMap:
name: my-config # ConfigMap 名称
items:
- key: config-file.txt # ConfigMap 中的键名
path: app.conf # 挂载到容器内的文件名
说明:
- 将 ConfigMap 中的
config-file.txt
挂载为容器内的/etc/config/app.conf
文件。
3. 直接使用 ConfigMap 的键值对
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
command: ["/bin/sh", "-c", "echo $MY_ENV_VAR"]
env:
- name: MY_ENV_VAR
valueFrom:
configMapKeyRef:
name: my-config
key: key1
说明:
- 在 Pod 的启动命令中使用 ConfigMap 的环境变量。
四、ConfigMap 的高级特性
1. 动态更新 ConfigMap
- 默认行为:
- 修改 ConfigMap 后,已运行的 Pod 不会自动更新配置(需重启 Pod 或应用支持热加载)。
- 如何实现动态更新:
- 使用
volume
挂载时,Kubernetes 会定期同步 ConfigMap 的变更(默认每 1 分钟检查一次)。 - 应用需要支持配置热加载(如 Nginx、Java 应用可以通过监听文件变化重新加载配置)。
- 使用
2. ConfigMap 的数据大小限制
- 单个 ConfigMap 的数据大小限制:
- 所有键值对的总大小不能超过 1MB(Kubernetes 的限制)。
- 超过限制的解决方案:
- 将大文件拆分为多个小文件,存储在多个 ConfigMap 中。
- 使用外部存储(如 Config Server、Vault)管理大配置。
3. ConfigMap 的加密
- 默认行为:
- ConfigMap 的数据以明文存储(可通过
kubectl get configmap
查看)。
- ConfigMap 的数据以明文存储(可通过
- 如何加密:
- 使用 Kubernetes 的 Secrets 替代 ConfigMap 存储敏感数据(Secrets 默认加密存储)。
- 使用第三方工具(如 HashiCorp Vault、AWS KMS)对 ConfigMap 进行加密。
4. ConfigMap 的命名空间隔离
- 默认行为:
- ConfigMap 是命名空间级别的资源,不同命名空间的 ConfigMap 互不干扰。
- 跨命名空间使用:
- 可以通过
kubectl get configmap <configmap名> -n <命名空间>
查看其他命名空间的 ConfigMap。 - 但 Pod 只能使用其所在命名空间的 ConfigMap(除非通过特殊配置跨命名空间访问)。
- 可以通过
五、ConfigMap 与 Secret 的区别
特性 | ConfigMap | Secret |
---|---|---|
用途 | 存储非敏感配置(如配置文件、环境变量) | 存储敏感数据(如密码、Token、证书) |
数据存储方式 | 明文存储(可通过 kubectl get configmap 查看) | 默认加密存储(但可通过 kubectl get secret 查看 Base64 编码的数据) |
数据大小限制 | 1MB | 1MB |
典型使用场景 | 应用配置、环境变量 | 数据库密码、API Key、TLS 证书 |
注意:
- 如果配置包含敏感信息(如密码),应该使用 Secret 而不是 ConfigMap。
- ConfigMap 和 Secret 都可以通过
volume
或env
挂载到 Pod 中。
六、ConfigMap 的常见问题
1. 如何查看 ConfigMap 的内容?
# 查看 ConfigMap 的详细信息
kubectl get configmap <configmap名> -o yaml
# 查看 ConfigMap 的键值对(明文)
kubectl get configmap <configmap名> -o jsonpath='{.data}'
2. 如何修改 ConfigMap?
# 修改 ConfigMap 的键值对
kubectl edit configmap <configmap名>
# 或者通过命令行更新
kubectl create configmap <configmap名> --from-literal=key1=new-value1 --dry-run=client -o yaml | kubectl apply -f -
3. 如何删除 ConfigMap?
kubectl delete configmap <configmap名>
4. 如何调试 ConfigMap 的挂载问题?
- 检查 Pod 是否成功挂载 ConfigMap:
kubectl exec -it <pod名> -- ls /etc/config # 检查挂载的文件 kubectl exec -it <pod名> -- cat /etc/config/app.conf # 查看文件内容
- 检查 ConfigMap 是否存在:
kubectl get configmap <configmap名>
七、总结
特性 | 说明 |
---|---|
ConfigMap 的作用 | 存储非敏感配置数据(配置文件、环境变量) |
创建方式 | 命令行或 YAML 文件 |
使用方式 | 挂载为环境变量或文件(Volume 挂载) |
动态更新 | 默认不自动更新,需重启 Pod 或应用支持热加载 |
数据大小限制 | 1MB |
与 Secret 的区别 | ConfigMap 存储非敏感数据,Secret 存储敏感数据 |
典型使用场景 | 应用配置、环境变量、多环境配置管理 |
最佳实践:
- 将非敏感配置存储在 ConfigMap 中,敏感配置存储在 Secret 中。
- 使用
volume
挂载 ConfigMap 时,确保应用支持配置热加载。 - 定期检查 ConfigMap 的内容,避免配置泄露或错误。
(二) Kubernetes Secret
Secret 是 Kubernetes 中用于存储敏感数据(如密码、Token、证书、SSH 密钥等)的对象,它比 ConfigMap 更安全,因为默认会对数据进行 Base64 编码存储(虽然仍需额外加密措施)。Secret 可以被 Pod 挂载为环境变量或文件,供应用程序使用。
一、Secret 的核心作用
- 存储敏感数据:
- 存储密码、API Key、数据库凭证、TLS 证书、SSH 密钥等敏感信息。
- 安全存储:
- 默认对数据进行 Base64 编码(但需注意:Base64 不是加密,只是编码,敏感数据仍需额外保护)。
- 动态管理:
- 可以独立于容器镜像管理敏感配置,避免硬编码。
- 权限控制:
- 可以通过 Kubernetes 的 RBAC 控制 Secret 的访问权限。
二、Secret 的创建方式
1. 通过命令行创建
# 创建一个简单的 Secret(键值对形式)
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=123456
# 从文件创建 Secret(将文件内容作为敏感数据)
kubectl create secret generic my-secret --from-file=username.txt --from-file=password.txt
# 从目录创建 Secret(将目录下所有文件作为敏感数据)
kubectl create secret generic my-secret --from-file=./secret-dir/
2. 通过 YAML 文件创建
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque # 默认类型,表示通用 Secret
data:
# 键值对形式(值必须是 Base64 编码)
username: YWRtaW4= # "admin" 的 Base64 编码
password: MTIzNDU2 # "123456" 的 Base64 编码
说明:
data
字段中的值必须是 Base64 编码(可以使用echo -n "value" | base64
生成)。- 如果使用
stringData
字段,则可以直接存储明文(Kubernetes 会自动编码):stringData: username: admin password: 123456
三、Secret 的使用方式
1. 挂载为环境变量
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: DB_USERNAME # 环境变量名
valueFrom:
secretKeyRef:
name: my-secret # Secret 名称
key: username # Secret 中的键名
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: password
说明:
- 将 Secret 中的
username
和password
挂载为 Pod 的环境变量。
2. 挂载为文件(Volume 挂载)
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: /etc/secret # 挂载到容器内的路径
volumes:
- name: secret-volume
secret:
secretName: my-secret # Secret 名称
items:
- key: username # Secret 中的键名
path: db_username # 挂载到容器内的文件名
- key: password
path: db_password
说明:
- 将 Secret 中的
username
和password
挂载为容器内的/etc/secret/db_username
和/etc/secret/db_password
文件。
3. 直接使用 Secret 的键值对
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx
command: ["/bin/sh", "-c", "echo $DB_USERNAME"]
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
说明:
- 在 Pod 的启动命令中使用 Secret 的环境变量。
四、Secret 的高级特性
1. 动态更新 Secret
- 默认行为:
- 修改 Secret 后,已运行的 Pod 不会自动更新配置(需重启 Pod 或应用支持热加载)。
- 如何实现动态更新:
- 使用
volume
挂载时,Kubernetes 会定期同步 Secret 的变更(默认每 1 分钟检查一次)。 - 应用需要支持配置热加载(如数据库连接池可以监听文件变化重新加载配置)。
- 使用
2. Secret 的数据大小限制
- 单个 Secret 的数据大小限制:
- 所有键值对的总大小不能超过 1MB(Kubernetes 的限制)。
- 超过限制的解决方案:
- 将大文件拆分为多个小文件,存储在多个 Secret 中。
- 使用外部存储(如 HashiCorp Vault、AWS Secrets Manager)管理大敏感数据。
3. Secret 的加密
- 默认行为:
- Secret 的数据以 Base64 编码存储(可通过
kubectl get secret
查看)。 - Base64 不是加密,敏感数据仍可能被泄露(需额外加密措施)。
- Secret 的数据以 Base64 编码存储(可通过
- 如何加密:
- 使用 Kubernetes 的 加密 at Rest 功能(需配置 etcd 加密)。
- 使用第三方工具(如 HashiCorp Vault、AWS KMS)对 Secret 进行加密。
- 使用 Sealed Secrets(开源工具,将 Secret 加密后存储在 Git 中)。
4. Secret 的命名空间隔离
- 默认行为:
- Secret 是命名空间级别的资源,不同命名空间的 Secret 互不干扰。
- 跨命名空间使用:
- 可以通过
kubectl get secret <secret名> -n <命名空间>
查看其他命名空间的 Secret。 - 但 Pod 只能使用其所在命名空间的 Secret(除非通过特殊配置跨命名空间访问)。
- 可以通过
五、Secret 与 ConfigMap 的区别
特性 | Secret | ConfigMap |
---|---|---|
用途 | 存储敏感数据(如密码、Token、证书) | 存储非敏感配置(如配置文件、环境变量) |
数据存储方式 | 默认 Base64 编码(需额外加密) | 明文存储(可通过 kubectl get configmap 查看) |
数据大小限制 | 1MB | 1MB |
典型使用场景 | 数据库密码、API Key、TLS 证书 | 应用配置、环境变量 |
安全性 | 更高(但需额外加密措施) | 较低(明文存储) |
注意:
- 如果配置包含敏感信息(如密码),必须使用 Secret,而不是 ConfigMap。
- 即使使用 Secret,也应结合加密措施(如 etcd 加密、Vault)保护敏感数据。
六、Secret 的常见问题
1. 如何查看 Secret 的内容?
# 查看 Secret 的详细信息(Base64 编码)
kubectl get secret <secret名> -o yaml
# 解码 Secret 的内容(查看明文)
kubectl get secret <secret名> -o jsonpath='{.data}' | jq -r 'to_entries[] | "\(.key): \(.value | @base64d)"'
说明:
@base64d
是jq
的命令,用于解码 Base64 数据(需安装jq
工具)。
2. 如何修改 Secret?
# 修改 Secret 的键值对
kubectl edit secret <secret名>
# 或者通过命令行更新(需重新编码)
kubectl create secret generic <secret名> --from-literal=key1=new-value1 --dry-run=client -o yaml | kubectl apply -f -
3. 如何删除 Secret?
kubectl delete secret <secret名>
4. 如何调试 Secret 的挂载问题?
- 检查 Pod 是否成功挂载 Secret:
kubectl exec -it <pod名> -- ls /etc/secret # 检查挂载的文件 kubectl exec -it <pod名> -- cat /etc/secret/db_username # 查看文件内容
- 检查 Secret 是否存在:
kubectl get secret <secret名>
七、Secret 的最佳实践
- 敏感数据必须使用 Secret:
- 密码、Token、证书等敏感信息绝对不能使用 ConfigMap 存储。
- 结合加密措施:
- 使用 Kubernetes 的 etcd 加密或第三方工具(如 Vault)保护 Secret。
- 最小权限原则:
- 通过 RBAC 限制 Pod 对 Secret 的访问权限。
- 定期轮换 Secret:
- 定期更新数据库密码、API Key 等敏感数据。
- 避免硬编码:
- 不要在容器镜像或代码中硬编码敏感信息。
八、总结
特性 | 说明 |
---|---|
Secret 的作用 | 存储敏感数据(密码、Token、证书) |
创建方式 | 命令行或 YAML 文件(值需 Base64 编码) |
使用方式 | 挂载为环境变量或文件(Volume 挂载) |
动态更新 | 默认不自动更新,需重启 Pod 或应用支持热加载 |
数据大小限制 | 1MB |
与 ConfigMap 的区别 | Secret 存储敏感数据,ConfigMap 存储非敏感配置 |
典型使用场景 | 数据库密码、API Key、TLS 证书 |
安全性 | 比 ConfigMap 更高,但仍需额外加密措施 |
最佳实践:
- 敏感数据必须使用 Secret,而非 ConfigMap。
- 结合 etcd 加密或 Vault 保护 Secret。
- 定期轮换敏感数据,避免泄露风险。