因为pod是有生命周期的,pod一重启,里面的数据就没有了。所以我们需要数据持久化存储。
在k8s中,存储卷不属于容器,而是属于pod。也就是说同一个pod中的容器可以共享一个存储卷。
存储卷可以是宿主机上的目录,也可以是挂载在宿主机上的外部设备。
存储卷类型
- emptyDIR存储卷 :pod一重启,存储卷也删除,这叫emptyDir存储卷。一般用于当做临时空间或缓存关系
- hostPath存储卷 :宿主机上目录作为存储卷,这种也不是真正意义实现了数据持久性。
- SAN(iscsi)或NAS(nfs、cifs): 网络存储设备
- 分布式存储(ceph,glusterfs,cephfs,rbd) :
- 云存储(亚马逊的EBS,Azure Disk,阿里云): 这种是网络存储的,一般只有k8s在云上部署才会用到。
查看资源定义清单的字段:
[root@master ~]# kubectl explain pod.spec.volumes
[root@master ~]# kubectl explain pod.spec.volumes.emptyDir
...
一、emptyDIR存储卷
一个emptyDir 第一次创建是在一个pod被指定到具体node的时候,并且会一直存在在pod的生命周期当中,正如它的名字一样,它初始化是一个空的目录,pod中的容器都可以读写这个目录,这个目录可以被挂在到各个容器相同或者不相同的的路径下。当一个pod因为任何原因被移除的时候,这些数据会被永久删除。注意:一个容器崩溃了不会导致数据的丢失,因为容器的崩溃并不移除pod;
emptyDir 磁盘的作用:
(1)普通空间,基于磁盘的数据存储
(2)作为从崩溃中恢复的备份点
(3)存储那些那些需要长久保存的数据,例web服务中的数据
默认的,emptyDir 磁盘会存储在主机所使用的媒介上,可能是SSD,或者网络硬盘,这主要取决于你的环境。当然,我们也可以将emptyDir.medium的值设置为Memory来告诉Kubernetes 来挂在一个基于内存的目录tmpfs,因为tmpfs速度会比硬盘快多了,但是,当主机重启的时候所有的数据都会丢失。
下图资源定义清单中,定义了两个容器:myapp和busybox
存储卷为:html
myapp容器将html存储卷挂载到/usr/share/nginx/html/ 下;
busybox将html存储卷挂载到/data/下;
[root@master volumes]# kubectl apply -f pod.demo.yaml
[root@master volumes]# kubectl get pods
NAME READY STATUS RESTARTS AGE
...
pod-demo 2/2 Running 0 7s
验证:
a、查看容器的ip:
[root@master volumes]# kubectl get pods -o wide
pod-demo 2/2 Running 0 34m 10.244.1.58 node01 <none> <none>
b、访问
[root@master volumes]# curl 10.244.1.58
Mon Jan 28 08:01:05 UTC 2019
Mon Jan 28 08:01:07 UTC 2019
Mon Jan 28 08:01:09 UTC 2019
Mon Jan 28 08:01:11 UTC 2019
Mon Jan 28 08:01:13 UTC 2019
二、hostPath存储卷
hostPath宿主机路径,就是把pod所在的宿主机之上的脱离pod中的容器名称空间的之外的宿主机的文件系统的某一目录和pod建立关联关系;
在pod删除时,存储数据不会丢失。
查看资源定义清单字段:
[root@master volumes]# kubectl explain pods.spec.volumes.hostPath
FIELDS:
path <string> -required-
type <string>
type支持的值:
(1)资源定义清单
(2)准备数据文件
node01:
[root@node01 ~]# mkdir -p /data/pod/volume1/
[root@node01 ~]# vim /data/pod/volume1/index.html
node02:
[root@node02 ~]# mkdir -p /data/pod/volume1/
[root@node02 ~]# vim /data/pod/volume1/index.html
(3)创建pod
[root@master volumes]# kubectl apply -f pod-hostpath-vol.yaml
[root@master volumes]# kubectl get pods -o wide
pod-vol-hostpath 1/1 Running 0 4m51s 10.244.1.59 node01 <none> <none>
(4)验证
(a)可以访问
(b)
然后删掉pod,再重新创建,看文件是否还可以访问;
[root@master volumes]# kubectl get pods -o wide
pod-vol-hostpath 1/1 Running 0 38s 10.244.1.60 node01 <none> <none>
结果证明还是可以访问的;
hostPath可以实现持久存储,但是它是将数据存在node节点上,当node节点故障时,也会导致数据的丢失;
三、nfs共享存储
(1)在store主机
安装nfs:
[root@store ~]# yum install nfs-utils -y
创建共享目录:
[root@store ~]# mkdir -pv /data/volumes
[root@store ~]# vim /etc/exports
启动nfs:
[root@store ~]# systemctl start nfs
(2)在各node节点上
安装nfs包:
[root@node01 ~]# yum install nfs-utils -y
[root@node02 ~]# yum install nfs-utils -y
hosts文件:
测试挂载:
[root@node01 ~]# mount -t nfs store:/data/volumes /mnt
[root@node02 ~]# mount -t nfs store:/data/volumes /mnt
发现可以正常挂载,然后再卸载掉:
[root@node01 ~]# umount /mnt
[root@node02 ~]# umount /mnt
(3)在master节点上
查看资源定义清单字段:
[root@master ~]# kubectl explain pods.spec.volumes.nfs
创建资源定义清单:
创建pod:
[root@master volumes]# kubectl apply -f pod-vol-nfs.yaml
[root@master volumes]# kubectl get pods -o wide
pod-vol-nfs 1/1 Running 0 3m40s 10.244.1.61 node01 <none> <none>
在store上:
[root@store ~]# vim /data/volumes/index.html
<h1>NFS Store</h1>
在master上访问:
发现可以访问,这样数据就有了持久能力,当node节点故障时,数据不会丢失;
我们现在用的是自助式pod,没有用控制器;
用了控制器来创建pod,当pod故障时,控制器会基于模板自动创建pod,关联至共享存储;
四、PV、PVC
- pv、pvc是k8s提供的两种API资源,用于抽象存储细节;
- pvc和pv的关系与pod和node关系类似,前者消耗后者的资源;
- pvc可以向pv申请指定大小的存储资源并设置访问模式;
- PV是集群中的资源。 PVC是对这些资源的请求;
PV和PVC之间的相互作用遵循这个生命周期:
Provisioning(配置)--> Binding(绑定)-->Using(使用)--> Releasing(释放) --> Recycling(回收)
查看pvc、pv资源定义清单字段:
[root@master ~]# kubectl explain pvc
[root@master ~]# kubectl explain pvc.spec
[root@master ~]# kubectl explain pv
[root@master ~]# kubectl explain pv.spec
(1)在store上
[root@store ~]# cd /data/volumes/
[root@store volumes]# mkdir v{1,2,3,4,5}
[root@store volumes]# vim /etc/exports
[root@store volumes]# exportfs -arv #不用重启nfs服务,配置文件就会生效
[root@store volumes]# showmount -e #查看
(2)定义一个nfs格式的pv
[root@master ~]# kubectl explain pv.spec.nfs
定义pv时不要定义名称空间,PV是集群级别的资源,不属于哪个名称空间;
pvc可以有名称空间;
pv资源定义清单,创建几个pv出来:
创建:
RECLAIM POLICY:回收策略
Retain:保留;当pod被删除,pv上的数据依然保留;
(3)定义pvc,并被一个pod使用
资源定义清单
创建
[root@master volumes]# kubectl apply -f pod-vol-pvc.yaml
查看pv,找到了一个合适的pv进行绑定
查看pvc