Kubernetes 1.14:本地永久卷GA

s :Michelle Au(Google),Matt Schallert(Uber),Celina Ward(Uber)

本地永久卷 该功能已在Kubernetes 1.14中提升为GA。 它首先在Kubernetes 1.7中作为alpha引入,然后 贝塔 在Kubernetes 1.10。 GA里程碑表明Kubernetes用户可能依赖于该功能 及其用于生产的API。 GA功能受Kubernetes保护 弃用 policy.

什么是本地永久卷?

本地永久卷表示直接附加到单个磁盘的本地磁盘 Kubernetes Node.

Kubernetes 提供了功能强大的批量插件系统,可启用Kubernetes workloads to use a 宽 variety 块和文件存储以持久化数据。最 这些插件中的一个启用远程存储-这些远程存储系统持续存在 数据独立于数据起源的Kubernetes节点。远程 存储通常无法提供一致的高性能保证 本地直接连接的存储。使用本地永久卷插件, Kubernetes工作负载现在可以使用 应用程序开发人员已习惯的相同数量的API。

与HostPath卷有何不同?

为了更好地了解本地永久卷的好处, compare it to a HostPath卷. HostPath卷从以下位置挂载文件或目录 主机节点的文件系统放入Pod。类似地,本地永久卷 将本地磁盘或分区安装到Pod中。

最大的区别是Kubernetes调度程序了解哪个节点 本地永久卷属于。在HostPath卷中,引用了 调度程序可能会将HostPath卷移动到另一个节点,从而导致 数据丢失。但是使用本地持久卷,Kubernetes调度程序可以确保 使用本地持久卷的Pod总是安排在同一节点上。

虽然可以通过持久卷声明(PVC)引用HostPath卷或 直接内联到pod定义中,本地持久卷只能是 通过PVC引用。这提供了额外的安全优势,因为 持久卷对象由管理员管理,以防止Pod 能够访问主机上的任何路径。

其他好处包括在以下过程中支持块设备的格式化 使用fsGroup进行装载和卷所有权。

GA有何新功能?

从1.10开始,我们主要致力于改善 功能,使其可以投入生产。

唯一的主要功能是可以指定原始块设备和 让Kubernetes自动格式化并挂载文件系统。这减少了 之前必须格式化和挂载设备的负担 Kubernetes.

GA的局限性

在GA,本地永久卷不支持 动态音量 provisioning. However there is an 外部 controller 可用于帮助管理本地 节点上单个磁盘的PersistentVolume生命周期。这包括 创建PersistentVolume对象,清理并重新使用磁盘 已由应用程序释放。

如何使用本地永久卷?

工作负载可以使用相同的请求本地持久卷 PersistentVolumeClaim接口作为远程存储后端。这很容易 跨集群,云和本地交换出存储后端 environments.

First, a StorageClass should be created that sets volumeBindingMode: WaitForFirstConsumer to enable 卷拓扑感知 scheduling. 该模式指示Kubernetes等待绑定PVC,直到计划使用它的Pod。

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

然后,可以将外部静态预配器 配置并 run 创建PV 用于节点上的所有本地磁盘。

$ kubectl get pv
NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM  STORAGECLASS   REASON      AGE
local-pv-27c0f084   368Gi      RWO            Delete           Available          local-storage              8s
local-pv-3796b049   368Gi      RWO            Delete           Available          local-storage              7s
local-pv-3ddecaea   368Gi      RWO            Delete           Available          local-storage              7s

之后,工作负载可以通过创建PVC和Pod或 带volumeClaimTemplates的StatefulSet。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: local-test
spec:
  serviceName: "local-service"
  replicas: 3
  selector:
    matchLabels:
      app: local-test
  template:
    metadata:
      labels:
        app: local-test
    spec:
      containers:
      - name: test-container
        image: k8s.gcr.io/busybox
        command:
        - "/bin/sh"
        args:
        - "-c"
        - "sleep 100000"
        volumeMounts:
        - name: local-vol
          mountPath: /usr/test-pod
  volumeClaimTemplates:
  - metadata:
      name: local-vol
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "local-storage"
      resources:
        requests:
          storage: 368Gi

