跳到主要内容

配置与存储

ConfigMap

ConfigMap 用于存储非敏感配置数据(键值对、配置文件)。

创建 ConfigMap

# 从字面量创建
kubectl create configmap app-config \
--from-literal=DB_HOST=mysql \
--from-literal=DB_PORT=3306

# 从文件创建
kubectl create configmap nginx-config \
--from-file=nginx.conf

# 从目录创建
kubectl create configmap configs \
--from-file=./config-dir/
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_HOST: "mysql"
DB_PORT: "3306"
LOG_LEVEL: "info"
# 多行配置文件
app.properties: |
server.port=8080
spring.datasource.url=jdbc:mysql://mysql:3306/mydb
logging.level.root=INFO

使用 ConfigMap

pod-with-configmap.yaml
spec:
containers:
- name: app
image: myapp
# 方式 1:环境变量(单个)
env:
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DB_HOST
# 方式 2:批量注入所有 key
envFrom:
- configMapRef:
name: app-config
# 方式 3:挂载为文件
volumeMounts:
- name: config-volume
mountPath: /etc/config
readOnly: true
volumes:
- name: config-volume
configMap:
name: app-config
items: # 可选:只挂载特定 key
- key: app.properties
path: application.properties

Secret

Secret 存储敏感信息(密码、Token、证书)。值以 Base64 编码存储。

创建 Secret

# 从字面量
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password='S3cret!'

# 从文件
kubectl create secret generic tls-secret \
--from-file=tls.crt --from-file=tls.key

# TLS 类型
kubectl create secret tls app-tls \
--cert=server.crt --key=server.key
secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
# data 中的值必须 Base64 编码
data:
username: YWRtaW4= # echo -n 'admin' | base64
password: UzNjcmV0IQ==
# 或使用 stringData(明文,K8s 自动编码)
stringData:
api-key: my-super-secret-key

使用 Secret

spec:
containers:
- name: app
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secret
Secret 安全

K8s Secret 默认只是 Base64 编码,不是加密。需要额外措施:

  1. 启用 etcd 静态加密(EncryptionConfiguration)
  2. 使用 Sealed SecretsExternal Secrets Operator
  3. 集成外部密钥管理(Vault、AWS Secrets Manager)
  4. 配置 RBAC 限制 Secret 访问权限

持久化存储

PV / PVC / StorageClass

概念角色说明
PV管理员集群级存储资源,预先创建
PVC用户存储请求声明(大小、模式)
StorageClass自动化动态创建 PV,按需分配

PV(静态分配)

pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany # RWX:多节点读写
persistentVolumeReclaimPolicy: Retain # 回收策略
nfs:
server: 192.168.1.100
path: /exports/data

PVC

pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce # RWO:单节点读写
resources:
requests:
storage: 5Gi
storageClassName: standard # 指定 StorageClass

StorageClass(动态分配,推荐)

storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true # 允许扩容
volumeBindingMode: WaitForFirstConsumer # 延迟绑定

在 Pod 中使用

spec:
containers:
- name: app
volumeMounts:
- name: data
mountPath: /app/data
volumes:
- name: data
persistentVolumeClaim:
claimName: app-data

访问模式

模式缩写说明
ReadWriteOnceRWO单节点读写
ReadOnlyManyROX多节点只读
ReadWriteManyRWX多节点读写(NFS/Ceph)
ReadWriteOncePodRWOP单 Pod 读写(K8s 1.22+)

回收策略

策略说明
RetainPVC 删除后 PV 保留数据,需手动清理
DeletePVC 删除后自动删除 PV 和底层存储
Recycle已弃用

常见面试问题

Q1: ConfigMap 和 Secret 的区别?

答案

维度ConfigMapSecret
用途非敏感配置敏感信息
存储明文Base64 编码
大小限制1 MiB1 MiB
内存存储可选 tmpfs(mountPath 挂载时)
RBAC通常宽松应严格限制

两者使用方式相同:环境变量注入或卷挂载。

Q2: PV 和 PVC 如何实现存储解耦?

答案

PV/PVC 模式将存储供给(管理员)和存储消费(开发者)分离:

  1. 管理员创建 PV(或配置 StorageClass 动态创建)
  2. 开发者创建 PVC 声明需要的存储大小和模式
  3. K8s 自动将 PVC 绑定到匹配的 PV
  4. Pod 通过 PVC 使用存储

开发者不需要关心底层存储是 NFS、Ceph 还是云盘。

Q3: K8s 配置更新时 Pod 会自动重启吗?

答案

  • 环境变量方式:ConfigMap/Secret 更新后,已运行的 Pod 不会自动更新。需要重启 Pod 或使用 Reloader
  • 卷挂载方式:kubelet 会自动更新挂载的文件(延迟 ~1 分钟),但应用需要支持文件变更检测
  • 推荐使用 Reloader 自动触发滚动更新

相关链接