当DevOps撞上物联网

管理员账号

2016-12-23

小编说:DevOps 领域在近年来变得流行而普遍。它强调不同的角色之间共同协作,以及如何工作得更加紧密,就像这个词语的词根暗示的那样——开发和运维。但是DevOps和物联网有什么关系?

本文选自《DevOps实践》,将与您探讨DevOps和物联网的关系以及与您动手制作一个简单的物联网设备。

DevOps和物联网有什么关系?

迄今为止,我们讨论的物联网的基础,基本上是寻常的互联网加上我们无法想象的节点数。我们也看到,在未来的几年中,能以各种形式联网的设备数量将继续呈指数增长。这一增长将是因特网的机器对机器部分。

但是,对于更加关注快速交付的DevOps,真的适合关键嵌入式设备的大型网络吗?

经典的反例是DevOps在核设施或者在诸如心脏起搏器的医疗器械中。但是单纯地更快发布不是DevOps的核心理念。它是通过将不同学科的人紧密联系在一起工作,更快、更准确地发布。

这意味着让类产品环境的测试环境贴近开发者,同时大家的合作更加紧密。

这么说的话,看起来DevOps可以用在保守的传统行业。

当然,不能低估面临的挑战:

嵌入式设备的生命周期比传统的客户端——服务器计算机要长。消费者不能期望在每个产品周期都升级。同样,工业设备部署的地方更换起来可能很昂贵。

相比桌面计算机,物联网设备失败的模式更多。这让测试变得更加困难。

在工业部门和企业部门,可追溯性和可审计性是很重要的。这和在服务器上部署是一样的,但物联网端点比服务器更多。

传统的DevOps可以将很小的变更部署到用户的一个子集。如果修改不工作,我们可以修复并重新部署。如果对我们一个已知的用户群来说网页渲染很糟糕,并且这个问题可以快速修复,潜在的风险就很小。另一方面,如果一个单的物联网设备控制的物体,例如一道门或一个工业机器人出现故障时,造成的后果可能是灾难性的。

物联网领域对于DevOps来说挑战很大,但是换种方式不见得会更好。DevOps也是一个工具箱,你需要思考从中找挑出的工具是否能正确应对当前工作。

我们仍然可以使用许多DevOps工具箱中的工具,只需要确保我们在做正确的事情,而不只是在不理解问题的前提下实现想法。

下面是一些建议:

只要你在测试实验室中,失败和快速周转是可以的。

确保你的测试实验室和产品环境接近。

在实验室不要只使用最新版本,也要兼容旧版本。

DevOps的物联网设备动手实验室

为了得到动手环节的灵感,让我们来制作一个简单的物联网设备,它可以连接到Jenkins服务器并且显示出构建的状态。通过这种方式,将我们尝试的物联网设备和DevOps结合起来!

在构建失败的情况下,将闪烁的LED作为状态显示。这个项目很简单,但是聪明的读者可以以此为基础扩展项目。为本次练习挑选的物联网设备比较灵活,可以实现比LED闪烁更多的功能。

该项目将有助于说明一些可能性以及物联网的挑战。

NodeMCU Amica是来自Espressif的基于ESP8266芯片的可编程的小设备。除了基本的ESP8266芯片,Amica板额外的特性让开发更加容易。

下面是一些设计的规格:

Tensilica Xtensa LX106是一个32位的RISC CPU,运行频率为80MHz。

它的Wi-Fi芯片允许它连接到我们的网络和Jenkins服务器。

NodeMCU Amica板有一个USB接口可以给固件编程并连接到电源适配器。ESP8266芯片需要一个USB到串口的适配器去连接USB接口,它由NodeMCU板提供。

板子有几个输入/输出的端口,可以连接到某些硬件上来可视化构建的状态。开始我们会做得比较简单,只使用连接到设备上某个端口的板载的LED。

NodeMCU自带的固件可以通过Lua语言来编程。Lua是一种高级语言,可以快速实现原型。顺便提一句,它在游戏编程领域也很流行,也可以从另一方面说明Lua的高效。

考虑到它提供的这么多功能,这个设备相当便宜:

很多地方都可以买到NodeMCU Amica,从电子商店到网上经销商。

买到NodeMCU不难,从硬件的角度来说项目也很简单,在实践中也可以采用Arduino或者树莓派,如果它们更容易获得。

下面是一些NodeMCU的入门提示:

NodeMCU包含的固件提供了交互式Lua解释器,可以通过串行端口访问。你通过串行线来直接开发代码。在你的开发机上安装串行通信软件。这样的软件有很多,比如在Linux下的Minicom和Windows下的Putty。

使用串口设置9600波特率、八位、无奇偶校验和一个停止位。这个设置通常缩写为9600 8N1。

既然我们已经有了串行终端连接,将NodeMCU连到USB端口,切换到终端,验证你在终端的窗口看到了提示符。

如果你使用的是Minicom,提示的窗口如下:

开始写代码前,根据具体的NodeMCU的出厂设置,你可能需要往设备烧录固件的镜像。如果在前一步你看到了提示符,就不需要烧录固件的镜像。如果以后你需要在镜像中加更多的特性就得重新烧录镜像。

