前提

需要验证的类型CSI NFS, LOCAL, HostPath

  1. 准备nfs服务器——-master节点做nfs服务器
  2. 准备csi驱动———-参考confluence
  3. LOCAL, HostPath是k8s支持的pv类型。———-自己配置即可
  4. 访问模式(accessModes)
    用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:

image.png

  1. 支持的存储

image.png

  1. 想做的事:重点关注 节点亲和性 和 访问模式 的属性,关注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

  1. <a name="FUGqC"></a>
  2. ### 2. 创建pv.yaml
  3. 1. pv1设置accessModes是ReadWriteOnce
  4. 2. pv2正常
  5. 3. pv3设置节点亲和性为node1
  6. ```yaml
  7. apiVersion: v1
  8. kind: PersistentVolume
  9. metadata:
  10. name: nfs-pv1
  11. spec:
  12. capacity:
  13. storage: 1Gi
  14. accessModes:
  15. - ReadWriteOnce
  16. persistentVolumeReclaimPolicy: Retain
  17. nfs:
  18. path: /root/data/pv1
  19. server: 10.2.238.171
  20. ---
  21. apiVersion: v1
  22. kind: PersistentVolume
  23. metadata:
  24. name: nfs-pv2
  25. spec:
  26. capacity:
  27. storage: 2Gi
  28. accessModes:
  29. - ReadWriteMany
  30. persistentVolumeReclaimPolicy: Retain
  31. nfs:
  32. path: /root/data/pv2
  33. server: 10.2.238.171
  34. ---
  35. apiVersion: v1
  36. kind: PersistentVolume
  37. metadata:
  38. name: nfs-pv3
  39. spec:
  40. capacity:
  41. storage: 3Gi
  42. accessModes:
  43. - ReadWriteMany
  44. persistentVolumeReclaimPolicy: Retain
  45. nfs:
  46. path: /root/data/pv3
  47. server: 10.2.238.171
  48. nodeAffinity:
  49. required:
  50. nodeSelectorTerms:
  51. - matchExpressions:
  52. - key: kubernetes.io/hostname
  53. operator: In
  54. values:
  55. - k8s-node1

3. 创建pvc.yaml

  1. pvc1设置accessModes是ReadWriteOnce
  2. pvc2正常
  3. 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:

  • ReadWriteMany resources: requests: storage: 1Gi ```

    4. 创建pod.yaml

  1. pod1 echo pv and pvc accessModes ReadWriteOnce
  2. pvc2正常
  3. 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

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:
    • name: volume mountPath: /root/ volumes:
    • name: volume persistentVolumeClaim: claimName: nfs-pvc3 readOnly: false ```

      5. 操作

      ```powershell

      创建 pv

      [root@k8s-master01 ~]# kubectl create -f pv-nfs.yaml persistentvolume/pv1 created persistentvolume/pv2 created persistentvolume/pv3 created

