凯特•
开发人员主

边缘设备在硬件和功能上有很大差异,即使是在相同的技术空间内。知道了这些,我们如何设计一个高效、可扩展、可靠的解决方案来更新这些设备上的软件,同时最大限度地减少用户的停机时间?这个问题没有万能的解决方案,但我们有一些工具和技术可以让解决问题变得更容易。了解为什么这是一个重要且难以解决的问题,并了解可以实现的工具和策略,以简化部署到嵌入式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.
不频繁或不存在的软件更新,无论原因是什么,使得边缘设备在任何人的网络中都是一个严重的安全漏洞。你的消费者,你的客户,一个商业网络,一个家庭网络,这是一个问题。每个人都知道未打补丁的软件是个问题。这可能意味着允许将用户客户端数据暴露给恶意第三方,以及利用设备进行僵尸网络或加密货币挖掘。这种情况已经在大范围内发生,而且今天还在继续发生。对医疗安全的影响甚至更加极端,但请记住,几年前,当一群人的智能家用电器,比如智能冰箱或其他东西,它们被用作僵尸网络的一部分,被用作ddos攻击其他服务,因为它们被暴露出来,很难更新。那…真的很危险。好的。我们承认这是一个问题。为什么我们不解决这个问题? Why does this still exist? We are flat-out still not building for it.
所以,很多这样的设备都不具备更新的功能。他们希望运行与他们发布的软件版本相同的软件,直到它们崩溃。这些设备的更新策略正在刷新它们。这是很危险的,因为你有多少次写了一个没有bug的软件呢?你对QA团队把握每一个可能的边缘情况有多大信心?我知道我们都想认为我们是巫师,我们是超级可靠的大师,天才工程师,但那不是现实。事实并非如此。因为你不应该那么自信。
每千行代码中平均有1到25个错误。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不会给我们买一辆真正的车,在测试中可能会坏掉,这是公平的。我不生你的气,什洛米。我们必须根据几个月前我举办的黑客松(Hackathon)创建自己的游戏。所以我们在一条大赛道中间设置了一个赛车模拟器,它配有踏板、轮子、车手屏幕、赛车椅和赛道周围的绿色屏幕,这样他们就可以看到一些好看的东西。我要确保会议开始前一切都准备好了。我们允许人们以两种方式之一与它交互:作为开发人员,为汽车编写和推送更新,或者在其他人更新时驾驶汽车。是的,我们确实让会议中心地板上的真正的随机人员编写代码并将其推送到我们的演示中。我们对此非常非常有信心,实际上这只出现过一次问题。 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管道将被用于协调所有这些。hth华体会最新官方网站我们将分别更详细地讨论每个工具。K3S只是Kubernetes,但是少了5个。这也是开源中最可爱的口号,我喜欢。K3S实际上只是一个轻量级的Kubernetes。它专为边缘设备而设计,仅使用512MB的RAM,生成仅40MB的二进制文件,并且对操作系统的要求非常非常低。需要依赖的包只有Containerd, Flannel, Core DNS CNI和一些实用程序,如ip表和socat。它被包装在启动器中,阻止了一些更复杂的问题,如生成TLX证书的安全通信,并为您设置了一些选项。然后我们还依赖Helm Kubernetes的包管理器。我想你们中的很多人已经熟悉Helm了,但对于房间里不熟悉的人,我将简要地介绍一下。Helm使用图表来描述复杂的应用程序,并允许容易重复和可预测的安装。
图表是应用程序外观的最终权威。它们还易于转移,并在出现错误时支持回滚。这是赫尔姆图表的一部分。对于这个演示,如果你以前从未见过Helm图表语法,它将构建一个微服务,我们将使用它来控制带有赛车轮设计的微型汽车,用于视频游戏。这里的语法相当简单。就像DevOps中的所有东西一样,最终,它只是Yaml。在Yaml上运行它。结果就是使用这些工具这两个特殊的开源工具,对汽车上运行的应用程序进行了快速高效的更新。从开发人员推送更新到汽车部署的平均时间约为35秒,完全不会打断用户。它可能在设备使用时发生。
这并不是说它一定会在设备使用时发生。以汽车为例,我不认为在实际操作中应该如此。对于大多数更新,我认为应该得到相关用户的同意,或者我们至少应该告诉他们发生了什么。但在设计边缘设备时考虑到这一策略意味着你可以无声地更新。对于根本没有任何用户交互,也不需要完整固件更新的边缘设备,这可能是一个非常有吸引力的选择,如果你正在构建一个暖通空调系统,一个智能暖通空调系统或人们不太想要或不需要经常摆弄的系统,这可能是一个很好的选择。接下来我们来看看固件的工作流程。这个有点复杂。与软件工作流程类似,这是固件更新工作流程中正在进行的工作的概述。Yocto -用于创建我们的构建,我们有处理所有事件的管道。同样,x射线检查我们的包是否有漏洞或违反政策。
我们也再次使用Artifactory,但这次不仅仅是存储二进制文件。它正在处理Yocto的一些工作负载—存储它的构建缓存,以便稍后更快地处理,Mender用于处理空中部署。我们来谈谈Mender。嵌入式Linux设备的空中更新。Mender tick了我们正在寻找的几个盒子,所有的更新都经过加密签名和验证,它支持自动回滚到以前的构建,如果发生故障,它允许几种不同的安装策略。但我将重点讲双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策略就为边缘部署增加了很多额外的速度和安全性。但是我们仍然需要解决构建的大小问题,因为它们有点大。进入Yocto项目,为任何硬件架构提供自定义Linux发行版。 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和实现器进行空中更新,OSTree已经被一些不同的Linux发行版使用,这是一个很好的工具。我们选择Mender而不是OSTree并没有什么真正的原因,我想只是我们首先遇到了Mender。下一个是熔岩。 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 and Mender或OSTree。一定要将Yocto构建缓存存储在Artifactory中,并确保Yocto实际设置为使用它。谢谢你们今天花时间听我的演讲,我希望我给你们带来了一些有用的信息,或者至少是一个有趣的观点。如果你有问题,我会在聊天中回答他们一会儿。你也可以通过推特@Dixie3Flatline联系我,或者直接发邮件给我KatC@JFrog.com祝你们接下来的会议愉快。

试试JFrog免费!