从 lite-apiserver 看 SuperEdge 边缘节点自治

引言

在 SuperEdge 0.2.0版本中,lite-apiserver 进行了重大的架构升级和功能加强。本文将从 lite-apiserver 实现及其与其它 SuperEdge 组件协同的角度,分析 SuperEdge 的边缘自治能力,给你们的研究和选型提供参考。git

边缘节点自治

在云边协同的边缘计算场景中,边缘节点经过公网与云端链接。边缘节点众多,网络环境复杂,网络质量良莠不齐。边缘节点须要与云端弱网或断网状况下,继续正常工做,已运行的业务不受影响,达到边缘节点自治的目的。
为了实现边缘节点自治,须要处理如下场景:github

  1. 边缘节点与云端断连,可是它自己正常,上面运行的业务容器应该不被驱逐,也没有新的业务容器调度到该节点上
  2. 边缘节点与云端断连时,边缘节点上的 Kubernetes 组件和业务容器可继续运行
  3. 边缘节点与云端断连时,边缘节点重启后,节点上的 Kubernetes 组件和业务容器可运行
  4. 边缘节点与云端恢复后,边缘节点上的数据与云端保持一致

SuperEdge 使用分布式节点健康检查组件 edge-health 来处理场景1,使用 lite-apiserver 来应对场景二、三、4。bootstrap

lite-apiserver 是运行在边缘节点上的轻量级 apiserver,它代理节点上全部组件和业务容器访问云端 kube-apiserver 的请求,并对请求结果作高效缓存。在云边断连的状况下,利用这些缓存提供服务,实现边缘自治的能力。api

lite-apiserver 设计特性

lite-apiserver除了知足边缘节点自治的功能需求外,还须要知足如下设计特性:缓存

支持全部 Client 类型

做为边缘节点上访问云端 kube-apiserver 的惟一“出口”,lite-apiserver 须要支持全部类型的 Client ,包括以 bin (如 kubelet 等)或 pod (如 flannel\kube-proxy 等)形式运行的 Kubernetes 组件,以及以 InCluster 方式访问 kube-apiserver 的业务容器。
更进一步,若是边缘节点网络环境特殊,须要以代理等方式才能访问云端 kube-apiserver时,只用给 lite-apiserver 设置代理,全部组件便可正常访问云端 kube-apiserver,不须要每一个组件作单独的配置。安全

支持缓存全部类型资源

支持缓存全部类型资源,Kubernetes 内置资源和 Custom Resources。
边缘节点上运行的 Kubernetes 组件和业务容器的请求 kube-apiserver 的资源多样,若是只缓存部分资源类型或仅支持 Kubernetes 内置资源类型,在云边断连时,可能由于读取不到对应的缓存致使组件或业务失败,达不到边缘节点自治的效果。固然,支持全部类型资源的缓存(尤为是 Custom Resources ),也给数据的解析和处理带来了不小挑战。网络

安全

边缘节点分布普遍,环境复杂,更容易形成安全风险。安全问题也在边缘计算和 Kubernetes 管理中愈来愈受重视。
给 lite-apiserver赋予一个访问权限,其代理的全部请求扔掉自身的权限方式,都使用 lite-apiserver 的权限访问云端的 kube-apiserver,是一种常见的访问控制方案。因为 lite-apiserver 须要访问和处理全部类型的资源,则该权限必然是一个“超级”权限。在这种情形下,某一个边缘节点上的恶意程序就能够经过 lite-apiserver 对集群的全部资源进行操做,可能对整个集群进行恶意破坏。
所以,从安全角度,lite-apiserver 从设计上不该拥有一个“超级”权限,可使用 Kubernetes 组件和业务容器原有的认证和鉴权方式,访问云端 kube-apiserver。架构

支持多种缓存存储

根据 IDC 对边缘计算分层的定义,边缘分为 Heavy Edge(边缘数据中心)和 Light Edge(低功耗计算平台)。针对不一样的场景,lite-apiserver 能够采用不一样的缓存存储策略来达到更优的效果。在 Light Edge 中,lite-apiserver 使用文件存储缓存以下降其自己的系统开销,提高通用性。在 Heavy Edge 中,lite-apiserver 可采用 KV 存储等提高读写性能。app

下面咱们将从 lite-apiserver 的架构和关键技术方面,介绍其如何实现以上的功能需求和设计特性。异步

lite-apiserver 架构与关键技术

架构

lite-apiserver架构如图

