打破内网壁垒,从云端一次添加成百上千的边缘节点

466 阅读7分钟

作者

李腾飞,腾讯容器技术研发工程师,腾讯云TKE后台研发,SuperEdge核心开发成员。

王冬,腾讯云TKE后台研发工程师,专注容器云原生领域,SuperEdge 核心开发人员,现负责腾讯云边缘容器TKE Edge私有化相关工作。

背景

在边缘计算的场景中,边缘节点分布在不同的区域,而且大多数边缘节点是藏在NAT网络背后的,且边缘节点和云端之间是单向网络(边缘节点可以访问云端,云端无法直接访问边缘节点)。这种场景下如何批量的将众多的边缘节点添加到一个边缘集群是一个问题?如果有一种机制,让用户可以从云端批量添加和重装位于边缘的节点,是一件解放生产能力的大事。针对这一需求,SuperEdge 项目研发了 Penetrator 组件,实现了从云端批量的添加和重装节点的能力。

需求分析

总体来说,具体的需求可以细分为两种:

云端控制面能直接 ssh 到边缘节点

该场景下,云端管控平面和边缘节点有可能运行在同一内网内,也有可能公网可通,无论是哪种形式,总之在云端控制平面能直接 ssh 到边缘节点。这种场景使用最朴素的方式即可,即直接手动或者通过工具 ssh 到边缘节点完成节点添加,无需使用复杂的方式。

云端控制面不能 ssh 到边缘节点

该场景下,云端管控平面和边缘节点不在同一内网,有可能是单向网络,如:边缘节点位于 NAT 网络。这种情况下,边缘节点可以访问管控平面,但是无法从管控平面直接 SSH 到边缘节点。这种场景是本文重点处理的重点,针对这种场景设计出了一种简化边缘节点添加的组件 Penetrator。

Penetrator的架构设计

云端管控平面无法直接连接边缘节点,现有的解决方案是搭建跳板机访问内网节点,边缘节点可能处于不同的内网中,在每个内网环境都搭建跳板,会带来额外的机器资源的开销和运维人员的工作量。在云端管控平面可以连接用户集群的 apiserver 的情况下,可以在管控平面向用户集群的 apiserver 下发一个添加节点的 job,job被调度到集群内的一个节点执行,具体实现如下图所示:

在云端管控平面运行k8s,管理用户的k8s集群,因此可以在云端的管控平面运行 Operator 来实现。

Penetrator 通过集群内节点添加节点

用户通过 kubectl 向 apiserver 发送请求,创建一个 nodes-task-crd CRD,Penetrator 监听到 task 任务创建之后,Penetrator 就会创建一个job任务,同时会生成 job 运行所需的 configmap 配置文件,这个 job 任务会被调度到指定的node-1节点上执行添加节点的操作。创建的 job 和 configmap 的 ownerReference 指向 nodes-task-crd CRD,在 CRD 删除之后 Kubernetes 的 GC 会自动删除生成的 job 和 configmap。

Penetrator 会周期请求用户集群的 apiserver,查询 job 的运行状态,如果 job 不存在,则会去请用户集群的apiserver,获取节点的安装状态,在节点没有全部安装完成,会根据未完成安装的节点信息重新下发 job 运行所需的 configmap 配置文件 add-node-cm,同时也会重新下发 job。为避免多个任务在同一个目标机器上执行添加节点的命令,对于一个添加节点的 task,有且只有一个 job,同时还要保对于一个用户的 k8s 集群,只能创建一个task 任务。

Penetrator云端直连添加节点

与通过集群内的节点添加节点不同,添加节点的job是运行在管控平面的k8s集群,具体设计如下图所示:

如图所示,用户通过 kubectl 向 apiserver 发送请求,创建一个 nodes-task-crd crd,Penetrator 监听到 task 任务创建之后,会创建 job 运行所需的 configmap 配置文件 add-node-cm 和登录目标机器节点的 ssh 的密码(passwd) 或私钥 (sshkey) 的secret,同时会创建一个 add-node-job job。add-node-job 运行在管控平面的 k8s 集群内,ssh 登录内网的节点,执行安装节点的命令。

Penetrators 实现的功能

批量安装边缘节点

NodeTask 的 spec.要添加的节点的 ip 列表,Penetrator 会根据节点名前缀生成节点名,将节点名和信息保存到configmap 中,下发job时挂载该 configmap 做为 job 的启动配置文件。

批量重装边缘节点

