大规模 IoT 边缘容器集群管理的几种架构 -6- 个人体验及推荐

简介: 大规模 IoT 边缘容器集群管理的几种架构 -6- 个人体验及推荐

概述

在前文,我列出以下几种解决方案:

  • Rancher + K3s
  • HashiCorp 解决方案 — Nomad + Docker
  • Portainer + Docker
  • Kubeedge

其中,Rancher + K3s 是基于且兼容 K8s 的解决方案;Kubeedge 是构建于 K8s 之上的,但是核心的 Kubeedge 架构是完全另外一套体系;而 Hashicorp 解决方案和 Portainer 解决方案可以说是和 K8s 没有关系,主要是基于 Docker 等容器的。而且也可以基于其他的驱动(如 podman 等等)

笔者基于边缘架构主要为:单片 arm 开发板 的情况,对以上的各个方案进行了深入的体验。

在深入体验另外 2 个容器平台:hashicorp nomad 和 portainer 时,明显感触到:相比 k8s k3s,这 2 个更适合物联网场景。(本章先抛开 KubeEdge 不谈,KubeEdge 我个人认为是适合更复杂的、和业务耦合更深或者需要调度边缘 AI 的高级边缘计算体系。)

K8s 不适合物联网,原因有:

  • 资源占用高,
  • 对网络要求高
  • 网络模型复杂。

K3s 只是(部分)解决了资源占用的问题,但是后两个问题仍然存在。

📝Notes

K3s 是完全兼容 K8s 的发行版,从 1.23 之后,随着 K8s 功能的增加,K3s 也变得越来越重。

根据 K3s 安装要求:

  • 对于 arm64 设备,操作系统必须使用 4k 页面大小;
  • CPU/ 内存 最低是 1 核 512MB 内存,推荐是 2 核 1G; 但是实际应用场景中,要求会更高,一般内存都是 2G 起步。
  • 更要命的是对存储的要求,K3s 默认启动需要的 K8s 镜像,差不多就需要占用 4-6 G 的空间,如果运行 etcd, 那么 SD 卡这种边缘场景常见的存储是无法满足的。
    关于网络模型,近期 K3s 也添加了和 tailscale 整合 的功能以进一步简化网络模型。但是 K8s 自带的 主机网络 /Service IP/Cluster IP 是绕不过去的。

这两个,相比 k3s 都更轻量。而且对网络要求不高,甚至所有设备可以只用一套 server 端管理。

网络模型也很简单,主机网络就行。

此外,这两个针对物联网场景还有特殊优化,如 网络单向联通;边缘端断线情况下优化;支持管理非 docker 资源等等。

Rancher + K3s 模型在边缘存在的问题

在实际应用中,Rancher + K3s 的边缘部署架构如下:

Rancher + K3s 边缘架构

Rancher + K3s 落地案例

落地案例更明显:

  • 1 套:“云”中部署一套 Rancher 集群,Rancher 负责管理下属所有的“边”中的 K3s 集群,Rancher 集群中同时可以部署云端的业务应用,负责和边缘侧业务系统同步, 以及下发数据或指令。
  • N 套:“边” 设备中安装 K3s,K3s 中部署“边”的业务应用,供“端”连接使用。🐾这里一个 " 边 " 就是需要一套 K3s 集群的,也就是说既有 K3s Worker, 也有 K3s Master.
  • “端”作为业务应用的最边缘端,通过网络连接“边”,完成业务组网,形成以“边”为中心的业务应用。

这样的架构在实际应用中,存在什么问题呢?

" 边 " 端存储容量

很多边端设备只有 8G 存储,除去系统和一些必要的软件包,空间就剩 4 - 6 G 了,而且 K8s 是对存储空间有强制 GC 的。那么极端情况下,可能 K3s master 都 pull 不下来完整的镜像包,导致系统报错,K3s 启动失败。

" 边 " 端存储性能不足

" 边 " 端存储主要是 SD 卡或 emmc 存储,如果下边挂载较多 K3s worker. K3s Master 还面临存储性能 IO 不足的情况。

