背景
为了提升边缘节点在弱网情况下的自治能力,SuperEdge 做了很多工作,比如:边缘节点在断网的情况下可以保证节点层面正常运行以及 fail over,但是在高可用层面仍然存在缺陷: 边缘地域节点在离线状态下,pod 无法在地域节点之间迁移,同时断网情况下边缘地域无法实现本地自运维能力。为了这些满足高可用的需求,SuperEdge 推出了Kins(K3s in SuperEdge)来支持边缘地域部署 K3s 集群实现边缘地域的高可用性。通过 Kins
的特性,用户可以在云端通过控制边缘节点池(NodeUnit),使用 K8s API 在边缘地域独立拉起标准的 K3s 集群,并和 SuperEdge 的组件共存,为用户的业务提供标准的边缘 K3s 集群服务,同时提供升级、添加/删除节点、集群回收等全生命周期管理能力。
设计与实现
架构设计
现有设计的困境
现有 SuperEdge 的设计,在断网的情况下,边缘节点的自治能力的核心是基于节点与pod的强绑定关系,也就是说在断网情况下,pod 只能绑定在固定的节点上进行恢复,而不能跨节点迁移,其核心原因在于如果实现了断网迁移的话,和云端 apiserver 链接恢复后,云端和边端的 apiserver 的数据同步会出现不一致问题,因此 SueprEdge 的架构限制了边缘地域的这种高可用能力。
SuperEdge 现有的节点池(NodeUnit)能力设计时始终受到这种强绑定关系的掣肘,边缘节点组件 lite-apiserver 的设计也受制于这种掣肘,lite-apiserver 作为影子apiserver (shadow apiserver)只缓存本节点的pod资源。节点池(NodeUnit)虽然作为一个节点池,但是节点之间又无法组成集群能力实现集群层面高可用,因此在断网情况下高可用性会打一定的折扣。
我们退而求其次,考虑是否能够将节点池(NodeUnit)使用云原生方式提升为标准 K3s 集群,对业务侧直接开放 K3s 入口供用户使用,实现在断网情况下的集群级高可用能力,因此我们提出了Kins
的解决方案。
自治能力的跨越提升
为了满足高可用的需求,需要使 pod 可以在节点池(NodeUnit)内节点之间漂移,打破节点和pod的强绑定关系,具体设计如下:在边缘节点池(NodeUnit)中通过类似 K8s on K8s 的方式运行 K3s 独立集群,用户可以将需要满足fail over的应用运行在 K3s 集群中,同时 SuperEdge 的节点自治能力保障 K3s 独立集群的 K3s-agent 和 K3s-server 在断网情况下的正常运行,这样就将自治能力从节点跨越提升到集群级别。
具体实现
新的设计方案需要在节点上同时运行kubelet
和k3s-agent
,这两个组件都会在节点上创建和运行 pod,因此需要 共享运行时、pod网络和pod存储,下面分别展开描述:
运行时的设计
containerd
基于不同 ns 隔离来自不同kubelet
的PLEG(Pod Lifecycle Event Generator),同时通过资源保留隔离一个节点两个kubelet的容器资源分配,因此需要开发能转发不同containerd
namspace的CRI(Container Runtime Interface) server,从而达到使用最小的资源开销做到共享统一运行时组件。
网络设计
Kins 在网络上的设计原则是不额外引入单独的网络栈,不增加额外的网络损耗,K3s 独立集群和 SuperEdge 集群共用同Flannel网络方案,由于Flannel配置的 podcidr
为SuperEdge节点的 podcidr
,因此 K3s-agent 创建的出来的 pod 的 podIp 也在这个podcidr
网段内,而不在 K3s-server 分配的节点 podcidr 网段内,也就是说 SuperEdge 创建的 pod 和 Kins 创建的 pod 都是处于统一的网路平面,因此需要对每个Kins节点计算剩余的可用IP数量从而限制最大的pod创建数量。
在 Service 和 NodePort 的处理上,为了避免两个 kube-proxy 同时写转发规则可到导致的冲突(kube-proxy会restore节点上转发规则),因此节点上的 kube-proxy 需要同时watch
SuperEdge 和 K3s 集群的 Service 和 Endpoint,同时要求 K3s 集群的 Service cidr 和 Nodeport 端口范围要和 SuperEdge 的区分开。为了实现此功能,需要拓展 SuperEdge 的边缘节点组件application-wrapper
能力,application-wrapper
组件的功能拦截和过滤 kube-proxy watch
的 SuperEdge 集群的 Endpoint 资源,引入 Kins 能力后,application-wrapper
组件会额外 watch
K3s 的 Apiserver,从而在同一节点网络栈内实现 K3s 的 Dnat 和 Snat 能力。
存储设计
kubelet 和 K3s-agent 共用同一个运行时,为了将创建的 pod 的区分开来,需要再创建容器时传入不同的路径,比如podLogsRootDirectory,这个路径在 kubelet 中是一个常量(/var/log/pods),因此需要再编译 K3s-agent 时需要修改 podLogsRootDirectory 的路径值。
如何使用 Kins 特性
创建节点池并开启 Kins 特性
apiVersion: site.superedge.io/v1alpha2
kind: NodeUnit
metadata:
name: {{.nodeuintName}}
spec:
autonomyLevel: L4
nodes:
- edge-node-1
...
type: edge
使用 yaml 创建创建边缘节点池,autonomyLevel
设置L3\L4\L5,其中L3为标准节点节点、L4为单 master K3s 节点池、L5为三 master K3s 节点池,节点池创建之后,site-manager
会watch
到NodeUint资源,然后进行 K3s 独立集群的创建,具体创建流程如下:
site-manager watch
到 AutonomyLevel为L4\L5的NodeUnit。创建 cri-wrapper daemonset 到该站点上所有节点。 site-manager 在站点内选出合适的三个节点做 Kins 集群 master。 计算合适的 Kins server(K8s控制面) service cidr和 NodePort range(这里不能和SuperEdge的有冲突)。 创建三个kins server deployment和service,并将server pod所在的 SuperEdge 节点标记为不可调度,即当前无法支持动态混部,一个NodeUnit一旦被 Kins 接管,那么他的计算能力就全部转移到 Kins。 创建 Kins agent(K8s节点上组件)到站点内所有节点,并计算节点上已经分配的计算资源和网络资源,然后确定 Kins agent 参数。
创建kins集群所需的资源都在kins-system
namespace下,比如访问 Kins 集群 apiserver 的 kubeconfig,这个 kubeconfig 可以用在边缘节点访问 Kins apiserver,如果想要通过云端访问,请参照下面小结---云端运维K3s独立集群
云端运维 K3s 独立集群
设计实现
在边缘节点池连网的情况下,SuperEdge 集群提供了通过云端访问 K3s 独立集群的 apiserver 的入口,用户可以通过 Tunnel 隧道远程运维边缘 K3s 集群。具体设计如下图所示:
在kubeconfig
中配置proxy-url
指向 tunnel-cloud 的 http-proxy 端口,会在 kubectl 想 K3s-server 发送请求之前建立一条 http-proxy 隧道,该隧道是建立在 Tunnel 双向隧道基础之上的,然后 kubectl 到 K3s-server 之间的数据交互都是通过这条隧道完成的,http-proxy 隧道是无侵入性的,会透传 kubectl 和 K3s-server 交互的 https 数据,因此能支持 token 和 client 证书访问 K3s-server。
kubeconfig 配置
获取集群的 K3s 集群的 kubeconfig
kubectl -n kins-system get cm {{.nodeuintName}}-cm-kins -o=jsonpath='{.data.kubeconfig\.conf}
选取 name 为 http-proxy 的 nodePort 作为 http-proxy-port,SuperEdge 集群的 master 节点的外网ip作为 tunnel-cloud-ip,根据获取的 tunnel-cloud-ip 和 http-proxy-port 在 kubeconfig 中添加 proxy-url 参数
kubectl -n edge-system get svc tunnel-cloud -o=jsonpath='{.spec.ports}' | jq '.[] | {name:.name , nodePort:.nodePort}'
使用 {{.nodeuinitName-svc-kins.kins-system}}
替换 kubeconfig 中的 server 参数
总结与展望
Kins 特性是 SuperEdge 社区在提升边缘地域自治能力方面的一次突破性探索,将自治能力的粒度从节点级别提升到节点池级别,满足了用户在边缘场景下边缘地域高可用的需求。Kins 特性已经在社区 release,同时也上线到公有云产品,欢迎大家试用,并提出你宝贵的 issue。我们也会继续完善 Kins 特性,并进一步提升边缘端自治能力,满足更多边缘计算领域的需求。