01. ConfigMap——配置管理
把配置硬编码在镜像里是个坏习惯——换个环境就要重新打镜像。ConfigMap 把配置从镜像里抽出来,运行时以环境变量或文件形式注入 Pod。
ConfigMap 存键值对,键是配置项名,值是配置内容。可以存简单的 key=value,也可以存整个配置文件(Nginx 配置、Java properties 等)。大小限制 1MB。
使用方式:
1. 环境变量——把 ConfigMap 的键值对注入为容器的环境变量
2. 挂载为文件——把 ConfigMap 挂载到容器里某个目录,每个键是一个文件
3. 命令行参数——通过 env 注入后再传给命令
ConfigMap 更新后,环境变量的方式不会自动更新(Pod 要重建)。挂载文件的方式会延迟自动更新(kubelet 定期同步)。
bash
# 从字面值创建
kubectl create configmap app-config \
--from-literal=DB_HOST=db-service \
--from-literal=DB_PORT=5432
# 从文件创建
kubectl create configmap nginx-config --from-file=nginx.conf
# YAML 方式
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_HOST: "db-service"
DB_PORT: "5432"
app.properties: |
server.port=8080
logging.level=INFOConfigMap 里可以存一个完整的配置文件——用竖线加缩进(YAML 多行字符串语法),然后把整个 ConfigMap 挂载为文件。
02. Secret——敏感数据管理
Secret 跟 ConfigMap 类似,但专门存敏感信息——密码、Token、证书、SSH Key。数据以 Base64 编码存储(注意不是加密!只是编码,任何人都能解码)。
Secret 类型:
Opaque——通用类型,就是你存的任意键值对
kubernetes.io/tls——TLS 证书和私钥
kubernetes.io/dockerconfigjson——Docker registry 的登录凭证
kubernetes.io/basic-auth——用户名密码
创建后使用方法跟 ConfigMap 一样:环境变量注入或文件挂载。Secret 在 etcd 里默认不加密,生产环境建议开 etcd 加密或者用外部密钥管理服务(Vault、Sealed Secrets)。
bash
# 创建 Secret
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password='MyP@ssw0rd'
# TLS Secret
kubectl create secret tls my-tls \
--cert=cert.pem --key=key.pem
# YAML 方式
data:
username: YWRtaW4= # base64 编码的 admin
password: TXlQQHNzdzByZA==
# 使用 Secret(Pod YAML 里)
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: passwordSecret 的 Base64 只是编码不是加密!任何能 kubectl get secret 的人都能解码。要真正的加密用 Sealed Secrets 或 Vault。
03. ConfigMap 和 Secret 的更新机制
ConfigMap 和 Secret 更新后,Pod 里的值不会立刻生效:
环境变量方式:只有在 Pod 启动时读取。改了 ConfigMap,Pod 的环境变量还是旧值。必须重建 Pod。
文件挂载方式:kubelet 定期同步(默认约 60 秒),会把最新的值更新到容器里的文件。但应用需要自己检测文件变化并重载配置(如 nginx -s reload)。
如果应用不支持热重载文件,更新配置的麻烦流程就是:改 ConfigMap → 重启 Pod。
还有一种方式:用 deployment 的 annotation 记录 ConfigMap 的 hash,hash 变了自动触发滚动更新。这是比较优雅的自动更新方案。
yaml
# 滚动更新时触发 Pod 重建
# Deployment YAML 的 template.metadata.annotations 里加
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}04. 环境变量注入与 Pod 配置最佳实践
给容器注入配置的最佳实践:
1. 非敏感的简单配置(数据库地址、端口)→ ConfigMap 挂为环境变量
2. 配置文件(nginx.conf、Java properties)→ ConfigMap 挂载为文件
3. 密码、Token、证书 → Secret 挂载为文件(比环境变量更安全)
4. 配置验证 → 在容器启动脚本里检查必需的环境变量是否都设了
5. 合理使用默认值——没设时有回退方案,不崩
环境变量的优先级(从高到低):容器直接 env > Secret envFrom > ConfigMap envFrom。如果有同名环境变量,高优先级的覆盖低优先级的。
yaml
# Pod——同时使用 ConfigMap 和 Secret
spec:
containers:
- name: app
image: myapp:latest
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: db-secret
env:
- name: NODE_ENV
value: "production"
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
volumes:
- name: nginx-config
configMap:
name: nginx-configenvFrom 会把这个 ConfigMap 或 Secret 的所有键值对注入为环境变量。一行搞定,比逐个 env valueFrom 方便。
05. Helm Chart——K8s 的包管理器
如果每个环境都手写一套 YAML 文件,维护起来会很痛苦。Helm 是 K8s 的包管理器——把一组 K8s YAML 模板化,用 values.yaml 来定制每个环境的配置。
Helm Chart 的结构:
Chart.yaml——chart 的元数据(名称、版本、依赖)。
values.yaml——默认的配置值。
templates/——K8s 资源模板(Deployment、Service、ConfigMap 等),用 Go 模板语法嵌入式地引用 values。
安装 chart:helm install my-app ./chart -f values-prod.yaml。-f 可以覆盖默认的 values。
升级:helm upgrade my-app ./chart --set image.tag=v2.0。用 --set 快速覆盖单个值。
Helm 的模板函数库很丰富:default(兜底值)、quote(加引号)、indent(缩进)、toYaml(转 YAML)。在 templates 里用 .Values.xxx 引用 values.yaml 的值。
yaml
# Chart.yaml
apiVersion: v2
name: my-app
version: 1.0.0
appVersion: "2.0.0"
# values.yaml
replicas: 3
image:
repository: myapp
tag: latest
service:
port: 80
type: ClusterIP
resources:
limits:
cpu: 500m
memory: 256Mi
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
spec:
replicas: {{ .Values.replicas }}
template:
spec:
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
{{- toYaml .Values.resources | nindent 10 }}Helm 的 lookup 函数可以从已存在的 K8s 资源里取信息(如共享的 Secret),避免在 values.yaml 里重复写相同配置。
知识测验
第 1/5 题正确 0
ConfigMap 和 Secret 的主要区别?
下一节
下一节 部署策略