" 边 " 端 K3s Master 和 Worker 对网络要求高

由于 K3s 是完全兼容 K8s 的,而 K8s 的 watch-list 机制是为稳定的数据中心场景设计的。在边端,也对网络要求很高。但是这在边端是不可能的情况,在实践中,边端出现:

  • Master 和 Worker 长时间不通
  • Master 和 Worker 时不时不通
  • Worker 长时间离线
  • DNS 网络异常
  • Master 能连 Worker, Worker 连不到 Master
  • Master 不能连 Worker, Worker 能连 Master
  • Master 和 Worker 间带宽很小
  • Master 和 Worker IP 地址变动

各种各样网络不稳定的情况太常见了,以上任何一种情况,都可能导致 K3s worker 上应用异常、K3s master 异常甚至整个 K3s 边端集群异常。

这一点是基于 K8s 的边缘架构存在的最大问题

" 云 " 端和 " 边 " 端对网络要求也高 异常后无法自愈

" 云 " 端和 " 边 " 端是通过 Rancher 的 Agent 来连接的,走的是 websocket 协议。

但是实际应用中,还是发现 " 云 " 端和 " 边 " 端对网络要求也高," 云 " 端要管理 " 边 " 端,是有大量的数据要实时同步的,网络出现异常后,也会导致 " 边 " 端离线,无法自愈重连。

" 边 " 端自愈能力差

因为 " 边 " 端复杂的网络情况与 K8s 架构的不相容,导致实际应用中," 边 " 端自愈能力很差。

在 " 边 " 端异常的情况下,十有八九都是需要人工登录边端处置恢复的。

" 边 " 端对 CPU 和 内存资源要求也高

" 边 " 端是一套完整的 K8s 集群,那么这些服务都是需要启动的:

  • etcd 或 K3s kine + sqlite
  • k8s api server
  • k8s scheduler
  • k8s 各种 controller
  • CRI: 容器运行时 containerd
  • CNI: 网络插件
  • CSI: 至少也是 local-path pod
  • CoreDNS
  • Metrics Server
  • Ingress: Traefik
  • kubelet
  • kubeproxy

除了这些 pod, 还需要主机级别的服务:

  • IPTables 或 nftables
  • Netfilter
  • Overlay fs

这么一大堆 Pod 和服务都要启动,对边缘端的 CPU 和 内存资源也是巨大的消耗。

" 边 " 端网络模型复杂

还是 K8s 带来的问题," 边 " 端是一套完整的 K8s/k3s 集群,那么 " 边 " 端网络模型自然包括:

  • Host Network
  • Service Network
  • Cluster Network
  • DNS

要实现 K8s CNI 模型,又会引入 overlay 网络。

甚至为了实现 " 云 " “边” “端” 的联通,可能还需要引入:

  • 隧道网络
  • 边缘网关网络

进一步提升了网络的复杂性!

导致出现问题非常难以处理,简单问题复杂化。

小结

Rancher + K3s, 在边缘计算场景下的网络拓扑架构是:

  • 1 套:“云”中部署一套 Rancher 集群,Rancher 负责管理下属所有的“边”中的 K3s 集群,Rancher 集群中同时可以部署云端的业务应用,负责和边缘侧业务系统同步, 以及下发数据或指令。
  • N 套:“边” 设备中安装 K3s,K3s 中部署“边”的业务应用,供“端”连接使用。🐾这里一个 " 边 " 就是需要一套 K3s 集群的,也就是说既有 K3s Worker, 也有 K3s Master.
  • “端”作为业务应用的最边缘端,通过网络连接“边”,完成业务组网,形成以“边”为中心的业务应用。

K3s 是基于 K8s 的兼容实现,同时因为网络拓扑架构,导致这种架构存在以下问题:

  • " 边 " 端存储容量不足
  • " 边 " 端存储性能不足
  • " 边 " 端无法满足 K3s Master 和 Worker 对网络的高要求
  • " 云 " 端和 " 边 " 端对网络要求也过高 异常后无法自愈
  • " 边 " 端自愈能力差
  • " 边 " 端对 CPU 和 内存资源要求也高
  • " 边 " 端网络模型复杂

