zoukankan      html  css  js  c++  java
  • 容器化 RDS:你须要了解数据是怎样被写"坏"的

    版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/79877076

    640?wxfrom=5&wx_lazy=1

     

    容器化 RDS 系列文章:

     

    即使不使用 Kubernetes,在编排持久化 workload 时,你都须要了解编排框架和 Cloud Provider 是怎样交互的。数据又是怎样被写"坏"的。下面描写叙述的场景具有普遍意义,也是必须要回答的问题。

    640?wxfrom=5&wx_lazy=1

    简单场景

    640

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

    640


    Volume 使用流程大致例如以下:

    640


    • 生成 Volume

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

    略微复杂一点

    640

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

    • MySQL具备重建/故障切换/又一次调度的能力

     

    640

    Volume 使用流程也会更复杂一些:

    640


    • 生成 Volume

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

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

    • Volume 从原节点 unmount

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


    相比上个场景。添加了3个环节。
    复杂一点

    640

    大多数情况下 Kubernetes 不会直接管理 bare-metal。而是执行在第三方 Cloud Provider 上(GCE/Azure/AWS/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。

    640


    Volume 使用流程也会更复杂一些:

    640

    • 生成 Volume

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

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

    • 数据库实例由于recreate/failover/rescheduling,被调度其它节点

    • Volume 从原节点 unmount

    • Volume 从原节点 detach

    • attach 到新节点

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


    再复杂一点

    640

    须要继续思考一个问题:谁来“通知”Cloud Provider?
    Kubernetes 1.3 之前,以上全部的工作由 Kubelet 完毕。由Volume Plugin 适配第三方 Cloud Provider 的逻辑。

    640


    但 Kubelet 是执行在 Node 端的 Agent。
    一旦 Node 重新启动 / Crash / 网络故障,都会导致无法“通知”Cloud Provider,即便该 Volume 已经没有应用訪问。Cloud Provider 都不会让不论什么节点使用它。
    当然。还会有其它问题,譬如多个 Kubelet 带来的“race condition”。


    解耦 Attach-Mount-Unmount-Detach

    640

    流程不变,Kubernetes 1.3 之后。尝试使用专门的 Controller 管理 Attach 和 Detach 操作。

    640


    该 Controller 被叫做 AttachDetach Controller。它执行在已有的 Controller Plane 上。

    640


    通过“volumes.kubernetes.io/controller-managed-attach-detach”启动该特性(默认使用该特性)。
    问题还没有解决

    640

    attach-mount-umount-detach流程的串行有序是保障数据不被写“坏”的基础。

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

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

     

    所以。假设 Volume 不能被 Kubelet 成功地 unmount,AttachDetach Controller 不能进行 detach 操作。
    又回到之前的问题。
    Kubelet 是执行在 Node 端的 Agent,一旦 Node 重新启动 / Crash / 网络故障,都会导致无法完毕 unmount 操作。 
    AttachDetach Controller 不可能无限制的等待前置动作 unmount,所以通过參数 maxWaitForUnmountDuration(默认6分钟)解决该问题。

    640

    超过 maxWaitForUnmountDuration。AttachDetach Controller 会启动 force detaching。


    这破坏了 attach-mount-umount-detach 流程的串行有序,一个 RW Volume 在多个节点上挂载的可能性出现了。


    数据可能被写“坏"

    640

    Kuberetes 集群的正常执行,依赖 API Server 跟 Kubelet 的正常交互,能够理解为”心跳”。

    640


    “心跳”丢失的可能性非常多,譬如:

    1. Node 重新启动 / Crash。

    2. Node 跟 API Server 网络故障;

    3. Node 在高负载下,Kubelet无法获得 CPU 时间分片;

    4. 等等

    换句话说,一旦“心跳”丢失,集群无法推断 Node 的真实状态。

    这时执行在 Controller Plane 之上的 NodeLifecycle Controller 会把该节点标记为“ConditionUnknown”。
    一旦超过阈值podEvictionTimeout,NodeLifecycle Controller会对该节点上执行的 MySQL 进行驱赶,Scheduler会将 MySQL调度到其它“available”节点。
    配合上 force detaching 导致的“多点挂载”,多个实例对同一个 Volume 的“Write”导致“Data Corruption”。

    640

  • 相关阅读:
    【题解】【BT】【Leetcode】Populating Next Right Pointers in Each Node
    【题解】【BT】【Leetcode】Binary Tree Level Order Traversal
    【题解】【BST】【Leetcode】Unique Binary Search Trees
    【题解】【矩阵】【回溯】【Leetcode】Rotate Image
    【题解】【排列组合】【素数】【Leetcode】Unique Paths
    【题解】【矩阵】【回溯】【Leetcode】Unique Paths II
    【题解】【BST】【Leetcode】Validate Binary Search Tree
    【题解】【BST】【Leetcode】Convert Sorted Array to Binary Search Tree
    第 10 章 判断用户是否登录
    第 8 章 动态管理资源结合自定义登录页面
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/9907359.html
Copyright © 2011-2022 走看看