从零开始入门 K8s | 应用存储和持久化数据卷:核心知识

做者 | 至天 阿里巴巴高级研发工程师node

1、Volumes 介绍

Pod Volumes

首先来看一下 Pod Volumes 的使用场景:微信

  • 场景一:若是 pod 中的某一个容器在运行时异常退出,被 kubelet 从新拉起以后,如何保证以前容器产生的重要数据没有丢失?
  • 场景二:若是同一个 pod 中的多个容器想要共享数据,应该如何去作?

以上两个场景,其实均可以借助 Volumes 来很好地解决,接下来首先看一下 Pod Volumes 的常见类型:网络

  1. 本地存储,经常使用的有 emptydir/hostpath;
  2. 网络存储:网络存储当前的实现方式有两种,一种是 in-tree,它的实现代码是放在 K8s 代码仓库中的,随着 K8s 对存储类型支持的增多,这种方式会给 K8s 自己的维护和发展带来很大的负担;而第二种实现方式是 out-of-tree,它的实现实际上是给 K8s 自己解耦的,经过抽象接口将不一样存储的 driver 实现从 K8s 代码仓库中剥离,所以 out-of-tree 是后面社区主推的一种实现网络存储插件的方式;
  3. Projected Volumes:它实际上是将一些配置信息,如 secret/configmap 用卷的形式挂载在容器中,让容器中的程序能够经过 POSIX 接口来访问配置数据;
  4. PV 与 PVC 就是今天要重点介绍的内容。

 

Persistent Volumes

l1

接下来看一下 PV(Persistent Volumes)。既然已经有了 Pod Volumes,为何又要引入 PV 呢?咱们知道 pod 中声明的 volume 生命周期与 pod 是相同的,如下有几种常见的场景:<br />架构

  • 场景一:pod 重建销毁,如用 Deployment 管理的 pod,在作镜像升级的过程当中,会产生新的 pod而且删除旧的 pod ,那新旧 pod 之间如何复用数据?
  • 场景二:宿主机宕机的时候,要把上面的 pod 迁移,这个时候 StatefulSet 管理的 pod,其实已经实现了带卷迁移的语义。这时经过 Pod Volumes 显然是作不到的;
  • 场景三:多个 pod 之间,若是想要共享数据,应该如何去声明呢?咱们知道,同一个 pod 中多个容器想共享数据,能够借助 Pod Volumes 来解决;当多个 pod 想共享数据时,Pod Volumes 就很难去表达这种语义;
  • 场景四:若是要想对数据卷作一些功能扩展性,如:snapshot、resize 这些功能,又应该如何去作呢?

以上场景中,经过 Pod Volumes 很难准确地表达它的复用/共享语义,对它的扩展也比较困难。所以 K8s 中又引入了 **Persistent Volumes **概念,它能够将存储和计算分离,经过不一样的组件来管理存储资源和计算资源,而后解耦 pod 和 Volume 之间生命周期的关联。这样,当把 pod 删除以后,它使用的 PV 仍然存在,还能够被新建的 pod 复用。less

PVC 设计意图

l2

了解 PV 后,应该如何使用它呢?运维

用户在使用 PV 时实际上是经过 PVC,为何有了 PV 又设计了 PVC 呢?主要缘由是为了简化 K8s 用户对存储的使用方式,作到职责分离。一般用户在使用存储的时候,只用声明所需的存储大小以及访问模式。微服务

访问模式是什么?其实就是:我要使用的存储是能够被多个 node 共享仍是只能单 node 独占访问(注意是 node level 而不是 pod level)?只读仍是读写访问?用户只用关心这些东西,与存储相关的实现细节是不须要关心的。学习

经过 PVC 和 PV 的概念,将用户需求和实现细节解耦开,用户只用经过 PVC 声明本身的存储需求。PV是有集群管理员和存储相关团队来统一运维和管控,这样的话,就简化了用户使用存储的方式。能够看到,PV 和 PVC 的设计其实有点像面向对象的接口与实现的关系。用户在使用功能时,只需关心用户接口,不需关心它内部复杂的实现细节。阿里云

既然 PV 是由集群管理员统一管控的,接下来就看一下 PV 这个对象是怎么产生的。插件

Static Volume Provisioning

第一种产生方式:静态产生方式 - 静态 Provisioning。

l3

