---
url: /courses/kubernetes-cluster/10-storage-config-secrets/index.md
---
# 第十节 存储、配置与敏感信息

::: tip 本课目标
为虚构业务“云帆商城”划分临时数据、节点数据和持久数据边界；使用 PVC、ConfigMap 与 Secret 解耦数据和配置，并通过删除重建实验验证哪些内容真正保留下来。
:::

## 10.1 接单：容器删除后，数据应该去哪

容器可替换，但不同数据的生命周期要求不同：

| 类型 | 本课示例 | 生命周期边界 |
| --- | --- | --- |
| 容器文件层 | Nginx 临时缓存 | 容器重建后不保证保留 |
| emptyDir | 同一 Pod 内交换文件 | Pod 存在期间保留，Pod 删除后消失 |
| hostPath | kind 节点实验目录 | 绑定某个节点，不具备生产级可移植性 |
| PVC | 业务数据目录 | 与 Pod 解耦，由 PV 和回收策略决定 |

## 10.2 临时共享与节点绑定

**emptyDir** 在 Pod 被分配到节点时创建，同一 Pod 的多个容器可共享；容器重启不会清空它，但 Pod 删除会清空。

```bash
kubectl apply -f manifests/10-storage/volume-baseline.yaml
kubectl logs -n yunfan-shop yunfan-shared-volume -c reader
kubectl exec -n yunfan-shop yunfan-node-data -- cat /node-data/visits
```

在 kind 中，`hostPath` 指向节点容器内的路径，不是个人电脑的同名路径。它适合认识节点绑定，不作为跨节点数据库存储方案。

## 10.3 PVC：把持久数据请求交给存储系统

PVC 是对存储容量和访问模式的请求；StorageClass 决定动态供给方式，PV 表示实际存储资源。先确认本地集群的默认类：

```bash
kubectl get storageclass
kubectl get storageclass standard -o yaml
```

本课把 `PersistentVolumeClaim`、ConfigMap 和 Secret 一起挂载。Secret 使用 `stringData` 只是为了提高实验清单可读性。

`training-only` 是公开实验占位值，不得替换成真实密码后提交。Secret 的 base64 表示不是加密；生产环境还需要最小权限、静态加密、外部密钥系统和轮换策略。

## 10.4 删除重建：用实验验证生命周期

先读取数据与配置，不输出 Secret：

```bash
kubectl apply -f manifests/10-storage/persistent-config.yaml
kubectl wait -n yunfan-shop \
  --for=condition=Ready pod/yunfan-data-check \
  --timeout=120s
kubectl exec -n yunfan-shop yunfan-data-check -- cat /data/history
kubectl exec -n yunfan-shop yunfan-data-check -- cat /config/storefront.properties
kubectl exec -n yunfan-shop yunfan-data-check -- printenv APP_MODE
```

删除并重建 Pod：

```bash
kubectl delete pod yunfan-data-check -n yunfan-shop
kubectl apply -f manifests/10-storage/persistent-config.yaml
kubectl wait -n yunfan-shop \
  --for=condition=Ready pod/yunfan-data-check \
  --timeout=120s
kubectl exec -n yunfan-shop yunfan-data-check -- cat /data/history
```

历史文件应出现两行，证明数据跨 Pod 重建保留。这个结论只覆盖当前 PVC 与本地 provisioner，不等同于已经具备备份、容灾或多节点共享能力。

## 10.5 故障演练：PVC 为什么 Pending

复制 PVC 清单并把 `storageClassName` 改为不存在的 `missing-class`，资源名改为 `yunfan-data-pending`。应用后检查：

```bash
kubectl get pvc -n yunfan-shop
kubectl describe pvc yunfan-data-pending -n yunfan-shop
kubectl get storageclass
```

诊断结论必须包含：

```text
现象：PVC 长时间 Pending
证据：事件提示 storageclass.storage.k8s.io "missing-class" not found
根因：请求引用了不存在的 StorageClass
修复：改回已存在的 standard，再重新申请 PVC
```

清理故障资源：

```bash
kubectl delete pvc yunfan-data-pending -n yunfan-shop
```

## 10.6 配置更新边界

* ConfigMap 或 Secret 作为卷挂载时，kubelet 会周期性更新文件，但不是瞬时事务。
* 通过环境变量注入的值不会自动进入已运行进程，需要重建 Pod。
* 使用 `subPath` 挂载单个文件时，不会接收自动更新。
* 配置更新成功不代表应用一定重新加载，应由应用机制或滚动发布完成闭环。

## 10.7 交付

1. 临时卷、hostPath、PVC、ConfigMap 与 Secret 清单。
2. Pod 删除前后的 `/data/history` 对比证据。
3. PVC、PV 与 StorageClass 的绑定截图。
4. 一份不包含真实凭据的配置安全说明和 Pending 故障工单。

{{reflection-checkpoint:storage-config-secrets-check}}

## 本章小测

{{assessment:storage-config-secrets}}

## 本章小结

* emptyDir、hostPath 与 PVC 的生命周期和可移植性不同。
* PVC 通过 StorageClass 与 PV 把应用需求和存储实现解耦。
* ConfigMap 保存非敏感配置，Secret 需要额外的访问控制、加密和轮换措施。
* “删除 Pod 后数据还在”只是持久性的一项证据，不等于备份与容灾已经完成。
