本文讲的是从交通灯模型到Docker化IC编程,【编者的话】本文通过一个树莓派制作交通灯系统的例子,介绍了树莓派如何应用Docker来简化开发与发布流程。本文作者是一位有20年经验的软件工程师,同时也是自动化设备的狂热爱好者。
我家七岁的小朋友问我交通灯是怎么工作的。在解释一大堆抽象概念前,我决定用LED灯和电线做一个手工的实物教具。最终我们要实现一个被应用程序控制的带按钮的行人过街系统——当然,这个应用是被Docker化(Dockerized)后跑在树莓派3代(Raspberry Pi 3)上的。
硬件规格
首先我们需要制作电路。要完成这个教具,你需要如下硬件
- 树莓派 3代,但是任何其他型号也是可以的
- Adafruit T-Cobbler Plus
- 电路板
- 2x 红色, 1x 黄色 and 2x 绿色 LED灯
- 5x 220Ω 电阻
- 1x 1kΩ 电阻
- 1x 10kΩ 电阻
- 1x 按钮
- 1x 树莓派专用usb电源
- 电线
软件实现
应用程序使用Python编写,它的核心逻辑是基于 Bob Rathbone的一篇博客Raspberry PI Traffic Lights。我增加了更多的LED灯从而把程序改造成符合本地的交通规则。你能从GitHub上找到源代码。
- 定义GPIO引脚。
- 初始化GPIO端口:在应用的最开始部分,我初始化了GPIO的端口并且关闭了所有的LED灯。因为它们可能在上一次运行时被打开了。
- 主循环:主循环开始运行时车辆行驶方向为绿灯。在这种情况下十字路口的按钮会被实时监测。
- 行人过街:按钮被按动后,程序的下一段代码块将车辆行驶方向的灯变成红灯,行人方向的灯变为绿灯。然后在回到最开始的状态。
这就完成了整个应用。我可以向我女儿解释交通灯是怎么工作的,并且她可以玩它好一阵呢。本该到此结束这个故事了,但是由于我是用Docker发布我的应用的,这将会是另外一个新故事了。
Docker化所有的东西
我希望保存我的工作成果并且让它能够被我和其他人所复用。所以除了将源代码上传到GitHub仓库外,我也Docker化了应用的开发与发布过程。在Docker及其工具的帮助下,在一台普通设备如MacBook上开发应用是非常容易的。
甚至在几个月后并且经历了一些其他项目后,因为有了这样一套标准的方式,我还能非常轻松的玩转那个应用。你既不需要备份SD卡的镜像,也不需要将树莓派上安装的应用记录下来。
如图所示,你需要在笔记本电脑上安装如下工具:
- flash tool 使用HypriotOS烧录SD卡镜像
- Docker Machine 构建与树莓派Docker Engine之间的安全链接
- Docker Compose 使用一行命令轻松启动Docker化的应用
- Docker Client 执行其它Docker命令
我不会深入讲解如何链接笔记本电脑与树莓派中的Docker Engine。那是上一篇博客的部分内容——关于如何使用docker-machine。
Dockerfile
我们需要一个Dockerfile去构建Docker镜像。使用一份Python基础镜像并且安装必要的工具和依赖。然后我们添加应用源代码并且定义了执行命令。
docker-compose.yml
Docker Compose 可以被用于简化容器的运行。使用docker-compose.yml配置文件我们可以记录启动容器所需的参数。这份文件会被放到Git上做版本化管理,所以我们不会忘记如何去运行这个容器。
开发应用
当我们开发应用或者想要修改源代码时,Docker镜像会使用新代码重新构建镜像。这些只需要一行命令:
docker-compose build
运行应用
docker-compose up
如果你想再次停止应用,只需按CTRL+C
。你也可以连按这个按钮去杀掉应用。
长期运行
你可以在启动命令中增加-d
去自动运行应用。如果docker-compose.yml 配置文件中的重启策略配置为总是(always),那么容器将会在树莓派启动后自动启动。这对于需要伴随树莓派启动而启动的硬件工程是非常有用的。
docker-compose up -d
如果你想停止应用,只需要使用如下命令
docker-compose kill
共享Docker化应用
使用Docker的好处是很容易与其他人共享Docker化的应用。作为一个应用的开发者你只需要将Docker镜像推送到Docker Hub中。其他人就可以从中拉取这个镜像,并且在完全不知道里面安装了什么工具或者依赖的情况下运行这个镜像。
推送Docker镜像
docker images docker tag dockerrpitrafficlight_trafficlight stefanscherer/rpi-traffic-light docker push stefanscherer/rpi-traffic-light
这样Docker镜像就被传送到Docker Hub中了。我的例子的镜像地址:stefanscherer/rpi-traffic-light。
与其他人共享
如果有人想要搭建交通灯系统并运行你的程序,他应该使用如下一小段修改过的docker-compose.yml去拉取我已经发布的Docker镜像,而不是自己去构建它。
version: '2' services: trafficlight: image: stefanscherer/rpi-traffic-light devices: - "/dev/mem:/dev/mem" cap_add: - SYS_RAWIO restart: always
然后使用以下命令运行应用
docker-compose up -d
或者将所有参数添加到命令行上
docker run --rm --cap-add SYS_RAWIO --device /dev/mem stefanscherer/rpi-traffic-light
这个命令会检测如果本地的树莓派中没有该镜像那么就去Docker Hub上拉取这个Docker镜像。拉取完成后,它会运行包含应用程序的Docker容器。
使用这个方法任何应用都可以如此来做发布,而不用关心使用什么编程语言。
原文链接:How to build a traffic light (翻译:高洪涛)
===========================================
译者介绍
高洪涛,当当网架构师,开源数据库分库分表中间件Sharding-JDBC作者。目前从事Docker相关调研工作。
原文发布时间为:2016-03-24
本文作者:gaohongtao
本文来自合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:从交通灯模型到Docker化IC编程