静态 Provisioning:由集群管理员事先去规划这个集群中的用户会怎样使用存储,它会先预分配一些存储,也就是预先建立一些 PV;而后用户在提交本身的存储需求(也就是 PVC)的时候,K8s 内部相关组件会帮助它把 PVC 和 PV 作绑定;以后用户再经过 pod 去使用存储的时候,就能够经过 PVC 找到相应的 PV,它就可使用了。

静态产生方式有什么不足呢?能够看到,首先须要集群管理员预分配,预分配实际上是很难预测用户真实需求的。举一个最简单的例子:若是用户须要的是 20G,然而集群管理员在分配的时候可能有 80G 、100G 的,但没有 20G 的,这样就很难知足用户的真实需求,也会形成资源浪费。有没有更好的方式呢?

Dynamic Volume Provisioning

第二种访问方式:动态 Dynamic Provisioning。

l4

动态供给是什么意思呢?就是说如今集群管理员不预分配 PV,他写了一个模板文件,这个模板文件是用来表示建立某一类型存储(块存储,文件存储等)所需的一些参数,这些参数是用户不关心的,给存储自己实现有关的参数。用户只须要提交自身的存储需求,也就是 PVC 文件,并在 PVC 中指定使用的存储模板(StorageClass)。

K8s 集群中的管控组件,会结合 PVC 和 StorageClass 的信息动态,生成用户所须要的存储(PV),将 PVC 和 PV 进行绑定后,pod 就可使用 PV 了。经过 StorageClass 配置生成存储所须要的存储模板,再结合用户的需求动态建立 PV 对象,作到按需分配,在没有增长用户使用难度的同时也解放了集群管理员的运维工做。

2、用例解读

接下来看一下 Pod Volumes、PV、PVC 及 StorageClass 具体是如何使用的。

Pod Volumes 的使用

l5

首先来看一下 Pod Volumes 的使用。如上图左侧所示,咱们能够在 pod yaml 文件中的 Volumes 字段中,声明咱们卷的名字以及卷的类型。声明的两个卷,一个是用的是 emptyDir,另一个用的是 hostPath,这两种都是本地卷。在容器中应该怎么去使用这个卷呢?它其实能够经过 volumeMounts 这个字段,volumeMounts 字段里面指定的 name 其实就是它使用的哪一个卷,mountPath 就是容器中的挂载路径。

这里还有个 subPath,subPath 是什么?

先看一下,这两个容器都指定使用了同一个卷,就是这个 cache-volume。那么,在多个容器共享同一个卷的时候,为了隔离数据,咱们能够经过 subPath 来完成这个操做。它会在卷里面创建两个子目录,而后容器 1 往 cache 下面写的数据其实都写在子目录 cache1 了,容器 2 往 cache 写的目录,其数据最终会落在这个卷里子目录下面的 cache2 下。

还有一个 readOnly 字段,readOnly 的意思其实就是只读挂载,这个挂载你往挂载点下面其实是没有办法去写数据的。

另外 emptyDir、hostPath 都是本地存储,它们之间有什么细微的差异呢?emptyDir 实际上是在 pod 建立的过程当中会临时建立的一个目录,这个目录随着 pod 删除也会被删除,里面的数据会被清空掉;hostPath 顾名思义,其实就是宿主机上的一个路径,在 pod 删除以后,这个目录仍是存在的,它的数据也不会被丢失。这就是它们二者之间一个细微的差异。

静态 PV 使用

l6

接下来再看一下,PV 和 PVC 是怎么使用的。

先看一个静态 PV 建立方式。静态 PV 的话,首先是由管理员来建立的,管理员咱们这里以 NAS,就是阿里云文件存储为例。我须要先在阿里云的文件存储控制台上去建立 NAS 存储,而后把 NAS 存储的相关信息要填到 PV 对象中,这个 PV 对象预建立出来后,用户能够经过 PVC 来声明本身的存储需求,而后再去建立 pod。建立 pod 仍是经过咱们刚才讲解的字段把存储挂载到某一个容器中的某一个挂载点下面。

那么接下来看一下 yaml 怎么写。集群管理员首先是在云存储厂商那边先去把存储建立出来,而后把相应的信息填写到 PV 对象中。

l7

刚刚建立的阿里云 NAS 文件存储对应的 PV,有个比较重要的字段:capacity,即建立的这个存储的大小,accessModes,建立出来的这个存储它的访问方式,咱们后面会讲解总共有几种访问方式。

