PV、PVC、StorageClass 概览

为何如此设计

  1. 解耦对存储的使用与维护
  2. 拓展不同的存储需求

定义

PV 描述的是持久化存储数据卷。这个 API 对象主要定义的是⼀个持久化存储在宿主机上的⽬录,⽐如⼀个 NFS 的挂载⽬录。通常情况下,PV 对象是由运维⼈员事先创建在 Kubernetes 集群⾥待⽤的。类似于接口的具体实现,干活的打工人。 PVC 描述的是 Pod 所希望使⽤的持久化存储的属性。PVC 对象通常由开发⼈员创建;或者以 PVC 模板的⽅式成为 StatefulSet 的⼀部分,然后由 StatefulSet 控制器负责创建带编号的 PVC。类似于接口,不提供具体实现

PV与PVC匹配绑定

规则

  1. 两者的 spec 字段匹配
  2. 两者的 storageClassName 字段必须相同

过程

通过 operator 机制,为每个未处于 Bound 状态的 PVC,遍历所有可用的 PV,来匹配到合适的 PV。

结果

在 PVC 的 spec.volumeName 字段上填写上 PV 的名称

两阶段处理

  1. Attach 调用存储系统的 API 将存储挂载到 Pod 将要调度到的 Node 上;

由 AttachDetachController 管理。它不断地检查每⼀个 Pod 对应的 PV,和 这个 Pod 所在宿主机之间挂载情况。从⽽决定,是否需要对这个 PV 进⾏ Attach(或者 Dettach)操作。 作为⼀个 Kubernetes 内置的控制器,Volume Controller ⾃然是 kube-controller-manager 的⼀部分。所以,AttachDetachController 也⼀定是运⾏在 Master 节点上的。当然,Attach 操作只需要调⽤公有云或者具体存储项⽬的 API,并不需要在具体的宿主机上执⾏操作。

  1. Mount
  2. 格式化存储设备
  3. 绑定挂载到 Pod 中

由 VolumeManagerReconciler 管理。它必须发⽣在 Pod 对应的宿主机上,所以必须是 kubelet 组件的⼀部分。它运⾏起来之后,是⼀个独⽴于 kubelet 主循环的 Goroutine(不堵塞 kubelet 主控循环)。

PV 管理方式

  • Static Provisioning

创建 PVC 之后,由运维人员手动创建 PV 的方式

  • Dynamic Provisioning

创建 PVC 时指定 StorageClass,由 StorageClass 中指定的 provisioner 来创建对应的 PV。

StorageClass

当 PVC 中指定的 StorageClass 存在时,调用对应的 provisioner 来创建 PV;否则去匹配带有相同 StorageClass 的 PV。 如果 PVC 中未指定 StorageClass,当集群已经开启了名叫 DefaultStorageClass 的 Admission Plugin时,它就会为 PVC 和 PV ⾃动添加⼀个默认的 StorageClass;否则,PVC 的 storageClassName 的值就是“”,这也意味着它只能够跟 storageClassName 也是“”的 PV 进⾏绑定。

本地持久化卷的实现

延迟绑定:当使用本地存储后,需要延迟 PV 与 PVC 之间的绑定时机到 Pod 调度时,避免出现 PV 与 Pod 不在同一节点上面的问题。

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

Read more

容器镜像(4):镜像的常用工具箱

容器镜像(4):镜像的常用工具箱

前几篇在讲多架构镜像时已经用过 skopeo 和 crane 做镜像复制,这篇系统整理这两个工具的完整能力,同时介绍几个日常操作镜像时同样好用的工具。 一、skopeo:不依赖 Daemon 的镜像瑞士军刀 skopeo 的核心价值是绕过 Docker daemon,直接与 Registry API 交互。上一篇用它做镜像复制和离线传输,但它的能力远不止于此。 1.1 安装 # Ubuntu / Debian sudo apt install -y skopeo skopeo --version # skopeo version 1.15.1 1.2 inspect:免拉取检查镜像元数据 docker inspect 需要先把镜像拉到本地,skopeo inspect 直接向 Registry

容器镜像(3):多架构镜像构建

容器镜像(3):多架构镜像构建

一、什么是多架构镜像 1.1 OCI Image Index 上一篇介绍了单平台镜像的结构:一个 Manifest 指向 Config 和若干 Layer blob。多架构镜像在此之上多了一层——OCI Image Index(也叫 Manifest List),是一个轻量的索引文件,把多个单平台 Manifest 组织在一起: $ docker manifest inspect golang:1.22-alpine { "schemaVersion": 2, "mediaType": "application/vnd.oci.image.index.v1+json", "manifests&

容器镜像(2):containerd 视角下的镜像

容器镜像(2):containerd 视角下的镜像

一、为什么需要了解 containerd 如果你只用 docker run 跑容器,从来不关心底层,那可以不了解 containerd。但如果你在用 Kubernetes,或者想真正理解"容器运行时"是什么,containerd 是绕不开的。 事实上,当你执行 docker run 的时候,containerd 早就在后台悄悄工作了——Docker 从 1.11 版本开始,就把核心运行时剥离出来交给 containerd 负责。 1.1 Docker 的架构演变 早期的 Docker(1.10 及之前)是一个"大一统"的单体程序:一个 dockerd