下面是一个用wget命令下载固件的例子。发布的版本号用整数和浮点数表示,根据你的需要去选择具体的版本。对于嵌入式的应用来说,整数的固件版本通常就足够用了:

   wget https://github.com/nodemcu/nodemcu-firmware/releases/
   download/0.9.6-dev_20150704/nodemcu_integer_0.9.6-dev_20150704.bin

你也可以在开发机器上通过GitHub源码直接构建固件镜像,或者也可以根据你的规格使用在线构建服务区构建一个固件。

在线构建的服务地址是http://nodemcu-build.com/。

值得一看。如果不出意外,构建统计图颇为耐人寻味。

既然已经有了一个合适的固件文件,你需要安装固件烧录工具,才能把固件镜像文件上传到NodeMCU:

git clone https://github.com/themadinventor/esptool.git

按照代码库中的README安装指南文件来安装。

如果不喜欢README中建议的系统安装,你可以根据你的系统发行版去安装pyserial的依赖并在git克隆的目录中运行这个工具。

下面是安装pyserial依赖的命令例子:

sudo dnf install pyserial

实际的固件上传需要一些时间完成,但是进度条的显示可以让你知道发生了什么。

下面的例子是在本书撰写时,在命令行中上传0.9.6固件的命令:

sudo python ./esptool.py --port /dev/ttyUSB0 write_flash 0x00000 nodemcu_
integer_0.9.6-dev_20150704.bin

如果在连接NodeMCU时串行命令行出现乱码,你可能需要为烧录固件的命令提供一些额外的参数:

sudo esptool.py --port=/dev/ttyUSB0 write_flash 0x0 nodemcu_
integer_0.9.6-dev_20150704.bin  -fs 32m -fm dio -ff 40m

命令esptool也有其他的功能,可以用来验证设置:

sudo ./esptool.py read_mac
Connecting...
MAC: 18:fe:34:00:d7:21
sudo ./esptool.py flash_id
Connecting...
Manufacturer: e0
Device: 4016

固件上传完成后,重置NodeMCU。

这个时候你应该已经有了一个带有NodeMCU欢迎提示的串行终端。通过使用工厂提供的NodeMCU固件或者上传一个新的固件到设备都可以达到这个状态。

现在,我们开始试试一些“hello world”风格的练习。

一开始,只要我们连接到NodeMCU Amica板GPIO引脚0上,LED就开始闪烁。如果你有其他类型的板子,你需要找出它是否有LED,如果有,输入/输出引脚是哪根。你也可以自己包装一个LED。

如果终端软件允许,你可以将程序作为文件上传到NodeMCU,或者直接在终端上敲击代码。

你可以首先试着点亮LED:

   gpio.write(0, gpio.LOW)  -- turn led on

然后用下面的命令关闭LED:

   gpio.write(0, gpio.HIGH) -- turn led off

现在,你可以循环下面的语句,其中穿插一些延迟语句:

   while 1 do                             -- loop forever
         gpio.write(0, gpio.HIGH)     -- turn led off
         tmr.delay(1000000)               -- wait one second
         gpio.write(0, gpio.LOW)      -- turn led on
         tmr.delay(1000000)               -- wait one second
   end

此时,你应该能够验证一个基本工作的设置。直接在终端输入代码有点原始。

NodeMCU有不同的开发环境来提高开发的体验。

在能够完成实验前,我们需要一些额外的提示。使用以下命令连接到无线网络:

   wifi.setmode(wifi.STATION)
   wifi.sta.config("SSID","password")

SSID和password需要用网络真实的SSID和密码替换掉。

如果NodeMCU正确连接你的无线网络,这个命令会打印出从网络的dhcpd服务器获得的IP地址:

   print(wifi.sta.getip())

这段代码会连接到www.nodemcu.com的HTTP服务器并且打印返回码:

   conn=net.createConnection(net.TCP, false)
   conn:on("receive", function(conn, pl) print(pl) end)
   conn:connect(80,"121.41.33.127")
   conn:send("GET / HTTP/1.1\r\nHost: www.nodemcu.com\r\n"
       .."Connection: keep-alive\r\nAccept: */*\r\n\r\n")

你可能还需要计时功能。下面的代码每隔1000毫秒打印hello world:

   tmr.alarm(1, 1000, 1, function()
       print("hello world")
   end )

在这里,我们声明了一个匿名函数并将其作为参数发送给timer函数,不经意地显露出了Lua的函数型范式。匿名函数每隔1000毫秒,也就是1秒被调用一次。

要停止timer,只需要执行:

   tmr.stop(1)

现在,你应该明白了所有可以自行完成实验的细节。如果遇到问题,可以参考本书源代码包中的代码。玩得开心!

读者评论

相关博文

  • DevOps和持续交付

    DevOps和持续交付

    管理员账号 2016-11-04

    小编说:DevOps 领域在近年来变得流行而普遍。由开发(developers)和运维(operations)组成的“共同协作”,归根结底,就是为了提高产品质量。 本文选自《DevOps实践》,您将了解如何在大规模敏捷背景和不同的敏...

    管理员账号 2016-11-04
    1145 2 0 0