而后有个 ReclaimPolicy,ReclaimPolicy 的意思就是:这块存储在被使用后,等它的使用方 pod 以及 PVC 被删除以后,这个 PV 是应该被删掉仍是被保留呢?其实就是 PV 的回收策略。

接下来看看用户怎么去使用该 PV 对象。用户在使用存储的时候,须要先建立一个 PVC 对象。PVC 对象里面,只须要指定存储需求,不用关心存储自己的具体实现细节。存储需求包括哪些呢?首先是须要的大小,也就是 resources.requests.storage;而后是它的访问方式,即须要这个存储的访问方式,这里声明为 ReadWriteMany,也即支持多 node 读写访问,这也是文件存储的典型特性。

l8

上图中左侧,能够看到这个声明:它的 size 和它的access mode,跟咱们刚才静态建立这块 PV 实际上是匹配的。这样的话,当用户在提交 PVC 的时候,K8s 集群相关的组件就会把 PV 的 PVC bound 到一块儿。以后,用户在提交 pod yaml 的时候,能够在卷里面写上 PVC 声明,在 PVC 声明里面能够经过 claimName 来声明要用哪一个 PVC。这时,挂载方式其实跟前面讲的同样,当提交完 yaml 的时候,它能够经过 PVC 找到 bound 着的那个 PV,而后就能够用那块存储了。这是静态 Provisioning 到被 pod 使用的一个过程。

动态 PV 使用

而后再看一下动态 Provisioning。动态 Provisioning 上面提到过,系统管理员再也不预分配 PV,而只是建立一个模板文件。

l9

这个模板文件叫 StorageClass,在 StorageClass 里面,咱们须要填的重要信息:第一个是 provisioner,provisioner 是什么?它其实就是说我当时建立 PV 和对应的存储的时候,应该用哪一个存储插件来去建立。

这些参数是经过 K8s 建立存储的时候,须要指定的一些细节参数。对于这些参数,用户是不须要关心的,像这里 regionld、zoneld、fsType 和它的类型。ReclaimPolicy 跟咱们刚才讲解的 PV 里的意思是同样的,就是说动态建立出来的这块 PV,当使用方使用结束、Pod 及 PVC 被删除后,这块 PV 应该怎么处理,咱们这个地方写的是 delete,意思就是说当使用方 pod 和 PVC 被删除以后,这个 PV 也会被删除掉。

接下来看一下,集群管理员提交完 StorageClass,也就是提交建立 PV 的模板以后,用户怎么用,首先仍是须要写一个 PVC 的文件。

l10

PVC 的文件里存储的大小、访问模式是不变的。如今须要新加一个字段,叫 StorageClassName,它的意思是指定动态建立 PV 的模板文件的名字,这里 StorageClassName 填的就是上面声明的 csi-disk。

在提交完 PVC以后,K8s 集群中的相关组件就会根据 PVC 以及对应的 StorageClass 动态生成这块 PV 给这个 PVC 作一个绑定,以后用户在提交本身的 yaml 时,用法和接下来的流程和前面的静态使用方式是同样的,经过 PVC 找到咱们动态建立的 PV,而后把它挂载到相应的容器中就可使用了。

PV Spec 重要字段解析

接下来,咱们讲解一下 PV 的一些重要字段:

l11

  • Capacity:这个很好理解,就是存储对象的大小;
  • **AccessModes:**也是用户须要关心的,就是说我使用这个 PV 的方式。它有三种使用方式。
    • 一种是单 node 读写访问;
    • 第二种是多个 node 只读访问,是常见的一种数据的共享方式;
    • 第三种是多个 node 上读写访问。