查看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

  1. <a name="t2kMn"></a>
  2. ### 6. 总结
  3. 1. 首先nfs支持的访问模式是三种:
  4. 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/ )
  5. > Kubernetes 使用卷访问模式来匹配 PersistentVolumeClaim 和 PersistentVolume。 在某些场合下,卷访问模式也会限制 PersistentVolume 可以挂载的位置。 卷访问模式并不会在存储已经被挂载的情况下为其实施写保护。 即使访问模式设置为 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany,它们也不会对卷形成限制。 例如,即使某个卷创建时设置为 ReadOnlyMany,也无法保证该卷是只读的。 如果访问模式设置为 ReadWriteOncePod,则卷会被限制起来并且只能挂载到一个 Pod 上。
  6. 如果要设置只读,可以在pod的readOnly: true
  7. 2. 如何实现节点亲和性:
  8. pv设置节点亲和性属性,当pv亲和某个节点时,pod就会被调度到该节点上。
  9. ---
  10. <a name="LzveY"></a>
  11. ### 7. 问题
  12. 1. 检验一下ReadWriteOnce这个属性,如果pv和pvc都是这种访问模式,同一个节点上不同pod访问卷,不同节点的pod访问卷?
  13. ~~没有这个问题了~~
  14. 3. 如果pv和pvc访问模式不一样,互相还能绑定到一起吗?不能
  15. 4. 如果pv亲和性是node1节点,pod节点选择器是node2节点,会发生什么?
  16. 也就是说如果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)
  17. <a name="t8kIX"></a>
  18. ## 二、 验证hostpath
  19. <a name="GBvCn"></a>
  20. ### 1. 创建pv.yaml
  21. ```yaml
  22. apiVersion: v1
  23. kind: PersistentVolume
  24. metadata:
  25. name: pv-hostpath
  26. labels:
  27. type: local
  28. spec:
  29. storageClassName: manual
  30. capacity:
  31. storage: 10Gi
  32. accessModes:
  33. - ReadWriteOnce
  34. hostPath:
  35. path: "/data/k8s/test/hostpath"
  36. nodeAffinity:
  37. required:
  38. nodeSelectorTerms:
  39. - matchExpressions:
  40. - key: kubernetes.io/hostname
  41. operator: In
  42. values:
  43. - k8s-node2

2. 创建pvc.yaml

  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4. name: pvc-hostpath
  5. spec:
  6. storageClassName: manual
  7. accessModes:
  8. - ReadWriteOnce
  9. resources:
  10. requests:
  11. storage: 3Gi

3. 创建pod.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: pv-hostpath-pod
  5. spec:
  6. volumes:
  7. - name: pv-hostpath
  8. persistentVolumeClaim:
  9. claimName: pvc-hostpath
  10. nodeSelector:
  11. kubernetes.io/hostname: k8snode1
  12. containers:
  13. - name: task-pv-container
  14. image: nginx
  15. ports:
  16. - containerPort: 80
  17. volumeMounts:
  18. - mountPath: "/usr/share/nginx/html"
  19. name: pv-hostpath

2.. 操作

  1. #在固定的节点执行
  2. #hostpath,pod不会节点漂移,固定一个节点
  3. $ echo 'Hello from Kubernetes hostpath storage' > /data/k8s/test/hostpath/index.html
  4. $ kubectl apply -f pv-hostpath.yaml
  5. persistentvolume/pv-hostpath created
  6. $ kubectl get pv pv-hostpath
  7. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  8. pv-hostpath 10Gi RWO Retain Available manual 58s
  9. $ kubectl create -f pvc-hostpath.yaml
  10. persistentvolumeclaim/pvc-hostpath created
  11. $ kubectl get pv -l type=local
  12. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  13. pv-hostpath 10Gi RWO Retain Bound default/pvc-hostpath manual 81m
  14. $ kubectl get pvc pvc-hostpath
  15. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  16. pvc-hostpath Bound pv-hostpath 10Gi RWO manual 6m47s
  17. $ kubectl create -f pv-hostpath-pod.yaml
  18. pod/pv-hostpath-pod created
  19. $ kubectl get pod pv-hostpath-pod
  20. NAME READY STATUS RESTARTS AGE
  21. pv-hostpath-pod 1/1 Running 0 105s
  22. $ kubectl describe pod pv-hostpath-pod
  23. $ kubectl exec -it pv-hostpath-pod -- /bin/bash
  24. root@pv-hostpath-pod:/# apt-get update
  25. root@pv-hostpath-pod:/# apt-get install curl -y
  26. root@pv-hostpath-pod:/# curl localhost
  27. Hello from Kubernetes hostpath storage
  28. #同样我们可以把 Pod 删除,然后再次重建再测试一次,
  29. #可以发现内容还是我们在 hostPath 种设置的内容。
  30. #重新创建这个 Pod 的话,之前创建的测试文件,依然被保存在这个持久化 Volume 当中
  31. $ kubectl delete -f pv-hostpath-pod.yaml
  32. $ kubectl apply -f pv-hostpath-pod.yaml
  33. $ kubectl exec -it pv-hostpath-pod /bin/sh
  34. # ls /usr/share/nginx/html
  35. index.html
  36. # cat /usr/share/nginx/html/index.html
  37. Hello from Kubernetes local pv storage
  38. #

4. 总结

  1. hostpath支持的访问模式只有ReadWriteOnce,就是单节点的可读可写
  2. hostpath如何实现节点亲和性,

    hostPath是单节点的本地存储卷方案,不提供任何基于node节点亲和性的pod调度管理支持;

所以亲和性必须要配置,不然pod可能会漂移
可以配置pv的节点亲和性或者配置pod的节点选择器,如果都要配他们不能有冲突,只配其中一项也可以。
pv节点亲和性验证文档 - 图3

5. 问题

  1. 尝试给hostpath的pv配节点亲和性

在node1节点上才有该挂载目录,当设置pod选择器是node1时,pod在node1上running,pod数据也正常
在node1节点上才有该挂载目录,当设置pv节点亲和性是node1时,pod在node1上running,pod数据也正常
在node1节点上才有该挂载目录,当设置pv节点亲和性是node2时,pod在node2上running,node2节点无挂载目录,无数据
pv节点亲和性验证文档 - 图4

hostPath是单节点的本地存储卷方案,不提供任何基于node节点亲和性的pod调度管理支持;

所以需要自己配,实验来看配置pv的亲和性或者配置pod节点选择器效果是一样的。

  1. 尝试和pod产生冲突 ——-匹配不到

image.png
image.png

  1. 传统的hostpath是在单节点上的存储,pod要绑定节点选择器,如果pod不绑定,他有可能漂移,那是不是访问不到?

确实

  1. 如果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没有区别

  1. <a name="b3wq1"></a>
  2. ## 三、 验证local
  3. <a name="o8vhI"></a>
  4. ### 1. 创建pv.yaml
  5. ```yaml
  6. apiVersion: v1
  7. kind: PersistentVolume
  8. metadata:
  9. name: pv-local
  10. spec:
  11. capacity:
  12. storage: 5Gi
  13. volumeMode: Filesystem
  14. accessModes:
  15. - ReadWriteOnce
  16. persistentVolumeReclaimPolicy: Delete
  17. storageClassName: local-storage
  18. local:
  19. path: /data/k8s/localpv # k8snode2节点上的目录
  20. nodeAffinity:
  21. required:
  22. nodeSelectorTerms:
  23. - matchExpressions:
  24. - key: kubernetes.io/hostname
  25. operator: In
  26. values:
  27. - k8s-node2

