200 lines
5.6 KiB
Markdown
200 lines
5.6 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"
|
|||
|
```
|
|||
|
|