一旦StatefulSet启动并运行,PVC都将绑定:

$ kubectl get pvc
NAME                     STATUS   VOLUME              CAPACITY   ACCESS MODES   STORAGECLASS      AGE
local-vol-local-test-0   Bound    local-pv-27c0f084   368Gi      RWO            local-storage     3m45s
local-vol-local-test-1   Bound    local-pv-3ddecaea   368Gi      RWO            local-storage     3m40s
local-vol-local-test-2   Bound    local-pv-3796b049   368Gi      RWO            local-storage     3m36s

当不再需要磁盘时,可以删除PVC。外部静态供应商 将清理磁盘并使PV再次可用。

$ kubectl patch sts local-test -p '{"spec":{"replicas":2}}'
statefulset.apps/local-test patched

$ kubectl delete pvc local-vol-local-test-2
persistentvolumeclaim "local-vol-local-test-2" deleted

$ kubectl get pv
NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                            STORAGECLASS   REASON      AGE
local-pv-27c0f084   368Gi      RWO            Delete           Bound       default/local-vol-local-test-0   local-storage              11m
local-pv-3796b049   368Gi      RWO            Delete           Available                                    local-storage              7s
local-pv-3ddecaea   368Gi      RWO            Delete           Bound       default/local-vol-local-test-1   local-storage              19m

你可以找到完整的 文件资料 Kubernetes 网站上的功能。

什么是合适的用例?

本地持久卷相对于远程持久存储的主要优势 是性能:本地磁盘通常提供更高的IOPS和吞吐量,而更低 与远程存储系统相比的延迟。

但是,使用时有一些重要的限制和注意事项 本地永久卷:

  • 使用本地存储将您的应用程序绑定到特定节点,从而使您的 应用程序难以安排。使用本地存储的应用程序应 指定较高的优先级,以便不需要本地优先级的较低优先级的广告连播 存储,必要时可以抢占。
  • 如果该节点或本地卷遇到故障并变得不可访问,则 该吊舱也变得不可访问。手动干预,外部控制器, 或可能需要操作员从这些情况中恢复过来。
  • 虽然大多数远程存储系统实现同步复制,但大多数本地 磁盘产品不提供数据持久性保证。意思是损失 磁盘或节点可能会导致该磁盘上的所有数据丢失

由于这些原因,仅应考虑将本地持久性存储用于 在应用程序层处理数据复制和备份的工作负载,因此 使应用程序能够抵御节点或数据故障和不可用性 尽管在单个磁盘级别上缺少这样的保证。

良好的工作负载示例包括软件定义的存储系统和 复制的数据库。其他类型的应用程序应继续高度使用 可用,可远程访问的持久存储。

Uber如何使用本地存储

M3,Uber的内部指标平台, 大规模试点本地永久卷 为了评估 M3DB — 开源的分布式时间序列数据库 由Uber创建。 M3DB的显着特征之一是它具有分片功能 指标划分为分区,将其复制三倍,然后平均 将副本分散在单独的故障域中。

在进行本地持久卷试验之前,M3DB仅在 Uber管理的环境。随着时间的流逝,出现了内部用例,要求 在依赖较少的环境中运行M3DB的能力。所以团队开始 探索选项。作为一个开源项目,我们希望提供 社区,可以通过开放源代码尽可能轻松地运行M3DB 堆栈,同时满足M3DB对高吞吐量,低延迟的要求 存储和扩展能力。

Kubernetes Local Persistent Volume接口具有高性能, 低延迟的保证很快就成为建立在其上的完美抽象 某个东西的上放。使用本地永久卷,单个M3DB实例可以轻松地 每秒处理多达60万次写入。这为峰值留出了足够的空间 在通常每秒处理数百万个指标的群集上。

由于M3DB还可以优雅地处理丢失单个节点或卷的情况,因此 本地持久卷的数据持久性保证不是问题。如果一个 节点发生故障,M3DB找到合适的替代节点,新节点开始流式传输 来自两个同伴的数据。

得益于Kubernetes调度程序对卷拓扑的智能处理, M3DB能够以编程方式将其副本均匀地分散在多个 所有可用云区域中的本地持久卷,或者 跨所有可用服务器机架的本地群集。