而且每个问题几乎无解。

边缘计算场景对容器编排的需求

结合上述场景,我理解的边缘计算场景对容器编排的需求:

  • " 边 " 端最好一个 agent, 不要引入过多其他镜像资源,也不要引入过多其他组件
  • 资源占用轻量,agent CPU 内存 存储都消耗极少
  • 最好统一 " 云 " 端管理," 边 " 端不需要再有一个消耗资源的管理端
  • 弱网环境适应性强
  • 自愈能力强
  • 不要额外再引入其他网络模型,最好能直接基于主机网络运行,也不强依赖 DNS

那么基于 Docker 的边缘容器集群管理方案:

  • HashiCorp Nomad
  • Portainer

就表现地更有优势。

Portainer 边缘计算

Portainer 架构

对于 Edge, Portainer 有专门优化,可以参考左侧的 Edge 架构。

  • " 云 " 端负责管理,portainer server 位于云端
  • " 边 " 端都是 Edge Agent
  • “云” " 边 " 不需要双向通信,而是 " 边 " 端通过直连或隧道定期去 Server 端 pull 信息

以上是针对网络模型的优化,使其更适合边缘计算的场景。

另外,Poratiner 的 Agent 非常轻量级,只使用大约 10MB 的内存,而且边缘端就只需要部署这一个 Agent, 这就是为什么它也可以在硬件资源有限的边缘设备上运行。唯一的依赖就是边缘端需要安装有 Docker.

开源版边缘功能

  • Edge Agent 默认网络策略:pull
  • Edge Compute 相关模块和菜单:
  • Edge Groups: 将一组边缘设备 / 环境通过静态 / 动态的方式归为一个 Edge Group, 方便批量管理
  • Edge Stacks: 类似 Docker Compose 的概念,可以将一套边缘服务批量推向一个或所有的 Edge Group
  • Edge Jobs: 类似 crontab 的功能,在边缘端批量运行 job.
  • 边缘应急特性支持:
  • Interl OpenAMT
  • FDO
  • 管理边缘端 OS 层文件系统(通过 docker linux socket 实现)

通过这些功能,Portainer 可以:

  • 边缘端通过 pull 心跳在复杂网络条件下保持与 Portainer Server 的联通和受管
  • 通过 Edge Compute 的 Edge Groups/Edge Stacks/Edge Jobs 模块,实现对边缘端的批量服务部署和 job 部署

但是开源版相比商业版,阉割的功能较多,比如开源版无法实现一键批量 onboarding 等重要边缘功能。

商业版额外功能

  • 一键 onboaring: 边缘设备一键批量安装
  • 安全通信:在复杂网络条件下,离线条件下,实现基于隧道的连接。
  • Edge Devices: 边缘设备管理
  • Waiting Room: 等候室,有选择地连接请求接入 server 端的边缘设备

小结

个人认为,相比 Rancher + k3s 的方案,portainer 的边缘计算解决方案有以下突出优势:

  • 资源占用少
  • 网络模型针对边缘网络优化

更详细来说,这些功能特性相比 Rancher + K3s 的更适合边缘场景:

  • " 云 " 端 Server, " 边 " 端只有 Agent
  • Edge Agent 轻量,运行内存 10MB 左右
  • Edge Agent pull 模型,针对边缘网络适应性强
  • 没有引入其他网络模型,也不强依赖 DNS

但是,开源版 portainer 也存在明显的功能缺失,最主要的功能缺失是:

  • 一键 onboaring: 边缘设备一键批量安装

的功能。

HashiCorp Nomad 边缘计算

Nomad 边缘参考架构

HashiCorp Nomad 自 1.3 版本以来,针对边缘端增加了很多实用功能:

  • 1.3 引入:Nomad 原生服务发现(简单场景下不再需要 Consul 组件)
  • 1.4 引入:
  • 健康检查
  • Nomad Variables(简单场景下不再需要 Vault 组件)
  • 1.5 引入:
  • 节点动态元数据,更方便 Node 动态管理
  • 1.6 引入:
  • Node Pool 节点池概念,更方便节点批量管理

