公司有个项目是运行在Raspberry Pi上面,这个项目涉及到Perl,Python,Java Applet,并且未来Pi的数量可能达到上千个。最近碰到了一样的代码遵循一样的部署脚本,在不同的树莓派上运行竟然到不同的结果。于是也想将Docker应用到树莓派上面去,使用docker主要优点:
1 消除环境差异,程序运行所依赖的环境已经一起打包,随身携带了
2 简化配置,只有docker相关配置,不再需要每个语言单独配置
3 重复利用
4 方便升级,之前有差异时,是重写镜像。。
5 方便管理,可以使用docker已有的工具来管理
6 性能接近原生应用
Raspberry Pi在jessie这个版本就已经支持了docker,检查版本:
$ lsb_release -da No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 8.0 (jessie) Release: 8.0 Codename: jessie
如果你的版本已经支持,直接执行以下命令就可以了:
curl -sSL https://get.docker.com | sh
如果你的版本不支持,你需要升级系统或重新刷镜像,可以采用hypriot
#下载 wget https://downloads.hypriot.com/hypriotos-rpi-v1.0.0.img.zip #解压 unzip hypriotos-rpi-v1.0.0.img.zip #查找 SD card ID lsblk #查找类似/dev/mmcblk0 #弹出SD卡 umount /run/media/mac/8734-1E4C #将镜像写入 SD card sudo dd if=hypriotos-rpi-v1.0.0.img of=/dev/mmcblk0 bs=1m
然后启动,默认的用户名/密码是pirate/hypriot。
当然也可以采用Debian或者是Alpine Linux来定制(Raspberry Pi仅支持 arm版本的系统,并且只能在arm平台上构建,或者这个)。
运行测试一下:
docker run -d -p 80:80 hypriot/rpi-busybox-httpd
访问以下树莓派的IP,就会看到一个非常神器的网页,而这个容器仅仅几M。在这里可以看到基于hypriot的好几个镜像,也可以搜索其他的raspberry pi镜像。
现在我们使用hypriot/rpi-python来构建一个使用Python Selenium测试带有Java Applet的网页:
docker run -idt -P --name web hypriot/rpi-python docker attach web
进入到容器里面,执行以下命令:
sudo apt-get update #安装openjdk sudo apt-get install openjdk-7-jdk #安装Firefox sudo apt-get install iceweasel #安装Java Applet插件 sudo apt-get install icedtea-7-plugin #安装虚拟桌面 sudo apt-get install xvfb #安装Python包管理工具 sudo apt-get install python-pip #安装selenium sudo pip install selenium #安装Python虚拟桌面库 sudo pip install pyvirtualdisplay
创建测试test.py:
from selenium import webdriver from selenium.webdriver.common.keys import Keys import time from pyvirtualdisplay import Display from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.firefox.firefox_binary import FirefoxBinary display = Display(visible=0, size=(800, 600)) display.start() caps = DesiredCapabilities.FIREFOX caps["marionette"] = False #caps["binary"] = "/usr/bin/firefox" firefox_binary = FirefoxBinary("/usr/bin/firefox") fp = webdriver.FirefoxProfile() fp.set_preference("security.enable_java", True ) fp.set_preference("plugin.state.java", 2) driver = webdriver.Firefox(firefox_profile=fp,firefox_binary=firefox_binary) driver.maximize_window() driver.get("http://businessconnect.telus.com/bandwidth/en_us/index.html?voip=on&voiplines=1&testlength=15&codec=g711&_=1470641590&startTest=on") time.sleep(120) mos = driver.find_element_by_class_name("sectiontitle18").find_element_by_tag_name("span").get_attribute("innerHTML") print mos driver.close() display.stop()
运行测试用例:
python test.py
如果仅仅是这样子,是行不通的,Java Applet的安全询问弹窗超出了浏览器范围是点击不到的,需要更为强大的组件来做,比如。
这里采用取巧的方法,首先把pyvirtualdisplay相关代码注释掉,在界面上观察具体的执行效果,并点击安全询问,运行通过。然后取消注释,再次运行,就可以了。最后将运行通过的配置文件/root/.icedtea目录拷贝出来,放到其他的树莓派里面就可以了。
如果碰到报错”selenium.common.exceptions.WebDriverException: Can’t load the profile”,通常是说Firefox或selenium版本太低,如果检查都不是,需要修改WebDriver的超时时间
nano /usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/webdriver.py
timeout从30秒改为120秒:
class WebDriver(RemoteWebDriver): # There is no native event support on Mac NATIVE_EVENTS_ALLOWED = sys.platform != "darwin" def __init__(self, firefox_profile=None, firefox_binary=None, timeout=120,
修改为容器后,提交变更:
root@black-pearl:/home/pirate# docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 04762770df2d hypriot/rpi-python "bash" 2 days ago Up 2 days web root@black-pearl:/home/pirate# docker commit 04762770df2d hypriot/rpi-python root@black-pearl:/home/pirate# docker rm web
运行新镜像
#docker run -idt -P --name web hypriot/rpi-python #映射程序目录和配置文件进去 docker run -idt -P --name web -v /home/pi:/home/pi -v /home/pi/.icedtea:/root/.icedtea hypriot/rpi-python
程序正常运行后,可以将这个镜像打包:
docker save -o hypriot.tar hypriot/rpi-python:latest
分发给其他树莓派运行:
docker load --input hypriot.tar docker images docker run -idt -P --name web -v /home/pi:/home/pi -v /home/pi/.icedtea:/root/.icedtea hypriot/rpi-python
这样子便可以利用docker工具来管理这个应用程序,比起原本复杂的环境配置要简单很多。
在查找Pi可用镜像的时候,顺便发现了一个IOT(internet of things)管理平台:resin。
参考链接:
add support to install Docker on raspbian/jessie
Getting started with Docker on your Raspberry Pi
How to get Docker running on your Raspberry Pi using Linux
Getting selenium python to work on Raspberry Pi Model B