2. 创建pvc.yaml

  1. kind: PersistentVolumeClaim
  2. apiVersion: v1
  3. metadata:
  4. name: pvc-local
  5. spec:
  6. accessModes:
  7. - ReadWriteOnce
  8. resources:
  9. requests:
  10. storage: 5Gi
  11. storageClassName: local-storage

3. 创建StorageClass对象

  1. apiVersion: storage.k8s.io/v1
  2. kind: StorageClass
  3. metadata:
  4. name: local-storage
  5. provisioner: kubernetes.io/no-provisioner
  6. volumeBindingMode: WaitForFirstConsumer

4. 创建pod.yaml

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: pv-local-pod
  5. spec:
  6. volumes:
  7. - name: example-pv-local
  8. persistentVolumeClaim:
  9. claimName: pvc-local
  10. nodeSelector:
  11. kubernetes.io/hostname: k8s-node1
  12. containers:
  13. - name: example-pv-local
  14. image: nginx
  15. ports:
  16. - containerPort: 80
  17. volumeMounts:
  18. - mountPath: /usr/share/nginx/html
  19. name: example-pv-local

5. 操作

  1. $ kubectl apply -f pv-local.yaml
  2. persistentvolume/pv-local created
  3. $ kubectl get pv
  4. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  5. pv-local 5Gi RWO Delete Available local-storage 24s
  6. $ kubectl apply -f pvc-local.yaml
  7. persistentvolumeclaim/pvc-local created
  8. $ kubectl get pvc
  9. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  10. pvc-local Bound pv-local 5Gi RWO local-storage 38s
  11. #创建这个 StorageClass 资源对象
  12. $ kubectl apply -f local-storageclass.yaml
  13. storageclass.storage.k8s.io/local-storage created
  14. #重新删除上面声明的 PVC 对象,重新创建
  15. $ kubectl delete -f pvc-local.yaml
  16. persistentvolumeclaim "pvc-local" deleted
  17. $ kubectl create -f pvc-local.yaml
  18. persistentvolumeclaim/pvc-local created
  19. $ kubectl get pvc
  20. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  21. pvc-local Pending local-storage 3s
  22. 我们可以发现这个时候,集群中即使已经存在了一个可以与 PVC 匹配的 PV 了,
  23. 但这个 PVC 依然处于 Pending 状态,也就是等待绑定的状态,
  24. 这就是因为上面我们配置的是延迟绑定,需要在真正的 Pod 使用的时候才会来做绑定。
  25. #直接创建这个 Pod
  26. $ kubectl apply -f pv-local-pod.yaml
  27. pod/pv-local-pod created
  28. $ kubectl describe pod pv-local-pod
  29. # PVC,会立刻变成 Bound 状态
  30. $ kubectl get pvc
  31. NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  32. pvc-local Bound pv-local 5Gi RWO local-storage 4m59s
  33. #在这个 Pod 的 Volume 目录里,创建一个测试文件
  34. $ kubectl exec -it pv-local-pod /bin/sh
  35. # cd /usr/share/nginx/html
  36. # echo "Hello from Kubernetes csi hoatpath" > hello.txt
  37. #
  38. # 在k8snode2节点上
  39. $ ls /data/k8s/localpv
  40. test.txt
  41. $ cat /data/k8s/localpv/test.txt
  42. Hello from Kubernetes local pv storage
  43. #重新创建这个 Pod 的话,之前创建的测试文件,依然被保存在这个持久化 Volume 当中
  44. $ kubectl delete -f pv-local-pod.yaml
  45. $ kubectl apply -f pv-local-pod.yaml
  46. $ kubectl exec -it pv-local-pod /bin/sh
  47. # ls /usr/share/nginx/html
  48. test.txt
  49. # cat /usr/share/nginx/html/test.txt
  50. Hello from Kubernetes local pv storage
  51. #
  52. # 删除pv
  53. 需要注意的是,我们上面手动创建 PV 的方式,即静态的 PV 管理方式,
  54. 在删除 PV 时需要按如下流程执行操作:
  55. 删除使用这个 PV Pod
  56. 从宿主机移除本地磁盘
  57. 删除 PVC
  58. 删除 PV
  59. 如果不按照这个流程的话,这个 PV 的删除就会失败。

