共计 4344 个字符,预计需要花费 11 分钟才能阅读完成。
背景
在边缘集群的场景下边缘节点散布在不同的区域,且边缘节点和云端之间是单向网络,边缘节点能够拜访云端节点,云端节点无奈间接拜访边缘节点,给边缘节点的运维带来很大不便,如果能够从云端 SSH 登录到边缘节点能够简化节点的运维工作。针对这一需要,SuperEdge 我的项目扩大了 tunnel 组件的能力,新增了 SSH 模块,让用户能够从云端 SSH 登录到边缘节点。
需要剖析
边缘集群的节点散布在不同的区域,边缘节点可能拜访云端 master 节点,但 master 节点无法访问边端区域内的节点,用户心愿通过拜访 master 节点的端口 SSH 登录到节点施行运维工作。
惯例计划
应用 SSH 端口转发技术能够实现 SSH 运维边缘节点性能,具体内容如下图所示:
- 边缘节点 node-A 和 node-B 通过 SSH 的近程转发 (ssh -R) 将云端 master-A 节点的 port-A 和 port-B 端口与本地 22 端口 (SSH Server 的端口) 绑定
- user 通过 SSH 的动静转发 (ssh -D) 与 master-A 建设 SSH 隧道同时在本地监听 local-port 端口
- local-port 的申请都会通过 SSH 连贯传到 master-A,由 master-A 转发,例如 SSH 登录 node-A:ssh -o ProxyCommand=”nc -X 5 -x 127.0.0.1:local-port 127.0.0.1 port-A”root@127.0.0.1,127.0.0.1 port-A 就是 master-A 转发时申请的指标地址。
惯例计划的毛病:
- 边缘节点映射端口治理简单
如图 2 所示,node-A 和 node-B 将本地的 22 端口在 master-A 上映射为不同的端口,SSH 登录指标节点须要指定其在 master- A 映射的端口,当边缘节点数量很多时端口映射治理非常复杂,间接导致计划不可行。 - 申请波及的多个连贯,减少了出错的概率
以 SSH 登录 node- A 为例,如图 1 所示,sshClient->local-port,user->master-A,master-A->port-A,master-A->node-A,node-A->sshServer,共计须要建设 5 条连贯。 - 云端和边端的 SSH 保护麻烦
边端节点和云端节点的 SSH 连贯,须要在边端节点上执行建设,且连贯不具备断开重连的能力,保护起来比拟麻烦。
tunnel 计划
架构设计
- SSH Client 申请 tunnel-cloud service 暴漏到外网的 NodePort-1 端口,service 依据负载平衡策略将申请转发 tunnel-cloud pod-A 或 tunnel-cloud pod-B。
- 如果申请转发到 pod-A(R.1.1),因为 node-A 没有和 pod-A 建设隧道,pod-A 会查问 coredns 获取与 node-A 建设隧道的 pod-B 的 podIp,而后将申请转发到 pod-B(R.1.2)
- pod-B 收到申请后将申请通过隧道转发到 node-A 的 tunnel-edge,tunnel-edge 将申请转发到 SSH Server。
本计划的劣势
- 在云端和边缘节点间的隧道不会映射端口,避开端口治理。
- 缩小了申请过程中的建设连接数,缩小了出错的概率
- 云端和边端的隧道具备断开重连机制,升高保护老本
云边隧道的建设
应用 gRPC 开源我的项目搭建长连贯隧道,gRPC 实现断开重连机制。
- tunnel-edge 向 tunnel-cloud 发送建设 gRPC 连贯的申请
tunnel-edge 在向 tunnel-cloud 的 NodePort-2 发送建设连贯的申请,申请中携带了所在节点的节点名和 token 信息,tunnel-cloud service 依据负载平衡策略将申请转发到 tunnel-cloud pod,如图 3 所示,将申请转发到 tunnel-cloud pod-B - tunnel-cloud 向 coredns 注册本 pod 的 podIp 和 tunnel-edge 所在的节点的节点名信息
tunnel-cloud 验证 tunnel-edge 申请信息中的 token 信息,验证通过后,节点申请信息中的节点名和本 pod 的 podIp 写入到 coredns - tunnel-cloud 返回 gRPC 连贯建设胜利的音讯
- tunnel-edge 和 tunnel-cloud 之间通过 gRPC 长连贯发送自定义协定音讯 StreamMsg
对于自定义协定音讯的字段定义请参考 一文读懂 SuperEdge 云边隧道
tunnel-cloud 转发的实现
-
SSH Client 申请 tunnel-cloud service 的 NodePort- 1 端口,发送 method 为 Connect 的 http 申请
SSH Client 通过工具 netcat 或 crokscrew 发送的 method 为 CONNECT HTTP 申请,即 ProxyCommand 的内容(ProxyCommand= “nc -X connect -x tunnel-cloudIp:NodePort-1 node-A 22” ),参数的定义如下:- -X: 参数为协定的类型,这里指定的 connect 是 HTTP CONNECT
- -x: HTTP Server 的 ip 地址和端口,这里指定的 tunnel-cloudIp:NodePort-1 是 tunnel-cloud service 暴漏到外网的 ip 和端口
- node-A 为边端节点的节点名
- 22 为边端节点 SSH Server 的监听的端口
tunnel-cloud service 依据负载平衡策略将 SSH Client 的申请转发到 tunnel-cloud pod,如架构设计图 3 所示如果转发到 tunnel-cloud pod-A,tunnel-cloud 的 HTTP Server 收到的音讯为 CONNECT node-A:22 HTTP/1.0 , 其中 node-A 为边端节点的节点名,22 为边端节点 SSH Server 监听的端口,因为 node- A 没有与 tunnel-cloud pod-A 建设云边隧道,因而 HTTP Server 会申请 coredns 获取 node-A 节点名对应的 tunnel-cloud 的 podIp,即为 tunnel-cloud pod-B , pod-A 会把申请转发给 pod-B
- tunnel-cloud 向 tunnel-edge 发送自定义协定音讯(StreamMsg.Type 为 connecting)
tunnel-cloud 会依据 HTTP CONNECT 的申请信息中获取云端和边端节点的隧道,并通过云边隧道向 tunnel-edge 发送自定义协定音讯用于与 SSH Server 建设 TCP 连贯,类型为 connecting - tunnel-edge 向 SSH Server 发送建设 TCP 连贯的音讯
tunnel-edge 在接管到 connecting 类型的自定义协定音讯之后依据音讯中 SSH Server 的 ip 和 port 发送建设 TCP 连贯的申请 - SSH Server 返回 TCP 连贯建设胜利的音讯给 tunnel-edge
- Tunnel-edge 返回自定义协定音讯 (StreamMsg.Type 为 conneted) 给 tunnel-cloud
tunnel-edge 在收到连贯建设胜利的音讯后向 tunnel-cloud 发送一个 TCP 连贯已建设的类型 connected 的自定义协定的音讯 - tunnel-cloud 返回 SSH Client 状态为 200 的 reponse 音讯
tunnel-cloud 在接管到 connected 的自定协定音讯后会 SSH Client 返回一个状态码为 200 的音讯:HTTP/1.1 200 Connection established - SSH Client 向 tunnel-cloud 发送 SSH 协定的音讯
SSH Client 在接管到状态码为 200 的响应音讯后,应用和 tunnel-cloud 曾经建设的隧道发送 SSH 协定数据 - tunnel-cloud 将 SSH 协定的音讯封装为自定义协定音讯 (StreamMsg.Type 为 content) 发送给 tunel-edge
- tunnel-edge 将 SSH 协定音讯通过 TCP 连贯发送给 SSH Server
- SSH Server 将 SSH 协定音讯发送给 tunnel-edge
- tunnel-edge 将 SSH 协定音讯封装为 content 类型的自定义音讯发送给 tunnel-cloud
- tunnel-cloud 将 SSH 协定音讯返回给 SSH Client
SSH 登录节点
性能演示的视频链接
前置条件
装置 corkscrew,Mac 间接应用 brew 装置
brew install corkscrew
或者,装置netcat(centos)
yum install -y netcat
SSH 登录节点
SSH 登录边缘节点 node-A-1,能够应用上面的命令:
ssh -o ProxyCommand= "corkscrew masterIP cloud-port node-A-1 22" root@127.0.0.1
或者
ssh -o ProxyCommand= "nc -X connect -x masterIP:cloud-port node-A-1 22" root@127.0.0.1
- materIP: master 节点所在节点的外网 ip
- cloud-port: NodePort 端口,对应的 SSH 模块的 Server 的端口
获取 cloud-port
kubectl -n edge-system get svc tunnel-cloud -o=jsonpath='{range .spec.ports[*]}{.name}{"\t"}{.nodePort}{"\n"}{end}' | grep ssh | awk '{print $2}'
总结
应用该计划,用户无需手动搭建,能够疾速 SSH 登录边端节点,施行运维工作。同时本计划提供的隧道绝对传统计划更便于保护且进步了稳定性,用户体验失去晋升。
将来瞻望
反对从云端对立 SSH 运维边缘节点是 tunnel 组件的加强性能,也是对 一文读懂 SuperEdge 云边隧道 的瞻望的实现,SuperEdge 开源之后社区小伙伴也对 tunnel 组件提了新的需要,大抵如下:
- 反对云端 apiserver 拜访边缘端的 webhook server
- 反对服务之间的跨区域互访
单干和开源
云边隧道的 SSH 运维边缘节点的新个性曾经在 SuperEdge release 0.4.0 开源,欢送大家体验。咱们也会继续晋升 Tunnel 的能力,实用更加简单的边缘网络场景,也欢送对边缘计算感兴趣的公司、组织及集体一起共建 SuperEdge 边缘容器我的项目。
<img src=”https://main.qcloudimg.com/raw/ded3f46433da0f1727caf3630effadf7.png” style=”zoom:50%;” />
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!