用户在提交 PVC 的时候,最重要的两个字段 —— Capacity 和 AccessModes。在提交 PVC后,K8s 集群中的相关组件是如何去找到合适的 PV 呢?首先它是经过为 PV 创建的 AccessModes 索引找到全部可以知足用户的 PVC 里面的 AccessModes 要求的 PV list,而后根据 PVC 的 Capacity,StorageClassName, Label Selector 进一步筛选 PV,若是知足条件的 PV 有多个,选择 PV 的 size 最小的,accessmodes 列表最短的 PV,也即最小适合原则。

  • ReclaimPolicy:这个就是刚才提到的,个人用户方 PV 的 PVC 在删除以后,个人 PV 应该作如何处理?常见的有三种方式。
    • 第一种方式咱们就不说了,如今 K8s 中已经不推荐使用了;
    • 第二种方式 delete,也就是说 PVC 被删除以后,PV 也会被删除;
    • 第三种方式 Retain,就是保留,保留以后,后面这个 PV 须要管理员来手动处理;
  • StorageClassName:StorageClassName 这个咱们刚才说了,咱们动态 Provisioning 时必须指定的一个字段,就是说咱们要指定到底用哪个模板文件来生成 PV ;
  • NodeAffinity:就是说我建立出来的 PV,它能被哪些 node 去挂载使用,实际上是有限制的。而后经过 NodeAffinity 来声明对node的限制,这样其实对 使用该 PV 的 pod 调度也有限制,就是说 pod 必需要调度到这些能访问 PV 的 node 上,才能使用这块 PV,这个字段在咱们下一讲讲解存储拓扑调度时在细说。

PV 状态流转

l12

接下来咱们看一下 PV 的状态流转。首先在建立 PV 对象后,它会处在短暂的pending 状态;等真正的 PV 建立好以后,它就处在 available 状态。

available 状态意思就是可使用的状态,用户在提交 PVC 以后,被 K8s 相关组件作完 bound(即:找到相应的 PV),这个时候 PV 和 PVC 就结合到一块儿了,此时二者都处在 bound 状态。当用户在使用完 PVC,将其删除后,这个 PV 就处在 released 状态,以后它应该被删除仍是被保留呢?这个就会依赖咱们刚才说的 ReclaimPolicy。

这里有一个点须要特别说明一下:当 PV 已经处在 released 状态下,它是没有办法直接回到 available 状态,也就是说接下来没法被一个新的 PVC 去作绑定。若是咱们想把已经 released 的 PV 复用,咱们这个时候一般应该怎么去作呢?

第一种方式:咱们能够新建一个 PV 对象,而后把以前的 released 的 PV 的相关字段的信息填到新的 PV 对象里面,这样的话,这个 PV 就能够结合新的 PVC 了;第二种是咱们在删除 pod 以后,不要去删除 PVC 对象,这样给 PV 绑定的 PVC 仍是存在的,下次 pod 使用的时候,就能够直接经过 PVC 去复用。K8s 中的 StatefulSet 管理的 Pod 带存储的迁移就是经过这种方式。

3、操做演示

接下来,我会在实际的环境中给你们演示一下,静态 Provisioning 以及动态 Provisioning 具体操做方式。

静态 Provisioning 例子

静态 Provisioning 主要用的是阿里云的 NAS 文件存储;动态 Provisioning 主要用了阿里云的云盘。它们须要相应存储插件,插件我已经提早部署在个人 K8s 集群中了(csi-nasplugin* 是为了在 K8s 中使用阿里云 NAS 所需的插件,csi-disk *是为了在 K8s 中使用阿里云云盘所须要的插件)。

l13

咱们接下来先看一下静态 Provisioning 的 PV 的 yaml 文件。

l14

volumeAttributes 是我在阿里云 nas 控制台预先建立的 NAS 文件系统的相关信息,咱们主要须要关心的有 capacity 为 5Gi; accessModes 为多 node 读写访问; reclaimPolicy:Retain,也就是当我使用方的 PVC 被删除以后,我这个 PV 是要保留下来的;以及在使用这个卷的过程当中使用的 driver。

而后咱们把对应的 PV 建立出来:

l15

咱们看一下上图 PV 的状态,已经处在 Available,也就是说它已经能够被使用了。

再建立出来 nas-pvc:

l16

咱们看这个时候 PVC 已经新建立出来了,并且也已经和咱们上面建立的 PV 绑定到一块儿了。咱们看一下 PVC 的 yaml 里面写的什么。

l17

其实很简单 ,就是我须要的大小以及我须要的 accessModes。提交完以后,它就与咱们集群中已经存在的 PV 作匹配,匹配成功以后,它就会作 bound。

接下来咱们去建立使用 nas-fs 的 pod:

l18

上图看到,这两个 Pod 都已经处在 running 状态了。

咱们先看一下这个 pod yaml:

l19

