• Pod挂载LocalStoragePv过程理解


     1处的控制循环Control Loop应该是:VolumeManagerReconciler

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Local Persistent Volume: 利用pv&pvc这种松耦合机制来实现直接使用宿主机上的本地磁盘目录,而不依赖于远程存储服务,来提供“持久化”的容器 Volume

    设计lpv过程需要考虑的两个问题:

    1. 如何把本地磁盘抽象成 PV(一个 PV 一块盘):pv对应的目录所挂载的磁盘不应该是宿主机根目录使用的硬盘,因为一旦pv不使用独立的磁盘,将会变成完全不可控,比如磁盘很容易被其他进程应用写满,甚至造成整个宿主机宕机。而且同一个磁盘的不同的目录之间也缺乏最基础的 I/O 隔离机制.

    2.  Pod 能被正确地调度到lpv 对应节点上(延迟绑定):常规的pv记录的是与节点无关的远程共享存储,而lpv则与某些节点关联在一起.

    考虑这样的场景:

    假设我的集群中有3个节点,分别是node1、node2、node3,其中node1和node2具有diskType=ssd的标签,且node1和node2已经使用独立的磁盘挂载到/mnt/disks/volA目录,node3使用独立的磁盘挂载到/mnt/disks/volB目录

    假设我的集群已经创建好了两个pv,分别是pvA和pvB

    pvA.yaml如下。字段nodeAffinity表明想要使用这个pv的pod只能被调度到带diskType=ssd标签的节点上,也就是node1、node2

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: example-pvA
    spec:
      capacity:
        storage: 1Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      local: #local字段表明这是一个Local Persistent Volume的pv
        path: /mnt/disks/volA
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: diskType
              operator: In
              values:
              - ssd
    

     pvB.yaml如下。字段nodeAffinity表明想要使用这个pv的pod只能被调度到带node3

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: example-pvB
    spec:
      capacity:
        storage: 1Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      local: local字段表明这是一个Local Persistent Volume的pv
        path: /mnt/disks/volB
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - node3
    

    pvc.yaml文件如下

    kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: example-local-claim
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: local-storage
    

    创建一个pod声明使用example-local-claim这个pvc,如果按照常规pv的处理模式来说,当pvc一旦创建,就会被volumeController的PersistentVolumeController控制循环检测到,并尝试寻找合适的pv进行绑定。Kubernetes将先调度 Pod 到某个节点上,然后,根据pv上定义的信息,通过“两阶段处理”来“持久化”这台机器上的 Volume 目录,进而完成 Volume 目录与容器的绑定挂载(将一个目录挂载到挂载点目录,而不是将一个设备挂载到挂载点目录)。在lpv上就不能通过这种方式处理了,因为如果pvc一经创建就选择一个pv绑定,在上面的例子中,如果pvc和pvB绑定,那么使用这个pvc的pod也就被限制在node3节点,如果pod这边又通过NodeAffinity节点亲和性或nodeSelector强制pod调度到节点node2,此时就会出现冲突,这个pod也就会一直pending了。

    k8s的lpv是通过pvc和pv的延迟绑定来解决这个冲突的:创建一个storageClass,配置volumeBindingMode为WaitForFirstConsumer,且在pvA和pvB中声明使用这个storageClass

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: local-storage
    provisioner: kubernetes.io/no-provisioner
    volumeBindingMode: WaitForFirstConsumer
    

     WaitForFirstConsumer表示第一个使用这个pvc的pod在调度过程中才决策合适的pv进行绑定。这样一来,k8s就可以综合考虑pod对Node的要求和pv对Node的要求,最终pvc选择和pvA进行绑定。

    参考资料:

    当前k8s支持的存储插件:https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

  • 相关阅读:
    Centos7配置局域网yum源报错——Error downloading packages: failed to retrieve packages...
    Centos7扩展根分区——不增加磁盘
    Paxos算法
    记一次业务中的大坑-MYSQL有重复数据下的增加主键
    填坑之路——Hadoop分布式缓存
    Java接口技术
    Java-IO操作性能对比
    Clob对象转换为String
    剖析Reflection.getCallerClass
    Java类的加载、链接和初始化
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/12025100.html
Copyright © 2020-2023  润新知