6. 总结

  1. local pv支持的访问模式,表里没有明显体现,除了ReadWriteOnce,看下其他行不行, ReadWriteOnce(单节点可读可写)、ReadOnlyMany(只读)、ReadWriteMany(RWX可读可写),ReadWriteManyPod(单pod)

ReadWriteOnce:支持,可读可写,pod就在存储所在节点
ReadWriteMany :支持,可读可写
ReadOnlyMany:支持,可读可写
ReadWriteManyPod:不支持
image.png
但这个属性看起来并不能对pod调度产生影响。而且ReadOnlyMany也可以写。
如果想只支持读,应该设置的是pod的ReadOnly为true,这样就不支持写了
image.png

  1. 如何实现节点亲和性

普通的pv是先调度pod,再持久化节点上的volume目录,local pv是调度器要知道节点和local pv对应的磁盘的关联关系,然后根据这个信息来调度 Pod,调度的时候考虑 Volume 的分布。
简单理解一下,local pv就是让pv亲和到有存储的节点,调度pod会考虑这个亲和性。

7. 问题

  1. 如果pv的节点亲和性和 pod节点亲和性或者pod选择器 有冲突会发生什么?

发生就是匹配不上,pod是Pending
image.png

  1. local的访问模式除了ReadWriteOnce,其他行不行?

