目录
k8s卷管理-2
之前已经介绍了本地存储和网络存储这两种类型,但是在生产环境中,这两种存储方式用的很少,而现在要介绍的存储方式才是使用率最高的
pv和pvc
他们的区别:
pv(PersistentVolume)是集群中的存储资源,所有的namespace都是可以查看到的,pv并不属于某一namespace,而是属于整个集群,它是由底层的存储服务器提供给k8s集群的
pvc(PersistentVolumeClaim)是表达用户对于pv的申请,它可以定义用户想要多少个G的存储空间,相当于购物车,你想要什么都放在这个请求里面,k8s会对你的请求给你分配对应的pv让你来使用,pvc是属于namespace的资源,不同的namespace是查不到其他namespace的资源的
他们之间的关系:
pv与pvc是一一对应的,一个pv只能绑定到一个pvc上,尽管资源没有分配完,那么剩下的也不会再次绑定给其他的pvc了
pv
pv的底层可以对接很多的存储系统,比如NFS,Ceph,Iscsi,cinde(已弃用),关于想要知道目前支持哪些后端存储的话可以到k8s的官方文档去查看
pv的定义
我就在这里使用nfs作为后端存储,因为nfs比较方便
apiVersion: v1 kind: PersistentVolume metadata: name: pv01 spec: # 这里是定义的pv的大小 capacity: storage: 5Gi # 卷的类型,由Filesystem 和 Block两种,如果你使用的是Iscsi这种那你就定义成Block,默认就是Filesystem volumeMode: Filesystem # pv的访问模式,ReadWriteOnce的意思是只允许一个节点以读写的方式挂载,但是一个节点上有多个pod的话,这些pod都能挂载。不能跨节点 accessModes: - ReadWriteOnce # 这里定义的就是后端存储的类型,地址啥的 nfs: path: /nfs server: 192.168.200.200
使用这个yaml文件去创建pv,验证一下是否所有的namespace都可以查得到
# 现在是在default命名空间下 [root@master k8s]# kubectl apply -f pv.yaml persistentvolume/pv01 created [root@master k8s]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv01 5Gi RWO Retain Available 4s # 切换命名空间到kube-system再次查看 [root@master k8s]# kubectl config set-context --current --namespace kube-system Context "kubernetes-admin@kubernetes" modified. [root@master k8s]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv01 5Gi RWO Retain Available 20s
我们可以看到,pv确实是所有的命名空间都可以查得到的,这个就是pv的定义,定义好了之后状态是可用,那么现在只需要等到一个有缘人发起一个pvc的请求,只要请求的访问模式一致,并且大小不超过pv的大小,那么这个pv就会被绑定咯,来看看pvc
pvc
pvc就是一个对pv请求的清单,比如我想要一个访问模式是ReadOnlyMany,并且大小是100G的pv,我只需要把这些条件表达出来,然后交给k8s,那么k8s集群就会去找有没有合适的pv分配给我,有的话那么pv就和我的pvc绑定上了,那么这个pv就不会再分配给别人了,尽管我请求的是100G,他这个PV有1T,那么剩下的空间也不会再分配出去了,也验证了前面所说的一一对应
pvc的定义
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: myclaim spec: accessModes: - ReadWriteOnce volumeMode: Filesystem # 这里是请求的资源大小,5G resources: requests: storage: 5Gi
我们来创建一下这个pvc,看看他是否能够成功绑定
[root@master k8s]# kubectl apply -f pvc.yaml persistentvolumeclaim/myclaim created [root@master k8s]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myclaim Bound pv01 5Gi RWO 3s [root@master k8s]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv01 5Gi RWO Retain Bound default/myclaim 5m
我们可以看到,pv和pvc的状态现在都变成了Bound,那么现在pv和pvc的定义就完成了
pv和pvc的绑定关系
如果你感兴趣的话,不妨尝试一下多创建几个pv,然后再去创建pvc,你会发现,只要资源能够匹配的上的话,他是随机给你分配pv的,或者说,现在只剩下一个pv是可用的,有2个用户都请求了这个pv,那么这个pv会分配给谁呢?答案是谁手速快那就分配给谁,你的请求先到达k8s集群,那么这个pv就是你的,如果我们想自己手动指定pv呢,可以做到吗?当然是可以的,我们只需要在pv的yaml文件里面加上storageClassName: 就可以了
手动指定pv与pvc绑定
# 将之前的pv的yaml文件复制过来,改动一行内容 apiVersion: v1 kind: PersistentVolume metadata: name: pv02 spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteOnce # 加上这一行内容,给他一个test名字,那么pvc在请求的时候必须带上这个参数,否则不会绑定 storageClassName: test nfs: path: /nfs server: 192.168.200.200
尝试一下pvc里面不带这个参数是否能绑定
[root@master k8s]# kubectl apply -f pv2.yaml persistentvolume/pv02 created [root@master k8s]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv02 5Gi RWO Retain Available test 11 # pvc的yaml文件还是之前那个,不做修改 [root@master k8s]# kubectl apply -f pvc.yaml persistentvolumeclaim/myclaim created [root@master k8s]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv02 5Gi RWO Retain Available test 41s [root@master k8s]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myclaim Pending 11s
我们可以看到,pv的状态依旧是可用,pvc的状态是pending,说明他们确实没有绑定上,现在我们将pvc里面也加上这一行参数
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: myclaim2 spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 5Gi storageClassName: test
使用这个yaml文件创建一个pvc看看效果
[root@master k8s]# kubectl apply -f pvc2.yaml persistentvolumeclaim/myclaim2 created [root@master k8s]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE myclaim2 Bound pv02 5Gi RWO test 6s [root@master k8s]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv02 5Gi RWO Retain Bound default/myclaim2 test 20s
我们发现他绑定上了,说明这个参数生效了,也就是说加上这个参数之后,光匹配模式和大小是不行的,还必须把这个存储类的名字也匹配上才行
pod使用pvc
pod挂载pvc
目前,pv和pvc的定义都已经说过了,但是好像没有涉及到pod,那么pod是如何去使用这个pv存储的呢?我们直接来看yaml文件,很容易理解
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: volume1 name: volume1 spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: volume1 resources: {} volumeMounts: - name: myvolume mountPath: /usr/share/nginx/html volumes: # 这里的名字是你给这个卷起的名字,可以随意,但是得和pod挂载的卷名一致 - name: myvolume # 在这里使用pvc,指定pvc的名字 persistentVolumeClaim: # 这里的名字必须要写你的pvc的名字 claimName: myclaim2 dnsPolicy: ClusterFirst restartPolicy: Always status: {}
看看效果
[root@master k8s]# kubectl apply -f pod_pvc.yaml pod/volume1 created [root@master k8s]# kubectl get pods NAME READY STATUS RESTARTS AGE volume1 1/1 Running 0 3s # 进入容器查看挂载点 [root@master k8s]# kubectl exec -it pods/volume1 -- /bin/bash root@volume1:/# df -hT Filesystem Type Size Used Avail Use% Mounted on overlay overlay 46G 14G 32G 31% / tmpfs tmpfs 64M 0 64M 0% /dev tmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup /dev/mapper/cs-root xfs 46G 14G 32G 31% /etc/hosts shm tmpfs 64M 0 64M 0% /dev/shm 192.168.200.200:/nfs nfs4 46G 15G 31G 32% /usr/share/nginx/html tmpfs tmpfs 3.8G 12K 3.8G 1% /run/secrets/kubernetes.io/serviceaccount tmpfs tmpfs 1.9G 0 1.9G 0% /proc/acpi tmpfs tmpfs 1.9G 0 1.9G 0% /proc/scsi tmpfs tmpfs 1.9G 0 1.9G 0% /sys/firmware
我们现在发现pod已经挂载了nfs了,我们再来创建一个pod
访问模式的区别
访问模式一共有4种,分别是
- ReadWriteOnce
卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。
- ReadOnlyMany
卷可以被多个节点以只读方式挂载。
- ReadWriteMany
卷可以被多个节点以读写方式挂载。
- ReadWriteOncePod
卷可以被单个 Pod 以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用 ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。
本文来自博客园,作者:FuShudi,转载请注明原文链接:https://www.cnblogs.com/fsdstudy/p/17958410
分类: CKA