目录
一、理论
1.存储卷
2.emptyDir 存储卷
3.hostPath卷
4.NFS共享存储
二、实验
1.emptyDir 存储卷
2.hostPath卷
3.NFS共享存储
三、问题
1.生成pod一直pending
四、总结
一、理论
1.存储卷
(1)概念
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时, kubelet会重启它,但是容器中的文件将丢失一容器以干净的状态(镜像最初的状态)重新启动。
其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。
(2)分类
本地:例如hostPath、emptyDir;
网络:例如NFS、Ceph、GlusterFS;
公有云:例如AWS EBS;
k8s资源:例如configmap、secret。
2.emptyDir 存储卷
(1)作用
emptyDir存储卷当Pod被分配给节点时,首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除Pod时, emptyDir中的数据将被永久删除。
(2)示例
[root@master demo]# mkdir /opt/volumes
[root@master demo]# cd /opt/volumes/
[root@master volumes]# vim pod-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-emptydirnamespace: defaultlabels:app: myapptier: frontend
spec:containers:- name: myappimage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80#定义容器挂载的内容volumeMounts:#使用的存储卷名称,如果跟下面的volume字段name值相同,则表示使用volume的这个卷- name: html#挂载到容器的哪个目录mountPath: /usr/share/nginx/html/- name: busyboximage: busybox:latestimagePullPolicy: IfNotPresentvolumeMounts:- name: html#在容器内定义挂载存储名称和挂载路径mountPath: /data/command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 5;done']#定义存储卷volumes:#定义存储卷的名称- name: html#定义存储卷的类型emptyDir: {}
[root@master volumes]# kubectl apply -f pod-emptydir.yaml[root@master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-emptydir 2/2 Running 0 3s 10.244.1.146 node01 <none> <none>#在上面定义了两个容器,其中一个容器输入日期到index.html中,然后验证范围nginx的htmnl是否可以获取日期
#同时,在进入两个容器里,查看挂载数据卷的目录的数据,以验证两个容器之间挂载的emptyDir实现共享[root@master volumes]# curl 10.244.1.146
wed Sep 20 06:07:26 UTC 2023
Wed Sep 20 06:07:31 UTC 2023
Wed Sep 20 06:07:36 UTC 2023
Wed Sep 20 06:07:41 UTC 2023
Wed Sep 20 06:07:46 UTC 2023
Wed Sep 20 06:07:51 UTC 2023
[root@master volumes]# kubectl exec -it pod-emptydir -c busybox sh
/ # cat /data/index.html
wed Sep 20 06:07:26 UTC 2023
Wed Sep 20 06:07:31 UTC 2023
Wed Sep 20 06:07:36 UTC 2023
Wed Sep 20 06:07:41 UTC 2023
Wed Sep 20 06:07:46 UTC 2023
Wed Sep 20 06:07:51 UTC 2023
[root@master volumes]# kubectl exec -it pod-emptydir -c myapp sh
/ # cat /usr/share/nginx/html/index.html
Wed Sep 20 06:07:26 UTC 2023
Wed Sep 20 06:07:31 UTC 2023
Wed Sep 20 06:07:36 UTC 2023
Wed Sep 20 06:07:41 UTC 2023
Wed Sep 20 06:07:46 UTC 2023
Wed Sep 20 06:07:51 UTC 2023
Wed Sep 20 06:07:56 UTC 2023
Wed Sep 20 06:08:01 UTC 2023
Wed Sep 20 06:08:06 UTC 2023
Wed Sep 20 06:08:11 UTC 2023
3.hostPath卷
(1)作用
hostPath卷将node节点的文件系统中的文件或者目录挂载到集群中。
hostPath可以实现持久存储,但是在node节点故障时,也会导致数据的丢失。
(2)示例
#在node01节点上创建挂载目录
[root@node01 ~]# mkdir -p /data/pod/volume1
[root@node01 ~]# echo 'node01.myweb.com' > /data/pod/volume1/index.html#在node02 节点上创建挂载目录
[root@node02 ~]# mkdir -p /data/pod/volume1
[root@node02 ~]# echo 'node02.myweb.com' > /data/pod/volume1/index.html
[root@master volumes]# vim pod-hostpath.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-hostpathnamespace: default
spec:containers:- name: myappimage: ikubernetes/myapp:v1#定义容器你挂载内容volumeMounts:#使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷- name: html#挂载值容器中哪个目录mountPath: /usr/share/nginx/htmlreadOnly: false#volumes字段定义了paues容器关联的宿主机或分布式文件系统存储卷 volumes:#存储卷名称- name: html#路径,为宿主机存储路径hostPath:#在宿主机上目录的路径path: /data/pod/volume1#定义类型,这表示如果宿主机没有此目录则会自动创建type: DirectoryOrCreate
[root@master volumes]# kubectl apply -f pod-hostpath.yaml [root@master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-hostpath 1/1 Running 0 14m 10.244.2.112 node02 <none> <none>
#访问测试
[root@master volumes]# curl 10.244.2.112
node02.myweb.com#删除pod后,再重建,验证是否依旧可以访问原来的内容
[root@master volumes]# kubectl delete -f pod-hostpath.yaml
pod "pod-hostpath" deleted
[root@master volumes]# kubectl apply -f pod-hostpath.yaml
pod/pod-hostpath created
[root@master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-hostpath 1/1 Running 0 6s 10.244.1.147 node01 <none> <none>
[root@master volumes]# curl 10.244.1.147
node01.myweb.com
4.NFS共享存储
(1)安装配置nfs服务
#在stor01(192.168.204.177)节点上安装nfs,并配置nfs服务
mkdir /data/volumes -p
echo 'this is david' >> /data/volumes/index.html
chmod 777 /data/volumes/yum -y install nfs-utils rpcbind#给204网段用户赋予读写权限、同步内容、不压缩共享对象root用户权限
vim /etc/exports
/data/volumes 192.168.204.0/24(rw,no_root_squash,sync)systemctl start rpcbind nfs#监听服务
[root@stor01 ~]# ss -antp | grep rpcbind
LISTEN 0 128 *:111 *:* users:(("rpcbind",pid=37036,fd=8))
LISTEN 0 128 :::111 :::* users:(("rpcbind",pid=37036,fd=11))showmount -e 192.168.204.177
Export list for host10:
/data/volumes 192.168.204.0/24#所有节点配置hosts映射,或者配置DNS解析
echo '192.168.204.177 stor01' >> /etc/hosts
(2)master 节点操作
apiVersion: v1
kind: Pod
metadata:name: pod-vo1-nfsnamespace: default
spec:#指定pod到 node01节点nodeName: node01containers:- name: myappimage: ikubernetes/myapp:v1volumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlnfs:path: /data/volumesserver: stor01
[root@master volumes]# kubectl apply -f pod-nfs-vo1.yaml
pod/pod-vo1-nfs created
[root@master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-vo1-nfs 1/1 Running 0 8s 10.244.1.148 node01 <none> <none>
#访问cluster ip
[root@master volumes]# curl 10.244.1.148
this is david
[root@master volumes]# kubectl delete pod pod-vo1-nfs
pod "pod-vo1-nfs" deleted[root@master volumes]# vim pod-nfs-vo1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-vo1-nfsnamespace: default
spec:#指定pod在node02节点nodeName: node02containers:- name: myappimage: ikubernetes/myapp:v1volumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlnfs:path: /data/volumesserver: stor01
[root@master volumes]# kubectl apply -f pod-nfs-vo1.yaml
pod/pod-vo1-nfs created
[root@master volumes]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-vo1-nfs 1/1 Running 0 3s 10.244.2.114 node02 <none> <none>
#访问测试
[root@master volumes]# curl 10.244.2.114
this is david
二、实验
1.emptyDir 存储卷
(1)示例
创建宿主机挂载目录
编写资源清单
生成资源
查看信息
在上面定义了两个容器,其中一个容器输入日期到index.html中,然后验证范围nginx的htmnl是否可以获取日期
同时,在进入两个容器里,查看挂载数据卷的目录的数据,以验证两个容器之间挂载的emptyDir实现共享
访问cluster ip
进入pod pod-emptydie里的busybox容器查看
进入pod pod-emptydie里的myapp容器查看
删除pod后,再重建,验证是否依旧可以访问原来的内容
原来内容已不在
2.hostPath卷
(1)示例
在node01节点上创建挂载目录
在node02 节点上创建挂载目录
编写资源清单文件
生成资源并查看信息
访问测试
删除pod后,再重建,验证是否依旧可以访问原来的内容
查看信息并访问测试,内容依然存在
3.NFS共享存储
(1)安装配置nfs服务
在stor01(192.168.204.177)节点上安装nfs,并配置nfs服务
安装
配置文件
重启服务
监听服务
查看共享目录
所有节点配置hosts映射,或者配置DNS解析
(2)master 节点操作
生成资源
查看信息,已分配到node01节点
删除pod
指定pod在node02节点
生成资源并查看信息,已分配到node02节点
访问测试。说明nfs实现了数据持久化
三、问题
1.生成pod一直pending
(1)报错
(2)原因分析
查看pod详细信息
[root@master volumes]# kubectl describe pod pod-emptydir
node节点有污点
(3)解决方法
查看污点
[root@master volumes]# kubectl describe nodes node01 | grep -i 'taints'
Taints: check=mycheck:NoExecute
[root@master volumes]# kubectl describe nodes node02 | grep -i 'taints'
Taints: check=mycheck:NoExecute
去除所有node节点污点
[root@master volumes]# kubectl taint nodes node01 check:NoExecute-
node/node01 untainted
[root@master volumes]# kubectl taint nodes node02 check:NoExecute-
node/node02 untainted
成功
2.shoumount -e未显示共享目录
(1)报错
(2)原因分析
配置文件关键词“squash”错误
(3)解决方法
修改配置文件
[root@stor01 ~]# vim /etc/exports
修改前:
修改后:
成功:
四、总结
容器崩溃不会导致Pod被删除,因此容器崩溃期间emptyDir中的数据是安全的。
hostPath卷将node节点的文件系统中的文件或者目录挂载到集群中。