凯特•
开发人员主

边缘设备在硬件和功能上差异很大,即使在同一技术领域也是如此。知道了这一点,我们如何设计一个高效、可扩展和可靠的解决方案来更新这些设备上的软件,同时最大限度地减少用户的停机时间?这个问题没有放之四海而皆通的解决方案,但是我们有一些工具和技术可以让解决这个问题变得更容易。准确地了解为什么这是一个需要解决的重要而困难的问题,并了解可以实现的工具和策略,以简化部署到边缘上的嵌入式linux设备。

视频记录

大家好。今天我要讲的是边缘设备的更新策略。这可能是一个难以解决的问题,特别是在处理具有不同功能的一系列设备时。但是我们可以使用一些工具和设计策略来解决一些痛点。首先,简单介绍一下我自己:我叫Kat Cosgrove,在进入开发者倡导领域之前,我在JFrog的物联网团队做了一年的软件工程师。我们的目标是将DevOps带到边缘,因为更新这些设备不应该如此困难。为了实现这一目标,我们发现了许多有趣的解决方案,我们可以将它们引入嵌入式Linux设备的CI/CD管道中,并最终构建了一个相当华丽的概念证明,展示了其中的几个解决方案。让我们先了解一下背景。这条边到底有多大?算上DOM、审查边缘设备或更智能的设备和网关,目前估计有204亿台边缘设备。

