目录
一.PV介绍
1.含义
称为持久化卷,是对底层的共享存储的一种抽象。一般情况下PV由 kubernetes管理员进行创建和配置,关联于底层具体的共享存储技术,并通过插件完成与共享存储的对接。
2.关键配置参数
这些参数在后面的例子中都有用到
(1)存储类型
这是要与底层存储对应的东西,像后面用到的nfs等类型
(2)存储能力
capacity,支持使用storage子项进行配置
(3)访问模式
accessModes,用户对于该存储资源的访问权限,有如下三种模式(因存储类型而异):
ReadWriteOnce(RWO):读写,被单个节点挂载
ReadOnlyMany(ROX): 只读,可被多节点挂载
ReadWriteMany(RWX):读写,可被多节点挂载
(4)回收策略
persistentVolumeReclaimPolicy,pv不供使用之后的三种处理策略(因存储类型而异):
Retain 保留数据,需要管理员手工清理数据
Recycle清除数据
Delete删除与 PV 相连的后端存储完成删除操作
(5)存储类别
storageClassName,设定一个类别,pvc需要匹配此类的pv时才能相匹配,pvc不申请具有类的pv时,只能与没有设定类的pv匹配,不能和设定了类的pv匹配
二.PVC介绍
1.含义
持久卷声明,是用户对于存储需求的一种声明。用户向kubernetes系统发出的一种资源需求申请(可以是访问模式,存储空间,存储类别的需求),kubernetes再进一步去申请PV
2.关键参数配置
(1)访问模式
accessModes,主要是配置用户对存储资源的访问权限
(2)筛选条件
selector,和以往的selector一样,对有label的pv进行选择
(3)存储类别
storageClassName,上文已提及
(4)资源请求
resources,通过requests-storage子项进行资源大小申请
三.PV和PVC的生命周期问题
1.PV的生命周期会有4个阶段
Available:可用状态,还未被任何 PVC 绑定
Bound:PV 已经被 PVC 绑定
Released:PVC 被删除,但是资源还未被集群重新声明
Failed:该 PV 的自动回收失败
2.用户申请空间PV的周期流程
管理员创建PV,用户创建PVC,kubernetes通过PVC请求去找符合条件的PV并将PV与PVC绑定,匹配成功后用户进行使用,不成功则将PVC标记为Pending状态,一直持续到匹配到下一个符合条件的PV
3.PV和PVC的使用/释放/回收
通过volume挂载来使用PVC,使用完毕后删除掉PVC即可,但是现在PV却不能立刻去绑定另外的PVC,因为上面不清楚是否还存在残留数据(取决于你PV配置的回收策略),清除完毕后就可以进行信心PVC的绑定
四.案例演示
如下案例以nfs,my-pv1,my-pv2,my-pvc1,my-pvc2,my-pod1,my-pod2等资源来演示,主要是演示对于nginx访问日志的简单存储问题
1.NFS配置
存储类型选择NFS来演示
[root@k8s-master pv]# cat /etc/exports
/root/pv/pv1 192.168.2.0/24(rw,no_root_squash) #共享后端目录,可以自己新建
/root/pv/pv2 192.168.2.0/24(rw,no_root_squash)
[root@k8s-master pv]# systemctl restart nfs
[root@k8s-master pv]# pwd
/root/pv
[root@k8s-master pv]# ll
total 12
-rw-r--r-- 1 root root 1011 Mar 7 20:14 pod.yaml
drwxr-xr-x 5 root root 74 Mar 7 20:16 pv1
drwxr-xr-x 5 root root 74 Mar 7 20:14 pv2
-rw-r--r-- 1 root root 353 Mar 6 21:54 pvc.yaml
-rw-r--r-- 1 root root 555 Mar 7 15:59 pv.yaml
2.新建PV
[root@k8s-master pv]# cat pv.yaml
apiVersion: v1
kind: Namespace
metadata:
name: myns
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv1
namespace: myns
spec:
capacity:
storage: 1G #共1G
accessModes:
- ReadWriteMany #可读写
persistentVolumeReclaimPolicy: Retain #需手动删除后端内容
nfs: #nfs挂载信息
path: /root/pv/pv1 #刚才建立的后端目录
server: 192.168.2.150
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv2
namespace: myns
spec:
capacity:
storage: 1G
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /root/pv/pv2
server: 192.168.2.150
3.新建PVC
[root@k8s-master pv]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc1
namespace: myns
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 500M #申请500M
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc2
namespace: myns
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 600M
4.新建Pod测试
[root@k8s-master pv]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod1
namespace: myns
spec:
containers:
- name: my-nginx1
image: nginx
ports:
- name: nginx-port1
containerPort: 80
volumeMounts:
- name: my-volume
mountPath: /var/log/nginx
- name: my-busybox1
image: busybox
command: ["/bin/sh","-c","tail -f /logs/access.log"]
volumeMounts:
- name: my-volume
mountPath: /logs
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-pvc1
---
apiVersion: v1
kind: Pod
metadata:
name: my-pod2
namespace: myns
spec:
containers:
- name: my-nginx2
image: nginx
ports:
- name: nginx-port2
containerPort: 80
volumeMounts:
- name: my-volume
mountPath: /var/log/nginx
- name: my-busybox2
image: busybox
command: ["/bin/sh","-c","tail -f /logs/access.log"]
volumeMounts:
- name: my-volume
mountPath: /logs
volumes:
- name: my-volume
persistentVolumeClaim:
claimName: my-pvc2
[root@k8s-master pv]# kubectl get pv,pvc,pod -n myns -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
persistentvolume/my-pv1 1G RWX Retain Bound myns/my-pvc1 22m Filesystem
persistentvolume/my-pv2 1G RWX Retain Bound myns/my-pvc2 22m Filesystem
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
persistentvolumeclaim/my-pvc1 Bound my-pv1 1G RWX 22m Filesystem
persistentvolumeclaim/my-pvc2 Bound my-pv2 1G RWX 22m Filesystem
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/my-pod1 2/2 Running 0 7m43s 10.244.107.195 k8s-node3 <none> <none>
pod/my-pod2 2/2 Running 0 7m43s 10.244.36.67 k8s-node1 <none> <none>
[root@k8s-master pv]# ansible all -m shell -a "curl 10.244.107.195" #访问产生日志
[root@k8s-master pv]# ansible all -m shell -a "curl 10.244.36.67"
[root@k8s-master pv]# cat pv1/access.log
10.244.36.64 - - [07/Mar/2024:12:15:05 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.169.128 - - [07/Mar/2024:12:15:05 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.153 - - [07/Mar/2024:12:15:05 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
[root@k8s-master pv]# cat pv2/access.log
10.244.169.128 - - [07/Mar/2024:12:15:20 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.151 - - [07/Mar/2024:12:15:20 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.107.192 - - [07/Mar/2024:12:15:20 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
5.模拟删除Pod后后端目录内数据不会受影响
[root@k8s-master pv]# kubectl get pods -n myns
NAME READY STATUS RESTARTS AGE
my-pod1 2/2 Running 0 14m
my-pod2 2/2 Running 0 14m
[root@k8s-master pv]# kubectl delete pod my-pod1 my-pod2 -n myns
pod "my-pod1" deleted
pod "my-pod2" deleted
[root@k8s-master pv]# ll
total 12
-rw-r--r-- 1 root root 1011 Mar 7 20:14 pod.yaml
drwxr-xr-x 5 root root 74 Mar 7 20:16 pv1
drwxr-xr-x 5 root root 74 Mar 7 20:14 pv2
-rw-r--r-- 1 root root 353 Mar 6 21:54 pvc.yaml
-rw-r--r-- 1 root root 555 Mar 7 15:59 pv.yaml
[root@k8s-master pv]# cat pv1/access.log
10.244.36.64 - - [07/Mar/2024:12:15:05 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
10.244.169.128 - - [07/Mar/2024:12:15:05 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
192.168.2.153 - - [07/Mar/2024:12:15:05 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"