1、kubernetes存储卷
(1)存储卷
Kubernetes提供的存储卷属于pod资源级别,共享于Pod内的所有容器,可用于在容器的文件系统之外存储应用存储的相关数据,也可独立pod生命周期之外实现数据的持久化。
(2)kubernetes支持的存储卷类型
Kubernetes支持非常丰富的出处卷类型,包括本地储存及各种网络存储,同时还支持Secret和ConfigMap这样的特殊存储资源。
由于网络存储配置使用复杂,对此,kubernetes设计了一种集群级别的资源PersistentVolume(PV)并由管理员配置存储系统,然后通过persistentVolumeClain(PVC)存储卷直接申请使用的机制简化了存储的使用配置过程。
(3)存储卷的使用方式
在pod中定义配置存储卷由两部分组成,一是通过pod.spec.volumes字段定义在Pod之上的存储卷列表;然后通过pod.spec.containers.volumeMount字段在容器上定义存储卷挂载列表,在容器中只能挂载在当前Pod资源中定义的具体存储卷。
在容器中定义挂载卷时的主要字段:
name:必选字段,指定要挂载的存储的名称,
mountPath:必选字段,挂载路径,即挂载容器的那个路径下
readOnly:是否挂载为只读卷
subPath:挂载存储卷时时使用的子路径
2、临时存储卷
(1)emptyDir
emptyDir是pod生命周期中的一个临时目录,生命周期跟随pod的生命周期;emptyDir存储卷通过pod.spec.volumes.emptyDir字段定义,主要的字段如下:
medium:存储介质的类型,值有”default”和“memory”,默认为default。
SizeLimit:当前存储卷的空间限额,默认值为nil,不限制。
# 定义一个自助式pod,定义一个emptyDir存储,定义两个容器并共享存储
[root@master01 volumes]# cat test-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-emptydir-dir
spec:
volumes:
- name: html
emptyDir: {}
containers:
- name: nginx
image: nginx:1.12
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: busybox
image: busybox
volumeMounts:
- name: html
mountPath: /html
command: ["/bin/sh", "-c"]
args:
- echo $(date) >> /html/index.html
(2)gitRepo存储卷
gitRepo存储卷可以看作是emptyDir存储卷的一种实际应用,但是该存储卷从kubernetes1.12开始已经被废弃。在创建使用gitRepo存储卷的pod时,首先会创建一个空目录(emptyDir)并克隆一份指定的git仓库中的数据至该目录下,然后再创建容器并挂载该存储卷。
创建gitRepo类型的存储卷时,主要的字段如下:
repository:必选字段,为Git仓库的URL
directory:目标目录的名称
revision:特定revision的提交哈希码
3、节点存储卷
hostPath类型的存储卷是指将工作节点上的某文件系统的目录或文件挂载于Pod中的一种存储卷,它可独立于Pod资源的生命周期,因而具有持久性,但是它是工作在本地节点的存储空间,仅适用于特定情况下的存储卷使用要求。
定义配置hostPath类型的存储卷时,主要是通过pod.spec.volumes.hostPath字段嵌套的path(用于指定工作节点上的目录路径)字段及type(用于指定存储卷的类型)字段来定义的,type值有:
DirectoryOrCreate:指定的路径不存在时自动创建
Directory:必须存在的目录路径
FileOrCreate:指定的路径不存在时自动将其创建为空文件
File:必须存在的文件路径
Socket:必须存在的Socket文件路径
CharDevice:必须存在的字符设备文件路径
BlockDevice:必须存在的块设备文件路径
# 定义一个使用hostpath存储卷的自助式pod
[root@master01 volumes]# cat test-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-hostpath-vol
spec:
volumes:
- name: html
hostPath:
path: /data/test/html
type: DirectoryOrCreate
containers:
- name: nginx
image: nginx:1.12
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
# 创建并查看该pod的详细信息
[root@master01 volumes]# kubectl apply -f test-hostpath.yaml
pod/test-hostpath-vol created
[root@master01 volumes]# kubectl get pods -o wide test-hostpath-vol
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-hostpath-vol 1/1 Running 0 2m49s 10.244.2.46 node02.dayi123.com <none> <none>
# 在该pod所在的节点上创建测试文件并测试
[root@node02 ~]# echo "$(date +%F-%T) test-volumes-hostpath" > /data/test/html/index.html
[root@node02 ~]# curl 10.244.2.46
2019-01-24-00:51:00 test-volumes-hostpath
4、网络存储器
Kubernetes支持众多类型的网络存储卷,包括传统的NAS或SAN设备(如NFS、Iscsi、fc)、分布式存储(如RDB、GlusterFS)、云端存储(如cinder、awsElasticBlockStore、azureDisk)及构建在各类存储系统之上的抽象管理层。
(1)NFS存储卷
Kubernetes的NFS存储卷用于将某实现存放的NFS服务器上的存储空间挂载到Pod中以供容器使用,NFS存储卷在pod对象终止后会被卸载并不会被删除。
NFS存储卷的定义是通过pod.spec.volumes.nfs地段定义,主要的嵌套字段有:
server:NFS服务器的IP地址或主机名
path:NFS服务器导出的文件系统路径
readOnly:是否以制度方式挂载
在使用nfs存储卷之前首先得有一个nfs服务器;先搭建一个nfs服务器,IP地址为192.168.17.195,主机名为nfs01.dayi123.com,并在各节点主机hosts文件中做解析。
# 安装nfs服务
[root@nfs01 ~]# yum install nfs-utils
# 配置nfs服务
[root@nfs01 ~]# cat /etc/exports
/data/volums/data01 192.168.17.0/24(rw,no_root_squass)
# 创建nfs挂载目录
[root@nfs01 ~]# mkdir /data/volums/data01/ -p
# 启动服务
[root@nfs01 ~]# systemctl start rpcbind
[root@nfs01 ~]# systemctl enable rpcbind
[root@nfs01 ~]# systemctl start nfs
[root@nfs01 ~]# systemctl enable nfs
# 查看nfs状态
[root@nfs01 ~]# showmount -e 192.168.17.195
Export list for 192.168.17.195:
/data/volums/data01 192.168.17.0/24
存在nfs网络文件系统后,就可以在各pod中使用nfs存储卷,nfs是文件系统级的共享服务,它支持同时存在的多路径挂载请求,但在使用nfs时需要在各节点安装nfs客户端工具(只需安装nfs-utils,不需要启动)
# 创建一个使用nfs存储卷的自助式运行nginx的pod
[root@master01 volumes]# cat test-nginx-nfsvol.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-nginx-nfsvol
spec:
volumes:
- name: html
nfs:
server: nfs01.dayi123.com
path: /data/volums/data01
readOnly: false
containers:
- name: nginx
image: nginx:1.12
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
# 创建并查看pod的详细信息
[root@master01 volumes]# kubectl apply -f test-nfs-vol.yaml
[root@master01 volumes]# kubectl get pods test-nginx-nfsvol -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-nginx-nfsvol 1/1 Running 0 14m 10.244.2.52 node02.dayi123.com <none> <none>
# 在nfs服务挂载的目录上写入数据通过nginx测试
[root@master01 volumes]# kubectl exec -it test-nginx-nfsvol -- /bin/sh
# echo "$(date +%F-%T) $(hostname) - TEST-NGINX-NFSVOLMS" >/usr/share/nginx/html/index.html
[root@master01 volumes]# curl 10.244.2.52
2019-01-24-07:45:46 test-nginx-nfsvol - TEST-NGINX-NFSVOLMS
由于nfs存储卷保存的数据是永久性的,所以删除使用nfs存储卷的pod重新创建后数据不会丢失。
# 删除并重新创建该pod并进行测试
[root@master01 volumes]# kubectl delete -f test-nginx-nfsvol.yaml
[root@master01 volumes]# kubectl apply -f test-nginx-nfsvol.yaml
[root@master01 volumes]# kubectl get pods test-nginx-nfsvol -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-nginx-nfsvol 1/1 Running 0 16s 10.244.2.53 node02.dayi123.com <none> <none>
[root@master01 volumes]# curl 10.244.2.53
2019-01-24-07:45:46 test-nginx-nfsvol - TEST-NGINX-NFSVOLMS
(2)RBD存储卷的使用
Kubernetes支持通过RBD卷类型使用ceph存储系统为Pod提供存储卷,要配置Pod资源使用RBD存储卷,需要满足以下的条件:
1)存在可用的ceph集群
2)需要在ceph rbd集群中创建一个能满足Pod资源需求数据存储需要的存储映像
3)在kubernetes集群内的各节点上安装ceph客户端程序包
RBD类型的存储卷是通过explain pod.spec.volumes.rbd字段定义的,主要的内嵌字段有:
monitors:必选字段,为ceph存储监视器,使用逗号分隔的字符串列表
image:必选字段,为rados image的名称
pool:rados存储池的名称,默认为RBD
user:rados用户名,默认为admin
keyring:RBD用户认证时使用的keyring文件路径,默认为/etc/ceph/keyring
secretRef:RBD用户认证时使用的保存有相应认证信息的Secret对象,会覆盖由keyring字段提供的秘钥信息
readOnly:是否以只读方式进行访问
fsType:要挂载的存储卷的文件系统类型
5、持久存储卷
直接使用自助式pod直接连接存储的方式与kubernetes向用户和开发隐藏底层架构的目标相背离;对此,kubernetes使用PersistentVolume(简称PV)子系统在系统和管理员之间添加一个自系统,解决了这种问题。
PersistentVolume是由集群管理员配置提供的某存储系统上的一段存储空间,是对底层共享存储的抽象,将共享存储作为一种可由用户申请使用的资源。用户对pv资源的使用是通过PersistentVolumeClaim(简称PVC)提出使用申请来完成绑定,它向PV申请特定大小的空间及访问模式,从而创建出PVC存储卷,再由pod资源通过PVC存储卷关联使用。
(1)PV的创建
PV对存储系统的创建可通过插件来实现,kubernetes可支持的插件可通过” kubectl explain PersistentVolume.spec”命令查看。Pv的资源定义清单中PersistentVolume.spec字段除了定义存储插件外,还可以定义的通用字段有:
1)Capacity:当前pv的容量
2)accessModes:定义访问模式,常用的值有:ReadWriteOnce(仅可被单个节点读写挂载,简写为RWO)、 ReadOnlyMany(可被多个节点制度挂载,简写为ROX)、ReadWriteMany(可悲多个节点只读挂载,简写为RWX)
3)persistentVolumeReclaimPolicy:PV空间被释放时的处理机制,选项有Retain(默认值,由管理员手动回收)、Recycle(空间回收,删除存储卷下所有文件,目前仅NFS和hostPath支持)、Delete(删除从存储卷)
4)volumeMode:卷模型,用于此卷可被用作文件系统还是块设备,默认为filesystem
5)storageClassName:当前pv所属的StorageClass的名称,默认空值。
6)mountOptions:挂载选项组成的列表,值有ro、soft、hard等
# 在创建爱你pv资源之前,查看可挂载的nfs存储目录
[root@master01 volumes]# showmount -e nfs01.dayi123.com
Export list for nfs01.dayi123.com:
/data/volums/vol03 192.168.17.0/24
/data/volums/vol02 192.168.17.0/24
/data/volums/vol01 192.168.17.0/24
/data/volums/data01 192.168.17.0/24
# 定义pv资源配置清单
[root@master01 volumes]# cat test-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv01
labels:
name: pv01
spec:
nfs:
server: nfs01.dayi123.com
path: /data/volums/vol01
accessModes: ["ReadWriteMany"]
capacity:
storage: 2Gi
volumeMode: Filesystem
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv02
labels:
name: pv02
spec:
nfs:
server: nfs01.dayi123.com
path: /data/volums/vol02
accessModes: ["ReadWriteOnce"]
capacity:
storage: 5Gi
volumeMode: Filesystem
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv03
labels:
name: pv03
spec:
nfs:
server: nfs01.dayi123.com
path: /data/volums/vol03
accessModes: ["ReadWriteMany","ReadWriteMany"]
capacity:
storage: 10Gi
volumeMode: Filesystem
# 创建并查看pv
[root@master01 volumes]# kubectl apply -f test-pv.yaml
[root@master01 volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
test-pv01 2Gi RWX Retain Available 5s
test-pv02 5Gi RWO Retain Available 5s
test-pv03 10Gi RWX Retain Available 5s
(2)创建PVC
PVC是存储卷类型的资源,它通过申请占用某个pv而创建,它与pv是一对一的关系,创建pvc申请pv时用户需要指定目标空间大小,访问模式,pv标签选择器和StoreClass等信息,pvc的spec字段嵌套的字段有:
accessMode:当前pvc的访问模式,可用模式与PV相同
resources:当前PVC存储卷需要占用的资源量的最小值
selector:绑定时对PV应用的标签选择器或匹配条件表达式,用于挑选要绑定的pv
storageClassVolume:所依赖的存储类的名称
volumeMode:卷模型,默认为Filesystem
volumeName:用于直接指定要绑定的PV的卷名
# 定义一个pvc资源,让它自动找合适的pv绑定
[root@master01 volumes]# cat test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pvc01
spec:
accessModes: ["ReadWriteMany"]
resources:
requests:
storage: 5Gi
# 创建并查看创建的PVC
[root@master01 volumes]# kubectl apply -f test-pvc.yaml
[root@master01 volumes]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-pvc01 Bound test-pv03 10Gi RWX 85s
# 查看pv的绑定状态
[root@master01 volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
test-pv01 2Gi RWX Retain Available 38m
test-pv02 5Gi RWO Retain Available 38m
test-pv03 10Gi RWX Retain Bound default/test-pvc01 38m
(3)在pod中使用PVC
创建好PVC资源后,可在Pod中通过” pod.spec.volumes.persistentVolumeClaim”字段去调用PVC,调用pvc时只要有以下的嵌套字段:
claimName:要调用的PVC的存储卷的名称,pvc要与pod在同一名称空间中
readOnly:是否将存储卷强制挂载为制度模式,默认为false。
# 定义一个pod资源调用pvc存储
[root@master01 volumes]# cat test-pod-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod-pvc
spec:
containers:
- name: pvc-nginx
image: nginx:1.12
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: test-pvc01
(4)存储类
Storage class(存储类)是kubernetes资源类型的一种,是由管理员为管理PV之便而按需创建的类别(逻辑组)。存储类支持PV的动态创建,当用户用到持久性存储时,需要创建pvc来绑定匹配的pv,当管理员手动创建的pv无法满足pvc的所有需求时,系统会按pvc的需求标准动态创建适配的pv。
1)存储类的创建
存储类资源的定义除了名称外,还需要定义的以下的三个关键字:
provisioner(供给方):提供给存储资源的存储系统
parameters:存储类使用参数描述要关联到的存储卷,不同的provisioner可用的参数各不相同
reclaimPolicy:为当前存储类活动动态创建的PV指定回收策略,可用值为Delete(默认值)和Retain
volumeBindingMode:定义如何为PVC完成供给和绑定
mountOptions:由当前类动态创建的PV的挂载选项列表
2)动态pv的供给
存储类创建完成后,在PVC的定义中指定使用的存储类资源的方式有两种,一是通过spec.storageClassName字段定义,另一种是使用volume.beta.kubernetes.io/storage-class注解信息。