看起来很多,是的。那么,它们现在是如何更新的呢?其中一些不能更新,它们是一次性设备,实际上是一次性的,当它们坏了就需要更换。很多正在更新的软件,都是用一种笨拙的方式来做的。这很耗时,或者支持它的基础设施很复杂,或者根本不能无线进行,需要物理访问。这要么对制造商来说很昂贵,因为他们必须派员工去那里支持设备,要么对用户来说很恼火。
用户不想再插入设备进行更新,这很公平,我不反对。但尽管如此,该行业显然正在蓬勃发展。大概有204亿台设备。这并不小。这不是一个微不足道的小行业。很明显,尽管它们在很大程度上不能很好地更新,但它确实在赚钱。那么,我们为什么要花时间和精力去改变那些看起来并不是成功障碍的东西呢?这真的很不方便。这不是小麻烦。我们的生活越来越依赖于边缘和物联网计算,设备在消费、工业、零售和医疗领域接管了越来越多的工作。 A lot of you probably work in those industries, and are very aware of that. People don’t want to spend lengthy amounts of time waiting for a software update to complete in an increasing number of parts of their lives, you know? And they definitely don’t want to have to plug the device into a computer to do it manually. It’s also dangerous.
无论出于何种原因,不频繁或不存在的软件更新都使边缘设备成为任何人网络中的严重安全漏洞。你的消费者,你的客户,一个商业网络,一个家庭网络,这是一个问题。每个人都知道未打补丁的软件是个问题。这可能意味着允许从用户客户端数据暴露给恶意第三方到用于僵尸网络或加密货币挖掘的设备的任何事情。这种情况已经在大范围内发生,而且今天还在继续发生。医疗安全的影响甚至更极端,但请记住,几年前,当一群人的智能家电,比如他们的智能冰箱或其他东西,它们被利用作为僵尸网络的一部分,攻击其他服务,因为它们暴露在外,很难更新。那真的很危险。好的。我们承认这是一个问题。为什么我们不解决这个问题? Why does this still exist? We are flat-out still not building for it.
所以,很多这样的设备在设计上都不具备更新的能力。他们希望运行与发货时相同的软件版本,直到出现故障。这些设备的更新策略是闪烁它们。这是很危险的,因为你编写一个没有bug的软件的频率是多少?你对QA团队捕获所有可能的边缘情况有多大信心?我知道我们都想认为我们是巫师,我们是超级可靠的大师,我们是天才的工程师,但事实并非如此。事实并非如此。因为你不应该那么自信。
每一千行代码中平均有1到25个bug。bug会进入产品,你不能赌你的代码是完美的,因为你并不完美,没有人是完美的。对不起。我们也不能真正依赖于设备的网络。承载这些设备的网络可能不稳定,连接可能断断续续,网络速度可能很慢,所以我们需要保持更新非常非常小,这可能意味着他们需要更频繁地进行更新,而且网络也可能不安全,所以这些更新需要以某种方式签名,这样我们才能知道它们是值得信赖的。这204亿台设备也没有在任何标准化的硬件上运行。每一类设备都运行在一些专门的设备上,在可用的通信协议、内存、存储空间、架构和操作系统的复杂性方面存在差异。那么,我们如何设计一个考虑到这些差异的系统,处理它们,并允许我们更容易地部署到更广泛的设备类别,而不仅仅是单一的板或设备类型?我们能否找到一个适用于各种规模市场的万能解决方案?可能不会。 I’m going to be honest with you, but we can build something that gets us one-size-fits-most or at least something that’s flexible enough that it can be applied to your specific situation with minimal effort. First, we have to think about the future.
我们需要停止制造不能更新的设备。一次性设备不再被接受。除了在野外有一群设备存在明显的安全问题,收集的数据如果有问题就无法修补之外,设计一次性电子产品的生态影响可能会因为一个错误而被扔掉,这是不可接受的。我喜欢向人们解释有多少这样的,蹩脚的一次性电子产品,这是东京奥运会本来应该在今年夏天举行的东京奥运会上所有的奖牌都是由废旧金属制成的从日本人民捐赠的废弃电子产品中提取。这绝对是一个令人难以置信的电子垃圾数量,我们不应该允许它继续下去。这是绝对不能接受的。我们还需要在设计时遵循这样的理念:你的产品应该在其使用寿命期间不断改进。这可能不适用于边缘设备,这些设备只是DOM数组的审查器将数据传递到其他地方,但它绝对适用于更智能的边缘设备和网关。一些边缘设备的预期寿命是5-10年,它们不应该从发布的那一刻起就变得更糟。一个
现在,我并不是说你需要建立一些永远不需要被替换的东西,因为这不是商业运作的方式,但你不应该让它立即降级。只要硬件没有过时,您应该能够对其进行改进。你知道,所以发布更新来改进你的实体产品,我不是要求十年,我要求几年。通过可衡量的改进来支持它,直到硬件过时,然后人们会替换它。我们还需要更加稳健地建设。脆弱的软件意味着脆弱的产品,你的用户不会信任它。所以,一个糟糕的更新不应该破坏设备。如果出现问题,需要有一种方法可以立即回滚。是值得信赖的。在将更新部署到边缘设备或在所有这些日子里部署更新有很多移动部分,特别是在边缘设备上,如果你有一个强大的CI/CD管道,对开发人员来说管理起来要容易得多。 Just, do your engineers a favor and don’t make them do all of this menial, repetitive stuff every single time. Automate it. Let’s talk about the proof of concept in question. For swampUP last summer, my team built a proof of concept demonstrating fast, reliable, over the air updates for edge devices. We went with a car as our example because it’s flashy, and it’s not something a lot of us think of as an IoT or edge device even though it totally is.
现在大多数汽车至少有2到3台电脑,包括信息娱乐系统,再加上一台用于传动和刹车的电脑,所以这是一个车轮上的数据中心。船上所有的电脑都需要更新。因为JFrog不会给我们买一辆真正的车,在测试过程中可能会损坏,这是公平的。我没有因为这个生你的气,什洛米。受几个月前我参加的黑客马拉松的启发,我们不得不建立自己的平台。所以我们在一个大型赛道中间设置了一个赛车模拟器,包括踏板、轮子、驾驶员的屏幕、赛车椅和赛道周围的绿色屏幕,这样他们就有了好看的东西。这是我在确保会议开始前一切准备就绪。我们允许人们以两种方式与它互动:作为开发人员,为汽车编写和推送更新,或者在别人更新的时候驾驶汽车。是的,我们确实让会议中心的随机人员编写代码并将其推送到我们的演示中。我们对此非常非常有信心,实际上它只出现过一次问题。 But what we found is that usually somebody from marketing wanted to be the developer and get like help from one of us and the developer wanted to drive the car, and then the person from marketing wanted to mess with the developer by pushing an update that made steering really lose, or inverted the video or something. It was fun for everybody but the car itself is just a heavily modified donkey car.
如果你不熟悉这些,我在参加黑客马拉松之前也不熟悉,这是一辆微型遥控车,用树莓派和摄像头改装过。使它能够做它的事情的库被称为驴,因此,驴车。在其最基本的形式,你可以建立一个大约250美元的零件和几个小时的时间,这真的很不错。一旦一切都准备好了,你就在用颜色鲜艳的遮罩胶带或纸在黑暗的地板上标记的跑道上记录10圈左右,你真的需要任何能产生强烈对比的东西。正如你所看到的,我们在黑色的地板上画了条纹。然后你只需将录制的图像和搅拌数据传回电脑,训练一个模型,然后将其交还给汽车。Donkey提供了一个CLI,它让所有这些变得非常非常简单,但是项目本身有非常好的文档,所以如果你想更深入地挖掘并对它进行一些修改,你完全可以。它们很有趣。一个完整的社区存在于修改和比赛这些东西。T
他们会给它们装上更大的电池,更强大的马达,更好的轮子,然后就开始比赛,这真的很酷。标准摄像头只是一个普通的树莓派摄像头,但有些人会增加第二个摄像头来实现立体视觉,或者增加一个更轻的摄像头来获得更好的深度感知。我们的比标准的要大一点,但仍然没有太多,我们只是把树莓派3B换成了一个带计算模块的3B+。所以它很像驴车,你也可以做这个。虽然演示的互动部分从技术角度来看并不具有革命性,但它的构建确实很有趣,但仍然相当复杂。我也很乐意回答关于这部分演示的问题,但让我们谈谈实际的软件更新。现在汽车是如何更新的?因此,绝大多数汽车无法通过无线接收软件更新。
我知道听到这段话的人开着特斯拉,他会说,“嗯,实际上……”是的,我知道,特斯拉可以做到,但我们说的不是特斯拉,我们说的是大多数汽车。因此,大多数汽车需要被带到服务中心进行软件更新,这可能需要很长时间。可以通过空中更新的汽车,这是少数,仍然需要一段时间才能做到,有时仍然需要几个小时,当任何部分进行时,汽车都无法行驶。不同的汽车仍然使用不同的主板,运行不同的操作系统,所以即使在市场的一个角落里,也没有标准化。
大约15%的汽车召回是由于需要更新的不良软件造成的。举个例子,几年前,捷豹为了解决一辆车的刹车问题不得不进行召回,那是一辆非常昂贵的豪车,而另一辆车把车主困在高速公路上几个小时,因为它可以进行无线更新,但它的处理方式不太聪明,而且它无法阻止一个坏消息。这个可怜的人在高速公路上被困在车里几个小时。那简直就是我的噩梦。所以这是一个非常真实,非常痛苦,而且非常潜在的危险的问题,它向我们展示了一系列可解决的问题,对最终用户和制造商都是如此。所有这些问题都集中在一个设备上,这是一个很好的例子,证明我们不必再这样做了。因为我们研究的是一辆汽车,我们非常非常有动力让这一切快速、可靠地发生,而且不会对用户造成伤害。
我知道那不是一辆真车,但我们假装那辆小车是一辆真车。让我们看看我们的工作流程和工具。我们使用了两种不同的工作流程,展示了两种不同的概念验证策略。对于一个工作流程,我们更新了运行在汽车上的软件,而不刷新其固件。它非常快,不会打断用户并且支持回滚。这个工作流程依赖于K3S和Helm。对于另一个版本,我们在几分钟内就更新了固件本身,如果出现问题,我们可以自动回滚,这个版本同样依赖于Mender、Yocto和Artifactory。
所有更新都使用x射线扫描漏洞,管道可以管理不同事件的触发。我们将首先看看软件工作流程。这只是对在设备上的软件更新工作流程中发挥作用的技术的快速概述。我们使用JFrog Artifactory来管理和存储所有不同的构建工件,以及处理从开发到生产的构建促进。x射线用于在发布之前扫描我们的包依赖关系,我们要确保我们不会意外地推送,比如一个已知的安全问题。K3S和Helm用于部署到汽车上。
由于它已经集成了JFrog产品,JFrog pipeline将用于编排所有这hth华体会最新官方网站些。我们将更详细地单独讨论每个工具。K3S只是Kubernetes,但比Kubernetes少5倍。这也是开源中最可爱的口号,我喜欢它。K3S实际上只是轻量级的Kubernetes。它是为边缘设备设计的,只使用512MB内存,生成的二进制文件只有40MB,对操作系统的要求非常非常低。需要依赖的包只是Containerd,法兰绒,核心DNS CNI和一些实用程序,如ip表和socat。它被包装在一个启动器中,阻止了一些更复杂的问题,如为安全通信生成TLX证书,它为你设置了一些选项。然后我们还依赖于Kubernetes的包管理器Helm。我想你们中的很多人已经熟悉Helm了,但对于不熟悉的人,我将简要介绍一下。Helm使用图表来描述复杂的应用程序,并允许轻松重复和可预测的安装。
图表是决定应用程序外观的最终权威。它们还可以很容易地转移注意力,并在出现问题时支持回滚。这是舵手图的一部分。在这个演示中,如果你以前从未见过Helm charts的语法,它构建了一个微服务,我们用它来控制带有赛车轮设计的微缩汽车,用于视频游戏。这里的语法相当简单。就像DevOps中的所有东西一样,最终,它只是Yaml。在上面运行一些Yaml。结果就是使用这些工具,这只是两个特殊的开源工具,对汽车上运行的应用程序进行了快速和高效的更新。从开发人员推送更新到部署到汽车上的平均时间约为35秒,对用户完全没有中断。它可能在设备使用过程中发生。
这并不是说在使用设备的时候就必须这样做。以汽车为例,我不认为在实际操作中应该如此。对于大多数更新,我认为应该得到相关用户的同意,或者我们至少应该告诉他们发生了什么。但是用这种策略来设计你的边缘设备确实意味着你可以悄悄地更新。对于没有任何用户交互的边缘设备,也不需要完整的固件更新,这可能是一个非常引人注目的选择,如果你正在构建一个HVAC系统,一个智能HVAC系统或一些人们并不真正想要或需要经常弄乱的东西,这可能是一个很好的选择。接下来我们将看一下固件工作流程。这个有点复杂。与软件工作流程类似,这里概述了固件更新工作流程中正在发生的事情。Yocto——用于创建我们的构建,我们有管道处理所有事件。再一次,x射线检查我们的包是否有漏洞或违反策略。
我们还将再次使用Artifactory,但这次不仅仅用于存储二进制文件。它为Yocto处理一些工作负载——存储它的构建缓存以使稍后的工作更快——Mender用于处理空中部署。我们来谈谈Mender。嵌入式Linux设备的无线更新。Mender满足了我们的一些要求,所有的更新都经过加密签名和验证,如果出现故障,它支持自动回滚到以前的构建,并且允许多种不同的安装策略。但我主要讲双AB策略。使用这种方法,在设备A和b上存在两个分区。引导加载程序知道当前哪个分区被指定为活动分区,哪个分区不是。它引导到指定为活动的分区。在更新期间,使用新固件更新非活动分区。 It streams directly there to the inactive partition and at this point the partition running the update is designated as active and on reboot, the Bootloader flips into that partition instead. Because the partition running the older software still exists although now it’s designated as inactive Mender offers us an additional layer of security.
如果新版本存在早期测试中未发现的问题,并导致其无法正确启动,Mender可以通过切换到非活动分区来自动回滚到以前的版本。那么,实际情况是这样的,你坐上车,开车去杂货店。当你开车去杂货店的时候,你的车得到一个更新,它开始流到分区B,假设这是目前不活跃的分区。所以当你开车去杂货店的时候,它下载到分区B,这根本不会打扰你。
你不会注意到,除了你的车可能会说:“嗨,你更新了。”你想继续下载这个吗?”你说“是”,你开车去杂货店,它不会打断你,除了那个。所以你进去,买东西,回来,装好你的杂货,然后你打开车,开车回家。就是这样。所以,虽然这个更新实际上花了你开车到杂货店整整15分钟的时间,但用户的感觉是,它在他们下次重启汽车时瞬间发生了。这本身就很酷。仅使用Mender的AB策略就可以为您的边缘部署增加许多额外的速度和安全性。但我们仍然需要解决构建的大小问题,因为它们有点大。进入为任何硬件体系结构提供自定义Linux发行版的Yocto项目。 Yocto drastically reduces resources used on the board and minimizes hardware requirements by building a distribution without certain modules, that are unnecessary for your particular hardware.
例如,你知道你只需要通过蓝牙进行通信。您构建了一个定制的Linux发行版,其中不包括以太网和WiFi模块。只是从一开始就不存在。BitBake用于为您的构建编写食谱,为不同的硬件配置和应用程序拉入层。我们为电路板本身使用了一层,树莓派3D+以及K3S和Mender的层。Yocto已经为常见配置提供了种类繁多的硬件层,可以让您更快地入门,如果需要,还可以编写自定义层来隔离特定的应用程序或行为。例如,这是元层的一部分,它将K3S添加到我们的Yocto构建中。Bitbake的语法非常简单,它允许并行执行python和shell脚本。您不需要成为python或shell脚本专家,它都相当简化,因此任何有足够动力的软件工程师都可以将其组合在一起。
第一个构建仍然需要一段时间,但我们可以在未来的构建中大大加快速度。Yocto缓存它在构建期间下载的所有内容,从而允许它进行增量更新。如果您没有使用此构建缓存,它将只重建更改的内容。这就是Artifactory发挥作用的地方。我们可以使用通用存储库来存储Yocto构建缓存,并告诉Yocto在后续构建过程中使用它。这一策略为我们减少了50%的构建时间。这是一个相当显著的速度差异。因此,结果是当从Artifactory提取构建缓存时,使用Mender处理部署和Yocto进行构建,完整的固件更新时间在第一次构建后的5到10分钟之间。构建尽可能小,最大限度地减少设备网络上低带宽的潜在问题。
对更新进行了签名,满足了安全需求,并且在出现故障时自动回滚。所以,我们成功了。我确实还有一些工具没有进入我们的概念验证,但仍然非常值得一提。首先是OSTree。它基本上是用于操作系统的Git。与Git一样,OSTree使用带有分支的内容寻址对象存储来跟踪有意义的文件树。这可以用于更新系统,甚至是增量更新,还支持回滚。这也有一个Yocto元层,它允许使用OSTree和actualizer进行空中更新。OSTree已经被一些不同的Linux发行版使用,这是一个很好的工具。我想,我们选择孟德而不是奥斯特里并没有什么真正的原因,只是因为我们先遇到了孟德。下一个是LAVA。 A testing framework for operating systems on embedded devices. LAVA stands for Linaro Automation and Validation Architecture and it’s a continuous integration system for deploying operating systems on physical and virtual hardware to run tests. A test can be simple, boot testing Bootloader testing or system level testing, and results are tracked overtime and data can be exported for further analysis.
我们在西雅图办公室的实验室里运行这个。LAVA是为了在开发过程中进行验证而设计的,尽管它测试工程师正在生成的代码是否在任何意义上对您来说都是有效的。根据上下文,可以测试Linux内核中的更改是否可以编译和引导,或者JCC生成的代码是否更小或更快。LAVA在设备管理方面非常出色,有100多个板的模板。如果你需要一种LAVA还不知道如何支持的设备类型,你可以添加自定义设备,尽管完全集成未知设备可能会很困难。我承认《LAVA》的学习曲线相当陡峭,但如果你需要管理大量不同的板子,这是值得的。好吧,让我们回顾一下。
现在许多边缘和物联网设备的更新方式,如果有的话,有点坏了。这是一个需要解决的巨大安全漏洞。事情本不必这样的。我们现在有技术可以很好地处理运行嵌入式Linux的边缘设备中的一些问题。一个现代的DevOps和一些开源工具可以很容易地将更新和安全补丁部署到您的边缘设备上,就像部署到任何其他应用程序上一样。
如果你只需要更新在设备上运行的应用程序,K3S和Helm可以使事情变得非常快速和容易,我知道Kubernetes有一个相当陡峭的学习曲线,我一开始也很害怕,但K3S更容易使用,我保证。如果您需要更新设备的固件本身,请考虑使用Yocto和Mender或OSTree。一定要将Yocto构建缓存存储在Artifactory中,并确保Yocto实际设置为可以使用它。感谢你们今天花时间听我的演讲,我希望我给你们带来了一些有用的信息,或者至少是一个有趣的观点。如果你有问题,我会在聊天中回答他们一会儿。你也可以通过推特@Dixie3Flatline联系我,或者给我发邮件KatC@JFrog.com祝会议愉快。

免费试用JFrog !