跳到主要内容

存储管理

Kubernetes 提供了强大的存储抽象,包括 PersistentVolume、ConfigMap、Secret 等,用于管理应用的数据和配置。

存储架构

PersistentVolume (PV)

PV 是集群管理员配置的存储资源:

apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem # Filesystem / Block
accessModes:
- ReadWriteOnce # 单节点读写
# - ReadOnlyMany # 多节点只读
# - ReadWriteMany # 多节点读写
persistentVolumeReclaimPolicy: Retain # Retain / Recycle / Delete
storageClassName: standard
# NFS 示例
nfs:
server: nfs-server.example.com
path: /exports/vol1

访问模式

模式说明
ReadWriteOnce (RWO)单节点读写
ReadOnlyMany (ROX)多节点只读
ReadWriteMany (RWX)多节点读写

回收策略

策略说明
Retain保留数据,需要手动处理
Delete删除 PV 和存储
Recycle删除数据(已废弃,推荐 Delete)

PersistentVolumeClaim (PVC)

PVC 是用户请求存储资源的声明:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
resources:
requests:
storage: 5Gi
accessModes:
- ReadWriteOnce
storageClassName: standard
# 可选:选择特定 PV
selector:
matchLabels:
type: fast

使用 PVC

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: my-pvc

PVC 状态

# 查看 PVC 状态
kubectl get pvc

# 描述 PVC
kubectl describe pvc my-pvc

StorageClass

StorageClass 动态创建 PV:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: kubernetes.io/gce-pd # 或 kubernetes.io/aws-ebs
parameters:
type: pd-ssd
replication-type: regional-pd
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

常用存储类型

云厂商Provisioner用途
AWSkubernetes.io/aws-ebsAWS EBS
GCPkubernetes.io/gce-pdGoogle PD
Azurekubernetes.io/azure-diskAzure Disk
阿里云kubernetes.io/disk.csi.aliyun.com云盘
NFSnfs.csi.k8s.ioNFS 存储

NFS StorageClass 示例

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
provisioner: nfs.csi.k8s.io
parameters:
server: nfs-server.example.com
path: /exports/vol1
reclaimPolicy: Retain
volumeBindingMode: Immediate

ConfigMap

ConfigMap 存储配置数据:

创建 ConfigMap

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

# 从环境变量文件创建
kubectl create configmap app-env \
--from-env-file=env.properties

# 从字面值创建
kubectl create configmap app-flags \
--from-literal=LOG_LEVEL=info \
--from-literal=MAX_CONNECTIONS=100

YAML 定义

apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
database_url: "postgres://db:5432/mydb"
cache_enabled: "true"
config.json: |
{
"logLevel": "info",
"maxConnections": 100
}

在 Pod 中使用

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app
env:
# 环境变量
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: my-config
key: database_url
- name: CACHE_ENABLED
valueFrom:
configMapKeyRef:
name: my-config
key: cache_enabled
envFrom:
- configMapRef:
name: my-config
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
volumes:
- name: config
configMap:
name: my-config
items:
- key: config.json
path: app.json

Secret

Secret 用于存储敏感数据:

创建 Secret

# 从文件创建
kubectl create secret generic db-credentials \
--from-file=username=./username.txt \
--from-file=password=./password.txt

# 从字面值创建
kubectl create secret generic api-key \
--from-literal=api-key=your-api-key

# 从 TLS 证书创建
kubectl create secret tls my-tls \
--cert=./cert.pem \
--key=./key.pem

YAML 定义

apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque # Opaque / kubernetes.io/tls / kubernetes.io/dockerconfigjson
data:
# Base64 编码
username: YWRtaW4=
password: cGFzc3dvcmQ=
stringData:
# 明文字符串(会自动编码)
api-key: "your-api-key"

在 Pod 中使用

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: credentials
mountPath: /etc/credentials
readOnly: true
volumes:
- name: credentials
secret:
secretName: db-credentials

临时存储

emptyDir

临时存储,随 Pod 删除:

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app
volumeMounts:
- name: temp-storage
mountPath: /tmp
volumes:
- name: temp-storage
emptyDir:
sizeLimit: 100Mi

临时卷(Ephemeral Volumes)

apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: app
image: my-app
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
csi:
driver: ephemeral.storage.kubernetes.io
volumeAttributes:
sizeLimit: "1Gi"
storage: "ephemeral"

存储最佳实践

1. 使用合适的 StorageClass

# 使用 SSD
storageClassName: fast-storage # 如 pd-ssd

# 使用普通存储
storageClassName: standard # 如 pd-standard

2. 设置资源请求

resources:
requests:
storage: 10Gi
limits:
storage: 20Gi

3. 使用动态 Provisioning

# 使用 StorageClass 动态创建
spec:
storageClassName: fast-storage

4. 保护敏感数据

# 使用 Secret 存储密码和密钥
# 使用 RBAC 限制 Secret 访问

数据持久化示例

MySQL 数据库

# PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: fast-storage
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc

存储调试

# 查看 PV
kubectl get pv

# 查看 PVC
kubectl get pvc

# 描述 PV
kubectl describe pv my-pv

# 描述 PVC
kubectl describe pvc my-pvc

# 查看 StorageClass
kubectl get storageclass

# 查看 Secret
kubectl get secret

# 查看 ConfigMap
kubectl get configmap

小结

本章我们学习了:

  1. PersistentVolume:集群存储资源
  2. PersistentVolumeClaim:存储请求声明
  3. StorageClass:动态存储 provisioning
  4. ConfigMap:配置数据管理
  5. Secret:敏感数据管理
  6. 临时存储:emptyDir 和临时卷

练习

  1. 创建一个 PVC 并在 Pod 中使用
  2. 使用 ConfigMap 存储应用配置
  3. 使用 Secret 存储数据库凭证
  4. 配置 NFS StorageClass 并创建 PV

准备好继续学习了吗?点击下一章了解配置管理!