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

pod宿主机挂载pv存储过程的更多相关文章

  1. Docker 记一次容器内部修改宿主机挂载目录用户权限后宿主机目录变化

    一.需求: 因公司需求,需制作mysql5.7.22 docker基础镜像,每个项目以此镜像启动一个数据库容器,并且每个项目挂载一个宿主机目录到镜像中数据存储下面用于数据持久化保存以便后期迁移至阿里云 ...

  2. docker容器与宿主机的数据交互

    在生产环境中使用 Docker ,往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,这必然涉及容器的数据管理操作. 方式一.Docker cp命令 docker cp :用于容器与主机之间 ...

  3. [HACK] docker runtime 挂载宿主机目录

    网上看到的很多所谓的挂载都是容器创建时期的挂载,而且参数都不清不楚,整理如下(--name别名自己加): docker run -v /src/path:/dest/path:rw ${IMAGE} ...

  4. Docker挂载宿主机目录

    一.普通方式直接挂载 1.查看已有容器 docker ps 2.进入容器并挂载 docker run -it -v /root/work/docker:/root/hzbtest tomcat:7.0 ...

  5. Docker Toolbox在window 10 home 下挂载宿主机目录到容器的正确操作

    由于我是window 10 home 而不是 pro版本,只能使用Docker Toolbox,其实docker for window对windows的支持更好,还有GUI,home版本安装Docke ...

  6. Docker中运行MySQL5.7并挂载宿主机目录到镜像

    原文:Docker中运行MySQL5.7并挂载宿主机目录到镜像 1.1 拉取mysql镜像 docker pull mysql:5.7 1.2 创建用于挂载的目录 mkdir -p /data/mys ...

  7. docker swarm集群挂载宿主机目录

    创建DOCKER集群,挂载宿主机目录src:宿主机目录,dst:容器目录 docker service create --name testrd --detach=false --mount type ...

  8. docker 启动mysql 挂载宿主机目录

    在使用docker run 运行镜像获取容器时,有些容器会自动产生一些数据,为了这些数据会因为container (容器)的消失而消失,保证数据的安全,比如mysql 容器在运行中产生的一些表的数据, ...

  9. Kubernetes中予许及限制(PodSecurityPolicy)使用宿主机资源

    1.在pod中使用宿主机命名空间.端口等资源 pod中的容器通常在分开的Linux命名空间中运行.这些命名空间将容器中的进程与其他容器中,或者宿主机默认命名空间中的进程隔离开来. 例如,每一个pod有 ...

随机推荐

  1. redis rehash

    rehash 随着操作的不断执行, 哈希表保存的键值对会逐渐地增多或者减少, 为了让哈希表的负载因子(load factor)维持在一个合理的范围之内, 当哈希表保存的键值对数量太多或者太少时, 程序 ...

  2. SQLEXPR_x64_CHS、SQLEXPRADV_x64_CHS、SQLEXPRWT_x64_CHS、SqlLocalDB、SQLManagementStudio_x64_CHS各版本说明

    LocalDB (SqlLocalDB)LocalDB 是 Express的一种轻型版本,该版本具备所有可编程性功能,但在用户模式下运行,并且具有快速的零配置安装和必备组件要求较少的特点.如果您需要通 ...

  3. python window窗口

    from Tkinter import * root=Tk() root.title('我是root窗口!') L=Label(root,text='我属于root') L.pack() f=Topl ...

  4. To avoid slowing down lookups on a near-full table, we resize the table when it's USABLE_FRACTION (currently two-thirds) full.

    https://github.com/python/cpython/blob/3.8/Objects/dictobject.c

  5. SpringMVC:HandlerInterceptor log 日志

    springMVC:HandlerInterceptor拦截器添加系统日志(权限校验)代码收藏 - LinkcOne - CSDN博客https://blog.csdn.net/qq_22815337 ...

  6. tomcat中设置Java 客户端程序的http(https)访问代理

    1.假定http/https代理服务器为 127.0.0.1 端口为8118 2.在tomcat/bin/catalina.sh脚本文件中设置JAVA_OPTS,如下图: 保存后重启tomcat就能生 ...

  7. ISO/IEC 9899:2011 条款6.8.1——标签语句

    6.8.1 标签语句 语法 1.labeled-statement: identifier    :    statement default    :    statement case    co ...

  8. python中修改列表元素的方法

    一.在for循环中直接更改列表中元素的值不会起作用: 如: l = list(range(10)[::2]) print (l) for n in l: n = 0 print (l) 运行结果: [ ...

  9. mobile crane 1

    void MobileCrane::rotateRope2() { //double r_angle1 = rotateRope + rorate3; //std::cout << &qu ...

  10. ES6深入浅出-7 新版的类(上集)-2.介绍JS中的类

    声明对象原型,公有属性. obj对象,它用一个属性__proto__记录了自己的原型 改掉它的原型为公有属性.那么obj这个对象及有了hi的方法.因为obj自己没有hi.那么就去自己的原型上去找了. ...