存储卷 #

一、存储卷概述 #

Volume是Kubernetes中Pod的存储抽象,用于解决容器数据持久化和共享问题。

1.1 为什么需要Volume #

text
容器存储问题
    │
    ├── 容器重启数据丢失
    │
    ├── 容器间数据不共享
    │
    └── 数据需要持久化保存

Volume解决方案
    │
    ├── 数据持久化
    │
    ├── 容器间数据共享
    │
    └── 外部存储挂载

1.2 Volume类型 #

类型 说明 用途
emptyDir 临时存储 容器间共享
hostPath 节点路径 访问节点文件
nfs NFS存储 网络存储
configMap 配置数据 注入配置
secret 敏感数据 注入密钥
persistentVolumeClaim 持久存储 动态存储

二、emptyDir #

2.1 基本用法 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: emptydir-demo
spec:
  containers:
  - name: writer
    image: busybox
    command: ["sh", "-c", "echo 'Hello' > /data/hello.txt && sleep 3600"]
    volumeMounts:
    - name: shared-data
      mountPath: /data
  - name: reader
    image: busybox
    command: ["sh", "-c", "cat /data/hello.txt && sleep 3600"]
    volumeMounts:
    - name: shared-data
      mountPath: /data
  volumes:
  - name: shared-data
    emptyDir: {}

2.2 内存存储 #

yaml
volumes:
- name: cache-volume
  emptyDir:
    medium: Memory
    sizeLimit: 256Mi

2.3 emptyDir特点 #

text
emptyDir特点
    │
    ├── Pod创建时创建
    │
    ├── Pod删除时删除
    │
    ├── 同Pod容器间共享
    │
    └── 可使用内存存储

三、hostPath #

3.1 基本用法 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: host-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: host-volume
    hostPath:
      path: /data/nginx
      type: DirectoryOrCreate

3.2 hostPath类型 #

类型 说明
DirectoryOrCreate 目录不存在则创建
Directory 必须是已存在的目录
FileOrCreate 文件不存在则创建
File 必须是已存在的文件
Socket Unix套接字
CharDevice 字符设备
BlockDevice 块设备

3.3 注意事项 #

text
hostPath注意事项
    │
    ├── 节点依赖性
    │   └── Pod迁移后数据不可访问
    │
    ├── 安全风险
    │   └── 可访问节点敏感文件
    │
    └── 权限问题
        └── 需要适当的文件权限

四、nfs #

4.1 基本用法 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: nfs-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: nfs-volume
      mountPath: /usr/share/nginx/html
  volumes:
  - name: nfs-volume
    nfs:
      server: 192.168.1.100
      path: /data/share
      readOnly: false

4.2 NFS服务配置 #

bash
# 安装NFS服务端
sudo apt install nfs-kernel-server

# 配置导出目录
echo "/data/share *(rw,sync,no_subtree_check)" >> /etc/exports

# 重启NFS服务
sudo systemctl restart nfs-kernel-server

五、configMap Volume #

5.1 挂载ConfigMap #

yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    server {
      listen 80;
      location / {
        root /usr/share/nginx/html;
      }
    }
---
apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-demo
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d
  volumes:
  - name: config
    configMap:
      name: nginx-config

5.2 挂载特定键 #

yaml
volumes:
- name: config
  configMap:
    name: nginx-config
    items:
    - key: nginx.conf
      path: default.conf

5.3 子路径挂载 #

yaml
volumeMounts:
- name: config
  mountPath: /etc/nginx/conf.d/default.conf
  subPath: nginx.conf

六、secret Volume #

6.1 挂载Secret #

yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=
  password: cGFzc3dvcmQ=
---
apiVersion: v1
kind: Pod
metadata:
  name: secret-volume-demo
spec:
  containers:
  - name: app
    image: mysql
    volumeMounts:
    - name: secret
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret
    secret:
      secretName: db-secret

6.2 Secret权限控制 #

yaml
volumes:
- name: secret
  secret:
    secretName: db-secret
    defaultMode: 0400
    items:
    - key: username
      path: user.txt
      mode: 0444

七、persistentVolumeClaim #

7.1 使用PVC #

yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: pvc-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: data
      mountPath: /usr/share/nginx/html
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: my-pvc

八、多容器共享Volume #

8.1 Sidecar模式 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: sidecar-demo
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: logs
      mountPath: /var/log/nginx
  - name: log-collector
    image: busybox
    command: ["sh", "-c", "tail -f /logs/access.log"]
    volumeMounts:
    - name: logs
      mountPath: /logs
  volumes:
  - name: logs
    emptyDir: {}

8.2 Ambassador模式 #

yaml
apiVersion: v1
kind: Pod
metadata:
  name: ambassador-demo
spec:
  containers:
  - name: app
    image: nginx
  - name: proxy
    image: envoyproxy/envoy
    volumeMounts:
    - name: config
      mountPath: /etc/envoy
  volumes:
  - name: config
    configMap:
      name: envoy-config

九、Volume管理 #

9.1 查看Volume #

bash
# 查看Pod Volume
kubectl describe pod <pod-name>

# 查看PVC
kubectl get pvc

# 查看PV
kubectl get pv

9.2 Volume调试 #

bash
# 进入容器查看挂载
kubectl exec -it <pod-name> -- df -h

# 查看挂载点
kubectl exec -it <pod-name> -- mount | grep /data

# 查看文件
kubectl exec -it <pod-name> -- ls -la /data

十、最佳实践 #

10.1 Volume选择 #

场景 推荐Volume
容器间共享 emptyDir
访问节点文件 hostPath
网络存储 nfs、PVC
配置文件 configMap
敏感数据 secret
持久存储 PVC

10.2 安全建议 #

yaml
# 只读挂载
volumeMounts:
- name: config
  mountPath: /etc/config
  readOnly: true

# 限制权限
volumes:
- name: secret
  secret:
    secretName: my-secret
    defaultMode: 0400

十一、总结 #

11.1 核心要点 #

Volume类型 用途 生命周期
emptyDir 临时存储 Pod级别
hostPath 节点存储 节点级别
nfs 网络存储 独立
configMap 配置数据 独立
secret 敏感数据 独立
PVC 持久存储 独立

11.2 下一步 #

掌握了Volume后,让我们学习 持久卷,深入了解PV和PVC的使用。

最后更新:2026-03-28