背景
OpenYurt 我的项目的使命是将 Kubernetes 在云端弱小的管控能力下放到边缘测,把海量的异构边缘资源纳入进一个对立的边缘计算平台中。但边缘场景的一些特点并不合乎为在云上运行而设计的 Kubernetes 的预设。这也正是 OpenYurt 须要解决的问题。边缘自治能力就是在这样的背景下诞生的。
与平安稳固的云上网络环境不同,在边缘场景中,边缘节点与云上的节点通常是不在一个网络立体内,须要通过公网与云端连贯。公网连贯带来了几方面的问题,比方昂扬的公网流量老本,跨网域通信能力的需要以及本文所关注的公网连贯的不稳定性问题。这些在 OpenYurt 体系里都失去了很好的解决。
咱们明天次要想和大家分享 OpenYurt 社区针对最初一个问题的思考,以及针对其而设计的 OpenYurt 边缘自治能力。
Kubernetes 在不稳固网络环境下的问题
咱们先看看原生 Kubernetes 在不稳固网络环境下会如何体现。当一个 Node 节点网络连接中断,那么接下来在 Kubernetes 集群会有一系列的动作来解决这个事件[1]。
- Node 节点上的 kubelet 在 10s 内发现网络问题,并且更新 NodeStatus,然而因为网络断开无奈上报到 Control Plane。
- Control Plane 的 NodeLifeCycle Controller 在 40s 内接管不到 Node 的心跳,该节点状态被调整为 Not Ready,不会再有新的 Pod 调度到该节点上。
- Control Plane 的 NodeLifeCycle Controller 在 5min 内接管不到 Node 的心跳,开始驱赶 Node 节点上所有的 Pod。
当一个节点无奈上报心跳,Kubernetes 集群据此判断该节点存在异样,作为异样资源它不再适宜反对下层的利用。这样的做法对于数据中心里全天 24h 随时在线的机器是适合的,但在网络环境简单的边缘场景里,这样的策略就有待商讨了。
首先,在一些边缘场景中,边缘节点须要被动地中断网络连接来反对断网保护的需要,此时原生 Kubernetes 会驱赶边缘容器,一些边缘组件也会因为 APIServer 无奈连贯,资源同步失败而报错,甚至退出,这显然是无奈承受的。更深刻一些,节点无奈上报心跳这个景象背地可能有两方面的起因,要么是机器故障带着所有的 workload 一起挂掉了,要么是机器仍在失常运行但网络断连。Kubernetes 对这两种状况不做别离,间接将没有心跳的节点置为 Not Ready。但在边缘场景中,网络断连是一种常见的场景甚至需要,咱们能不能分辨出这两类起因,仅在节点故障时才对 Pod 进行迁徙重建。
其次,还有一类典型的边缘业务甚至要求在节点故障时也不要对 Pod 进行驱赶,它们须要将特定的 Pod 绑定到特定的节点上。比方图像处理的利用须要绑定到摄像头对应的机器上,智慧交通的利用须要固定在某个路口的机器上。这种与节点绑定的需要实际上违反了 Kubernetes 将底层资源与下层利用隔离开的设计理念,但这也是边缘业务确有的诉求,是须要 OpenYurt 来反对的。
最初,咱们还须要思考断网重启的状况。在原生 Kubernetes 架构下,Slave Agent(Kubelet) 的容器信息都保留在内存中,而断网状态下又无奈从云端获取业务数据,如果此时边缘节点或者边缘节点的 Kubelet 产生异样重启,它们将无奈进行业务容器复原。
OpenYurt 边缘自洽能力保障业务继续运行
如果用一句话来总结边缘自治的需要,那就是保障弱网甚至断网环境下边缘业务的继续运行。而在 Kubernetes 体系下要实现这样的能力,咱们须要解决以下几个问题:
- 节点异样或重启时,内存数据失落,网络断连时业务容器无奈复原
- 网络长时间断连,云端控制器对业务容器进行驱赶
- 边缘业务如何绑定到特定边缘节点
OpenYurt 提供了从云到边一整套残缺的解决方案来应答边缘自治的挑战。
边缘侧数据缓存
在边缘测,OpenYurt 引入了一个重要的组件——YurtHub。YurtHub 在边缘节点上提供 web 缓存及申请代理的的能力,节点上零碎组件 (如 kubelet) 以及业务容器和云端通信都将经由该组件代理。
- 云边网络失常时,YurtHub 相当于一个带有数据缓存性能的“通明网关”,将申请转发到云端并缓存返回的数据。
- 云边网络断连时,YurtHub 将申请切流至本地缓存,使得边缘组件仍然能胜利获取资源。如果此时产生节点或组件重启,不须要依赖云端的数据,边缘业务能够通过本地数据缓存复原。
- 与云端的通信复原后,Yurthub 切流回云上的核心站点,本地缓存得以更新,代理申请恢复正常转发。
YurtHub 不仅优雅地解决了断网重启问题(问题 1),而且这一层对 APIServer 额定的封装也拓展出了许多其余重要的 OpenYurt 能力[2]。
核心式心跳代理机制
OpenYurt 对原生 Kubernetes 的 Pod 驱赶策略进行了肯定水平的加强。在原生 Kubernetes 中,边缘节点心跳肯定工夫没有上报时,云端控制器将对节点上 Pod 进行驱赶(删除并在失常节点上重建)。云边协同场景下,边缘业务有不一样的需要。一些业务期待云边网络断连造成心跳无奈上报时(此时节点自身失常),业务 Pod 能够放弃(不产生驱赶),仅节点故障时才对 Pod 进行迁徙重建。
OpenYurt 1.2 版本独创了基于 Pool-Coordinator+YurtHub 的核心式心跳代理机制,如下图:
- 节点的云边网络失常时,Kubelet 通过 YurtHub 组件同时上报心跳到云端和 Pool-Coordinator 两处。
- 节点的云边网络断连时,Kubelet 通过 YurtHub 组件上报心跳到云端失败,此时上报到 Pool-Coordinator 的心跳带上特定标签。
- Leader YurtHub 会实时 list/watch pool-coordinator 中的心跳数据,当取得的心跳数据中带有特定标签时将帮忙转发该心跳到云端。
通过 Pool-Coordinator 和 YurtHub 协同实现的心跳代理机制,保障了节点在云边网络断连状态下,心跳仍可持续上报到云端,从而保障节点上业务 Pod 不被驱赶(问题 2)。同时心跳被代理上报的节点,也会被实时加上非凡的 taints,用于限度管控调度新 Pod 到该节点。
节点绑定
一些边缘业务要求在节点故障时也不对 Pod 进行驱赶,将业务绑定到节点上。OpenYurt 提供了两个角度来解决这个问题。
第一个角度从节点的角度登程,比方心愿这个机器上的所有 Pod 都绑定到这台机器上。那么咱们能够给这个节点打上标签 http://node.beta.openyurt.io/autonomy=true。
第二个角度是从业务登程,比方之前提到的智慧交通的业务心愿它的生命周期和它运行的节点的生命周期保持一致。OpenYurt 1.2 版本新增了 http://apps.openyurt.io/binding 标签,如果 Pod 上带有这个标签,意味着这个 Pod 须要节点绑定的能力。
这两种形式实际上最终都是通过给对应 Pod 增加 toleration 实现绑定能力的。
总结
在边缘场景下,因为云边网络连接不稳固,须要边缘侧在短少云端反对时有肯定的自治能力。OpenYurt 基于原生 Kuberbetes 的架构,提出了一套非侵入式的解决方案,解决了边缘自治的几个痛点问题(节点断网重启,节点断网驱赶,节点业务绑定)。
相干链接
[1] 一系列的动作来解决这个事件 https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/589-efficient-node-heartbeats/README.md
[2] 许多其余重要的 OpenYurt 能力 https://openyurt.io/zh/docs/core-concepts/yurthub/
作者:陈璐、陈东
原文链接
本文为阿里云原创内容,未经容许不得转载。