pod yaml 里面声明了刚才咱们建立出来的 PVC 对象,而后把它挂载到 nas-container 容器中的 /data 下面。咱们这个 pod 是经过 deployment 建立两个副本,经过反亲和性,将两个副本调度在不一样的 node 上面。

l20

上图咱们能够看一下,两个 Pod 所在的宿主机是不同的。

以下图所示:咱们登录到第一个上面,findmnt 看一下它的挂载信息,这个其实就挂载在我声明的 nas-fs 上,那咱们再在下面 touch 个 test.test.test 文件,咱们也会登录到另一个容器,看一下它有没有被共享。

l21

咱们退出再登录另一个 pod(刚才登录的是第一个,如今登录第二个)。

以下图所示:咱们也 findmnt 一下,能够看到,这两个 pod 的远程挂载路径同样,也就是说咱们用的是同一个 NAS PV,咱们再看一下刚才建立出来的那个是否存在。

l22

能够看到,这个也是存在的,就说明这两个运行在不一样node上的 pod 共享了同一个 nas 存储。

接下来咱们看一下把两个 pod 删掉以后的状况。先删 Pod,接着再删一下对应的 PVC(K8s 内部对 pvc 对象由保护机制,在删除 pvc 对象时若是发现有 pod 在使用 pvc,pvc 是删除不掉的),这个可能要稍等一下。

l23

看一下下图对应的 PVC 是否是已经被删掉了。

l24

上图显示,它已经被删掉了。再看一下,刚才的 nas PV 仍是在的,它的状态是处在 Released 状态,也就是说刚才使用它的 PVC 已经被删掉了,而后它被 released 了。又由于咱们 RECLAIN POLICY 是 Retain,因此它这个 PV 是被保留下来的。

动态 Provisioning 例子

接下来咱们来看第二个例子,动态 Provisioning 的例子。咱们先把保留下来的 PV 手动删掉,能够看到集群中没有 PV了。接下来演示一下动态 Provisioning。

首先,先去建立一个生成 PV 的模板文件,也就是 storageclass。看一下 storageclass 里面的内容,其实很简单。

l25

如上图所示,我事先指定的是我要建立存储的卷插件(阿里云云盘插件,由阿里云团队开发),这个咱们已经提早部署好了;咱们能够看到,parameters部分是建立存储所须要的一些参数,可是用户不须要关心这些信息;而后是 reclaimPolicy,也就是说经过这个 storageclass 建立出来的 PV 在给绑定到一块儿的 PVC 删除以后,它是要保留仍是要删除。

l26

如上图所示:如今这个集群中是没有 PV 的,咱们动态提交一个 PVC 文件,先看一下它的 PVC 文件。它的 accessModes-ReadWriteOnce (由于阿里云云盘其实只能是单 node 读写的,因此咱们声明这样的方式),它的存储大小需求是 30G,它的 storageClassName 是 csi-disk,就是咱们刚才建立的 storageclass,也就是说它指定要经过这个模板去生成 PV。

l27

这个 PVC 此时正处在 pending 状态,这就说明它对应的 PV 还在建立过程当中。

l28

稍过一会,咱们看到已经有一个新的 PV 生成,这个 PV 其实就是根据咱们提交的 PVC 以及 PVC 里面指定的storageclass 动态生成的。以后 K8s 会将生成的 PV 以及咱们提交的 PVC,就是这个 disk PVC 作绑定,以后咱们就能够经过建立 pod 来使用了。

再看一下 pod yaml:

l29

pod yaml 很简单,也是经过 PVC 声明,代表使用这个 PVC。而后是挂载点,下面咱们能够建立看一下。

l30

以下图所示:咱们能够大概看一下 Events,首先被调度器调度,调度完以后,接下来会有个 attachdetach controller,它会去作 disk 的 attach 操做,就是把咱们对应的 PV 挂载到调度器调度的 node 上,而后Pod对应的容器才能启动,启动容器才能使用对应的盘。

l31

接下来我会把 PVC 删掉,看一下 PV 会不会根据咱们的 reclaimPolicy 随之删掉呢?咱们先看一下,这个时候 PVC 仍是存在的,对应的 PV 也是存在的。

l32

而后删一下 PVC,删完以后再看一下:咱们的 PV 也被删了,也就是说根据 reclaimPolicy,咱们在删除 PVC 的同时,PV 也会被删除掉。

l33

咱们的演示部分就到这里了。

4、架构设计

