目录
一、理论
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-emptydir
namespace: default
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
#定义容器挂载的内容
volumeMounts:
#使用的存储卷名称,如果跟下面的volume字段name值相同,则表示使用volume的这个卷
- name: html
#挂载到容器的哪个目录
mountPath: /usr/share/nginx/html/
- name: busybox
image: busybox:latest
imagePullPolicy: IfNotPresent
volumeMounts:
- 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-hostpath
namespace: default
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
#定义容器你挂载内容
volumeMounts:
#使用的存储卷名称,如果跟下面volume字段name值相同,则表示使用volume的这个存储卷
- name: html
#挂载值容器中哪个目录
mountPath: /usr/share/nginx/html
readOnly: 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-nfs
namespace: default
spec:
#指定pod到 node01节点
nodeName: node01
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
path: /data/volumes
server: 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-nfs
namespace: default
spec:
#指定pod在node02节点
nodeName: node02
containers:
- name: myapp
image: ikubernetes/myapp:v1
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
path: /data/volumes
server: 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节点的文件系统中的文件或者目录挂载到集群中。




















