创建一个pod,挂载hostPath存储卷
[root@k8s-master~]# cat hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-hostpath
spec:
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: test-nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data
type: DirectoryOrCreate
注意:
DirectoryOrCreate表示本地有/data目录,就用本地的,本地没有就会在pod调度到的节点自动创建一个
更新资源清单文件,并查看pod调度到了哪个物理节点
[root@k8s-master ~]# kubectl apply -f test-hostpath.yaml
pod/test-hostpath created
[root@k8s-master ~]# kubectl get pod test-hostpath -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-hostpath 1/1 Running 0 80s 172.16.69.248 k8s-node2
测试
###没有首页
[root@k8s-master ~]# curl 172.16.69.248
403 Forbidden
403 Forbidden
nginx/1.25.3
###生成首页
[root@k8s-node2 ~]# cd /data/
[root@k8s-node2 data]# ls
[root@k8s-node2 data]# echo 1111 > index.html
[root@k8s-master ~]# curl 172.16.69.248
1111
hostpath存储卷缺点
单节点,pod删除之后重新创建必须调度到同一个node节点,数据才不会丢失
如何调度到同一个nodeName呢 ? 需要我们再yaml文件中进行指定就可以
啦
apiVersion: v1
kind: Pod
metadata:
name: test-hostpath
spec:
nodeName: k8s-node2
containers:
- image: nginx
name: test-nginx
volumeMounts:
- mountPath: /usr/share/nginx/html
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data
type: DirectoryOrCreate
测试
[root@k8s-master ~]# kubectl apply -f test-hostpath.yaml
pod/test-hostpath configured
[root@k8s-master ~]# kubectl delete pod test-hostpath
pod "test-hostpath" deleted
[root@k8s-master ~]# kubectl apply -f test-hostpath.yaml
pod/test-hostpath created
[root@k8s-master ~]# kubectl get pod test-hostpath -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-hostpath 1/1 Running 0 9s 172.16.69.219 k8s-node2
[root@k8s-master ~]# curl 172.16.69.219
1111
3、k8s持久化存储:nfs
上节说的hostPath存储,存在单点故障,pod挂载hostPath时,只有调度到同一个节点,数据才不会丢失。那可以使用nfs作为持久化存储。
搭建nfs服务
以k8s的控制节点作为NFS服务端
[root@k8s-master ~]# yum install -y nfs-utils
在宿主机创建NFS需要的共享目录
[root@k8s-master ~]# mkdir /data -pv
mkdir: 已创建目录 "/data"
mkdir: 已创建目录 "/data"
配置nfs共享服务器上的/data目录
[root@k8s-master] ~]# systemctl enable --now nfs
[root@k8s-master] ~]# vim /etc/exports
/data 192.168.166.0/24(rw,sync,no_root_squash,no_subtree_check)
#使NFS配置生效
[root@k8s-master ~]# exportfs -avr
exporting 192.168.166.0/24:/data
所有的worker节点安装nfs-utils
yum install nfs-utils -y
systemctl enable --now nfs
#在k8s-node1和k8s-node2上手动挂载试试:
[root@k8s-node1 ~]# mount 192.168.166.7:/data /mnt
[root@k8s-node1 ~]# df -Th | grep nfs
192.168.166.7:/data nfs4 116G 6.7G 109G 6% /mnt
#nfs可以被正常挂载
#手动卸载:
[root@k8s-node1 ~]# umount /mnt
创建Pod,挂载NFS共享出来的目录
Pod挂载nfs的官方地址:https://kubernetes.io/zh/docs/concepts/storage/volumes/
[root@k8s-master ~]# cat nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-nfs
spec:
containers:
- name: test-nfs
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- name: nfs-volumes
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-volumes
nfs:
path: /data #共享目录
server: 192.168.166.7 ##nfs服务器地址
更新资源清单文件
[root@k8s-master ~]# kubectl apply -f test-nfs.yaml
pod/test-nfs created
查看pod是否创建成功
[root@k8s-master ~]# kubectl get pods -o wide | grep nfs
test-nfs 1/1 Running 0 55s 172.16.79.68 k8s-node1
测试
[root@k8s-master ~]# curl 172.16.79.68
403 Forbidden
403 Forbidden
nginx/1.25.3
#登录到nfs服务器,在共享目录创建一个index.html
[root@k8s-master ~]# cd /data/
[root@k8s-master volumes]# echo nfs > index.html
[root@k8s-master ~]# curl 172.16.79.68
nfs
上面说明挂载nfs存储卷成功了,nfs支持多个客户端挂载,可以创建多个pod,挂载同一个nfs服务器共享出来的目录;但是nfs如果宕机了,数据也就丢失了,所以需要使用分布式存储,常见的分布式存储有glusterfs和cephfs
4、k8s持久化存储: PVC
参考官网:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes
4.1.1 k8s PV是什么?
PersistentVolume(PV)是群集中的一块存储,由管理员配置或使用存储类动态配置。 它是集群中的资源,就像pod是k8s集群资源一样。 PV是容量插件,如Volumes,其生命周期独立于使用PV的任何单个pod。
4.1.2 k8s PVC是什么?
PersistentVolumeClaim(PVC)是用户使用存储的请求。 它类似于pod。Pod消耗节点资源,PVC消耗存储资源。 pod可以请求特定级别的资源(CPU和内存)。 pvc在申请pv的时候也可以请求特定的大小和访问模式(例如,可以一次读写或多次只读)。
4.1.3 k8s PVC和PV工作原理
PV是群集中的资源。 PVC是对这些资源的请求。
PV和PVC之间的相互作用遵循以下生命周期:
(1)pv的供应方式
可以通过两种方式配置PV:静态或动态。
静态的:
集群管理员创建了许多PV。它们包含可供群集用户使用的实际存储的详细信息。它们存在于Kubernetes API中,可供使用。
动态的:
当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时,群集可能会尝试为PVC专门动态配置卷。此配置基于StorageClasses,PVC必须请求存储类,管理员必须创建并配置该类,以便进行动态配置。
(2)绑定
用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前,pvc会保持未绑定状态
(3)使用
需要找一个存储服务器,把它划分成多个存储空间;
k8s管理员可以把这些存储空间定义成多个pv;
在pod中使用pvc类型的存储卷之前需要先创建pvc,通过定义需要使用的pv的大小和对应的访问模式,找到合适的pv;
pvc被创建之后,就可以当成存储卷来使用了,我们在定义pod时就可以使用这个pvc的存储卷;
pvc和pv它们是一一对应的关系,pv如果被pvc绑定了,就不能被其他pvc使用了;
我们在创建pvc的时候,应该确保和底下的pv能绑定,如果没有合适的pv,那么pvc就会处于pending状态。
(4)回收策略
当我们创建pod时如果使用pvc做为存储卷,那么它会和pv绑定,当删除pod,pvc和pv绑定就会解除,解除之后和pvc绑定的pv卷里的数据需要怎么处理,目前,卷可以保留、回收或删除:
1、Retain
当删除pvc的时候,pv仍然存在,处于released状态,但是它不能被其他pvc绑定使用,里面的数据还是存在的,当我们下次再使用的时候,数据还是存在的,这个是默认的回收策略。
2、Delete
删除pvc时即会从Kubernetes中移除PV,也会从相关的外部设施中删除存储资产。
4.1.4 创建pod,使用pvc作为持久化存储卷
1、创建nfs共享目录
#在宿主机创建NFS需要的共享目录
[root@k8s-master] ~]# mkdir /data/v{1..10} -p
#配置nfs共享宿主机上的/data/v1..v10目录
[root@k8s-master ~]# cat /etc/exports
/data 192.168.166.0/24(rw,no_root_squash)
/data/v1 192.168.166.0/24(rw,no_root_squash)
/data/v2 192.168.166.0/24(rw,no_root_squash)
/data/v3 192.168.166.0/24(rw,no_root_squash)
/data/v4 192.168.166.0/24(rw,no_root_squash)
/data/v5 192.168.166.0/24(rw,no_root_squash)
/data/v6 192.168.166.0/24(rw,no_root_squash)
/data/v7 192.168.166.0/24(rw,no_root_squash)
/data/v8 192.168.166.0/24(rw,no_root_squash)
/data/v9 192.168.166.0/24(rw,no_root_squash)
/data/v10 192.168.166.0/24(rw,no_root_squash)
#重新加载配置,使配置成效
[root@k8s-master ~]# exportfs -arv
2、如何编写pv的资源清单文件
#查看定义pv需要的字段
[root@k8s-master ~]# kubectl explain pv
KIND: PersistentVolume
VERSION: v1
DESCRIPTION:
PersistentVolume (PV) is a storage resource provisioned by an
administrator. It is analogous to a node. More info:
[https://kubernetes.io/docs/concepts/storage/persistent-volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes)
FIELDS:
apiVersion s
kind
metadata