PV 和 PVC 的处理流程

咱们接下来看一下 K8s 中的 PV 和 PVC 体系的完整处理流程。我首先看一下这张图的右下部分里面提到的 csi。

l34

csi 是什么?csi 的全称是 container storage interface,它是 K8s 社区后面对存储插件实现 ( out of tree ) 的官方推荐方式。csi 的实现大致能够分为两部分:

  • 第一部分是由 k8s 社区驱动实现的通用的部分,像咱们这张图中的 csi-provisioner和 csi-attacher controller;
  • 另一种是由云存储厂商实践的,对接云存储厂商的 OpenApi,主要是实现真正的 create/delete/mount/unmount 存储的相关操做,对应到上图中的 csi-controller-server 和 csi-node-server。

接下来看一下,当用户提交 yaml 以后,k8s 内部的处理流程。用户在提交 PVCyaml 的时候,首先会在集群中生成一个 PVC 对象,而后 PVC 对象会被 csi-provisioner controller watch 到,csi-provisioner 会结合 PVC 对象以及 PVC 对象中声明的 storageClass,经过 GRPC 调用 csi-controller-server,而后,到云存储服务这边去建立真正的存储,并最终建立出来 PV 对象。最后,由集群中的 PV controller 将 PVC 和 PV 对象作 bound 以后,这个 PV 就能够被使用了。

用户在提交 pod 以后,首先会被调度器调度选中某一个合适的node,以后该 node 上面的 kubelet 在建立 pod 流程中会经过首先 csi-node-server 将咱们以前建立的 PV 挂载到咱们 pod 可使用的路径,而后 kubelet 开始 create && start pod 中的全部 container。

PV、PVC 以及经过 csi 使用存储流程

咱们接下来经过另外一张图来更加详细看一下咱们 PV、PVC 以及经过 CSI 使用存储的完整流程。

l35

主要分为三个阶段:

  • 第一个阶段(Create 阶段)是用户提交完 PVC,由 csi-provisioner 建立存储,并生成 PV 对象,以后 PV controller 将 PVC 及生成的 PV 对象作 bound,bound 以后,create 阶段就完成了;
  • 以后用户在提交 pod yaml 的时候,首先会被调度选中某一个合适的 node,等 pod 的运行 node 被选出来以后,会被 AD Controller watch 到 pod 选中的 node,它会去查找 pod 中使用了哪些 PV。而后它会生成一个内部的对象叫 VolumeAttachment 对象,从而去触发 csi-attacher去调用 csi-controller-server 去作真正的 attache 操做,attach 操做调到云存储厂商 OpenAPI。这个 attach 操做就是将存储 attach到 pod 将会运行的 node 上面。第二个阶段 —— attach 阶段完成;
  • 而后咱们接下来看第三个阶段。第三个阶段发生在 kubelet 建立 pod 的过程当中,它在建立 pod 的过程当中,首先要去作一个 mount,这里的 mount 操做是为了将已经 attach 到这个 node 上面那块盘,进一步 mount 到 pod 可使用的一个具体路径,以后 kubelet 才开始建立并启动容器。这就是 PV 加 PVC 建立存储以及使用存储的第三个阶段 —— mount 阶段。

总的来讲,有三个阶段:第一个 create 阶段,主要是建立存储;第二个 attach 阶段,就是将那块存储挂载到 node 上面(一般为将存储 load 到 node 的 /dev 下面);第三个 mount 阶段,将对应的存储进一步挂载到 pod 可使用的路径。这就是咱们的 PVC、PV、已经经过 CSI 实现的卷从建立到使用的完整流程。

本文总结

本文内容就到此为止了,这里为你们简单总结一下:

  • 介绍了 K8s Volume 的使用场景,以及自己局限性;
  • 经过介绍 K8s 的 PVC 和 PV 体系,说明 K8s 经过 PVC 和 PV 体系加强了 K8s Volumes 在多 Pod 共享/迁移/存储扩展等场景下的能力的必要性以及设计思想;
  • 经过介绍 PV(存储)的不一样供给模式 (static and dynamic),学习了如何经过不一样方式为集群中的 Pod 供给所需的存储;
  • 经过 PVC&PV 在 K8s 中完整的处理流程,深刻理解 PVC&PV 的工做原理 。

阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,作最懂云原生开发者的技术公众号。

相关文章
相关标签/搜索