一万年来谁著史,三千里外欲封侯。这篇文章主要讲述[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 ~]#
?
---太晚了,就写到这吧,再见。
推荐阅读
- Redis持久化锦囊在手,再也不会担心数据丢失了
- 怼不过产品经理(因为你不懂DDD领域建模与架构设计)
- # yyds干货盘点 # 手把手教你进行Python网络爬虫中的Charles+Postern抓包
- [kubernetes] Endpoint 和 Service介绍与应用
- BGP RR反射器理论实验,BGP联盟详解 纯干货!
- [OpenCV实战]5 基于深度学习的文本检测
- [kubernetes] 交付dubbo之持续交付dubbo-monitor和dubbo-consumer(完结篇)
- 鸡肋的Redis事务
- kubesphere 3.1.1 部署有状态应用