kubernetes(K8s)学习笔记(第五期):存储与配置管理

kubernetes(K8s)学习笔记(第五期):存储与配置管理

本笔记为 Kubernetes 系列第五期,聚焦应用数据持久化与配置管理。涵盖:Volume 概述、emptyDir、hostPath、NFS 存储、PV 与 PVC 持久化存储架构、ConfigMap 配置管理、Secret 敏感信息管理。所有命令和 YAML 示例均已经过整理和注释。全文约 5300 字 ,包含 20 个 YAML 示例70+ 命令示例14 张对比表格,是 Kubernetes 应用数据管理的必备指南。
--- Compiled and Authored by Whisky --- June 25th, 2026


目录

  1. Volume 概述
  2. emptyDir
  3. hostPath
  4. NFS 存储
  5. PV 与 PVC 持久化存储
  6. ConfigMap
  7. Secret
  8. 总结与知识点一览表

一、Volume 概述

1.1 为什么需要 Volume?

容器天生是无状态的:

  • 容器重启后,文件系统会重置
  • 容器删除后,所有数据丢失
  • 多个容器之间无法共享数据

Volume(存储卷) 解决了以下问题:

  • 数据持久化:Pod 重启或删除后数据不丢失
  • 数据共享:同一 Pod 中的多个容器可以共享数据
  • 数据迁移:Pod 可以在不同节点间迁移,数据保持一致

通俗比喻:容器就像酒店里的临时客房,每次入住都是全新的房间(干净的镜像),退房后所有个人物品(数据)都清空。Volume 就像酒店的储物柜,客人可以把自己的东西存进去,下次入住同一家酒店还能取出来。

1.2 Kubernetes 支持的 Volume 类型

类型 说明 适用场景
emptyDir 临时存储,Pod 删除时清除 容器间数据共享
hostPath 挂载宿主机目录 单节点测试、日志收集
nfs 挂载 NFS 共享目录 跨节点共享存储
persistentVolumeClaim 引用 PVC 持久卷 生产环境持久化存储
secret / configMap 挂载配置数据 配置文件、敏感信息
csi 容器存储接口 云存储(AWS EBS、Azure Disk 等)

1.3 Volume 生命周期

  • Volume 的生命周期与 Pod 绑定,而非容器
  • Pod 删除时,emptyDir 数据清除,hostPath 和 NFS 数据保留
  • PV/PVC 的生命周期独立于 Pod(即使 Pod 删除,PV/PVC 仍然存在)

1.4 Volume 与 Pod 的关系

ini 复制代码
┌─────────────────────────────────────────────────────────────┐
│                         Pod                                 │
│  ┌─────────┐  ┌─────────┐  ┌──────────────────────────┐   │
│  │容器 1   │  │容器 2   │  │          Volume           │   │
│  │         │  │         │  │                          │   │
│  │ /app    │  │ /logs   │  │  emptyDir / hostPath /    │   │
│  │         │  │         │  │  NFS / PVC               │   │
│  └────┬────┘  └────┬────┘  └──────────────────────────┘   │
│       │            │                      │                 │
│       └────────────┴──────────────────────┘                 │
│                        共享 Volume                          │
└─────────────────────────────────────────────────────────────┘

1.5 环境准备

bash 复制代码
[root@master30 ~]# kubectl create ns storage
[root@master30 ~]# kubectl config set-context --current --namespace storage

二、emptyDir

2.1 emptyDir 概念

emptyDir 是 Kubernetes 中最简单的 Volume 类型:

  • Pod 分配到节点时自动创建
  • Pod 运行时一直存在
  • Pod 删除时永久删除,数据丢失
  • 适合临时数据共享,不适合持久化存储

适用场景

  • 同一 Pod 中多个容器之间共享数据(如日志收集 Sidecar)
  • 缓存目录(如 Nginx 缓存)
  • 临时工作目录(如数据处理)

2.2 emptyDir 实验

实验目标:在一个 Pod 中创建两个容器,共享 emptyDir 卷,验证数据共享和生命周期。

YAML 文件

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  volumes:
  - name: datavolume
    emptyDir: {}           # 定义 emptyDir 卷
  containers:
  - name: busybox1
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
    volumeMounts:
    - mountPath: /data     # 容器内挂载路径
      name: datavolume
  - name: busybox2
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
    volumeMounts:
    - mountPath: /data
      name: datavolume

