形象类比把K8s集群当成一栋公寓楼Pod 住户房间用完可销毁数据默认随房间消失NFS 楼下公共共享仓库所有住户共用的外置硬盘PV 物业提前划分好的固定储物格实实在在的存储空间PVC 住户写的储物申请单只说要多大空间不用管位置ConfigMap 普通纸质记事本存放明文普通配置Secret 带锁小保险柜存放密码、密钥等敏感数据总结Pod 中容器应用产生的 数据 的 目录挂载通常都放到pv类型的数据卷中而配置文件、环境变量等 的挂载处理 在k8s中 推荐 使用ConfigMap用来保存 不方便 明文存储 的敏感信息例如 数据库密码、账号、Token、密钥、私钥等 通常用Secret一、NFS 网络共享存储存储底层数据源1. 通俗解释网络文件同步系统,可以实现多台主机在指定目录下进行 资源同步。k8s借助NFS系统可以实现 有状态部署 的 硬盘资源的整合管理。跨服务器共享文件夹所有K8s节点都能读写同一份文件是K8s最常用的本地集群持久化存储。2. 最佳使用场景中小型K8s集群本地持久化数据日志收集、静态文件共享、数据库数据挂载多Pod共享同一份数据文件3. 实操搭建NFS服务腾讯云服务器环境假设 集群服务器有 5 台组成对应的 IP 地址分别是 1.1.1.1、2.2.2.2、3.3.3.3、4.4.4.4、5.5.5.5选集群其中一台机器当NFS服务端1.1.1.1其余所有节点2.2.2.2~5.5.5.5作为客户端3.1 服务端安装配置1.1.1.1执行# 安装nfsyuminstall-ynfs-utils rpcbind# 创建共享目录mkdir-p/data/k8s-nfs# 配置共享权限vim/etc/exports# 写入内容允许所有集群网段访问/data/k8s-nfs *(rw,sync,no_root_squash,no_all_squash)# 重启开机自启systemctl start rpcbindsystemctlenablerpcbind systemctl start nfssystemctlenablenfs# 生效配置exportfs-r# 查看共享目录showmount-elocalhost3.2 所有K8s节点客户端安装全部机器执行yuminstall-ynfs-utils# 测试挂载连通性showmount-e1.1.1.14. NFS 增删改查服务器层面增新建共享目录 写入exports配置查showmount -e 服务端IP改修改/etc/exports执行exportfs -r删删除目录、清空exports配置停止nfs服务5. 说明K8s 集群运行 不依赖 NFS。NFS 只是众多存储方案里的其中一种不是刚需。对于 ConfigMap 和 Secret 而言数据 存储在 etcd 的自然没有 任何影响。对于 PV 而言不用 nfs 类型 替换成别的存储后端云厂商云硬盘腾讯云 CBS、阿里云云盘等 即可。只有一种情况 必须装 NFS业务需要多台节点、多个 Pod 共享同一份数据文件比如多实例 Web 共用一份静态资源集群统一日志共享目录多 Pod 读写同一个上传文件这种场景才需要一台机器搭 NFS 服务端所有集群节点装 NFS 客户端除此之外一辈子不装都没事。二、PV 持久卷PersistentVolume1. 通俗解释集群管理员提前建好的存储空间直接绑定NFS目录定义好大小、权限、存储类型等着业务来申请使用。2. 最佳场景统一规划集群存储资源固定大小数据库、缓存数据持久化统一管控存储权限与读写策略3. 完整部署步骤3.1 编写 PV yamlnfs-pv.yamlapiVersion:v1kind:PersistentVolumemetadata:name:nfs-pv-10gspec:capacity:storage:10Gi# 分配10G空间accessModes:-ReadWriteMany# 多Pod同时读写nfs:path:/data/k8s-nfs# NFS服务端共享目录server:1.1.1.1# NFS服务端IPpersistentVolumeReclaimPolicy:Retain# 释放后保留数据3.2 创建PVkubectl apply-fnfs-pv.yaml4. PV 全套增删改查命令# 查所有PVkubectl getpv# 查看PV详细信息kubectl describepvnfs-pv-10g# 修改PV直接编辑kubectl editpvnfs-pv-10g# 删除PVkubectl deletepvnfs-pv-10g5. 业务案例提前创建20G、50G大小NFS-PV统一给MySQL、Redis业务预留存储。6. PV 需要 运维人员 提前创建好吗静态 PV必须运维提前建好没建就用不了 但 K8s 有免手动建 PV 的方案1. 先说传统模式你之前学的 NFSPVPVC规则死规定运维不手动创建PV → 集群里就没有可用存储空间开发写好PVC去申请存储集群里找不到匹配的PVPVC状态一直卡在Pending最终业务Pod挂载失败无法启动简单说静态卷模式无提前建好的PV PVC申请不到存储 用不了2. 不用运维提前建PV的方案生产最常用K8s 提供StorageClass 存储类作用自动创建PV流程彻底改变运维只配置一次「存储模板」比如NFS模板、云盘模板运维再也不用一个个手动建PV开发直接创建PVCK8s自动根据模板实时生成对应PV自动绑定直接正常使用通俗比喻老式静态PV管理员提前把一个个空柜子摆好建好PV你才能领StorageClassSC动态卷商场有自助存包机你一扫码申请机器当场变出柜子不用管理员提前摆两种模式对比模式有无SC流程优缺点静态存储不用SC运维手动建PV → 开发建PVC绑定运维麻烦必须提前规划动态存储配置SC运维配置SC规则 → 开发直接建PVC →自动生成PV按需创建运维零工作量生产首选StorageClass 常用命令增删改查# 查看所有存储类kubectl get sc# 查看详细信息kubectl describe sc nfs-dynamic-sc# 修改存储类kubectl edit sc nfs-dynamic-sc# 删除存储类kubectl delete sc nfs-dynamic-sc适合用 StorageClass生产正式环境99%企业在用业务量大、项目多不可能让运维手动一个个建PV微服务集群每个服务独立存储按需申请5G、10G、20G自动分配CI/CD自动发布项目流水线部署自动创建PVC自动生成存储云服务器K8s集群腾讯云/阿里云自带云盘SC直接用不用搭NFS弹性扩容业务临时扩容Pod自动申请存储用完释放不适合用 StorageClass极简测试单机集群自己学习玩一玩数量少手动建PV更快需要提前规划固定大容量存储超大数据库提前划分好固定分区三、PVC 持久卷声明PersistentVolumeClaim1. 通俗解释开发人员提交的存储申请单只填写我需要多大空间、读写权限K8s自动匹配空闲PV不用关心存储真实位置。2. 最佳场景业务项目申请持久化存储部署MySQL、Redis、Nginx日志持久化开发无需接触底层NFS只申请即可3. 完整部署步骤3.1 编写PVC yamlnfs-pvc.yamlapiVersion:v1kind:PersistentVolumeClaimmetadata:name:app-pvcspec:accessModes:-ReadWriteManyresources:requests:storage:10Gi# 申请10G存储3.2 创建PVC自动绑定PVkubectl apply-fnfs-pvc.yaml创建后自动匹配状态为Available的同规格PV状态变成Bound绑定成功。3.3 Pod挂载PVC实现数据持久化apiVersion:v1kind:Podmetadata:name:nginx-podspec:containers:-name:nginximage:nginxvolumeMounts:-name:data-volumemountPath:/usr/share/nginx/html# 容器内挂载目录volumes:-name:data-volumepersistentVolumeClaim:claimName:app-pvc# 引用上面PVC执行创建kubectl apply-fnginx-pod.yaml效果删除Pod重建网页数据依然保留在NFS服务器里。4. PVC 增删改查命令# 查看所有PVCkubectl get pvc# 查看绑定详情kubectl describe pvc app-pvc# 在线修改PVCkubectl edit pvc app-pvc# 删除PVCkubectl delete pvc app-pvc5. 实战场景部署MySQL数据库挂载PVC持久化库文件集群节点漂移数据不丢失。四、ConfigMap 明文配置中心1. 通俗解释存放明文普通配置的文件仓库比如端口、域名、超时时间、环境地址所有人都能看。2. 最佳使用场景项目配置文件、日志级别、接口地址Nginx配置、启动参数、开发环境变量非敏感通用配置统一管理3. 三种创建方式 实操方式1命令行快速创建最简单# 键值对创建kubectl create configmap app-config --from-literalenvprod,port8080# 从本地配置文件创建kubectl create configmap nginx-conf --from-file./nginx.conf方式2yaml标准创建configmap.yamlapiVersion:v1kind:ConfigMapmetadata:name:web-configdata:APP_ENV:productionLOG_LEVEL:infoDB_HOST:10.0.0.10创建kubectl apply-fconfigmap.yaml3种挂载使用方式注入环境变量挂载为配置文件启动命令引用示例Pod引用ConfigMapapiVersion:v1kind:Podmetadata:name:config-podspec:containers:-name:appimage:busyboxcommand:[sleep,3600]env:-name:ENVvalueFrom:configMapKeyRef:name:web-configkey:APP_ENV这个配置文件的作用创建一个 Pod里面运行一个 busybox 容器把 ConfigMap(web-config) 里的配置项 APP_ENV自动注入成容器内部的环境变量ENV容器启动后休眠 1 小时方便我们测试。4. ConfigMap 增删改查# 查询kubectl get configmap kubectl describe configmap web-config# 修改kubectl edit configmap web-config# 删除kubectl delete configmap web-config5. 业务案例统一管理微服务环境变量测试/生产环境一键切换ConfigMap实现环境切换。五、Secret 加密私密配置1. 通俗解释加密保险箱专门存放账号密码、数据库密码、Token、密钥数据默认Base64编码加密比明文安全。2. 最佳使用场景MySQL、Redis、MQ数据库账号密码接口密钥、JWT令牌、登录凭证集群内部私密授权信息3. 实操部署3.1 命令行创建推荐# 创建数据库账号密码secretkubectl create secret generic db-secret\--from-literaldb_userroot\--from-literaldb_pwd1234561.kubectl create secret含义执行创建 Secret 资源作用告诉 K8s 集群我要创建一个「加密配置保险箱」2.generic含义通用型 Secret作用最常用的Secret类型专门存账号、密码、Token、密钥等任意敏感键值对Secret 一共 3 种官方标准类型generic通用型 / 万能型→ 存任意敏感数据账号、密码、Token、密钥tls证书专用型→ 存HTTPS 证书 私钥网站加密用docker-registry镜像仓库专用型→ 存私有镜像仓库登录凭证拉私有镜像用3.db-secret含义给这个 Secret 起的名字作用后面 Pod 要引用这个密码时必须写这个名字4.--from-literal含义直接用「键值」的字面量方式创建作用不用写YAML文件命令行直接明文写配置最简单快捷5.db_userroot键名db_user数据库用户名键值root作用存数据库账号6.db_pwd123456键名db_pwd数据库密码键值123456作用存数据库密码3.2 yaml方式创建secret.yaml先加密明文echo-nroot|base64# 输出cm9vdAecho-n123456|base64# 输出MTIzNDU2写入yamlapiVersion:v1kind:Secretmetadata:name:db-secrettype:Opaquedata:db_user:cm9vdAdb_pwd:MTIzNDU2创建kubectl apply-fsecret.yaml3.3 Pod引用Secret注入密码# 1. 固定API版本Pod属于K8s核心v1版本APIapiVersion:v1# 2. 资源类型我要创建的是【Pod】K8s最小运行单元kind:Pod# 3. 元数据给Pod起名字metadata:name:mysql-pod# 这个Pod的名字叫 mysql-pod# 4. Pod规格定义Pod里装什么、怎么运行spec:containers:# 容器列表一个Pod里可以跑多个容器-name:mysql# 给容器起个名字mysqlimage:mysql:5.7# 用官方MySQL 5.7版本镜像固定写法# 核心重点环境变量配置密码安全核心env:# MySQL 官方镜像强制要求必须设置这个环境变量# 作用设置 MySQL 的 root 用户密码-name:MYSQL_ROOT_PASSWORD# 值不从YAML写死明文而是从【Secret】中读取valueFrom:# 明确告诉K8s值来自 Secret 加密配置secretKeyRef:name:db-secret# 读取哪个Secret→ 你创建的 db-secretkey:db_pwd# 读Secret里的哪个键→ db_pwd存的是1234564. Secret 增删改查命令# 查看kubectl get secret kubectl describe secret db-secret# 修改kubectl edit secret db-secret# 删除kubectl delete secret db-secret5. Secret 数据安全性 的保障Secret 真正的安全来自K8s 集群的 4 道安全锁安全锁 1RBAC 权限控制最重要不是谁都能查看 Secret只有集群管理员、授权账号才能kubectl get secret普通开发、外部人员根本看不到Secret 内容比喻Secret 是放在带锁保险柜里的纸条Base64 只是纸条上的字写歪了锁才是安全核心安全锁 2命名空间隔离Secret 只能在同一个 Namespace内使用跨项目、跨环境完全隔离无法窃取安全锁 3只存内存不写硬盘Pod 挂载的 Secret不会写入节点磁盘直接放在tmpfs内存临时文件中Pod 删除数据立刻消失不留痕迹安全锁 4传输全程 HTTPS 加密K8s 各组件之间传输 Secret全程 TLS 加密网络传输中不可能被窃听综上所述K8s 超级集群管理员可以毫无阻碍查看、解码、获取集群内任意所有 Secret 明文敏感数据没有任何遮挡。超级管理员拥有全局最高 RBAC 权限不受任何权限限制可以随意执行查看、导出所有 Secret 资源Secret 仅靠 Base64 编码管理员一键就能解码成明文6. 什么要用 Base64不是为了加密是为了兼容存储Secret 可以存二进制文件证书、图片、密钥etcd 只能存文本不能存二进制Base64 把二进制 → 纯文本方便 K8s 存储传输就是个格式转换工具和安全无关7. 生产环境真正的「高强度安全」怎么做如果你的业务是金融、支付等高安全要求开启 K8setcd 静态加密Secret 落盘加密存储搭配云厂商KMS 密钥管理服务腾讯云/阿里云严格 RBAC 权限禁止越权查看 Secret敏感密钥使用外部密钥管理系统不存 K8s