k8s存储
docker存储----k8s存储
docker的容器层可以提供存储:存储在可写层(CopyOnWrite)
docker的数据持久化解决方案:
data volume.---->1、bind mount 2、docker managervolume
其实两者没有什么显著差别,不同点在于,是否需要提前准备dockerHost上的相关文件或目录
Volume
与docker类似:将宿主机上的某个文件或者目录挂载到Pod内
emptyDir
举个栗子:
[root@master ~]# vim emptyDir.yaml
kind: Pod
apiVersion: v1
metadata:
name: producer-consumer
spec:
containers:
- name: producer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /producer_dir #容器内的路径
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello.txt; sleep 30000
- name: consumer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /consumer_dir
args:
- /bin/sh
- -c
- cat /consumer_dir/hello.txt; sleep 30000
volumes:
- name: shared-volume
emptyDir: {
}
总结:根据上述yaml文件分析,volumes是指k8s的存储方案.容器内volumeMounts使用的是volumes内定义的存储,所以现在可以理解为,volumes定义的dockerHost上的目录或文件,分别挂载到了producer(/producer_dir)和consumer(/consumer_dir)这个两个容器的对应目录。可以判断出在consumer这个容器的/consumer_dir目录下,应该也会有一个hello.txt的文件。
//验证查看conumer容器的日志
[root@master yaml]# kubectl logs producer-consumer consumer
hello world
//查看一个Pod运行在了那个Node节点上?
[root@master yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
producer-consumer 2/2 Running 0 102s 10.244.1.2 node01 <none> <none>
//到对应Node节点上查看该容器的详细信息(Mounts)
在对应节点docker ps 查看容器名称 找到容器名称后:
[root@node01 ~]# docker inspect k8s_consumer_producer-consumer_default_a7c (容器名称)
"Mounts": [
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/a7c2c37b-f1cf-4777-a37b-d3
"Destination": "/consumer_dir",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
PS: 查看到该容器的Mounts字段,等于是运行docker容器的时候使用这么一条命令:
docker run -v /producer_dir busybox
emptyDir的使用场景:如果Pod的被删除,那么数据也会被删除,不具备持计化。Pod内的容器,需要共享数据卷的时候,使用的临时数据卷。
HostPath
相对于emtpyDir来说,hostPath就等于运行容器是使用的命令:
docker run -v /host/path:/container/path
//这里没有创建新的yaml文件,直接将emptyDir.yaml文件的volumes字段更改为:hostPath.
[root@master yaml]# mkdir /data/hostPath -p
kind: Pod
apiVersion: v1
metadata:
name: producer-consumer
spec:
containers:
- name: producer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /producer_dir #容器内的路径
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello.txt; sleep 30000
- name: consumer
image: busybox
volumeMounts:
- name: shared-volume
mountPath: /consumer_dir
args:
- /bin/sh
- -c
- cat /consumer_dir/hello.txt; sleep 30000
volumes:
- name: shared-volume
hostPath:
path: "/data/hostPath"
总结: HostPath这种方式相比较emptyDir来说,持久化功能强,但它实际增加了Pod与host的耦合,所以大部分资源不会使用这种持久化方案,通常关于docker或者k8s集群本身才会使用
PV、PVC
PV:Persisten(持久的、稳固的)Volume
是k8s集群的外部存储系统,一般是设定好的存储空间(文件系统中的一个目录)
PVC: PersistenvolumeClaim(声明、申请)
如果应用需要用到持久化的时候,可以直接向PV申请空间。
基于NFS服务来创建的PV
主机名 | IP地址 |
---|---|
master | 192.168.1.20 |
node01 | 192.168.1.21 |
node02 | 192.168.1.22 |
//3台节点都安装nfs-工具包和rpc-bind服务。
[root@master ~]# yum -y install nfs-utils rpcbind
[root@node01 ~]# yum -y install nfs-utils rpcbind
[root@node02 ~]# yum -y install nfs-utils rpcbind
//这里准备将NFS服务部署在master节点上,需要在master节点上提前规划好共享的目录
[root@master ~]# mkdir /nfsdata
[root@master ~]# vim /etc/exeports
/nfsdata *(rw,sync,no_root_squash)
[root@master ~]# systemctl start rpcbind
[root@master ~]# systemctl enable rpcbind
[root@master ~]# systemctl start nfs-server
[root@master ~]# systemctl enable nfs-server
[root@node02 ~]# showmount -e 192.168.1.20
Export list for 192.168.1.20:
/nfsdata *
[root@node01 ~]# showmount -e 192.168.1.20
Export list for 192.168.1.20:
/nfsdata *
[root@node02 ~]# showmount -e 192.168.1.20
Export list for 192.168.1.20:
/nfsdata *
//创建pv.yaml文件
[root@master ~]# mkdir yaml
[root@master ~]# mkdir -p /nfsdata/pv1
[root@master ~]# cd yaml
[root@master yaml]# vim pv.yaml
kind: PersistentVolume
apiVersion: v1
metadata:
name: pv1
spec:
capacity: #PV的容量
storage: 1Gi
accessModes: #访问模式
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.168.1.20
[root@master yaml]# kubectl apply -f pv.yaml
[root@master yaml]# kubectl get pv
PS: pv所支持的访问模式:
ReadWriteOnce: PV能以read-write的模式mount到单个节点。
ReadOnlyMany: PV能以read-only 的模式mount到多个节点。
ReadWriteMany: PV能以read-write的模式Mount到多个节点。
persistentVolumeReclaimPolicy:PV空间的回收策略:
Recycle: 会清除数据,自动回收。
Retain: 需要手动清理回收。
Delete: 云存储专用的回收空间使用命令。
//创建一个PVC,向刚才的PV申请使用空间,注意,这里PV与PVC的绑定,通过storageClassName和accessModes这两个字段共同决定
[root@master yaml]# vim pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
[root@master yaml]# kubectl apply -f pvc.yaml
kubectl get pvc可以查看到pv和pvc关联上了
[root@master yaml]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc1 Bound pv1 1Gi RWO nfs 7s
总结:
1.当系统中的PV被绑定之后,就不会被其他PVC所绑定了。
2.如果系统中有多个可以满足PVC要求的PV,则系统会自动选择一个符合PVC申请空间大小的PV进行绑定,尽量不浪费存储空间。
//创建一个Pod,来使用上述PVC
[root@master yaml]# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: pod1
spec:
containers:
- name: pod1
image: busybox
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- name: mydata
mountPath: "/data"
volumes:
- name: mydata
persistentVolumeClaim:
claimName: pvc1
[root@master yaml]# kubectl apply -f pod.yaml
[root@master yaml]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod1 1/1 Running 0 43s
注意: 一定要提前创好pv.yaml文件nfs字段下path:的目录,否则pod创建失败
//验证,/data/pv1目录与Pod内"/data"目录的一致性
[root@master yaml]# cd /nfsdata/pv1/
[root@master pv1]# echo "hello" > test.txt
[root@master pv1]# kubectl exec pod1 cat /data/test.txt
hello
PV的空间回收
当回收策略为; recycle
[root@master ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pv1 1Gi RWO Recycle Bound default/pvc1 nfs 20m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc1 Bound pv1 1Gi RWO nfs 17m
// 验证dockerhost上PV上存放的数据
[root@master ~]# ls /nfsdata/pv1/
test.txt