可以支持:ReadWriteOnce、ReadWriteMany 、ReadOnlyMany

  1. 待续。。。

    四、验证csi

    1. 准备csi驱动

    参考confluence,confluence地址:https://confluence.aishu.cn/pages/viewpage.action?pageId=90547646

    2. 创建pv.yaml

    3. 创建pvc.yaml

    4. 创建pod.yaml

    5. 操作

    简单理解一下

  2. 准备ceph环境,集群要安装这个snapshot CRD,安装snapshot Collector,安装ceph-csi驱动,总之就是有存储,然后能满足打快照。

  3. ceph要和k8s整合,创建configMap保存信息,secret是认证。
  4. 假装用户有用户的namespace,创建用户的pvc,工作负载,并使其产生数据。
  5. 假如要对其备份,要对用户的pvc打快照,打完快照能看见VolumesnapshotContent的snapshotHandle,用这个snapshotHandle复制一份VolumesnapshotContent,根据VolumesnapshotContent创建Volumesnapshot,根据快照卷创建pvc,这样就算实现了对pvc的备份。
  6. 再把备份出来的这个pvc根据他创建工作负载,他就有pod,镜像容器用abclient,这样abclient就有访问这个pvc的存储的权力了。
  7. 再对这个存储备份。

操作一下———
补充:卡在使用abclient的镜像创建deployment,挂卷挂不上
image.png

6. 问题

  1. 关心访问模式吗?

不,用户创建pvc的时候只能是RWO,ReadWriteMany报错

  1. 关心pv节点亲和性吗?

实际上不关心,中间用的是快照转换了一下,有了一个一毛一样的pvc。

  1. 那关心什么?

待续。。。

五、总结

  1. 关于nfs:

给没有属性的pv绑定pvc,然后让不同的pod挂载,pod会被调度到不同的节点,能对挂载目录做读取和修改
给设置了访问模式为RWO的pv绑定pvc,然后让不同的pod挂载,pod也会被调度到不同的节点,能对挂载目录做读取和修改。因此访问模式不限制pod调度和访问。
给设置了节点亲和性的pv绑定pvc,然后让不同的pod挂载,pod会被调度到pv亲和的节点上执行,能对挂载目录做读取和修改。
综上,nfs即便不设置节点亲和性,存储也是共享的。访问模式也并没有对pod的调度和读写权限产生实际影响。

  1. 关于hostpath

给pv设置的存储类型为hostpath时,它是单节点存储,访问模式只支持RWO,所以必须对pod调度做设置,不然可能节点漂移,访问不到存储。
给设置了节点亲和性的pv绑定pvc,然后让不同的pod挂载,pod会被调度到pv亲和的节点上执行,能对挂载目录做读取和修改。(或者给pod设置节点选择器)
给hostpath挂载的目录时nfs目录时,虽然节点存储共享,但可能不知道底层是nfs,所以还是设置相关属性比较合理。
综上,hostpath也可以设置节点亲和性。从结果看和设置pod节点选择器一样,都能对调度产生影响。

  1. 关于local

local 也是必须设置节点亲和性,k8s scheduler需要使用PV的nodeAffinity描述信息保证pod能够调度到有对应local volume的Node上。它的调度与其他不同在于它要知道节点和local pv对应的磁盘的关联关系,然后根据这个信息来调度 Pod,所以要对StorageClass设置WaitForFirstConsumer,创建完pod之后,pv和pvc再实现绑定。
综上,local必须设置节点亲和性。

  1. 关于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创建pvimage.png
查看pv的yaml,pv也设置了节点亲和性,所以创建了2个pod都在master节点上
image.png
如果设置pod节点选择器是node1,那pod是pending,无法匹配
image.png
image.png
所以pv已经设置了这个属性,pod调度会被自动调度到该节点上,不需要做额外设置.