优步的运营经验

如上所述,尽管本地永久卷具有许多好处,但它们 还需要仔细计划并仔细考虑约束之前 致力于生产。在考虑我们的本地量策略时 对于M3DB,Uber必须考虑一些事项。

首先,我们必须考虑节点中的节点的硬件配置文件 Kubernetes集群例如,每个节点群集将有多少本地磁盘 有?它们将如何划分?

本地静态供应商提供 指导 帮助回答这些问题。最好能够将一个完整的磁盘专用于每个本地卷 (用于IO隔离)和每个卷的完整分区(用于容量隔离)。 在我们可以混合和匹配本地的云环境中,这更容易 磁盘。但是,如果在本地使用本地卷,则硬件限制可能是 限制因素取决于可用磁盘的数量及其 characteristics.

首次测试本地卷时,我们希望对 the effect 破坏 (自愿和非自愿)在使用 本地存储,因此我们开始测试一些故障方案。我们发现 当本地卷变得不可用而节点保持可用时(例如 就像在磁盘上执行维护时一样),使用本地卷的Pod将 卡在ContainerCreating状态,直到可以装入该卷为止。如果一个节点 变得不可用,例如,如果将其从集群中删除或 耗尽 , 然后在该节点上使用本地卷的Pod会卡在Unknown或 待定状态取决于是否正常删除了该节点。

从这些临时状态中恢复豆荚意味着必须删除PVC绑定 将广告连播移至其本地卷,然后删除该广告连播以使其成为 重新计划(或等到节点和磁盘再次可用)。我们拿了这个 建立我们的时候要考虑到 算子 对于M3DB,它会更改 重新调整Pod的群集拓扑,以使新的Pod正常运行 从其余两个对等点传输数据。最终,我们计划使 完全删除和重新计划的过程。

关于Pod状态的警报可以帮助引起人们对卡在本地卷上的注意,并且 特定于工作负载的控制器或操作员可以自动进行补救。 由于这些限制,最好从 自动升级或修复,实际上某些云提供商明确 将此作为最佳做法。

本地和云之间的可移植性

Uber决定为Uber建立业务流程时,Local Volumes扮演了重要角色 使用Kubernetes的M3DB,部分是因为它是有效的存储抽象 在本地和云环境中也是如此。远程存储解决方案有 跨云提供商的不同特征,某些用户可能不喜欢 在自己的数据中心中使用网络存储。另一方面, 本地磁盘相对普遍,并提供了更可预测的性能 characteristics.

通过使用云中的本地磁盘编排M3DB,可以更轻松地获取 和Kubernetes一起运行,我们获得了信心,我们仍然可以使用我们的 操作员无需任何修改即可在我们的本地环境中运行M3DB。正如我们 解决了此类问题后,我们将继续致力于如何在本地运行Kubernetes。 重要的悬而未决的问题是一个很大的缓解。

本地永久卷的下一步是什么?

正如我们在Uber的M3DB中看到的那样,本地持久卷已成功 用于生产环境。采用本地持久卷 持续增长,SIG存储继续寻求反馈以寻求解决方案 improve the feature.

最常见的要求之一是寻求一种可以帮助 从故障节点或磁盘进行恢复,目前是手动过程(或 必须内置到操作员中的东西)。 SIG存储正在调查 创建一个可以由工作负载使用的通用控制器 类似的恢复过程。

另一个流行的要求是使用lvm支持动态配置。这个可以 简化磁盘管理并提高磁盘利用率。 SIG储存现为 评估此功能可行性的性能折衷。

卷入

如果您对此功能有任何反馈或有兴趣参与 设计开发,加入 Kubernetes 存储 特殊兴趣小组 (SIG)。我们正在迅速发展,并随时欢迎新的贡献者。

特别感谢所有帮助将此功能引入GA的贡献者, 包括Chuqiang Li(lichuqiang),Dhiraj Hedge(dhirajh),Ian Chakeres (ianchakeres),JanŠafránek(jsafrane),Michelle Au(msau42),Saad Ali (saad-ali),叶成富(cofyc)和玉泉人(nickrenren)。