200 lines
5.5 KiB
Markdown
200 lines
5.5 KiB
Markdown
# Kubernetes存储卷
|
||
|
||
我们知道默认情况下容器的数据都是非持久化的,在容器消亡以后数据也跟着丢失,所以Docker提供了Volume机制以便将数据持久化存储。类似的,Kubernetes提供了更强大的Volume机制和丰富的插件,解决了容器数据持久化和容器间共享数据的问题。
|
||
|
||
## Volume
|
||
|
||
目前,Kubernetes支持以下Volume类型:
|
||
|
||
- emptyDir
|
||
- hostPath
|
||
- gcePersistentDisk
|
||
- awsElasticBlockStore
|
||
- nfs
|
||
- iscsi
|
||
- flocker
|
||
- glusterfs
|
||
- rbd
|
||
- cephfs
|
||
- gitRepo
|
||
- secret
|
||
- persistentVolumeClaim
|
||
- downwardAPI
|
||
- azureFileVolume
|
||
- vsphereVolume
|
||
- flexvolume
|
||
|
||
注意,这些volume并非全部都是持久化的,比如emptyDir、secret、gitRepo等,这些volume会随着Pod的消亡而消失。
|
||
|
||
## PersistentVolume
|
||
|
||
对于持久化的Volume,PersistentVolume (PV)和PersistentVolumeClaim (PVC)提供了更方便的管理卷的方法:PV提供网络存储资源,而PVC请求存储资源。这样,设置持久化的工作流包括配置底层文件系统或者云数据卷、创建持久性数据卷、最后创建claim来将pod跟数据卷关联起来。PV和PVC可以将pod和数据卷解耦,pod不需要知道确切的文件系统或者支持它的持久化引擎。
|
||
|
||
### PV
|
||
|
||
PersistentVolume(PV)是集群之中的一块网络存储。跟 Node 一样,也是集群的资源。PV 跟 Volume (卷) 类似,不过会有独立于 Pod 的生命周期。比如一个NFS的PV可以定义为
|
||
|
||
```yaml
|
||
apiVersion: v1
|
||
kind: PersistentVolume
|
||
metadata:
|
||
name: pv0003
|
||
spec:
|
||
capacity:
|
||
storage: 5Gi
|
||
accessModes:
|
||
- ReadWriteOnce
|
||
persistentVolumeReclaimPolicy: Recycle
|
||
nfs:
|
||
path: /tmp
|
||
server: 172.17.0.2
|
||
```
|
||
|
||
PV的访问模式有三种:
|
||
|
||
* 第一种,ReadWriteOnce:是最基本的方式,可读可写,但只支持被单个Pod挂载。
|
||
* 第二种,ReadOnlyMany:可以以只读的方式被多个Pod挂载。
|
||
* 第三种,ReadWriteMany:这种存储可以以读写的方式被多个Pod共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是NFS。在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。
|
||
|
||
### StorageClass
|
||
|
||
上面通过手动的方式创建了一个NFS Volume,这在管理很多Volume的时候不太方便。Kubernetes还提供了[StorageClass](https://kubernetes.io/docs/user-guide/persistent-volumes/#storageclasses)来动态创建PV,不仅节省了管理员的时间,还可以封装不同类型的存储供PVC选用。
|
||
|
||
GCE的例子:
|
||
|
||
```yaml
|
||
kind: StorageClass
|
||
apiVersion: storage.k8s.io/v1beta1
|
||
metadata:
|
||
name: slow
|
||
provisioner: kubernetes.io/gce-pd
|
||
parameters:
|
||
type: pd-standard
|
||
zone: us-central1-a
|
||
```
|
||
|
||
Ceph RBD的例子:
|
||
|
||
```yaml
|
||
apiVersion: storage.k8s.io/v1beta1
|
||
kind: StorageClass
|
||
metadata:
|
||
name: fast
|
||
provisioner: kubernetes.io/rbd
|
||
parameters:
|
||
monitors: 10.16.153.105:6789
|
||
adminId: kube
|
||
adminSecretName: ceph-secret
|
||
adminSecretNamespace: kube-system
|
||
pool: kube
|
||
userId: kube
|
||
userSecretName: ceph-secret-user
|
||
```
|
||
|
||
### PVC
|
||
|
||
PV是存储资源,而PersistentVolumeClaim (PVC) 是对PV的请求。PVC跟Pod类似:Pod消费Node的源,而PVC消费PV资源;Pod能够请求CPU和内存资源,而PVC请求特定大小和访问模式的数据卷。
|
||
|
||
```yaml
|
||
kind: PersistentVolumeClaim
|
||
apiVersion: v1
|
||
metadata:
|
||
name: myclaim
|
||
spec:
|
||
accessModes:
|
||
- ReadWriteOnce
|
||
resources:
|
||
requests:
|
||
storage: 8Gi
|
||
selector:
|
||
matchLabels:
|
||
release: "stable"
|
||
matchExpressions:
|
||
- {key: environment, operator: In, values: [dev]}
|
||
|
||
```
|
||
|
||
PVC可以直接挂载到Pod中:
|
||
|
||
```yaml
|
||
kind: Pod
|
||
apiVersion: v1
|
||
metadata:
|
||
name: mypod
|
||
spec:
|
||
containers:
|
||
- name: myfrontend
|
||
image: dockerfile/nginx
|
||
volumeMounts:
|
||
- mountPath: "/var/www/html"
|
||
name: mypd
|
||
volumes:
|
||
- name: mypd
|
||
persistentVolumeClaim:
|
||
claimName: myclaim
|
||
```
|
||
|
||
## emptyDir
|
||
|
||
如果Pod配置了emptyDir类型Volume, Pod 被分配到Node上时候,会创建emptyDir,只要Pod运行在Node上,emptyDir都会存在(容器挂掉不会导致emptyDir丢失数据),但是如果Pod从Node上被删除(Pod被删除,或者Pod发生迁移),emptyDir也会被删除,并且永久丢失。
|
||
|
||
```yaml
|
||
apiVersion: v1
|
||
kind: Pod
|
||
metadata:
|
||
name: test-pd
|
||
spec:
|
||
containers:
|
||
- image: gcr.io/google_containers/test-webserver
|
||
name: test-container
|
||
volumeMounts:
|
||
- mountPath: /test-pd
|
||
name: test-volume
|
||
volumes:
|
||
- name: test-volume
|
||
hostPath:
|
||
# directory location on host
|
||
path: /data
|
||
```
|
||
|
||
## 其他Volume说明
|
||
|
||
### hostPath
|
||
|
||
hostPath允许挂载Node上的文件系统到Pod里面去。如果Pod有需要使用Node上的文件,可以使用hostPath。
|
||
|
||
```yaml
|
||
- hostPath:
|
||
path: /tmp/data
|
||
name: data
|
||
```
|
||
|
||
### NFS
|
||
|
||
NFS 是Network File System的缩写,即网络文件系统。Kubernetes中通过简单地配置就可以挂载NFS到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持同时写操作。
|
||
|
||
```yaml
|
||
volumes:
|
||
- name: nfs
|
||
nfs:
|
||
# FIXME: use the right hostname
|
||
server: 10.254.234.223
|
||
path: "/"
|
||
```
|
||
|
||
### FlexVolume
|
||
|
||
注意要把volume plugin放到`/usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/<driver>`,plugin要实现`init/attach/detach/mount/umount`等命令(可参考lvm的[示例](https://github.com/kubernetes/kubernetes/tree/master/examples/volumes/flexvolume))。
|
||
|
||
```yaml
|
||
- name: test
|
||
flexVolume:
|
||
driver: "kubernetes.io/lvm"
|
||
fsType: "ext4"
|
||
options:
|
||
volumeID: "vol1"
|
||
size: "1000m"
|
||
volumegroup: "kube_vg"
|
||
```
|
||
|