[kubernetes] 持久化存储之emptyDir/HostPath/NFS

一万年来谁著史,三千里外欲封侯。这篇文章主要讲述[kubernetes] 持久化存储之emptyDir/HostPath/NFS相关的知识,希望能为你提供帮助。
        使用过docker的同学应该都知道,docker只有容器层是可读写的,如果不将容器提交为镜像,当容器被删除后,可读写层的数据也会被删除,无法保留。在docker的解决方案中,我们一般使用 -v 参数将一个目录挂载容器中,实现数据持久化存储。
        而在kubernetes中,数据持久化存储的解决方案更加丰富,今天主要是学习以下emptydir和hostpath这两种本地存储和网络存储nfs。



??01  emptyDir??
      emptyDir是一个空目录,不需要提前创建相关目录,他的声明周期和Pod是完全一致的,Pod被删除时,emptyDir也会被删除。emptyDir主要是用于同一个Pod内不同的容器之间共享工作过程中产生的文件。
        比如以下这种模型,busybox每隔1s向index.html写入当前时间,当用户不同的时间访问nginx提供的index.html时,就会产生不同的结果。再比如同个pod内有一个container产生临时数据,另一个container对数据进行分析并储存的场景,也可以使用emptyDir。

        准备emptydir.yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
name: emptydir-pod
labels:
app: emptydir-pod
spec:
selector:
matchLabels:
app: emptydir-pod
template:
metadata:
labels:
app: emptydir-pod
spec:
containers:
- image: harbor.od.com/public/nginx:v1.7.9
name: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-html
- image: harbor.od.com/public/busybox:latest
name: busybox
args:
- /bin/sh
- -c
- >
while :; do
echo "The Time is [$(date)]" > /data/html/index.html
sleep 1
done
volumeMounts:
- mountPath: "/data/html"
name: nginx-html
volumes:
- name: nginx-html
emptyDir:# 定义一个emptyDir,默认类型为目录
sizeLimit: 20Mi# 定义大小
---
apiVersion: v1
kind: Service
metadata:
name: emptydir-svc
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: emptydir-pod

        mptydir除了默认支持的目录以外,还可以支持Menory和HugePages,提供快的访问速率。
        应用资源
kubectl apply -f emptydir.yaml

    查看pod和svc
[root@host22 ~]# kubectl get pod,svc -o wide | grep emptydir
pod/emptydir-pod-5db4b4ccc7-vcrzn2/2Running028m172.7.22.7host22.yunwei.com< none> < none>
service/emptydir-svcClusterIP10.254.53.210< none> 80/TCP49mapp=emptydir-pod

        测试:

    登录容器所在node节点,查看挂载信息:
# kubectl describe pod emptydir-pod-5db4b4ccc7-vcrzn | grep "Container ID"
Container ID:docker://607b6415a944375de49d60fac8002d9bfe01f7bfd670c696d843720d0ea0791b
Container ID:docker://de5905b474f340147257dc124999c401c33afda76f10ff9f24767de18a83a179


    可以看出两个容器挂载的是同一个目录,而且这个目录是自动创建的。
      重启pod,查看目录内容是否会被清空
kubectl delete pod emptydir-pod-5db4b4ccc7-vcrzn

        再次查看挂载信息,很明显可以看到重启前后的目录不一样了,而且查看重启前的目录,已经不存在。-- 所以emptyDir和pod的生命周期是一致的。



??02 HostPath??
    与emptyDir相比,Hostpath的数据是独立于pod生命周期的。
      HostPath可以将node的目录/文件/socket/dev等文件挂载到pod中。比如jenkins将harbor仓库主机的docker的sock文件挂载到了pod内,实现镜像自动打包上传等场景会使用到HostPath。

【[kubernetes] 持久化存储之emptyDir/HostPath/NFS】    事实上HostPath比较少用,因为我们无法保证集群内每个主机都有相同的目录,目录中都有相同的内容,如果这都不能保证,那容器一次打包到处运行的特点就无法体现了。


?        本地资源的HostPath实验:?
      在一个节点上创建/data/html目录,并生成index.html文件,通过HostPath挂载给pod。

        资源配置清单:
cat hostpath.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hostpath-pod
labels:
app: hostpath-pod
spec:
selector:
matchLabels:
app: hostpath-pod
template:
metadata:
labels:
app: hostpath-pod
spec:
containers:
- image: harbor.od.com/public/nginx:v1.7.9
name: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-html
volumes:
- name: nginx-html
hostPath:
path: /data/html# node上的目录
type: Directory# 类型为目录
---
apiVersion: v1
kind: Service
metadata:
name: hostpath-svc
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: hostpath-pod

        准备目录:
[root@host22 ~]# mkdir /data/html
[root@host22 ~]# cd /data/html/
[root@host22 html]# vi index.html
hello 运维少年.

        应用:
kubectl apply -f hostpath.yaml

        查看pod
kubectl get pod -o wide


        很不幸,我只在host22上准备了/data/html资源,而pod被调度到了host21上,导致pod无法正常运行。--  如果无法保证集群内所有节点都有该目录且内容相同,建议不要使用本地资源hostpath。

        在host21上也建立相同的目录和内容
[root@host21 ~]# mkdir /data/html
[root@host21 ~]# cd /data/html/
[root@host21 html]# echo hello 运维少年 > index.html
[root@host21 html]#

        再查看相关资源
[root@host21 html]# kubectl get svc,pod -o wide | grep hostpath
service/hostpath-svcClusterIP10.254.15.227< none> 80/TCP7m56sapp=hostpath-pod
pod/hostpath-pod-74d8856d5b-p2vl71/1Running026s172.7.22.7host22.yunwei.com< none> < none>

    测试:



        删除pod,再查看数据是否被清除  -- 可以看到数据依旧还保留着。

        HostPath补充:
        支持的type:

        支持挂载模式:



??03 NFS??
        在节点网络与NFS Server网络互通的情况下,使用nfs存储可以保证container一次打包,集群内任意节点运行,和hostpath一样,nfs数据独立于pod的生命周期。


?    nfs实验:?

        host200上准备nfs资源 -- 略
        资源配置清单
cat nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-pod
labels:
app: nfs-pod
spec:
selector:
matchLabels:
app: nfs-pod
template:
metadata:
labels:
app: nfs-pod
spec:
containers:
- image: harbor.od.com/public/nginx:v1.7.9
name: nginx
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-html
volumes:
- name: nginx-html
nfs:
server: host200# nfs服务器
path: /data/nfs-volume/html# nfs目录
---
apiVersion: v1
kind: Service
metadata:
name: nfs-svc
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nfs-pod

        应用和测试:
[root@host22 ~]# kubectl apply -f nfs.yaml
deployment.apps/nfs-pod created
service/nfs-svc created
[root@host22 ~]# kubectl get pod,svc | grep nfs
pod/nfs-pod-7664d9f54b-pw76t1/1Running081s
service/nfs-svcClusterIP10.254.215.77< none> 80/TCP81s
[root@host22 ~]#

?


---太晚了,就写到这吧,再见。






    推荐阅读