一、容器中使用Volume
1、作为文件系统挂载
容器中通过volumeMounts字段使用Volume作为文件系统挂载:
(1)name字段指定使用哪个Volume;
(2)mountPath字段指定Volume在容器中的挂载路径;
(3)readOnly字段指定挂载的Volume是否只读;
(4)多个容器共享Volume时,可以隔离不同容器在Volume上数据存储的路径
subPath直接指定子目录的名字,
subPathExpr则指定${XXX},通过环境变量获取子目录的名字
这两个字段都默认为空,不能同时配置
(5)通过mountPropagation配置挂载传播
None(默认):此Volume挂载不会接收到任何后续挂载到该Volume(或子目录)下的挂载
HostToContainer:此Volume挂载将会接收到任何后续挂载到该Volume(或子目录)下的挂载
Bidirectional:类似HostToContainer,但容器创建的Volume挂载都将传播回主机和所有使用相同Volume的容器
三种挂载传播机制分别对应了Linux内核mount namespace的private、rslave、rshared传播机制
2、作为块设备挂载
容器中通过volumeDevices字段使用Volume作为块设备挂载
(1)name字段指定使用哪个Volume
(2)devicePath指定volume在容器中的挂载路径
二、Pod中声明Volume
1、本地存储

2、网络存储
3、云厂商提供的存储
4、配置文件
volumes:
- name: podinfo
projected:
sources:
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
5、CSI和FlexVolume
- Driver
- ReadyOnly
- FsType
- VolumeAttribute
- NodePublishSecretRef
- Driver
- ReadyOnly
- FsType
- SecretRef
- Options
6、PVC
PersistentVolumeSpec的数据结构
-
Capacity
- PersistentVolumeSource
- AccessModes
- VolumeMode
- ClaimRef
- PersistentVolumeReclaimPolicy
- StorageClassName
- MountOptions
- NodeAffinity
PersistentVolumeClaimSpec的数据结构
- AccessModes
- Selector
- VolumeName
- Resources
- StorageClassName
- VolumeMode
-
DataSource
快照体系
apiVersion: snapshot.storage.k8s.io/v1a1pha1
kind: VolumeSnapshotClass
metadata:
name: disk-snapshotclass
snapshotter: xxxxxx
apiVersion: snapshot.storage.k8s.io/v1a1pha1
kind: VolumeSnapshot
metadata:
name:disk-snapshot
namespace: xxx
spec:
snapshotClassName: disk-snapshotclass
source:
name: disk-pvc
kind: PersistentVolumeClaim
绑定
(1)静态产生方式 - Static Volume Provisioning


(2)动态产生方式 - Dynamic Volume Provisioning

-
metav1.TypeMeta
-
metav1.ObjectMeta
- Provisioner
Volume Plugin
|
Internal Provisioner
|
Config Example
|
AWSElasticBlockStore
|
✓
|
|
AzureFile
|
✓
|
|
AzureDisk
|
✓
|
|
CephFS
|
-
|
-
|
Cinder
|
✓
|
|
FC
|
-
|
-
|
FlexVolume
|
-
|
-
|
Flocker
|
✓
|
-
|
GCEPersistentDisk
|
✓
|
|
Glusterfs
|
✓
|
|
iSCSI
|
-
|
-
|
Quobyte
|
✓
|
|
NFS
|
-
|
-
|
RBD
|
✓
|
|
VsphereVolume
|
✓
|
|
PortworxVolume
|
✓
|
|
ScaleIO
|
✓
|
|
StorageOS
|
✓
|
|
Local
|
-
|
-
ReclaimPolicy
-
AllowVolumeExpansion
-
MountOptions
-
VolumeBindingMode
-
AllowedTopologies
-
Parameters
(3)静态产生方式下满足PV的拓扑限制
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-local
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /data
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- cn-beijing.192.168.1.147
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name:lacal-storage
provisioner: kubernetes.io/noprovisioner
volumeBindingMode:WaitFirstConsumer
PV和PVC的状态流转:
- 新建一个PV对象,把之前的released的PV的相关字段的信息填到新的PV对象里面,这个PV就可以结合新的PVC了;
- 删除Pod之后不删除PVC对象,这样给PV绑定的PVC还存在。下次Pod使用的时候,就可以直接通过PVC去复用。(K8s中的StatefulSet管理的Pod带存储的迁移就是通过这种方式)。
- 从PV的spec.claimRef字段删除PVC绑定信息,即可重新释放PV从而达到available。
7、ephemeral
三、Volume挂载流程

(1)PV Controller


(2)Attach/Detach Controller


(3)Volume manager

(4)Volume Plugins

-
Out-of-Tree类的Volume Plugins的代码放在Kubernetes内部,和Kubernetes一起发布、管理与迭代,缺点是迭代速度慢、灵活性差;
-
Out-of-Tree类的Volume Plugins的代码独立于Kubernetes,它是由存储商提供实现的,目前主要有Flexvolume和CSI两种实现机制。通过抽象接口将不同存储的driver实现从k8s代码仓库中剥离,是社区主推的一种实现网络存储插件的方式。
Volume Plugins的发现

参考资料:
[1] https://kubernetes.io/docs/home/
[2] https://edu.aliyun.com/roadmap/cloudnative
[3] 郑东旭《Kubernetes源码剖析》