一、配置管理:ConfigMap & Secret
核心:实现配置与容器镜像解耦,配置统一在集群管理,不写死在镜像内部。
1.ConfigMap(普通非敏感配置)
存储明文普通配置:配置文件、环境变量、参数;etcd 明文存储,严禁存放密码密钥。 ✅适合:日志级别、超时、nginx 配置、环境变量 ❌禁止:密码、token、私钥
创建 ConfigMap 四种方式
--from‑literal命令行键值对(测试临时)
kubectl create configmap my‑cm \
--from‑literal=DB_HOST=mysql‑svc \
--from‑literal=DB_PORT=3306
--from‑env‑file从.env环境变量文件创建
kubectl create configmap env‑cm --from‑env‑file=redis.env
--from‑file从本地配置文件 / 目录创建(保存完整配置文件内容)
kubectl create configmap nginx‑cm --from‑file=server.conf
- YAML 声明式创建(生产推荐,支持 GitOps)
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx‑conf
data:
# | 保留多行文本
server.conf: |
server {
listen 80;
}
Pod 中使用 ConfigMap 两种模式
①注入环境变量
configMapKeyRef:引入单个 key做环境变量envFrom:‑configMapRef:全部 key 批量注入环境变量
⚠环境变量方式更新 ConfigMap,Pod 不会自动生效,必须重启 Pod。
②挂载为文件卷(volumes+volumeMounts)
- 完整目录挂载(无 subPath) 把 CM 全部 key 挂载到容器目录;会覆盖容器目标目录原有全部文件;✅支持配置热更新,修改 CM 容器内文件异步自动刷新。
- subPath 子路径挂载(重点)
volumeMounts 下写
subPath: key名,只挂载单个文件,不会覆盖整个目录 ❗致命缺点:subPath 不支持热更新!修改 CM,容器文件不会变化,必须重启 Pod 才生效。
- items 筛选挂载(volumes.configMap.items) 在 volumes 层筛选 CM 中的部分 key,可以重命名文件名、设置文件权限 mode;✅支持热更新。
items:控制提供哪些文件;subPath:控制文件挂载到容器哪个路径,二者不能互相替代。
表格
| 特性 | items | subPath |
|---|---|---|
| 层级 | volumes.configMap 下 | volumeMounts 下 |
| 数量 | 可一次筛选多个 key | 一次只能映射单个 key |
| 热更新 | ✅支持 | ❌不支持 |
| 文件重命名 | 支持 path 重命名 | 不支持 |
2.Secret(存放敏感数据)
存储密码、TLS 证书、token;etcd 内部 Base64 编码,不是加密,只是简单编码,不是强加密;容器挂载后自动解码为明文。
Secret 四种 type 类型
表格
| type | 用途 |
|---|---|
Opaque(generic) | 通用,密码、密钥,最常用 |
kubernetes.io/dockerconfigjson | 私有镜像仓库认证 |
kubernetes.io/tls | 专门存 tls.crt、tls.key 证书,Ingress HTTPS 使用 |
kubernetes.io/service‑account‑token | ServiceAccount 自动生成,API 访问令牌 |
创建 Secret
1. 命令行
kubectl create secret generic mysql‑secret --from‑literal=root‑pwd='Root@123'
#tls证书secret
kubectl create secret tls example‑tls --cert=tls.crt --key=tls.key
2.yaml 方式:data 字段的值必须是 base64 编码字符串。
Pod 使用 Secret
用法和 ConfigMap 完全一致:
secretKeyRef:单个 key 注入环境变量envFrom:‑secretRef:批量全部注入环境变量- volumes 挂载为文件,同样支持 items、subPath,subPath 依旧不支持热更新。
面试区分 ConfigMap vs Secret 1.ConfigMap 存普通明文配置;Secret 存敏感信息,数据 base64 编码。 2. 二者使用方式完全一致:环境变量、文件挂载; 3.Secret 只是编码,不是加密,生产要配合 etcd 加密、RBAC 权限控制。
重要记忆:
- 环境变量方式:CM/Secret 更新,必须重启 Pod 才生效
- 目录完整挂载(无 subPath):✅热更新
- subPath 挂载:❌无热更新,必须重启 Pod
二、K8s Volume 存储卷基础卷
1.EmptyDir
- 生命周期:和 Pod 绑定,Pod 创建就生成,Pod 删除数据全部丢失;容器重启数据保留。
- 作用:同一个 Pod 内部多个容器之间共享临时目录。
- 默认存节点磁盘;也可以配置
emptyDir: {medium:Memory}使用内存 tmpfs,速度快,重启丢失。
❗不能持久化,Pod 漂移 / 删除数据全部消失。
volumes:
- name: share‑vol
emptyDir: {}
2.HostPath
把宿主机节点的文件 / 目录直接挂载进容器
⚠存储强绑定所在节点,Pod 调度漂移到别的节点,看不到原来数据;有安全逃逸风险;生产业务禁止使用,只适合单机调试、节点日志采集。
type 类型(重点)
表格
| type | 说明 |
|---|---|
| DirectoryOrCreate | 目录不存在自动创建 |
| FileOrCreate | 文件不存在自动创建空文件 |
| Directory | 目录必须已经存在,否则 Pod 启动失败 |
| File | 文件必须已经存在,否则 Pod 启动失败 |
3.NFS 网络存储
网络文件系统;独立服务器存放数据;Pod 删除、漂移,数据不会丢失;支持多节点同时读写。
- 服务端:安装 nfs‑server,配置
/etc/exports共享目录 - 所有 k8s 工作节点必须安装 nfs 客户端,否则 Pod 挂载失败。
volumes:
- name: nfs‑vol
nfs:
server: 192.168.1.100
path: /data/nfs‑share
三、PV & PVC(⭐)
解耦:PV 是管理员提供的存储资源;PVC 是用户存储申请;Pod 不直接碰底层存储,只挂载 PVC。 类比租房:PV = 房东的房子;PVC = 租客租房申请;绑定 = 签约。
PV (PersistentVolume) 持久卷
- 集群级别资源,不属于命名空间;管理员预先创建(静态供给),或者 StorageClass 动态自动创建。
- 描述存储:容量、访问模式、回收策略、后端存储(NFS/Ceph/CSI)。
PVC (PersistentVolumeClaim) 持久卷申领
- 命名空间级别资源;普通用户创建,只描述需要多大存储、访问模式,不用关心底层存储是什么。
- PVC 必须成功绑定 PV 之后,Pod 才可以挂载使用。
1.PV 访问模式 accessModes(PV、PVC 都要写)
表格
| 访问模式 | 全称 | 说明 | 典型存储 |
|---|---|---|---|
| RWO | ReadWriteOnce | 单节点读写:只能被一个节点挂载读写;同节点多个 Pod 可共享读写 | 云盘、local 本地盘、hostPath |
| ROX | ReadOnlyMany | 多节点只读;多个节点挂载,只能读不能写 | NFS、CephFS |
| RWX | ReadWriteMany | 多节点同时读写,跨节点多 Pod 读写共享 | NFS、NAS、CephFS |
注意:块存储(云 EBS)大多只支持 RWO,不支持 RWX。
2.PV 回收策略 persistentVolumeReclaimPolicy
决定 PVC 删除之后底层存储如何处理
- Retain(推荐生产默认) 删除 PVC,PV 状态变为
Released;数据保留,PV 保留;不会自动清理,需要管理员手动删除 PV、手动清理存储数据;防止误删丢失业务数据。 - Delete 删除 PVC,自动删除 PV,同时删除后端底层存储数据;云厂商 StorageClass 默认策略;⚠测试环境使用,生产重要数据慎用,误删数据直接丢失。
- Recycle:k8s1.20 已经废弃,不再使用。
3.PV 状态流转
表格
| 状态 | 含义 |
|---|---|
| Available | 空闲可用,等待 PVC 申领绑定 |
| Bound | 已经成功绑定 PVC,可以给 Pod 使用 |
| Released | PVC 被删除,PV 还保留;回收策略 Retain 时出现;不能直接被新 PVC 复用,需要管理员清理 |
| Failed | 自动回收操作失败 |
4.PV 与 PVC 绑定匹配三条件(静态 PV)
storageClassName必须完全一致(都为空也要同时为空)- PVC 请求 storage 容量 ≤ PV 的 storage 容量;优先选满足条件的最小容量 PV
- PVC 的 accessModes 必须是 PV accessModes 的子集。
不满足条件 → PVC 一直 Pending 状态。
静态 PV+PVC 完整 yaml 示例(NFS)
PV(集群资源,无 namespace)
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs‑pv‑1g
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
server: 192.168.1.100
path: /data/nfs‑share
PVC(命名空间资源)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my‑pvc
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 500Mi
storageClassName: nfs
Pod 挂载 PVC
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: html‑vol
mountPath: /usr/share/nginx/html
volumes:
- name: html‑vol
persistentVolumeClaim:
claimName: my‑pvc
5. 静态供给 vs 动态供给 StorageClass
- 静态供给:管理员手动一个个创建 PV;用户创建 PVC 去匹配已存在 PV。适合小规模。
- 动态供给 StorageClass:用户只需要创建 PVC,不用手动建 PV;StorageClass 调用存储插件 CSI,自动创建 PV 并且完成绑定;生产大规模集群主流方案。
核心命令
kubectl get pv #集群级别,无‑n
kubectl get pvc -n ns #命名空间资源,需要‑n
kubectl describe pv xxx
kubectl describe pvc xxx
四、汇总
- ConfigMap subPath 的坑? subPath 只挂载单个文件,不覆盖目录原有文件;但是不支持热更新,修改 ConfigMap,容器内文件不会自动更新,必须重启 Pod。
想要热更新,要么完整目录挂载,要么使用 items 方式。
- ConfigMap 环境变量更新会不会自动生效? 不会!环境变量注入方式,CM 修改之后Pod 不会感知,必须重启 Pod。
- ConfigMap 和 Secret 区别? ConfigMap 存放普通非敏感配置,明文存储;Secret 存放密码证书,内部 Base64 编码(只是编码,不等同加密);二者 Pod 使用语法完全一样。
- emptyDir、hostPath、NFS 三者区别
- emptyDir:Pod 生命周期;Pod 删除数据丢失;仅 Pod 内部多容器临时共享,不能持久化。
- hostPath:宿主机目录挂载;绑定节点,Pod 漂移丢失数据;安全风险,不用于生产业务。
- NFS:独立网络存储;Pod 删除 / 漂移数据仍然保留;实现真正持久存储。
- PV 两种回收策略 Retain 与 Delete 区别?
- Retain:删除 PVC,PV 保留,数据保留,状态 Released,管理员手动清理;生产保护数据,防止误删。
- Delete:删除 PVC 自动删除 PV 和底层存储;云环境默认,重要业务慎用,容易误丢数据。
- PV 和 PVC 是什么?二者关系? PV:集群级存储资源对象,由管理员提供,描述底层存储; PVC:命名空间级存储申请,用户声明需要多大存储、访问模式; PVC 根据条件匹配绑定 PV;Pod 挂载 PVC 间接使用 PV 存储;实现存储和计算解耦。
- PV 与 PVC 绑定的三个条件? ①storageClassName 完全匹配;②PVC 请求容量不大于 PV 容量;③PVC 访问模式是 PV 访问模式子集。
- accessModes RWO / ROX / RWX 区别?
- RWO:仅单个节点可以读写(云盘最常见)
- ROX:多节点只读
- RWX:多节点同时读写,一般依赖 NFS、NAS 分布式文件系统。
五、核心命令汇总
#configmap secret
kubectl get cm
kubectl get secrets
kubectl create configmap
kubectl create secret
#卷pv pvc
kubectl get pv
kubectl get pvc
kubectl describe pv <pv‑name>
kubectl describe pvc <pvc‑name>