使得其在边缘端,不再需要依赖:

  • Cosul
  • Vault

这 2 个组件,仅通过 Nomad Agent 就可以实现边缘端的:

  • 容器编排管理
  • 基本服务发现和管理
  • 变量参数 / 环境变量 / 配置管理

等功能。

与 Portainer 类似,其在边缘端也只有一个 Edge Agent. 内存占用也仅为 20-40 MB 左右。

Nomad 支持地理上遥远的客户端,这意味着 Nomad 服务器集群不需要在客户端附近运行。(K8s 就做不到这样。)

此外,断开连接的客户端的 allocations (分配) 可以正常重新连接,处理边缘设备遇到网络延迟或临时连接丢失的情况。

这里特别提到 Nomad 的 2 个参数:

max_client_disconnect

如果不设置此属性,Nomad 将运行其默认行为:当 Nomad 客户机的心跳失败时,Nomad 将把该客户机标记为停机 (down),并把 allocations 分配标记为丢失 (lost)。Nomad 将自动在另一个客户端上安排新的分配。但是,如果关闭的客户端重新连接到服务器,它将关闭其现有的分配。这是次优的,因为 Nomad 将停止在重新连接的客户端上运行分配,只是为了放置相同的分配。(K8s 的行为也是,且只能是这样。)

对于许多边缘工作负载,特别是具有高延迟或不稳定网络连接的工作负载,这是破坏性的,因为断开连接的客户端并不一定意味着客户端关闭。Allocations 可以继续在临时断开连接的客户端上运行。对于这些情况,就需要设置 max_client_disconnect 属性,以正常处理断开连接的客户端分配。

如果设置了 max_client_disconnect ,当客户端断开连接时,Nomad 仍将在另一个客户端上安排分配。但是,当客户端重新连接时:

  • Nomad 将重新连接的客户端标记为就绪 (ready)。
  • 如果有多个作业版本,Nomad 将选择最新的作业版本并停止所有其他分配。
  • 如果 Nomad 将丢失的分配重新调度到新客户端,并且新客户端具有更高的节点等级,则 Nomad 将继续新客户端中的分配并停止所有其他客户端。
  • 如果新客户端具有更差的节点排名或存在平局,则 Nomad 将恢复重新连接的客户端上的分配并停止所有其他客户端。

这是具有高延迟或不稳定网络连接的边缘工作负载的首选行为,尤其是在断开分配是有状态的情况下。

举例来说:

在某一个边缘设备中运行有 1 个 web 服务,此时,边缘设备与 (边缘容器管理的) Server 端断开连接

  • 在 K8s 中,就是 Node Unknown 或 NotReady 的状态,会认为 web 服务已宕机,会在另外一台边缘设备中启动 web 服务;在恢复连接后,发现最新的实例是在另一台边缘设备中,那么前一台设备的服务会被关闭。对于使用该 web 的用户来说,可能就是在边缘设备重新连接到 (边缘容器管理的) Server 端后发现 web 服务异常(被管理端关闭)
  • 在启用该参数的 Nomad 中,Node 会是 lost 状态,分配的服务会是 Unknown 状态。会在另外一台边缘设备中启动 web 服务;在恢复连接后,发现 web 服务正常运行,关闭后启动的 web 服务。对于使用该 web 的用户来说,体验是一直没有中断的。

Template change_mode

另外还有一个参数,是 Template 块下的 change_mode

将 Template 节 change_mode 设置为 noop。默认情况下, change_mode 设置为 restart ,如果您的客户端无法连接到 Nomad 服务器,这将导致任务失败。由于 Nomad 在边缘数据中心上调度此作业,因此如果边缘客户端与 Nomad 服务器断开连接(从而断开服务发现),则服务将使用先前的模板配置。

小结

