一、问题
k8s集群里面搭建了nfs storageclass,创建了一个sts资源动态申领了pv,存储大小1Gi,但是这个pv实际使用量突破了1Gi,这是为什么??
1.问题详细描述
sts的yaml文件
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
namespace: test
spec:
podManagementPolicy: OrderedReady
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
serviceName: nginx
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: 'core.harbor.domain/test/nginx-1.16.1:v1'
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
name: web
protocol: TCP
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /opt/web_app/nginx-1.16.1/html
name: www
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: harbor-secret
restartPolicy: Always
terminationGracePeriodSeconds: 30
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
creationTimestamp: null
name: www
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi // 申请了1Gi的大小
storageClassName: nfs // 存储类用nfs
volumeMode: Filesystem
PV和PVC,图里面能看到,pvc和pv的大小都是1Gi
pv已经挂载,这里发现一个新的问题,我明明申请了1Gi的存储空间,但是挂了98Gi
dd创建一个2G大小的文件查看目录使用情况
[root@k8s-node01 pvc-ba0eab51-7cd5-43ea-bd10-e7d459ad9129]# dd if=/dev/zero of=test bs=1M count=2048
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB) copied, 7.87055 s, 273 MB/s
[root@k8s-node01 pvc-ba0eab51-7cd5-43ea-bd10-e7d459ad9129]# ls
test
[root@k8s-node01 pvc-ba0eab51-7cd5-43ea-bd10-e7d459ad9129]# du -sh test
2.0G test
[root@k8s-node01 pvc-ba0eab51-7cd5-43ea-bd10-e7d459ad9129]# cd ..
[root@k8s-node01 kubernetes.io~nfs]# ls
pvc-ba0eab51-7cd5-43ea-bd10-e7d459ad9129
[root@k8s-node01 kubernetes.io~nfs]# du -sh pvc-ba0eab51-7cd5-43ea-bd10-e7d459ad9129/
2.0G pvc-ba0eab51-7cd5-43ea-bd10-e7d459ad9129/
二、问题分析
刚开始分析问题有点懵逼,不知道从那方面入手,后来只能与其他存储类做比较,这里用的是open-local(yoda)存储类
1.查看open-local的挂载情况
查看harbor的pv,大小是5Gi
[root@iZuf6gx89bn7oy70t13eojZ ~]# kubectl get pv |grep yoda-30a79add-a85b-49e9-b15b-52fef9d54b17
yoda-30a79add-a85b-49e9-b15b-52fef9d54b17 5Gi RWO Delete Bound harbor/data-harbor-trivy-0 yoda-lvm-default 78d
找到Pod分布的主机
[root@iZuf6gx89bn7oy70t13eojZ ~]# kubectl get pod -l component=trivy -n acs-harbor -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
harbor-trivy-0 1/1 Running 0 78d 172.24.0.190 izuf6fwtvytzi1qqc7glfxz <none> <none>
登入主机,查看挂载情况,挂载也是5Gi
[root@iZuf6fwtvytzi1qqc7glfxZ ~]# df -h |grep yoda-30a79add-a85b-49e9-b15b-52fef9d54b17
/dev/dm-10 4.9G 334M 4.6G 7% /var/lib/kubelet/pods/2105370b-b180-4b3c-911e-721a5514ff01/volumes/kubernetes.io~csi/yoda-30a79add-a85b-49e9-b15b-52fef9d54b17/mount
2.open-local的分区情况
openlocal申请pv的时候是将磁盘做了分区,再给分区分配5G的容量
[root@iZuf6fwtvytzi1qqc7glfxZ ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 100G 0 disk
└─vda1 253:1 0 100G 0 part /
vdb 253:16 0 600G 0 disk
├─vdb1 253:17 0 200G 0 part /var/lib/docker
├─vdb2 253:18 0 200G 0 part /var/lib/kubelet
├─vdb3 253:19 0 98G 0 part /data
└─yoda--30a79add--a85b--49e9--b15b--52fef9d54b17 252:10 0 5G 0 lvm /var/lib/kubelet/pods/2105370b-b180-4b3c-911e-721a5514ff01/volumes/kubernetes.io~csi/yoda-30a79add-a85b-49e9-b15b-52fef9d54b17/mount
3.nfs分区情况
sts的pod在node01上面,没发现新的分区,nfs的共享目录在/data下,而/data的分区是/dev/vdb3
[root@k8s-node01 kubernetes.io~nfs]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 253:0 0 100G 0 disk
└─vda1 253:1 0 100G 0 part /
vdb 253:16 0 500G 0 disk
├─vdb1 253:17 0 200G 0 part /var/lib/docker
├─vdb2 253:18 0 200G 0 part /var/lib/kubelet
└─vdb3 253:19 0 100G 0 part /data
nfs-server上面export配置和共享目录
[root@k8s-master nfs]# cat /etc/exports
/data/nfs 10.5.0.0/16(rw,no_root_squash,no_all_squash,sync)
4.挂载情况对比
open-local存储类创建pv的时候是将磁盘做了lv,然后将lv挂载到pod上面,只能使用5G
nfs存储类创建pv的时候是在共享目录下新生成一个文件夹,挂载的时候是将共享目录挂载且目录没有限制大小,所以能够使用98G
三、结论
k8s里面pod使用pv的大小跟pv的容量没有直接关系,而是跟挂载的文件系统大小有关系,pv的容量可以理解为给pv预留容量,当文件系统的可用容量<PV预留容量 时,pv创建失败,Pod也会Pending。
pv的实际使用量主要看挂载的文件系统大小,不同存储服务有不同的挂载机制,open-local可以将磁盘按照pv预留容量做lv直接挂载到pod,所以PV使用容量=PV预留容量;但是nfs没有分配容量的能力,只是在分区下创建了目录,将目录挂载到Pod,所以PV使用容量≠PV预留容量,出现了nfs 存储类pv使用容量超出pv预留容量的情况。