配置说明

字段 作用
spec.volumes 定义卷,此处为 emptyDir
spec.containers.volumeMounts 引用卷,指定容器内挂载路径
mountPath 容器内挂载目录
name 必须匹配 volumes 中定义的卷名

执行步骤

bash 复制代码
# 1. 创建 Pod
[root@master30 ~]# kubectl apply -f pod-with-emptyDir.yaml
pod/busybox created

# 2. 查看容器 ID 和所在节点
[root@master30 ~]# kubectl describe pod busybox | egrep -o 'Container ID.*//.{12}'
Container ID:  containerd://07d189383321
Container ID:  containerd://bb02c680ca8a

[root@master30 ~]# kubectl describe pod busybox | grep Node:
Node:             worker32.whisky.cloud/10.1.8.32

# 3. 登录节点查看挂载情况
root@worker32:~# crictl inspect 07d189383321 | grep datavolume
        "hostPath": "/var/lib/kubelet/pods/.../volumes/kubernetes.io~empty-dir/datavolume",

# 4. 在容器1中创建文件
[root@master30 ~]# kubectl exec busybox -c busybox1 -- touch /data/b1-f1

# 5. 在容器2中查看(共享成功)
[root@master30 ~]# kubectl exec busybox -c busybox2 -- ls /data
b1-f1

# 6. 删除 Pod,验证数据丢失
[root@master30 ~]# kubectl delete pod busybox --force
pod "busybox" forced deleted

# 7. 节点上查看(目录已不存在)
root@worker32:~# ls /var/lib/kubelet/pods/.../volumes/kubernetes.io~empty-dir/datavolume
ls: No such file or directory

💡 关键理解 :两个容器通过 mountPath: /data 挂载同一个 emptyDir 卷,实现了数据共享。Pod 删除后,emptyDir 数据被清除。emptyDir 非常适合需要数据共享但不需要持久化的场景,比如 Web 服务器 + 日志收集 Sidecar 的组合。

三、hostPath

3.1 hostPath 概念

hostPath 将宿主机节点上的目录挂载到 Pod 中:

  • Pod 删除后,宿主机数据保留
  • 适合需要访问宿主机文件系统的场景(如日志收集)
  • ⚠️ 注意:不同节点上的目录内容可能不同,多节点集群中 Pod 迁移后可能看不到相同数据