个人认为,相比 Rancher + k3s 的方案,HashiCorp Nomad 的边缘计算解决方案有以下突出优势:

  • 资源占用少 - 边缘只有 Nomad Agent
  • 管理端和 Agent 端可以物理距离很远 - 天南地北的所有边缘设备可以通过一个云端中心来管理
  • 相关参数针对边缘网络优化 - 如 max_client_disconnect

更详细来说,这些功能特性相比 Rancher + K3s 的更适合边缘场景:

  • " 云 " 端 Server, " 边 " 端只有 Agent
  • Nomad Agent 轻量,运行内存 20-40MB 左右
  • Nomad Agent 与 Server 心跳检测是基于 pull 模型,针对边缘网络适应性强
  • 专为边缘设计的 max_client_disconnect 参数
  • 没有引入其他网络模型,也不强依赖 DNS

另外,相比开源版 portainer, Nomad 还有一重优势,即:

  • 一键 onboaring: 边缘设备一键批量安装甚至是预安装

得益于 Nomad 的良好架构,其天生是为大规模容器编排而设计的,可以做到使用 Terraform 或 Ansible 一键批量部署,甚至是预安装(烧录). 典型如 Nomad Agent 配置,统一如下:

data_dir  = "/opt/nomad/data"
bind_addr = "0.0.0.0"
client {
  enabled = true
  servers = ["<nomad_server_ip_list>"]
}
HCL

总结

在 IoT 边缘容器集群管理领域,基于 K8s 的解决方案(包括 Rancher + K3s) 明显不太适应,笔者体验 2 年左右坑太多了,主要原因是:

  • 资源消耗高
  • 网络条件要求高
  • 网络模型复杂
  • 自愈能力差
  • 引入了过多额外组件

但是,HashiCorp Nomad,Portainer 相比 k8s k3s, 在物联网 / 边缘计算领域是更有优势的。值得一试。因为它们:

  • 轻量:只有一个 Agent 且内存占用极低
  • 针对边缘网络做了特殊优化
  • 没有引入复杂网络模型(如 Service Network, Pod Network, Overlay Network…, 主要依赖 Host Network, 容器端口映射,顶多多一个 bridge 网络), 不依赖 DNS
  • 自愈能力强
  • 没有引入了过多额外组件,就多了一个 Agent

我个人更推荐使用 Nomad (小规模 / 家庭场景可以使用 Portainer).

以上.

