目录
什么是ConfigMap
ConfigMap 是 Kubernetes 中的一种 API 对象,用于将非机密性的配置数据(如配置文件、环境变量、命令行参数等)与容器镜像解耦,从而更灵活地管理应用的配置。它通过键值对的形式存储数据,并可以被 Pod 以多种方式引用,使得应用的配置可以独立于代码进行修改和更新。
核心特性
- 解耦配置与镜像
- 将配置数据(如数据库连接字符串、日志级别等)从容器镜像中分离,避免因配置变更而重新构建镜像。
- 支持动态更新配置(需配合滚动重启或热加载机制)。
- 多用途支持
- 可作为环境变量、命令行参数、配置文件挂载到 Pod 中。
- 支持存储单个值或整个文件内容。
- 非机密性数据
- ConfigMap 仅用于存储非敏感配置。敏感数据(如密码、密钥)应使用 Secret 对象。
创建 ConfigMap
ConfigMap可以使用目录、单个文件或字符值的方式创建,使用kubectl创建一个ConfigMap的命令格式
kubectl create configmap <map-name> <data-source>
- map-name:ConfigMap的名称。
- data-sourece:数据源,可以是数据的目录、文件或字符值。
ConfigMap中数据是以键值对的形式保存的,其中:
- key:文件名或密钥
- value:文件内容或字符值
基于文件创建 ConfigMap
将本地文件的内容直接存储到 ConfigMap 中,适合配置文件(如 nginx.conf
application.properties
)或键值对文件(如 .env
)。
单个文件创建
# 将文件内容作为 ConfigMap 的一个键(键名为文件名)
kubectl create configmap my-config --from-file=./config.yaml
生成的ConfigMap(yaml)
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
config.yaml: |
apiVersion: v1
database:
host: db.example.com
port: 5432
多个文件创建
# 将多个文件存储为不同的键
kubectl create configmap my-config \
--from-file=./config.yaml \
--from-file=./settings.json
生成的ConfigMap(yaml)
data:
config.yaml: |
apiVersion: v1
database: ...
settings.json: |
{ "logLevel": "debug" }
从目录创建
# 将目录下所有文件存储为 ConfigMap(键名为文件名)
kubectl create configmap my-config --from-file=./config-dir/
在Pod中使用ConfigMap
通过 env
注入环境变量(直接引用键值)
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: DB_HOST # 环境变量名
valueFrom:
configMapKeyRef:
name: my-config # ConfigMap 名称
key: database.host # ConfigMap 中的键
通过 envFrom
批量注入(适用于多个键值对)
apiVersion: v1
kind: Pod
metadata:
name: envfrom-pod
spec:
containers:
- name: my-container
image: nginx
envFrom:
- prefix: APP_ # 可选:为所有环境变量添加前缀
configMapRef:
name: my-config
以文件形式挂载(适合完整配置文件)
apiVersion: v1
kind: Pod
metadata:
name: volume-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/app/config.yaml # 容器内路径
subPath: config.yaml # 可选:仅挂载 ConfigMap 中的 config.yaml 键
volumes:
- name: config-volume
configMap:
name: my-config # ConfigMap 名称
自定义 ConfigMap 键值对
如果不想从文件创建,可以直接在 YAML 中定义 ConfigMap 的键值对:
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-config
data:
# 简单键值对
database.host: "db.example.com"
database.port: "5432"
# 多行文本(如配置文件)
nginx.conf: |
user nginx;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name example.com;
}
}
ConfigMap限制
ConfigMap 在 Kubernetes 中虽能高效管理配置,但存在以下关键限制,需在设计和使用时重点关注:
大小限制
- 默认上限:单个 ConfigMap 的数据大小不能超过 1MB(具体限制可能因 Kubernetes 版本或集群配置略有差异)。
- 应对策略:
- 将大型配置拆分为多个 ConfigMap(如按功能模块划分)。
- 使用其他存储方案(如数据库、独立文件服务或持久化卷 PV)。
- 对于敏感数据,优先使用 Secret(同样有 1MB 限制,但更适合加密存储)。
命名空间隔离
- 作用域限制:ConfigMap 仅在创建它的命名空间(Namespace)内可见,不同命名空间的 Pod 无法互相引用。
- 示例:若 ConfigMap
my-config
位于dev
命名空间,则prod
命名空间的 Pod 无法使用它。
引用顺序要求
- 依赖关系:Pod 必须在 ConfigMap 创建后才能引用它。若 ConfigMap 不存在,Pod 会启动失败并报错。
- 解决方式:
- 通过
kubectl apply -f
先创建 ConfigMap,再部署 Pod。 - 使用 Helm 或 Kustomize 等工具管理资源依赖关系。
- 通过
挂载路径限制
- 目录挂载:通过
volumeMounts
挂载 ConfigMap 时,mountPath
必须是目录路径,不能直接挂载为单个文件。 - 文件覆盖:挂载后,容器内目标目录下的原有文件会被 ConfigMap 的内容覆盖(除非使用
subPath
指定单个文件)。 - 示例:
volumes:
- name: config-volume
configMap:
name: my-config
items: # 可选:仅挂载特定键
- key: "config.yaml"
path: "config.yaml" # 挂载为目录下的单个文件
volumeMounts:
- name: config-volume
mountPath: "/etc/app" # 必须是目录
readOnly: true
数据类型限制
- 仅支持字符串:ConfigMap 的所有数据(键和值)必须为字符串类型。若需存储非字符串数据(如数字、布尔值),需手动转换为字符串格式。
- 多行文本:可通过
|
或>
符号存储多行内容(如配置文件):
data:
nginx.conf: |
server {
listen 80;
server_name example.com;
}
动态更新限制
- 更新不自动生效:修改 ConfigMap 后,已挂载的 Pod 不会自动感知变化(除非应用支持热加载或重启 Pod)。
- 触发更新方式:
- 手动重启 Pod(如通过
kubectl rollout restart
)。 - 使用第三方工具(如 Argo Rollouts)实现自动滚动更新。
- 手动重启 Pod(如通过
静态 Pod 限制
- 无法引用:通过
--manifest-url
或--config
自动创建的静态 Pod(由 kubelet 直接管理)无法引用 ConfigMap。 - 替代方案:将静态 Pod 转换为常规 Pod(通过 Deployment 或 DaemonSet 管理)。
RBAC 权限控制
- 需显式授权:若集群启用了 RBAC,需确保服务账号(ServiceAccount)有权限读取 ConfigMap(通过
Role
或ClusterRole
绑定configmaps
资源)。 - 示例 RBAC 规则:
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
加密数据管理Secret
在 Kubernetes 中,Secret 是一种用于存储和管理敏感信息的核心资源对象,专门用于解决密码、令牌、密钥等敏感数据的配置问题,避免将这些数据直接暴露在镜像或 Pod 规约中
核心特性
- 敏感数据保护
- 存储密码、OAuth 令牌、SSH 密钥、TLS 证书等敏感信息,防止硬编码在镜像或配置文件中。
- 默认以 Base64 编码存储(非加密),但可通过集群级加密增强安全性。
- 灵活访问控制
- 支持通过 RBAC(基于角色的访问控制) 限制访问权限,确保只有授权的 Pod 或用户能读取 Secret。
- 动态更新能力
- 修改 Secret 后,挂载为 Volume 的 Pod 可自动同步更新(默认 1 分钟同步周期),但通过 环境变量 引用的需重启 Pod 生效。
- 类型化支持
- Opaque:通用类型,存储任意 Base64 编码数据(如密码、密钥)。
- kubernetes.io/service-account-token:存储服务账号令牌,自动挂载到 Pod 的
/run/secrets/kubernetes.io/serviceaccount
。 - kubernetes.io/dockercfg / kubernetes.io/dockerconfigjson:存储私有 Docker 仓库认证信息。
- kubernetes.io/tls:存储 TLS 证书和私钥,用于加密通信。
使用方式
创建 Secret
命令行创建:
# 从键值对创建 Opaque Secret
kubectl create secret generic my-secret --from-literal=username=admin --from-literal=password=1f2d1e2e67df
# 从文件创建 TLS Secret
kubectl create secret tls tls-secret --cert=path/to/cert.pem --key=path/to/key.pem
- YAML定义:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # Base64 编码的 "admin"
password: MWYyZDFlMmU2N2Rm # Base64 编码的 "1f2d1e2e67df"
在 Pod 中使用
作为环境变量:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
- 挂载为 Volume:
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: "/etc/secrets"
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secret
- 用于 Docker 镜像拉取:
apiVersion: v1
kind: Pod
metadata:
name: private-reg-pod
spec:
containers:
- name: my-container
image: myprivateregistry.com/myapp:latest
imagePullSecrets:
- name: my-reg-secret # 引用预先创建的 Docker 仓库认证 Secret
安全增强措施
- 启用静态加密
- 使用 EncryptionConfig 和 EncryptionProvider 插件(如 AES-CBC、KMS)对存储在 etcd 中的 Secret 数据加密:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources: ["secrets"]
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- 更新 API Server 配置并重启以应用加密:
--encryption-provider-config=/path/to/encryption-config.yaml
最小权限原则
- 通过 RBAC 限制 Secret 的访问权限,例如:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch"]
- 定期轮换与审计
- 定期更新 Secret 内容(如密码、证书),并审计使用情况以降低泄露风险。
- 集成外部密钥管理
- 使用 HashiCorp Vault、AWS Secrets Manager 等外部工具管理 Secret,通过 CSI 驱动或初始化容器动态注入。
与 ConfigMap 的对比
特性 | Secret | ConfigMap |
---|---|---|
数据类型 | 敏感数据(密码、密钥、证书) | 非敏感配置(环境变量、配置文件) |
存储方式 | Base64 编码(默认)或加密存储 | 明文存储 |
更新生效 | Volume 挂载自动同步,环境变量需重启 | 需应用支持热加载或重启 |
典型场景 | 数据库凭证、TLS 证书、API 令牌 | Nginx 配置、应用属性文件 |