kubernetes-handbook/concepts/volume.md

200 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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
对于持久化的VolumePersistentVolume (PV)和PersistentVolumeClaim (PVC)提供了更方便的管理卷的方法PV提供网络存储资源而PVC请求存储资源。这样设置持久化的工作流包括配置底层文件系统或者云数据卷、创建持久性数据卷、最后创建claim来将pod跟数据卷关联起来。PV和PVC可以将pod和数据卷解耦pod不需要知道确切的文件系统或者支持它的持久化引擎。
### PV
PersistentVolumePV是集群之中的一块网络存储。跟 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"
```