如果您有更好的经验, 欢迎交流探讨~

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
9月前
|
Kubernetes Cloud Native 微服务
探索云原生技术:容器化与微服务架构的融合之旅
本文将带领读者深入了解云原生技术的核心概念,特别是容器化和微服务架构如何相辅相成,共同构建现代软件系统。我们将通过实际代码示例,探讨如何在云平台上部署和管理微服务,以及如何使用容器编排工具来自动化这一过程。文章旨在为开发者和技术决策者提供实用的指导,帮助他们在云原生时代中更好地设计、部署和维护应用。
|
10月前
|
机器学习/深度学习 自然语言处理 分布式计算
大规模语言模型与生成模型:技术原理、架构与应用
本文深入探讨了大规模语言模型(LLMs)和生成模型的技术原理、经典架构及应用。介绍了LLMs的关键特点,如海量数据训练、深层架构和自监督学习,以及常见模型如GPT、BERT和T5。同时,文章详细解析了生成模型的工作原理,包括自回归模型、自编码器和GANs,并讨论了这些模型在自然语言生成、机器翻译、对话系统和数据增强等领域的应用。最后,文章展望了未来的发展趋势,如模型压缩、跨模态生成和多语言多任务学习。
1218 3
|
5月前
|
监控 NoSQL 算法
百万级URL重定向工程:大规模网站架构设计与性能优化实战
本文深入探讨了大规模重定向系统的核心挑战与解决方案,涵盖技术瓶颈分析、分布式架构设计、十亿级URL处理策略、全球化部署方案及全链路监控体系。通过数学建模与性能优化,提出三层架构模型,并结合一致性哈希分片算法实现高效路由。同时,对比不同架构的吞吐量与容灾能力,分享某电商平台实践案例,展示性能显著提升。最后展望重定向即服务(RaaS)未来趋势,包括AI动态路由、量子安全跳转和边缘智能等关键技术,为企业提供扩展性强、稳定性高的系统设计参考。
144 25
|
7月前
|
机器学习/深度学习 缓存 自然语言处理
DeepSeek背后的技术基石:DeepSeekMoE基于专家混合系统的大规模语言模型架构
DeepSeekMoE是一种创新的大规模语言模型架构,融合了专家混合系统(MoE)、多头潜在注意力机制(MLA)和RMSNorm归一化。通过专家共享、动态路由和潜在变量缓存技术,DeepSeekMoE在保持性能的同时,将计算开销降低了40%,显著提升了训练和推理效率。该模型在语言建模、机器翻译和长文本处理等任务中表现出色,具备广泛的应用前景,特别是在计算资源受限的场景下。
965 29
DeepSeek背后的技术基石:DeepSeekMoE基于专家混合系统的大规模语言模型架构
|
10月前
|
Kubernetes Cloud Native 持续交付
容器化、Kubernetes与微服务架构的融合
容器化、Kubernetes与微服务架构的融合
322 82
|
9月前
|
Prometheus Kubernetes 监控
OpenAI故障复盘 - 阿里云容器服务与可观测产品如何保障大规模K8s集群稳定性
聚焦近日OpenAI的大规模K8s集群故障,介绍阿里云容器服务与可观测团队在大规模K8s场景下我们的建设与沉淀。以及分享对类似故障问题的应对方案:包括在K8s和Prometheus的高可用架构设计方面、事前事后的稳定性保障体系方面。
|
7月前
|
监控 Kubernetes Cloud Native
基于阿里云容器服务Kubernetes版(ACK)的微服务架构设计与实践
本文介绍了如何基于阿里云容器服务Kubernetes版(ACK)设计和实现微服务架构。首先概述了微服务架构的优势与挑战,如模块化、可扩展性及技术多样性。接着详细描述了ACK的核心功能,包括集群管理、应用管理、网络与安全、监控与日志等。在设计基于ACK的微服务架构时,需考虑服务拆分、通信、发现与负载均衡、配置管理、监控与日志以及CI/CD等方面。通过一个电商应用案例,展示了用户服务、商品服务、订单服务和支付服务的具体部署步骤。最后总结了ACK为微服务架构提供的强大支持,帮助应对各种挑战,构建高效可靠的云原生应用。
|
7月前
|
监控 Cloud Native Java
基于阿里云容器服务(ACK)的微服务架构设计与实践
本文介绍如何利用阿里云容器服务Kubernetes版(ACK)构建高可用、可扩展的微服务架构。通过电商平台案例,展示基于Java(Spring Boot)、Docker、Nacos等技术的开发、容器化、部署流程,涵盖服务注册、API网关、监控日志及性能优化实践,帮助企业实现云原生转型。
|
9月前
|
Kubernetes 安全 数据安全/隐私保护
云卓越架构:容器安全最佳实践
本次分享由阿里云智能集团解决方案架构师张玉峰主讲,主题为“云卓越架构:容器安全最佳实践”。内容涵盖容器安全的挑战、云原生容器安全架构及典型场景。首先分析了容器安全面临的问题,如镜像漏洞和权限管理。接着介绍了容器安全架构的五个维度:身份权限管理、配置安全检查、运行时防护、镜像安全检测及发布的安全管控。最后通过具体场景展示了容器身份与权限管理、密钥管理、运行时防入侵等最佳实践,强调了安全左移的重要性,确保从开发到运行的全生命周期安全覆盖。
|
10月前
|
Kubernetes Cloud Native Docker
云原生之旅:从传统架构到容器化服务的演变
随着技术的快速发展,云计算已经从简单的虚拟化服务演进到了更加灵活和高效的云原生时代。本文将带你了解云原生的概念、优势以及如何通过容器化技术实现应用的快速部署和扩展。我们将以一个简单的Python Web应用为例,展示如何利用Docker容器进行打包和部署,进而探索Kubernetes如何管理这些容器,确保服务的高可用性和弹性伸缩。