应用场景:从存储池获取RW Volume,挂载到指定Node上,并在该Node上启动持久化应用MySQL。

Volume的使用流程是

  • 生成Volume

  • mount到数据库实例所在节点,数据库启动

复杂场景

从存储池获取Volume,挂载到指定Node上,并在该Node上启动持久化应用MySQL

MySQL具备重建/故障切换/重新调度能力

Volume的使用流程将变得复杂一些:

  • 生成Volume

  • mount到数据库实例所在节点,数据库启动

  • 数据库实例因为recreate/failover/rescheduling,被调度新节点

  • Volume从源节点unmount

复杂场景-02

多数情况下,kubernetes不会直接管理bare-metal,而是运行在第三方的Cloud Provider(GCE/Azure/OpenStack)。Kubernetes作为Volume的使用者,由Cloud Provider负责Volume的生命周期。

因此,mount/unmount会发生一些变化:

  • Volume在mount之前,需要通知Cloud Provider

  • Volume在unmount之后,需要通知Cloud Provider

如果Volume在unmount之后,没有通知Cloud Provider,Cloud Provider将保证Volume不会挂载到其他Node。

而“多点挂载”在大多数场景下会导致Data Corruption,因此上面的两个步骤十分必要。

Cloud Provider需要感知Volume的使用场景,比如,GCE是不允许RW Volume同时挂载到多个节点,而这两个步骤称为attach/detach

Volume的使用流程:

  • 生成Volume

  • attach到数据库实例所在节点

  • mount到数据库实例所在节点,数据库启动

  • 数据库实例因为recreate/failover/rescheduling,被调度到其他节点

  • Volume从原节点unmount

  • Volume从原节点detach

  • attach到新节点

  • mount到新节点,数据库启动

复杂场景-03

在kubernetes 1.3之前,通知Cloud Provider的工作由kubelet完成,会由Volume Plugin适配第三方Cloud Provider的逻辑。

kubelet是运行在Node端的Agent。

一旦Node重启/Crash/网络故障,都会导致无法通知Cloud Provider。此时,即使Volume已经没有应用访问,但Cloud Provider也不会让任何节点使用它。

复杂场景-04

kubernetes 1.3之后,尝试使用专门的Controller管理Attach和Detach操作。

该Controller称为AttachDetach Controller,运行在已有的Controller Plane上。

通常,使用volumes.kubernetes.io/controller-managed-attach-detach 启动该特性。

问题继续-01

attach-mount-unmount-detach流程的串行有序是保证数据不被写坏的基础。

  • Volume在mount之前,kubelet会确认是否已经attach

  • Volume在detach之前,AttachDetach Controller会确认是否已经unmount

如果,Volume不能被kubelet成功的unmount,AttachDetach Controller不能进行detach操作。

AttachDetach Controller不可能无限制的等待前置动作unmount,所以通过参数maxWaitForUnmountDuration 解决问题。

当超过maxWaitForUnmountDuration时间时,AttachDetach Controller会启动force detaching。

这样,就会破坏attach-mount-unmount-detach的串行流程,一个RW Volume在多个节点的挂载的可能性就出现了。

问题继续-02

Kubernetes集群的正常运行,依赖API Server与kubelet的正常交互,可以将其理解为“心跳”。

心跳丢失的可能性很多:

  • Node重启/Crash

  • Node与API Server的网络故障

  • Node在高负载下,kubelet无法获得CPU时间分片

一旦心跳丢失,集群将无法判断Node真实状态。运行在Controller Plane的NodeLifecycle Controller会将该节点标记为ConditionUnknown

一旦超过阈值podEvictionTimeout,NodeLifecycle Controller会对该节点上运行的MySQL进行驱逐,Scheduler会将MySQL调度到其他的available节点。

配合force detaching导致的“多点挂载”,多个实例对同一个Volume的Write将会导致Data Corruption。

【参考】

1。 原文链接:https://docs.google.com/document/d/1Q0xYOGpHvZ0LFXpzG98f6tZeWguBjgvBaGrSDiTkMXM/edit

2。微信链接:http://mp.weixin.qq.com/s/fgOqXIVUA1yfpIi1udTdvA

results matching ""

    No results matching ""