Volume
本节我们讨论 Kubernetes 的存储模型 Volume,学习如何将各种持久化存储映射到容器。
其含义是它们的生命周期可能很短,会被频繁地销毁和创建。容器销毁时,保存在容器内部文件系统中的数据都会被清除。
为了持久化保存容器的数据,可以使用 Kubernetes Volume。
Volume 的生命周期独立于容器,Pod 中的容器可能被销毁和重建,但 Volume 会被保留。
kubernetes Volume种类:
emptyDir
emptyDir 是最基础的 Volume 类型。正如其名字所示,一个 emptyDir Volume 是 Host 上的一个空目录。
emptyDir Volume 对于容器来说是持久的,对于 Pod 则不是。当 Pod 从节点删除时,Volume 的内容也会被删除。但如果只是容器被销毁而 Pod 还在,则 Volume 不受影响。
① 文件最底部 volumes 定义了一个 emptyDir 类型的 Volume shared-volume。
② producer 容器将 shared-volume mount 到 /producer_dir 目录。
③ producer 通过 echo 将数据写到文件 hello 里。
④ consumer 容器将 shared-volume mount 到 /consumer_dir 目录。
⑤ consumer 通过 cat 从文件 hello 读数据。
hostPath Volume
这里定义了三个 hostPath volume k8s、certs 和 pki,分别对应 Host 目录 /etc/kubernetes、/etc/ssl/certs 和 /etc/pki。
如果 Pod 被销毁了,hostPath 对应的目录也还会被保留,从这点看,hostPath 的持久性比 emptyDir 强。不过一旦 Host 崩溃,hostPath 也就没法访问了。
外部 Storage Provider
如果 Kubernetes 部署在诸如 AWS、GCE、Azure 等公有云上,可以直接使用云硬盘作为 Volume,下面是 AWS Elastic Block Store 的例子:
要在 Pod 中使用 ESB volume,必须先在 AWS 中创建,然后通过 volume-id 引用。其他云硬盘的使用方法可参考各公有云厂商的官方文档。
Kubernetes Volume 也可以使用主流的分布式存,比如 Ceph、GlusterFS 等,下面是 Ceph 的例子:
Ceph 文件系统的 /some/path/in/side/cephfs 目录被 mount 到容器路径 /test-ceph。
当然,运维这样的存储系统通常不是项简单的工作,特别是对可靠性、高可用和扩展性有较高要求时。
Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足。
PV & PVC
Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足。
拿前面 AWS EBS 的例子来说,要使用 Volume,Pod 必须事先知道如下信息:
Pod 通常是由应用的开发人员维护,而 Volume 则通常是由存储系统的管理员维护。开发人员要获得上面的信息:
Kubernetes 给出的解决方案是 PersistentVolume 和 PersistentVolumeClaim。
PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。
NFS PersistentVolume
部署节点搭建nfs服务器
创建 PV
#vim nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.146.151
② accessModes
指定访问模式为 ReadWriteOnce
,支持的访问模式有:
ReadWriteOnce – PV 能以 read-write 模式 mount 到单个节点。
ReadOnlyMany – PV 能以 read-only 模式 mount 到多个节点。
ReadWriteMany – PV 能以 read-write 模式 mount 到多个节点。
③ persistentVolumeReclaimPolicy
指定当 PV 的回收策略为 Recycle
,支持的策略有:
Recycle – 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*
。
Delete – 删除 Storage Provider 上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。
④ storageClassName
指定 PV 的 class 为 nfs
。相当于为 PV 设置了一个分类,PVC 可以指定 class 申请相应 class 的 PV。
#kubectl apply -f nfs-pv1.yml
#kubectl get pv
创建pvc
#vim nfs-pvc1.yml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mypvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
#kubectl apply -f nfs-pvc1.yml
Pod使用pvc
接下来就可以在 Pod 中使用存储了,Pod 配置文件 pod1.yml
如下:
kind: Pod
apiVersion: v1
metadata:
name: mypod1
spec:
containers:
- name: mypod1
image: busybox
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/mydata"
name: mydata
volumes:
- name: mydata
persistentVolumeClaim:
claimName: mypvc
验证
通过pvc回收pv
#kubectl delete -f pod1.yml
#kubectl delete pvc mypvc1
当数据清除完毕,mypv1 的状态重新变为 Available,此时则可以被新的 PVC 申请。
因为 PV 的回收策略设置为 Recycle,所以数据会被清除,但这可能不是我们想要的结果。如果我们希望保留数据,可以将策略设置为 Retain。