每次创建的 NodeTask 都会有唯一标签,NodeTask 在安装完节点之后会给节点打上该标签,同时 NodeTask 使用 label 判断节点是否安装完成,重装时节点的标签和 NodeTask 标签不一致,就会对节点执行重装操作。

Penetrator 的在 SuperEdge 的具体使用

功能演示的视频链接

用 edgeadm 搭建 SuperEdge Kubernetes 边缘集群

如何搭建:用edgeadm一键安装边缘独立Kubernetes 集群

部署 Penetrator

在 SuperEdge Kubernetes 边缘集群 Master 节点执行如下命令:

kubectl apply -f https://raw.githubusercontent.com/superedge/superedge/main/deployment/penetrator.yaml

具体使用见:使用 penetrator 添加边缘节点

创建边缘节点密钥的 secret

Penetrator 组件是基于 Kubernetes 的 CRD 实现的,要用 Penetrator 进行边缘节点的批量安装,需要提供边缘节点的登录方式,可以通过下面的方式提供:

  • 使用 SSH 的密码文件 passwd 创建 sshCredential

    kubectl -n edge-system create secret generic login-secret --from-file=passwd=./passwd
    
  • 或者,使用 SSH 的私钥文件 sshkey 创建 sshCredential

    kubectl -n edge-system create secret generic login-secret --from-file=sshkey=./sshkey
    

    其中./passwd 和./sshkey 文件中分别保存的是目标节点 root 用户的登录口令和私钥(明文)

用 Penetrator 批量添加或批量重装边缘节点

下面分别给出批量添加边缘节点和批量重装节点的 yaml:

批量添加边缘节点的例子

apiVersion: nodetask.apps.superedge.io/v1beta1
kind: NodeTask
metadata:
name: nodes
spec:
nodeNamePrefix: "edge"        #节点名前缀,节点名的格式: nodeNamePrefix-随机字符串(6位)
targetMachines:                    #待安装的节点的ip列表
  - 172.21.3.194
  - 172.21.3.195
sshCredential: login-secret     #存储目标节点root用户的登录口令(passwd)或者私钥(sshkey)的Secret
proxyNode: vm-2-117-centos  #集群内某个节点的节点名,该节点起到跳板机的作用,要求必须可以使用targetMachines中的ip地址ssh到待安装的节点

效果:

kubectl get nodes –show-labels | grep edge | wc -l
50

批量重装边缘节点的例子

apiVersion: nodetask.apps.superedge.io/v1beta1
kind: NodeTask
metadata:
name: nodes
spec:
nodeNamesOverride:            #重装节点的节点名和IP
  edge-1mokvl: 172.21.3.194 #此处支持更改节点nodename,如:172.21.3.194节点之前的nodename为a,本次重装更改成edge-1mokvl
sshCredential: login-secret
proxyNode: vm-2-117-centos

效果: 重装 edge-uvzzijv4 节点之前

kubectl get nodes -o wide –show-labels
NAME               STATUS   LABELS
edge-uvzzijv4    Ready   app.superedge.io/node-label=nodes-lokbfd
...

重装 edge-uvzzijv4 节点之后

kubectl get nodes -o wide –show-labels
NAME               STATUS    LABELS
edge-uvzzijv4   Ready      app.superedge.io/node-label=nodes-pfu8en

批量任务状态查看

在执行完批量操作后,可查询 task 的具体状态。

NodeTask 的 Status 中包含任务的执行状态 (creating和ready) 和未安装完成节点的节点名和IP,可以使用下面命令查看:

kubectl get nt NodeTaskName -o custom-columns='STATUS:status.nodetaskStatus'

任务在执行过程的成功和错误信息以事件的形式上报的apiserver,可以使用下面命令查看:

kubectl -n edge-system get event

小结

针对云端管控平面和边缘节点不同的网络情况,选择不同的批量添加节点的形式,实现在云端管控平面批量添加节点。同时,添加 kubernetes 集群节点时需要安装文件,通过内网分发,缩短节点安装的时间,提高了节点安装的效率。

未来展望

未来我们会支持使用 Penetrator 在多集群纳管的场景下支持添加集群的节点。

合作和开源

Penetrator 组件已经在 SuperEdge release 0.4.0 开源,欢迎大家体验。我们也会成持续提升 Penetrator 的能力,简化边缘集群场景下节点的操作,也欢迎对边缘计算感兴趣的公司、组织及个人一起共建 SuperEdge 边缘容器项目。