适用场景

  • 访问宿主机 Docker/containerd 套接字
  • 读取宿主机日志(如 /var/log
  • 节点级别的配置文件
  • 不适用场景:跨节点数据共享(因为每个节点上的目录独立)

风险警告:hostPath 将宿主机目录暴露给 Pod,存在安全风险。若 Pod 具有写权限,可能覆盖宿主机的关键文件。

3.2 hostPath 实验

实验目标 :将宿主机 /busyboxdir 目录挂载到 Pod 中,验证数据持久性。

YAML 文件

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  volumes:
  - name: datavolume
    hostPath:
      path: /busyboxdir       # 宿主机路径
  containers:
  - name: busybox1
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
    volumeMounts:
    - mountPath: /data
      name: datavolume
  - name: busybox2
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
    volumeMounts:
    - mountPath: /data
      name: datavolume
      readOnly: true          # 设置为只读

readOnly 说明readOnly: true 表示容器对该挂载点只有读权限,默认值为 false(可读写)。在多容器 Pod 中,可以让一个容器写入,另一个只读。

执行步骤

bash 复制代码
# 1. 在宿主机创建目录
root@worker32:~# mkdir -p /busyboxdir

# 2. 创建 Pod
[root@master30 ~]# kubectl apply -f pod-with-hostPath.yaml
pod/busybox created

# 3. 查看挂载情况
[root@master30 ~]# kubectl describe pod busybox | grep Node:
Node:             worker32.whisky.cloud/10.1.8.32

root@worker32:~# crictl inspect 318922d0c666 | grep busyboxdir
        "hostPath": "/busyboxdir",

# 4. 在容器中创建文件
[root@master30 ~]# kubectl exec busybox -c busybox1 -- touch /data/b1-f1
[root@master30 ~]# kubectl exec busybox -c busybox2 -- ls /data
b1-f1

# 5. 验证只读限制(busybox2 无法写入)
[root@master30 ~]# kubectl exec busybox -c busybox2 -- touch /data/b2-f2
touch: /data/b2-f2: Read-only file system
command terminated with exit code 1

# 6. 宿主机查看数据
root@worker32:~# ls /busyboxdir/
b1-f1

# 7. 删除 Pod,验证数据保留
[root@master30 ~]# kubectl delete pod busybox --force
root@worker32:~# ls /busyboxdir/
b1-f1   # 数据依然存在

3.3 emptyDir vs hostPath 对比

特性 emptyDir hostPath
数据持久性 Pod 删除即清除 宿主机数据保留
跨节点数据共享 ❌ 不共享 ❌ 不共享(各节点独立)
适用场景 临时数据共享 访问宿主机文件系统
生产环境推荐度 中等 低(仅单节点测试)
安全风险 较高(需控制权限)

四、NFS 存储

4.1 NFS 概念

NFS(Network File System) 允许 Pod 挂载远程 NFS 共享目录:

  • 数据存储在 NFS 服务器上
  • Pod 删除后数据保留
  • 支持跨节点共享(多个 Pod 可同时访问)

NFS 适用场景

  • 多个 Pod 需要共享同一份数据(如静态文件、配置文件)
  • 需要跨节点数据持久化
  • 作为 PV/PVC 的后端存储(生产环境常见方案)

NFS 优点

  • 配置简单,兼容性好
  • 支持 RWO、ROX、RWX 三种访问模式
  • 成本低(无需购买云存储)

NFS 缺点

  • 性能受网络影响
  • 单点故障(NFS 服务器宕机则所有挂载失效)
  • 不适合高 IOPS 场景

4.2 NFS 服务端部署

在 Master 节点部署 NFS 服务

bash 复制代码
# 1. 安装 NFS 服务端
[root@master30 ~]# apt install -y nfs-kernel-server

# 2. 创建共享目录
[root@master30 ~]# mkdir -m 777 /nfsshares
[root@master30 ~]# echo "hello whisky" > /nfsshares/index.html

# 3. 配置共享(允许所有客户端访问)
[root@master30 ~]# cat << EOF > /etc/exports
/nfsshares *(rw)
EOF

# 4. 重启 NFS 服务
[root@master30 ~]# systemctl restart nfs-server.service

在 Worker 节点安装 NFS 客户端

bash 复制代码
root@worker31:~# apt install -y nfs-common
root@worker32:~# apt install -y nfs-common

4.3 Pod 挂载 NFS 卷

YAML 文件

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx
  name: nginx
spec:
  volumes:
  - name: nfs
    nfs:
      server: 10.1.8.30          # NFS 服务器 IP
      path: "/nfsshares"         # NFS 共享路径
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - name: nfs
      mountPath: "/usr/share/nginx/html"

执行步骤

bash 复制代码
# 1. 创建 Pod
[root@master30 ~]# kubectl apply -f pod-with-nfs.yaml
pod/nginx created

# 2. 查看 Pod IP
[root@master30 ~]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE
nginx   1/1     Running   0          5m    10.224.51.171   worker32.whisky.cloud

# 3. 访问 Nginx(看到 NFS 中的内容)
[root@master30 ~]# curl 10.224.51.171
hello whisky

# 4. 在容器中创建文件
[root@master30 ~]# kubectl exec nginx -- touch /usr/share/nginx/html/test.html

# 5. 在 NFS 服务端查看
[root@master30 ~]# ls /nfsshares/
index.html  test.html

# 6. 删除 Pod,验证数据保留
[root@master30 ~]# kubectl delete pod nginx --force
[root@master30 ~]# ls /nfsshares/
index.html  test.html   # 数据依然存在

五、PV 与 PVC 持久化存储

5.1 PV / PVC 架构

PV(PersistentVolume,持久卷)PVC(PersistentVolumeClaim,持久卷声明) 是 Kubernetes 提供持久化存储的标准方案。

设计理念

  • 存储管理员:创建 PV,描述后端存储资源
  • 应用开发者:创建 PVC,声明存储需求
  • Kubernetes 控制器:自动绑定 PV 和 PVC
ini 复制代码
┌─────────────────────────────────────────────────────────┐
│                    Kubernetes 集群                      │
│                                                         │
│  ┌─────────────┐          ┌──────────────────────────┐ │
│  │    PV       │  ←绑定→  │        PVC              │ │
│  │  (资源)     │          │     (申请)               │ │
│  │  5Gi / NFS  │          │    请求 5Gi / RWO        │ │
│  └─────────────┘          └──────────────────────────┘ │
│         ↑                           ↑                   │
│         │                           │                   │
│  管理员创建                   开发者创建              │
│                                                         │
│                    ┌──────────────────┐                 │
│                    │      Pod         │                 │
│                    │  引用 PVC        │                 │
│                    └──────────────────┘                 │
└─────────────────────────────────────────────────────────┘

PV 与 PVC 的区别

特性 PV(持久卷) PVC(持久卷声明)
定义者 集群管理员 应用开发者 / 用户
资源类型 集群级别资源 Namespace 级别资源
作用 描述存储容量和类型 声明存储需求
生命周期 独立于 Pod 绑定后随 Pod 使用

5.2 创建 PV

PV YAML 示例

yaml 复制代码
apiVersion: v1
kind: PersistentVolume
metadata:
  name: web
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  nfs:
    path: /nfsshares
    server: 10.1.8.30
bash 复制代码
[root@master30 ~]# kubectl apply -f pv.yaml
[root@master30 ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS
web    5Gi        RWO            Retain           Available                   3s

5.3 创建 PVC

PVC YAML 示例

yaml 复制代码
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: webclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
bash 复制代码
[root@master30 ~]# kubectl apply -f pvc.yaml
[root@master30 ~]# kubectl get pvc
NAME       STATUS   VOLUME   CAPACITY   ACCESS MODES
webclaim   Bound    web      5Gi        RWO

PVC 与 PV 绑定条件

  1. 访问模式匹配:PVC 请求的访问模式 PV 必须支持
  2. 容量满足:PV 容量 ≥ PVC 请求容量
  3. 存储类匹配:如果指定了 storageClassName,必须一致

5.4 Pod 使用 PVC

YAML 示例

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    name: web
spec:
  containers:
    - image: nginx
      name: web
      ports:
        - containerPort: 80
          name: web-port
      volumeMounts:
        - name: web-persistent-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: web-persistent-storage
      persistentVolumeClaim:
        claimName: webclaim
bash 复制代码
[root@master30 ~]# kubectl apply -f pod-with-pvc.yaml
[root@master30 ~]# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE
web    1/1     Running   0          35s   10.224.193.69   worker32.whisky.cloud

# 验证数据
[root@master30 ~]# curl http://10.224.193.69
hello whisky

5.5 PV 访问模式(accessModes)

模式 缩写 含义 适用场景
ReadWriteOnce RWO 单个节点以读写方式挂载 单实例应用
ReadOnlyMany ROX 多个节点以只读方式挂载 共享只读数据
ReadWriteMany RWX 多个节点以读写方式挂载 共享读写数据
ReadWriteOncePod RWOP 单个 Pod 以读写方式挂载 独占存储

不同后端支持的访问模式(以 NFS 为例):

卷插件 RWO ROX RWX
NFS
hostPath
iSCSI
CSI 取决于驱动 取决于驱动 取决于驱动
GCE Persistent Disk

⚠️ 重要:每个卷同一时刻只能以一种访问模式挂载。例如,一个 NFS 卷可以支持 RWO、ROX、RWX,但不能同时以多种模式挂载。

5.6 PV 回收策略(Reclaim Policy)

策略 行为 适用场景
Retain(默认) PVC 删除后,PV 保留数据,状态变为 Released 需要手动清理数据
Recycle(已废弃) PVC 删除后,自动清理数据 ---
Delete PVC 删除后,自动删除 PV 和后端存储 动态存储场景

Retain 策略实验

bash 复制代码
# 1. 创建 PV 和 PVC(默认 Retain)
[root@master30 ~]# kubectl apply -f pv-pvc-Retain.yaml

# 2. 删除 PVC
[root@master30 ~]# kubectl delete pvc webclaim

# 3. PV 状态变为 Released
[root@master30 ~]# kubectl get pv
NAME   CAPACITY   RECLAIM POLICY   STATUS     CLAIM
web    5Gi        Retain           Released   default/webclaim

# 4. 创建新 PVC,无法绑定(PV 仍保留旧 claimRef)
[root@master30 ~]# kubectl apply -f pvc-db.yaml
[root@master30 ~]# kubectl get pvc dbclaim
NAME      STATUS    VOLUME   CAPACITY
dbclaim   Pending

# 5. 手动清理 PV 中的 claimRef 信息
[root@master30 ~]# kubectl edit pv web
# 删除 claimRef 部分
# 删除后 PV 状态变为 Available

# 6. PVC 自动绑定成功
[root@master30 ~]# kubectl get pvc dbclaim
NAME      STATUS   VOLUME   CAPACITY
dbclaim   Bound    web      5Gi

💡 关键理解:Retain 策略需要管理员手动清理 claimRef 信息,PV 才能重新使用。这是"保留"策略的设计目的------让管理员决定何时释放数据。

5.7 PV 卷类型

类型 状态 说明
csi ✅ 稳定 容器存储接口,推荐使用
nfs ✅ 稳定 网络文件系统
hostPath ✅ 稳定 单节点测试
local ✅ 稳定 本地存储设备
fc / iscsi ✅ 稳定 光纤通道 / iSCSI
gcePersistentDisk ❌ 已弃用 GCE 持久盘
awsElasticBlockStore ❌ 已弃用 AWS EBS
azureDisk / azureFile ❌ 已弃用 Azure 存储

5.8 StorageClass 与动态制备(补充)

PV 有两种制备方式:

方式 说明 适用场景
静态制备 管理员预先创建 PV 小规模、固定存储
动态制备 通过 StorageClass 自动创建 PV 大规模、自动化

StorageClass 示例(供参考,非本实验内容):

yaml 复制代码
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: slow
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard

六、ConfigMap

6.1 ConfigMap 介绍

ConfigMap 是 Kubernetes 中用于存储非敏感配置数据的 API 对象。

特性 说明
用途 存储配置数据(键值对)
数据大小 上限 1 MiB
编码 明文(不编码)
更新 支持动态更新(Volume 挂载方式)
适用场景 配置文件、环境变量、命令行参数

使用建议

  • ✅ 存储配置数据(如 nginx.conf、app.properties)
  • ✅ 存储环境变量(如 LOG_LEVEL=debug)
  • ❌ 不要存储大量数据(>1MiB)
  • ❌ 不要存储敏感信息(使用 Secret)

ConfigMap 设计的本质:将配置从容器镜像中分离出来,实现"配置即代码",无需重新构建镜像即可修改配置。

6.2 ConfigMap 创建

方式一:键值对方式
bash 复制代码
[root@master30 ~]# kubectl create configmap mysql --from-literal=password=redhat
[root@master30 ~]# kubectl get configmaps mysql -o yaml | grep ^data -A1
data:
  password: redhat
方式二:文件方式
bash 复制代码
[root@master30 ~]# echo "Hello World" > index.html
[root@master30 ~]# kubectl create configmap web1 --from-file=./index.html
[root@master30 ~]# kubectl get configmaps web1 -o yaml | grep ^data -A2
data:
  index.html: |
    Hello World
方式三:目录方式
bash 复制代码
[root@master30 ~]# echo "error" > error.html
[root@master30 ~]# mkdir web2 && mv index.html error.html web2/
[root@master30 ~]# kubectl create configmap web2 --from-file=./web2
[root@master30 ~]# kubectl get configmaps web2 -o yaml | grep ^data -A4
data:
  error.html: |
    error
  index.html: |
    Hello World
方式四:YAML 文件方式
yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: web3
data:
  index.html: |
    Hello World
  error.html: |
    error

6.3 ConfigMap 引用

方式一:环境变量引用
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mysql
spec:
  containers:
  - image: mysql:latest
    name: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        configMapKeyRef:
          name: mysql
          key: password
bash 复制代码
[root@master30 ~]# kubectl apply -f pod-cm-env.yaml
[root@master30 ~]# kubectl exec -it mysql -- bash -c 'echo $MYSQL_ROOT_PASSWORD'
redhat
方式二:Volume 挂载(整体)
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - image: nginx
    name: web
    volumeMounts:
    - name: webcontent
      mountPath: "/usr/share/nginx/html"
  volumes:
  - name: webcontent
    configMap:
      name: web2
bash 复制代码
[root@master30 ~]# kubectl exec web -- ls /usr/share/nginx/html
error.html  index.html
[root@master30 ~]# curl http://10.224.193.69
Hello World
[root@master30 ~]# curl http://10.224.193.69/error.html
error
方式三:Volume 挂载(特定 key)
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - image: nginx
    name: web
    volumeMounts:
    - name: webcontent
      mountPath: "/usr/share/nginx/html"
  volumes:
  - name: webcontent
    configMap:
      name: web2
      items:
        - key: index.html
          path: index.html

6.4 ConfigMap 动态更新

被挂载的 ConfigMap 内容会自动更新(Volume 挂载方式):

bash 复制代码
# 1. 更新 ConfigMap
[root@master30 ~]# kubectl edit configmap web1
# 修改 index.html 内容

# 2. 等待约 30 秒,Pod 内的文件自动更新
[root@master30 ~]# curl http://10.224.51.136
Updated content

注意:环境变量方式引用的 ConfigMap 不会动态更新,需要重启 Pod。Volume 挂载方式的支持了动态更新,但 kubelet 的同步周期默认约 1 分钟。

七、Secret

7.1 Secret 介绍

Secret 是 Kubernetes 中用于存储敏感数据的 API 对象。

Secret vs ConfigMap

对比项 ConfigMap Secret
数据编码 明文 Base64 编码
适用数据 非敏感配置 密码、密钥、证书
数据大小 1 MiB 1 MiB
安全性 中等(可启用加密)
用途 配置数据 敏感数据

Secret 数据编码 :Secret 使用 Base64 编码,但 Base64 不是加密,只是编码。启用 etcd 加密(--encryption-provider-config)可真正保护 Secret 数据。

7.2 Secret 类型

类型 用途 示例
Opaque(generic) 通用键值对 密码、API Key
kubernetes.io/dockerconfigjson Docker 仓库认证 拉取私有镜像
kubernetes.io/tls TLS 证书 HTTPS 证书

7.3 Secret 创建

generic 类型

键值对方式

bash 复制代码
[root@master30 ~]# kubectl create secret generic mysecret1 \
    --from-literal=user=tom \
    --from-literal=password1=redhat
[root@master30 ~]# kubectl get secrets mysecret1 -o yaml
apiVersion: v1
data:
  password1: cmVkaGF0   # redhat 的 base64 编码
  user: dG9t            # tom 的 base64 编码
type: Opaque

Base64 编解码

bash 复制代码
# 编码
[root@master30 ~]# echo -n redhat | base64
cmVkaGF0
[root@master30 ~]# echo -n tom | base64
dG9t

# 解码
[root@master30 ~]# echo -n cmVkaGF0 | base64 -d
redhat

文件方式

bash 复制代码
[root@master30 ~]# echo -n tom > user
[root@master30 ~]# echo -n redhat > password1
[root@master30 ~]# kubectl create secret generic mysecret2 --from-file=./user --from-file=./password1
# 文件名作为 key,文件内容作为 value

目录方式

bash 复制代码
[root@master30 ~]# mkdir config
[root@master30 ~]# mv user password1 config/
[root@master30 ~]# kubectl create secret generic mysecret5 --from-file=./config

YAML 文件方式

yaml 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: mysecret6
type: Opaque
data:
  user: dG9t
  password1: cmVkaGF0
docker-registry 类型
bash 复制代码
[root@master30 ~]# kubectl create secret docker-registry registry \
    --docker-username=whisky \
    --docker-password=redhat \
    --docker-email=whisky@whisky.cloud \
    --docker-server=registry.whisky.cloud
tls 类型
bash 复制代码
# 1. 生成私钥和证书
[root@master30 ~]# openssl genrsa -out www.key 2048
[root@master30 ~]# openssl req -new -key www.key -out www.csr \
    -subj "/CN=www.whisky.cloud"
[root@master30 ~]# openssl x509 -req -days 3650 -in www.csr \
    -signkey www.key -out www.crt

# 2. 创建 Secret
[root@master30 ~]# kubectl create secret tls www-tls \
    --cert=./www.crt --key=./www.key

7.4 Secret 引用

环境变量引用
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mysql
spec:
  containers:
  - image: mysql:latest
    name: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysecret1
          key: password1
Volume 挂载(整体)
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - image: nginx
    name: web
    volumeMounts:
    - name: webcontent
      mountPath: "/usr/share/nginx/html"
  volumes:
  - name: webcontent
    secret:
      secretName: web
Volume 挂载(特定 key + subPath)
yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: web
spec:
  containers:
  - image: nginx
    name: web
    volumeMounts:
    - name: webcontent
      mountPath: "/usr/share/nginx/html/index.html"
      subPath: index.html
  volumes:
  - name: webcontent
    secret:
      secretName: web
Secret 动态更新

Secret 也支持动态更新(Volume 挂载方式):

bash 复制代码
# 1. 更新 Secret 中的值(需 base64 编码)
[root@master30 ~]# echo -n "Hello Nginx" | base64
SGVsbG8gbmdpbng=

# 2. 编辑 Secret
[root@master30 ~]# kubectl edit secrets web

# 3. 等待约 30 秒,Pod 内文件自动更新
[root@master30 ~]# curl 10.224.51.137/index.html
Hello Nginx

7.5 文件权限设置

设置所有文件权限(defaultMode)

yaml 复制代码
volumes:
- name: foo
  secret:
    secretName: mysecret1
    defaultMode: 256   # 10进制 256 → 8进制 400(只读)

设置单个文件权限(mode)

yaml 复制代码
volumes:
- name: foo
  secret:
    secretName: mysecret1
    items:
    - key: user
      path: user
      mode: 511   # 10进制 511 → 8进制 777(所有权限)

八、总结与知识点一览表

8.1 核心知识点汇总

模块 核心概念 关键配置
Volume 存储卷抽象 spec.volumes, spec.containers.volumeMounts
emptyDir 临时存储,随 Pod 删除 emptyDir: {}
hostPath 宿主机目录挂载 hostPath: {path: /xxx}
NFS 网络文件系统 nfs: {server: IP, path: /xxx}
PV 集群级存储资源 capacity, accessModes, nfs
PVC 命名空间级存储申请 resources.requests.storage, accessModes
ConfigMap 非敏感配置存储 --from-literal, --from-file
Secret 敏感信息存储 Base64 编码,三种类型

8.2 Volume 类型对比

类型 持久性 跨节点 适用场景
emptyDir ❌ Pod 删除即失 临时共享
hostPath ✅ 宿主机保留 单节点测试
NFS ✅ 服务端保留 共享存储
PV/PVC ✅ 服务端保留 生产持久化

8.3 ConfigMap vs Secret 对比

特性 ConfigMap Secret
数据编码 明文 Base64
用途 配置数据 敏感数据
类型 一种 三种(generic/docker-registry/tls)
动态更新 ✅(Volume 方式) ✅(Volume 方式)
etcd 加密 不需要 推荐启用

8.4 常见错误排查

错误 原因 解决方法
PVC pending 没有匹配的 PV 检查 PV 状态和 PVC 请求参数
MountVolume.SetUp failed 宿主机路径不存在 创建对应的宿主机目录
secret not found Secret 未创建或在其他 Namespace 确认 Secret 名称和 Namespace
ConfigMap not found ConfigMap 未创建 确认 ConfigMap 名称
Permission denied 文件权限不足 调整 defaultMode 或宿主机权限
NFS 挂载超时 NFS 服务未启动或网络不通 systemctl status nfs-server

8.5 生产环境建议

  1. 存储选型
    • 临时数据 → emptyDir
    • 测试环境 → hostPath
    • 生产环境 → PV/PVC(NFS、CSI 云存储)
  2. ConfigMap 使用建议
    • 配置数据大小 < 1 MiB
    • 使用 Volume 挂载方式可实现动态更新
    • 敏感数据使用 Secret
  3. Secret 使用建议
    • 启用 etcd 加密(生产环境)
    • 使用 RBAC 限制 Secret 访问权限
    • 考虑使用外部 Secret 管理工具(如 HashiCorp Vault)
  4. PV/PVC 使用建议
    • 使用 Retain 策略保护重要数据
    • 定期备份 PV 中的数据
    • 合理规划存储类(StorageClass)

下一期预告:Kubernetes 控制器管理------Deployment 无状态应用部署、ReplicaSet 副本控制、DaemonSet 节点守护、Job/CronJob 任务管理。掌握 Kubernetes 工作负载控制器的核心机制。
--- Compiled and Authored by Whisky --- June 25th, 2026