从总体上看,lite-apiserver 启动一个 HTTPS Server 接受全部 Client 的请求(https request),并根据 request tls 证书中的 Common Name 选择对应的 ReverseProxy(若是 request 没有 mtls 证书,则使用 default),将 request 转发到 kube-apiserver。当云边网络正常时,将对应的返回结果(https response)返回给client,并按需将response异步存储到缓存中;当云边断连时,访问kube-apiserver超时,从缓存中获取已缓存的数据返回给client,达到边缘自治的目的。

  • HTTPS Server
    监听 localhost 的端口(SurperEdge 中为51003)接受 Client 的 Https 请求。
  • Cert Mgr && Transport Mgr
    Cert Mgr 负责管理链接 kube-apiserver 的 TLS 客户端证书。它周期性加载配置的TLS证书,若是有更新,通知Transport Mgr建立或更新对应的transport。
    Transport Mgr负责管理transport。它接收Cert Mgr的通知,建立新的transport,或者关闭证书已更新的transport的旧链接。
  • Proxy
    根据 request mtls 证书中的 Common Name 选择对应的 ReverseProxy(若是 request 没有 mtls 证书,则使用 default),将 request 转发到 kube-apiserver。若是请求成功,则将结果直接给 Client 返回,并调用 Cache Mgr 缓存数据;若是请求失败,则从 Cache Mgr 中读取数据给 Client。
  • Cache Mgr
    根据 Client 的类型分别缓存 Get 和 List 的结果数据,并根据 Watch 的返回值,更新对应的 List 数据。

关键技术

1. HTTPS Server

在当前架构下,lite-apiserver 只处理本节点的全部请求,使用 HTTP Server 能够知足性能和安全要求。然而,大部分组件和业务容器采用 client-go 库访问 kube-apiserver,若是使用 HTTP Server,Client 本身的认证和鉴权信息所有丢失,不符合权限管理的要求。所以必须采用 HTTPS Server。lite-apiserver 的 TLS Server 证书,需用 kube-apiserver 的 Server 证书相同的CA签发。

2. 支持 InCluster 方式访问

通常的 Client 经过指定 kube-apiserver 的 URL 访问 kube-apiserver,使用 lite-apiserver 时,只需将原来 kube-apiserver 的 URL 替换为 lite-apiserver 的地址便可。
在 Pod 中访问 kube-apiserver 的推荐方式是经过 kubernetes.default.svc 这个 DNS 名称,该名称将会解析为服务 IP,而后服务 IP 将会路由到 kube-apiserver。在这种场景下使用 lite-apiserver 须要一些小小的"魔法"。
在 SuperEdge 中,application-grid-wrapper 以 DaemonSet 的形式部署在每一个边缘节点上,经过给 kube-proxy 只返回本区域内的 endpoints 来达到访问在区域内闭环的目的。利用这个特性,application-grid-wrapper 把 kubernetes 这个 Service 的 endpoint 改成 lite-apiserver 的地址, 返回给本节点 kube-proxy,便可支持 InCluster 方式访问。

3. 支持 Client 的 Bootstrap Token 和证书轮换

lite-apiserver 使用 Client 本身的认证和鉴权方式,访问云端的 kube-apiserver。对于 static token、bootstrap token、service account 等方式,lite-apiserver 只需透传 Http Request 的 Header 中包含的认证鉴权信息便可。对于 TLS 客户端证书的认证方式,lite-apiserver 经过读取配置文件,加载全部 Client 用到的 TLS 客户端证书,使用这些证书构造对应的 HTTPS 请求 kube-apiserver。
为了支持 Client 的 Bootstrap Token 和证书轮换,lite-apiserver 须要周期性的加载和更新这些证书。kube-controller-manager 签发的证书默认时间是1年,lite-apiserver 加载 TLS 客户端证书周期不宜太短。但若是证书加载周期时间过长,kubelet 使用 Bootstrap Token 的场景中会存在证书更新不及时的问题。为了处理这些场景,lite-apiserver 采用一种“优雅”的证书加载策略:当加载证书出现错误或证书过时时,进入快速加载模式,周期是1s; 加载证书均成功时,进入普通加载模式,周期是30min。
当证书更新后,lite-apiserver 使用 client-go 提供的closeAll方法,关闭已存在的链接,以防认证鉴权失败。

4. 缓存解析和更新

lite-apiserver 须要支持缓存全部类型的资源,缓存的解析和更新是 lite-apiserver 实现的关键之一。lite-apiserver 分别缓存每一个 Client 的对资源的 Get 和 List 请求,这样虽然形成了必定的存储空间的浪费,可是也避免了复杂的资源版本转换。对于 Watch 类型的请求结果,lite-apiserver 采用unstructured.UnstructuredJSONScheme 解析出资源的 meta 信息,进而更新相应的 List 数据。

展望

SuperEdge 正式开源以来,获得了普遍的关注。SuperEdge 在快速迭代开发中,lite-apiserver 也有很多可扩展点,欢迎你们积极参与,共同打造一个优秀的云原生边缘容器项目。

  • 内存中缓存部分高频更新的资源,提高性能
  • 支持更多种类存储
  • 性能和内存优化,适应更普遍的边缘场景
相关文章
相关标签/搜索