代码镜像不应该把所有环境信息写死。
同一套镜像,开发环境连测试库,生产环境连正式库。
这类非敏感配置,放 ConfigMap。
敏感信息,比如密码、Token、证书,放 Secret。
类比一下:
ConfigMap = 公开作战手册
Secret = 加锁保险箱一个 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: city-web-config
data:
APP_NAME: "software-city"
APP_ENV: "production"
NGINX_PORT: "80"一个 Secret:
apiVersion: v1
kind: Secret
metadata:
name: city-web-secret
type: Opaque
stringData:
DB_PASSWORD: "super-secret-password"
API_TOKEN: "token-123456"在 Deployment 里使用它们:
apiVersion: apps/v1
kind: Deployment
metadata:
name: city-api
spec:
replicas: 2
selector:
matchLabels:
app: city-api
template:
metadata:
labels:
app: city-api
spec:
containers:
- name: api
image: ghcr.io/example/city-api:1.0.0
envFrom:
- configMapRef:
name: city-web-config
- secretRef:
name: city-web-secret或者把 ConfigMap 挂成文件:
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
volumes:
- name: config
configMap:
name: city-web-config命令上也常这样建:
kubectl create configmap city-web-config --from-literal=APP_ENV=production
kubectl create secret generic city-web-secret --from-literal=DB_PASSWORD=super-secret-password但这里要特别警惕两个误区:
ConfigMap 不保密。
它就是普通配置,不是保险箱。Secret 也不是“天然绝对安全”。
官方文档明确提醒:默认情况下,Secret 存在 API Server 背后的etcd里并不自动加密落盘。生产里至少要配好:- Encryption at Rest
- 最小权限 RBAC
- 访问范围控制
- 必要时外部 Secret Store
还有一个很容易踩坑的点:
- ConfigMap/Secret 作为环境变量注入时,改了通常不会自动热更新到已有 Pod
- 作为卷挂载时,变更会最终同步,但不是瞬时