- 前提
- 操作
- 创建目录
- 暴露服务
- 重启服务
- 创建 pv
- 查看pv
- 创建pvc
- 查看pvc
- 查看pv,已处于绑定状态
- 创建pod
- 查看pod
- 查看pvc
- 查看pv
- 查看nfs中的文件存储
- 同样我们可以把 Pod 删除,然后再次重建再测试一次,
- 可以发现内容还是我们在 hostPath 种设置的内容。
- 重新创建这个 Pod 的话,之前创建的测试文件,依然被保存在这个持久化 Volume 当中
- ls /root/
- cat /root/out.txt
- 创建目录
- 暴露服务
- 重启服务
- 把hostpath共享目录加到nfs服务器上
- 挂载该目录到node节点上
- pod漂移的时候存储也能共享
- 如果底层是nfs的存储,设置pv的节点亲和性,对pod的调度与普通hostpath没有区别
- 四、验证csi
- 五、总结
- hostpath的csi驱动验证
前提
需要验证的类型CSI NFS, LOCAL, HostPath
- 准备nfs服务器——-master节点做nfs服务器
- 准备csi驱动———-参考confluence
- LOCAL, HostPath是k8s支持的pv类型。———-自己配置即可
- 访问模式(accessModes)
用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
- 支持的存储
- 想做的事:重点关注 节点亲和性 和 访问模式 的属性,关注pod的调度
操作
一、 验证nfs
1. 准备nfs服务器
```powershell创建目录
[root@nfs ~]# mkdir /root/data/{pv1,pv2,pv3} -pv
暴露服务
[root@nfs ~]# more /etc/exports /root/data/pv1 (rw,no_root_squash) /root/data/pv2 (rw,no_root_squash) /root/data/pv3 *(rw,no_root_squash)
重启服务
[root@nfs ~]# systemctl restart nfs
[root@nfs ~]# showmount -e
<a name="FUGqC"></a>
### 2. 创建pv.yaml
1. pv1设置accessModes是ReadWriteOnce
2. pv2正常
3. pv3设置节点亲和性为node1
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
nfs:
path: /root/data/pv1
server: 10.2.238.171
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv2
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /root/data/pv2
server: 10.2.238.171
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv3
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /root/data/pv3
server: 10.2.238.171
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node1
3. 创建pvc.yaml
- pvc1设置accessModes是ReadWriteOnce
- pvc2正常
- pvc3正常
```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc1
namespace: dev
spec:
accessModes:
- ReadWriteOnce resources: requests: storage: 1Gi
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc2 namespace: dev spec: accessModes:
- ReadWriteMany resources: requests: storage: 1Gi
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc4 namespace: dev spec: accessModes:
- pod1 echo pv and pvc accessModes ReadWriteOnce
- pvc2正常
- pvc3正常
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod1
namespace: dev
spec:
containers:
- name: busybox
image: busybox:1.30
command: [“/bin/sh”,”-c”,”while true;do echo pv and pvc accessModes ReadWriteOnce >> /root/out.txt; sleep 10; done;”]
volumeMounts:
- name: volume mountPath: /root/ volumes:
- name: volume persistentVolumeClaim: claimName: nfs-pvc1 readOnly: false
- name: busybox
image: busybox:1.30
command: [“/bin/sh”,”-c”,”while true;do echo pv and pvc accessModes ReadWriteOnce >> /root/out.txt; sleep 10; done;”]
volumeMounts:
apiVersion: v1 kind: Pod metadata: name: nfs-pod2 namespace: dev spec: containers:
- name: busybox
image: busybox:1.30
command: [“/bin/sh”,”-c”,”while true;Hello from Kubernetes nfs pv >> /root/out.txt; sleep 10; done;”]
volumeMounts:
- name: volume mountPath: /root/ volumes:
- name: volume persistentVolumeClaim: claimName: nfs-pvc2 readOnly: false
apiVersion: v1 kind: Pod metadata: name: nfs-pod3 namespace: dev spec: nodeSelector: kubernetes.io/hostname: k8s-node1 containers:
- name: busybox image: busybox:1.30 command: [“/bin/sh”,”-c”,”while true;nfs pv nodeAffinity is node1 >> /root/out.txt; sleep 10; done;”] volumeMounts:
查看pv
[root@k8s-master01 ~]# kubectl get pv -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS AGE VOLUMEMODE pv1 1Gi RWX Retain Available 10s Filesystem pv2 2Gi RWX Retain Available 10s Filesystem pv3 3Gi RWX Retain Available 9s Filesystem
kubectl create ns dev
创建pvc
[root@k8s-master01 ~]# kubectl create -f pvc-nfs.yaml persistentvolumeclaim/pvc1 created persistentvolumeclaim/pvc2 created persistentvolumeclaim/pvc3 created
查看pvc
[root@k8s-master01 ~]# kubectl get pvc -n dev -o wide NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE pvc1 Bound pv1 1Gi RWX 15s Filesystem pvc2 Bound pv2 2Gi RWX 15s Filesystem pvc3 Bound pv3 3Gi RWX 15s Filesystem
查看pv,已处于绑定状态
[root@k8s-master01 ~]# kubectl get pv -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM AGE VOLUMEMODE pv1 1Gi RWx Retain Bound dev/pvc1 3h37m Filesystem pv2 2Gi RWX Retain Bound dev/pvc2 3h37m Filesystem pv3 3Gi RWX Retain Bound dev/pvc3 3h37m Filesystem
创建pod
[root@k8s-master01 ~]# kubectl create -f pod-nfs.yaml pod/pod1 created pod/pod2 created
查看pod
[root@k8s-master01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod1 1/1 Running 0 14s 10.244.1.69 node1
pod2 1/1 Running 0 14s 10.244.1.70 node1
kubectl describe pod nfs-pod1 -n dev
查看pvc
[root@k8s-master01 ~]# kubectl get pvc -n dev -o wide NAME STATUS VOLUME CAPACITY ACCESS MODES AGE VOLUMEMODE pvc1 Bound pv1 1Gi RWX 94m Filesystem pvc2 Bound pv2 2Gi RWX 94m Filesystem pvc3 Bound pv3 3Gi RWX 94m Filesystem
查看pv
[root@k8s-master01 ~]# kubectl get pv -n dev -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM AGE VOLUMEMODE pv1 1Gi RWX Retain Bound dev/pvc1 5h11m Filesystem pv2 2Gi RWX Retain Bound dev/pvc2 5h11m Filesystem pv3 3Gi RWX Retain Bound dev/pvc3 5h11m Filesystem
查看nfs中的文件存储
[root@nfs ~]# more /root/data/pv1/out.txt node1 node1 [root@nfs ~]# more /root/data/pv2/out.txt node2 node2
同样我们可以把 Pod 删除,然后再次重建再测试一次,
可以发现内容还是我们在 hostPath 种设置的内容。
重新创建这个 Pod 的话,之前创建的测试文件,依然被保存在这个持久化 Volume 当中
$ kubectl delete -f pods.yaml
$ kubectl apply -f pods.yaml
$ kubectl exec -it nfs-pod1 /bin/sh -n dev
ls /root/
test.txt
cat /root/out.txt
Hello from Kubernetes local pv storage
<a name="t2kMn"></a>
### 6. 总结
1. 首先nfs支持的访问模式是三种:
ReadWriteOnce(单节点可读可写)、ReadOnlyMany(只读)、ReadWriteMany(RWX可读可写)<br /> 首先如果pv和pvc都是RWO,找到不同pod配置上该pvc,不同pod并不在同一节点。对节点调度的影响没有发现。<br /> 其次尝试从不同节点的pod往pv挂载的nfs目录里写数据,也都可以写进去。<br /> 。。。。这个属性究竟是什么影响,还需要继续验证。<br />------------这个属性理论上没有影响,它不做强制限制<br />[https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/ ](https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/ )
> Kubernetes 使用卷访问模式来匹配 PersistentVolumeClaim 和 PersistentVolume。 在某些场合下,卷访问模式也会限制 PersistentVolume 可以挂载的位置。 卷访问模式并不会在存储已经被挂载的情况下为其实施写保护。 即使访问模式设置为 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany,它们也不会对卷形成限制。 例如,即使某个卷创建时设置为 ReadOnlyMany,也无法保证该卷是只读的。 如果访问模式设置为 ReadWriteOncePod,则卷会被限制起来并且只能挂载到一个 Pod 上。
如果要设置只读,可以在pod的readOnly: true
2. 如何实现节点亲和性:
pv设置节点亲和性属性,当pv亲和某个节点时,pod就会被调度到该节点上。
---
<a name="LzveY"></a>
### 7. 问题
1. 检验一下ReadWriteOnce这个属性,如果pv和pvc都是这种访问模式,同一个节点上不同pod访问卷,不同节点的pod访问卷?
~~没有这个问题了~~
3. 如果pv和pvc访问模式不一样,互相还能绑定到一起吗?不能
4. 如果pv亲和性是node1节点,pod节点选择器是node2节点,会发生什么?
也就是说如果pv对pod的调度的设置和pod自己的调度冲突,会发生什么?<br />会挂不上<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2639475/1655690450245-b6d8a56a-14b4-4b16-bf28-cbf51ee702c3.png#clientId=u6dba93a4-51c6-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=235&id=udcd3bbcf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=235&originWidth=977&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29892&status=done&style=none&taskId=u77b375f1-2c41-4066-a980-734263f0836&title=&width=977)<br />报错原因是无法匹配<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/2639475/1655690402923-1a3987d8-fc0c-4117-ac1c-907853a1b32f.png#clientId=u6dba93a4-51c6-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=66&id=u0c70840a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=66&originWidth=1256&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6255&status=done&style=none&taskId=u26bfa0de-efb3-40b7-8a17-837bbafbd20&title=&width=1256)
<a name="t8kIX"></a>
## 二、 验证hostpath
<a name="GBvCn"></a>
### 1. 创建pv.yaml
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-hostpath
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/data/k8s/test/hostpath"
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node2
2. 创建pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-hostpath
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
3. 创建pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pv-hostpath-pod
spec:
volumes:
- name: pv-hostpath
persistentVolumeClaim:
claimName: pvc-hostpath
nodeSelector:
kubernetes.io/hostname: k8snode1
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-hostpath
2.. 操作
#在固定的节点执行
#hostpath,pod不会节点漂移,固定一个节点
$ echo 'Hello from Kubernetes hostpath storage' > /data/k8s/test/hostpath/index.html
$ kubectl apply -f pv-hostpath.yaml
persistentvolume/pv-hostpath created
$ kubectl get pv pv-hostpath
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-hostpath 10Gi RWO Retain Available manual 58s
$ kubectl create -f pvc-hostpath.yaml
persistentvolumeclaim/pvc-hostpath created
$ kubectl get pv -l type=local
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-hostpath 10Gi RWO Retain Bound default/pvc-hostpath manual 81m
$ kubectl get pvc pvc-hostpath
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-hostpath Bound pv-hostpath 10Gi RWO manual 6m47s
$ kubectl create -f pv-hostpath-pod.yaml
pod/pv-hostpath-pod created
$ kubectl get pod pv-hostpath-pod
NAME READY STATUS RESTARTS AGE
pv-hostpath-pod 1/1 Running 0 105s
$ kubectl describe pod pv-hostpath-pod
$ kubectl exec -it pv-hostpath-pod -- /bin/bash
root@pv-hostpath-pod:/# apt-get update
root@pv-hostpath-pod:/# apt-get install curl -y
root@pv-hostpath-pod:/# curl localhost
Hello from Kubernetes hostpath storage
#同样我们可以把 Pod 删除,然后再次重建再测试一次,
#可以发现内容还是我们在 hostPath 种设置的内容。
#重新创建这个 Pod 的话,之前创建的测试文件,依然被保存在这个持久化 Volume 当中
$ kubectl delete -f pv-hostpath-pod.yaml
$ kubectl apply -f pv-hostpath-pod.yaml
$ kubectl exec -it pv-hostpath-pod /bin/sh
# ls /usr/share/nginx/html
index.html
# cat /usr/share/nginx/html/index.html
Hello from Kubernetes local pv storage
#
4. 总结
- hostpath支持的访问模式只有ReadWriteOnce,就是单节点的可读可写
- hostpath如何实现节点亲和性,
hostPath是单节点的本地存储卷方案,不提供任何基于node节点亲和性的pod调度管理支持;
所以亲和性必须要配置,不然pod可能会漂移
可以配置pv的节点亲和性或者配置pod的节点选择器,如果都要配他们不能有冲突,只配其中一项也可以。
5. 问题
- 尝试给hostpath的pv配节点亲和性
在node1节点上才有该挂载目录,当设置pod选择器是node1时,pod在node1上running,pod数据也正常
在node1节点上才有该挂载目录,当设置pv节点亲和性是node1时,pod在node1上running,pod数据也正常
在node1节点上才有该挂载目录,当设置pv节点亲和性是node2时,pod在node2上running,node2节点无挂载目录,无数据
hostPath是单节点的本地存储卷方案,不提供任何基于node节点亲和性的pod调度管理支持;
所以需要自己配,实验来看配置pv的亲和性或者配置pod节点选择器效果是一样的。
- 尝试和pod产生冲突 ——-匹配不到
- 传统的hostpath是在单节点上的存储,pod要绑定节点选择器,如果pod不绑定,他有可能漂移,那是不是访问不到?
确实
- 如果hostpath挂的路径是nfs服务器的路径 ```go
创建目录
[root@nfs ~]# mkdir /data/k8s/test/hostpath
暴露服务
[root@nfs ~]# more /etc/exports /root/data/pv1 (rw,no_root_squash) /root/data/pv2 (rw,no_root_squash) /root/data/pv3 (rw,no_root_squash) /data/k8s/test/hostpath (rw,no_root_squash)
重启服务
[root@nfs ~]# systemctl restart nfs
[root@nfs ~]# showmount -e
把hostpath共享目录加到nfs服务器上
挂载该目录到node节点上
mount -t nfs 10.2.238.171:/data/k8s/test/hostpath /root/mount_data
pod漂移的时候存储也能共享
如果底层是nfs的存储,设置pv的节点亲和性,对pod的调度与普通hostpath没有区别
<a name="b3wq1"></a>
## 三、 验证local
<a name="o8vhI"></a>
### 1. 创建pv.yaml
```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-local
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /data/k8s/localpv # k8snode2节点上的目录
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node2
2. 创建pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-local
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: local-storage
3. 创建StorageClass对象
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
4. 创建pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pv-local-pod
spec:
volumes:
- name: example-pv-local
persistentVolumeClaim:
claimName: pvc-local
nodeSelector:
kubernetes.io/hostname: k8s-node1
containers:
- name: example-pv-local
image: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: example-pv-local
5. 操作
$ kubectl apply -f pv-local.yaml
persistentvolume/pv-local created
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-local 5Gi RWO Delete Available local-storage 24s
$ kubectl apply -f pvc-local.yaml
persistentvolumeclaim/pvc-local created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-local Bound pv-local 5Gi RWO local-storage 38s
#创建这个 StorageClass 资源对象
$ kubectl apply -f local-storageclass.yaml
storageclass.storage.k8s.io/local-storage created
#重新删除上面声明的 PVC 对象,重新创建
$ kubectl delete -f pvc-local.yaml
persistentvolumeclaim "pvc-local" deleted
$ kubectl create -f pvc-local.yaml
persistentvolumeclaim/pvc-local created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-local Pending local-storage 3s
我们可以发现这个时候,集群中即使已经存在了一个可以与 PVC 匹配的 PV 了,
但这个 PVC 依然处于 Pending 状态,也就是等待绑定的状态,
这就是因为上面我们配置的是延迟绑定,需要在真正的 Pod 使用的时候才会来做绑定。
#直接创建这个 Pod
$ kubectl apply -f pv-local-pod.yaml
pod/pv-local-pod created
$ kubectl describe pod pv-local-pod
# PVC,会立刻变成 Bound 状态
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-local Bound pv-local 5Gi RWO local-storage 4m59s
#在这个 Pod 的 Volume 目录里,创建一个测试文件
$ kubectl exec -it pv-local-pod /bin/sh
# cd /usr/share/nginx/html
# echo "Hello from Kubernetes csi hoatpath" > hello.txt
#
# 在k8snode2节点上
$ ls /data/k8s/localpv
test.txt
$ cat /data/k8s/localpv/test.txt
Hello from Kubernetes local pv storage
#重新创建这个 Pod 的话,之前创建的测试文件,依然被保存在这个持久化 Volume 当中
$ kubectl delete -f pv-local-pod.yaml
$ kubectl apply -f pv-local-pod.yaml
$ kubectl exec -it pv-local-pod /bin/sh
# ls /usr/share/nginx/html
test.txt
# cat /usr/share/nginx/html/test.txt
Hello from Kubernetes local pv storage
#
# 删除pv
需要注意的是,我们上面手动创建 PV 的方式,即静态的 PV 管理方式,
在删除 PV 时需要按如下流程执行操作:
删除使用这个 PV 的 Pod
从宿主机移除本地磁盘
删除 PVC
删除 PV
如果不按照这个流程的话,这个 PV 的删除就会失败。
6. 总结
- local pv支持的访问模式,表里没有明显体现,除了ReadWriteOnce,看下其他行不行, ReadWriteOnce(单节点可读可写)、ReadOnlyMany(只读)、ReadWriteMany(RWX可读可写),ReadWriteManyPod(单pod)
ReadWriteOnce:支持,可读可写,pod就在存储所在节点
ReadWriteMany :支持,可读可写
ReadOnlyMany:支持,可读可写
ReadWriteManyPod:不支持
但这个属性看起来并不能对pod调度产生影响。而且ReadOnlyMany也可以写。
如果想只支持读,应该设置的是pod的ReadOnly为true,这样就不支持写了
- 如何实现节点亲和性
普通的pv是先调度pod,再持久化节点上的volume目录,local pv是调度器要知道节点和local pv对应的磁盘的关联关系,然后根据这个信息来调度 Pod,调度的时候考虑 Volume 的分布。
简单理解一下,local pv就是让pv亲和到有存储的节点,调度pod会考虑这个亲和性。
7. 问题
- 如果pv的节点亲和性和 pod节点亲和性或者pod选择器 有冲突会发生什么?
发生就是匹配不上,pod是Pending
- local的访问模式除了ReadWriteOnce,其他行不行?
可以支持:ReadWriteOnce、ReadWriteMany 、ReadOnlyMany
-
四、验证csi
1. 准备csi驱动
参考confluence,confluence地址:https://confluence.aishu.cn/pages/viewpage.action?pageId=90547646
2. 创建pv.yaml3. 创建pvc.yaml
4. 创建pod.yaml
5. 操作
简单理解一下
准备ceph环境,集群要安装这个snapshot CRD,安装snapshot Collector,安装ceph-csi驱动,总之就是有存储,然后能满足打快照。
- ceph要和k8s整合,创建configMap保存信息,secret是认证。
- 假装用户有用户的namespace,创建用户的pvc,工作负载,并使其产生数据。
- 假如要对其备份,要对用户的pvc打快照,打完快照能看见VolumesnapshotContent的snapshotHandle,用这个snapshotHandle复制一份VolumesnapshotContent,根据VolumesnapshotContent创建Volumesnapshot,根据快照卷创建pvc,这样就算实现了对pvc的备份。
- 再把备份出来的这个pvc根据他创建工作负载,他就有pod,镜像容器用abclient,这样abclient就有访问这个pvc的存储的权力了。
- 再对这个存储备份。
操作一下———
补充:卡在使用abclient的镜像创建deployment,挂卷挂不上
6. 问题
- 关心访问模式吗?
不,用户创建pvc的时候只能是RWO,ReadWriteMany报错
- 关心pv节点亲和性吗?
实际上不关心,中间用的是快照转换了一下,有了一个一毛一样的pvc。
- 那关心什么?
五、总结
- 关于nfs:
给没有属性的pv绑定pvc,然后让不同的pod挂载,pod会被调度到不同的节点,能对挂载目录做读取和修改
给设置了访问模式为RWO的pv绑定pvc,然后让不同的pod挂载,pod也会被调度到不同的节点,能对挂载目录做读取和修改。因此访问模式不限制pod调度和访问。
给设置了节点亲和性的pv绑定pvc,然后让不同的pod挂载,pod会被调度到pv亲和的节点上执行,能对挂载目录做读取和修改。
综上,nfs即便不设置节点亲和性,存储也是共享的。访问模式也并没有对pod的调度和读写权限产生实际影响。
- 关于hostpath
给pv设置的存储类型为hostpath时,它是单节点存储,访问模式只支持RWO,所以必须对pod调度做设置,不然可能节点漂移,访问不到存储。
给设置了节点亲和性的pv绑定pvc,然后让不同的pod挂载,pod会被调度到pv亲和的节点上执行,能对挂载目录做读取和修改。(或者给pod设置节点选择器)
给hostpath挂载的目录时nfs目录时,虽然节点存储共享,但可能不知道底层是nfs,所以还是设置相关属性比较合理。
综上,hostpath也可以设置节点亲和性。从结果看和设置pod节点选择器一样,都能对调度产生影响。
- 关于local
local 也是必须设置节点亲和性,k8s scheduler需要使用PV的nodeAffinity描述信息保证pod能够调度到有对应local volume的Node上。它的调度与其他不同在于它要知道节点和local pv对应的磁盘的关联关系,然后根据这个信息来调度 Pod,所以要对StorageClass设置WaitForFirstConsumer,创建完pod之后,pv和pvc再实现绑定。
综上,local必须设置节点亲和性。
- 关于csi
csi是根据对用户的pvc打快照,然后再根据快照再创建pvc,创建pv是动态创建的,根据StorageClass。因此pv亲和性无需设置。
csi - 容器存储接口 (CSI)
hostPath - HostPath 卷 (仅供单节点测试使用;不适用于多节点集群; 请尝试使用 local 卷作为替代)
local - 节点上挂载的本地存储设备
nfs - 网络文件系统 (NFS) 存储
ps:支持的csi驱动
https://kubernetes-csi.github.io/docs/drivers.html
hostpath的csi驱动验证
hostpath根据StorageClass的provisioner: hostpath.csi.k8s.io创建pv
查看pv的yaml,pv也设置了节点亲和性,所以创建了2个pod都在master节点上
如果设置pod节点选择器是node1,那pod是pending,无法匹配
所以pv已经设置了这个属性,pod调度会被自动调度到该节点上,不需要做额外设置.