Windows下ROS Docker环境的搭建方法

247
2
2020年3月16日 16时29分

前言

Docker是一个开源的应用容器引擎。应用Docker能够将应用程序与基础架构独立开,用管理应用程序的方式管理基础架构,并使得应用程序的开发、测试和交付部署的运行环境保持一致,从而提升效率,实现快速交付。在容器化技术大放异彩的今天,Docker更是炙手可热。Docker通过轻量级的虚拟化,真正做到“Build, Ship And Run Any App, Anywhere”。

 

本文介绍如何在Windows环境下安装和配置Docker,使用ROS官方提供的Docker镜像,或基于其他第三方基础镜像自行制作支持ROS的Docker镜像,运行ROS经典例程——键盘控制小乌龟运动。

 

另外,古月居定制了支持PROBOT机器人运行环境的官方Docker镜像,并通过阿里云镜像市场开放下载,感兴趣的朋友可参考本文下载和使用该镜像。无需ROS2GO或Ubuntu虚拟机,无需安装ROS相关的任何软件,在Windows下快速搭建PROBOT ROS上位机,让机械臂控制变得如此简单!

 

一、Windows安装Docker环境

Docker Toolbox还是Docker for Windows?

Windows下搭建Docker环境有两种方式,安装Docker Toolbox或Docker for Windows。

 

对于Docker for Windows,PC需满足以下条件:

● 64位操作系统,Windows 10 Pro,专业版、企业版和教育版(家庭版不支持)

● 开启虚拟化和Hyper-V

 

很遗憾,第一个条件很可能已经打消了各位选择Docker for Windows的念头。别担心,Docker Toolbox要求要低得多。64位操作系统,Windows 7及以上版本都可以安装Docker Toolbox。

 

Docker Toolbox其实是通过Oracle VM Virtualbox安装Linux虚拟机,在虚拟机中安装和配置Docker,再和Windows建立必要的通信,使得Windows 终端支持Docker命令。这种方式,Docker环境实际上运行在虚拟机中,因此效率或许会打折扣。有条件安装Docker for Windows的朋友们,个人推荐还是使用Docker for Windows吧,可以避开使用虚拟机的各种麻烦。需注意的是,Docker for Windows 和 Docker Toolbox互不兼容,如果同时安装两者的话,还需要一些额外的配置。

安装Docker Toolbox

笔者PC为Win10家庭版,无法安装Docker for Windows。因此,通过Docker Toolbox安装Docker CE(Community Edition: 社区版)。笔者安装的版本为DockerToolbox-18.03.0-ce.exe。安装过程很简单,不再赘述。

100

 

安装完成后,桌面新增Oracle VM VirtualBox、Kitematic、Docker Quickstart Terminal三个图标。

 

Docker Toolbox 是一个Docker工具集,包含:

● Docker CLI 客户端,运行 Docker 引擎以创建镜像和容器;

● Docker Machine,支持在 Windows 终端运行 Docker 引擎命令;

● Docker Compose,运行 docker-compose 命令;

● Kitematic,Docker的GUI界面。

● Docker QuickStart,快速配置好Docker的命令行环境;

● Oracle VM Virtualbox,和VMware类似的虚拟机管理工具。

 

由于Docker引擎使用了Linux特有的内核特性,无法直接运行在Windows上。安装Docker Toolbox之后,我们可以使用docker-machine命令创建和管理Linux虚拟机,通过虚拟机运行Docker引擎,间接支持Docker环境。

 

配置Docker环境

Docker Toolbox的Docker QuickStart可帮助新手快速配置Docker环境。

1.    双击Docker Quickstart Terminal图标打开命令终端。第一次运行Docker Quickstart Terminal时,PC会自动进行Docker环境配置,通过VirtualBox自动创建名为default的Linux虚拟机。另外,程序会自动从GitHub尝试下载最新版boot2docker程序,但可能由于下载速度“感人”,多数情况会下载失败或者卡住不动,造成Docker环境无法完成配置。

 

解决办法:将Docker Toolbox安装目录下的boot2docker.iso复制到C:\Users\用户名\.docker\machine\cache,断开PC网络后,再次启动Docker QuickStart。失去网络连接的配置程序只好从本地找boot2docker,之后即可完成Docker环境的所有配置。Docker环境初始化完成后,就可以在联网状态下启动Docker QuickStart,不会再自动下载boot2docker。

 

2.   Docker Machine启动成功后,会看到快乐的小鲸鱼,并显示Docker宿主机的IP,即Linux虚拟机的IP,如下为192.168.99.100。

                     ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""\___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           \______ o           __/
             \    \         __/
              \____\_______/

docker is configured to use the default machine with IP 192.168.99.100
For help getting started, check out the docs at https://docs.docker.com

3.   最后,测试Docker是否安装配置成功。如下,使用docker run命令运行一个容器。由于本地还没有hello-world镜像,默认将先从Docker Hub下载该镜像,下载完成后再创建对应的容器并运行。

$ docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete                                                                                             Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest
                                                                                                
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

二、使用ROS官方Docker镜像

ROS和Docker

ROS官方已经对Docker支持做了非常多的工作,从wiki可以了解到具体内容: Getting started with ROS and Docker。笔者看到ROS已经发布了各种版本的Docker镜像,可从ROS的Docker Hub官方网站直接下载和使用。但考虑到Docker镜像的体积和安全性,ROS官方镜像只安装了ros-core、ros-base等核心的ROS软件包,并没有添加对图形化桌面的支持。确实,X11、X server等图形界面支持所需的依赖包体积都比较大。目前笔者看到,kinetic-ros-core-xenial镜像只有200+ MB,而kinetic-ros-base-xenial也只有300+ MB,确实非常小巧。

Deployment suggestionsThe available tags include supported distros along with a hierarchy 
tags based off the most common meta-package dependencies, designed to 
have a small footprint and simple configuration:
ros-core: barebone ROS install
ros-base: basic tools and libraries (also tagged with distro name with LTS version as latest)
robot: basic install for robots
perception: basic install for perception tasks

The rest of the common meta-packages such as desktop and desktop-full are hosted on automatic build repos under OSRF's Docker Hub profile here.
 These meta-packages include graphical dependencies and hook a host of 
other large packages such as X11, X server, etc. So in the interest of 
keep the official images lean and secure, the desktop packages are just 
be hosted with OSRF's profile.

可是,没有图形化桌面是万万不能的!ROS推荐到OSRF(开源机器人基金会)的官方Docker Hub网站下载带有图形化界面的desktop-full版本。

 

ROS官方镜像的下载与使用

在ROS或OSRF官方Docker Hub仓库中选择合适的镜像,使用以下命令下载。如下载 kinetic-desktop-full-xenial,大小为1.02G,也是非常小巧的了。

$ docker pull osrf/ros:kinetic-desktop-full-xenial

由于笔者尚未使用过该镜像,无法做更具体的描述,感兴趣的朋友可自行尝试。

 

三、自行制作支持ROS的Docker镜像

笔者并未选择ROS或OSRF官方镜像,而是使用其他配置好图形化桌面的第三方镜像来制作支持ROS的Docker镜像。以下详细介绍该镜像的创建过程,大家也可以通过以下命令从阿里云镜像市场直接下载和使用笔者制作好的镜像。

$ docker pull registry.cn-hangzhou.aliyuncs.com/ps-micro/kinetic-base-xfce-vnc


选择并下载基础镜像

制作Docker镜像之前,充分调研并选择合适的基础镜像是非常重要的。在能够满足自身需求的前提下,应尽量选择体积更小的镜像作为基础镜像。如果已经能够满足需求,笔者推荐大家使用ROS或OSRF提供的官方镜像作为基础镜像,省去了安装和配置ROS的步骤。

 

笔者选择了consol/ubuntu-xfce-vnc作为基础镜像。从作者开源的Dockerfile可以看到,该镜像使用ubuntu:16.04作为基础镜像,安装了xfce4图形化桌面,以及VNC服务器和noVNC客户端,支持VNC Viewer和Web两种图形化远程访问方式。

 

通过docker [image] pull命令从Docker Hub中下载该镜像:

$ docker pull consol/ubuntu-xfce-vnc


镜像下载加速

Docker Hub毕竟是国外网站,有过经历的朋友们都应该会发现直接从Docker Hub下载镜像的速度实在让人”感动“,而且频繁卡住不动。

 

如何能更快地下载镜像?方法之一是从国内云服务商提供的Docker镜像市场中寻找是否也有想要的镜像,一般会比Docker Hub下载快很多,常见的有腾讯云、网易云、阿里云等等。另一种方法是使用镜像加速器。提供容器镜像服务的厂商也很多,笔者用过阿里云和DaoCloud加速器,之后下载速度明显快了很多,而且网络也更加稳定。很好很开心。

 

下面以阿里云为例,介绍一下配置镜像加速器的步骤。

1. 注册并登陆阿里云账号,登陆后点击进入控制台;

1

 

2.进入控制台后,搜索容器镜像服务;

2

3.创建镜像仓库;

3

4. 点击左侧栏中的镜像加速器,就可以看到你的加速器地址;

4

 

5.如何配置镜像加速器?可参考以上阿里云提供的Windows平台操作文档。

对于使用Docker Toolbox,并且还未创建虚拟机的用户可使用以下命令创建一个安装有Docker环境的Linux虚拟机,指定虚拟机名称为default,并配置上加速器地址:

docker-machine create --engine-registry-mirror=加速器地址 -d virtualbox default

而我们其实已经在前面创建了Linux虚拟机,打开Oracle VM VirtualBox即可看到有一个名为default的虚拟机正在运行。

5

因此,我们无需重新创建虚拟机,只需在/etc/docker/daemon.json添加以下内容,配置加速器地址:

{
  "registry-mirrors": ["加速器地址"]
}

 

由于该配置文件在虚拟机中,可以双击进入该虚拟机命令行界面,使用vi进行修改(恭喜不熟悉vi编辑器的朋友,您又可以乘机新增一个技能包了)。如果没有该文件需自行创建。

$ vi /etc/docker/daemon.json

 

6

6.配置完成后重启default虚拟机。可通过VirtualBox,或者以下命令重启虚拟机。

$ docker-machine restart


使用Dockerfile创建镜像

1.在任意位置创建一个新文件夹,如docker-build。如果您也需要替换基础镜像自带的桌面背景,可选择合适图片放置在该文件夹下。

 

2.在docker-build下新建一个名为Dockerfile的文件,并添加如下内容。

FROM consol/ubuntu-xfce-vnc

# 切换到root,root才有权限进行安装软件等操作
USER 0

# 替换桌面背景
# COPY ./图片文件名 /headless/.config/bg_sakuli.png

# 编辑sources.list,使用国内软件源
# 根据自己需求安装一些linux工具,如ping、tftp
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak && \
    sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
    apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y iputils-ping tftp lsb-core && \
    apt-get clean
    
# 安装ROS及其编译工具,配置ROS环境
# 安装turtlesim功能包
RUN sh -c 'echo "deb http://mirrors.ustc.edu.cn/ros/ubuntu xenial main" > /etc/apt/sources.list.d/ros-latest.list' && \
    apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116 && \
    apt-get -y update && \
    apt-get -y install ros-kinetic-ros-base --allow-unauthenticated && \
    apt-get -y install ros-kinetic-turtlesim --allow-unauthenticated && \
    echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc && \
    apt-get -y install python-rosinstall python-rosinstall-generator python-wstool build-essential libblas-dev liblapack-dev --allow-unauthenticated && \
    apt-get clean
    
# 在生成镜像之前切换回default
USER 1000

3.编写完Dockerfile之后,可通过docker [image] build命令创建镜像。键入以下命令查看使用方法。

$ docker build --help
Usage:  docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile


docker build支持的OPTIONS很多,这里我们仅需要使用-t选项,用以指定新镜像的标签。

$ docker build -t kinetic-base-xfce-vnc .


注: 需在docker-build路径下执行以上命令。最后的“.”指定了PATH参数,即读取Dockerfile的路径,并且指定该路径下的所有数据将作为创建镜像的上下文。

 

4.生成镜像的过程可能非常耗时,这是由于Dockerfile中的apt-get update、安装ros-kinetic-ros-base等命令执行就需要较长时间,甚至可能会创建失败。若多次尝试后仍然无法创建成功,笔者建议可以考虑下一小节介绍的方法,即使用基于已有容器手动创建镜像。

基于已有容器创建镜像

若通过编译Dockerfile已成功创建了镜像,则请跳过本节。

 

1.首先,使用基础镜像启动一个容器,并进入容器的命令行界面。

$ docker run -it --rm --user 0 consol/ubuntu-xfce-vnc bash
......
------------------ EXECUTE COMMAND ------------------
Executing command: 'bash'
USER_ID: 0, GROUP_ID: 0
root@17aa50728c58:~#

2.在容器中通过Linux命令进行修改软件源,安装ROS等操作,实现和Dockerfile命令一样的效果。

 

3.完成所有修改后,使用docker [container] commit命令提交为一个新的镜像。提交时可使用容器ID指定容器。

$ docker commit --help
Usage:  docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
......
$ docker commit -m "Commit my changes" [CONTAINER ID] kinetic-base-xfce-vnc

容器ID即为命令行界面中root@后面的字母和数字组合,或可通过docker ps命令查看:

$ docker ps
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                NAMES
17aa50728c58        consol/ubuntu-xfce-vnc   "/dockerstartup/vnc_…"   12 seconds ago      Up 12 seconds       5901/tcp, 6901/tcp   zen_gates

4.创建成功后,在容器命令行中键入Ctrl+d,或exit即可退出。由于docker run启动容器时添加了–rm选项,退出后将自动删除容器。

启动容器

以上两种创建镜像方法最终的效果是一致的,可通过docker images命令查看本地主机上已有镜像的基本信息,确认镜像是否创建成功。

$ docker images
REPOSITORY              TAG      IMAGE ID       CREATED       SIZE
kinetic-base-xfce-vnc   latest   96155f8a8c56   4 weeks ago   2.53GB                                                   latest              96155f8a8c56        4 weeks ago         2.53GB

 

可以看到制作的镜像超过了2.5GB,体积已经比较大了。

 

使用以下命令使用新镜像启动一个容器:

$ docker run -it \
    --rm \
    -e VNC_RESOLUTION=1920x1080 -p 5901:5901 -p 6901:6901 \
    kinetic-base-xfce-vnc bash

注:-e VNC_RESOLUTION=1920×1080指定了图形化界面的分辨率,-p 5901:5901 -p 6901:6901指定了容器端口与本地主机的端口号映射关系,可自行设定。

访问容器的桌面系统

1.安装VNC Viewer

VNC Viewer是一款非常简单易于使用的远程控制软件。consol/ubuntu-xfce-vnc基础镜像预安装了VNC Server,我们可以通过VNC Viewer远程登录容器的可视化界面进行操作。笔者安装的版本为VNC-Viewer-6.20.113-Windows.exe,安装过程非常简单,不再赘述。

7

 

2.VNC Viewer登录

打开VNC Viewer,搜索框输入VNC Server的IP和Port,此处为192.168.99.100:5901。回车后输入密码,默认密码为 vncpasswd。

8注:笔者自行替换了桌面图片。

 

3.浏览器(noVNC)登录

除了VNC Viewer登录,该镜像还支持Web远程访问。打开浏览器,网址栏输入 http://192.168.99.100:6901/?password=vncpassword,可登录容器的桌面系统,界面效果和VNC Viewer登录一致。

四、Docker运行小乌龟例程

1.右击桌面,点击Open Terminal Here 打开一个终端。

9

2.输入以下命令启动ROS Master。

$ roscore

 

10

 

3.打开一个新终端,使用rosrun启动turtlesim仿真器节点,看到熟悉的小乌龟。

$ rosrun turtlesim turtlesim_node

11

 

4.打开一个新终端,运行键盘控制节点。按下键盘上的方向键,控制小乌龟移动。

$ rosrun turtlesim turtle_teleop_key

12

五、Docker运行PROBOT Anno

古月居定制了支持PROBOT机器人运行环境的官方Docker镜像,并通过阿里云镜像市场开放下载。大家可以按照以下步骤下载和使用该镜像,无需ROS2GO或Ubuntu虚拟机,无需安装ROS相关的任何软件,在Windows下快速搭建PROBOT ROS上位机,让机械臂控制变得如此简单!

 

下载镜像

从阿里云镜像市场下载PROBOT Docker镜像。

$ docker pull registry.cn-hangzhou.aliyuncs.com/ps-micro/probot-kinetic-base-xfce-vnc

 


注:下载到本地的镜像名为 registry.cn-hangzhou.aliyuncs.com/ps-micro/probot-kinetic-base-xfce-vnc,名字很长,可使用以下命令为其打上一个更简短的Tag(当然您可以打个更短的)。

$ docker tag registry.cn-hangzhou.aliyuncs.com/ps-micro/probot-kinetic-base-xfce-vnc probot-kinetic-base-xfce-vnc

 


挂载ROS上位机源码

PROBOT Docker镜像中并没有ROS上位机的源码,只是配置了其运行环境,包括必须的ROS功能包、gazebo和函数库。利用这一特性,将具体应用和运行环境分开。因此,该镜像不仅仅支持PROBOT Anno,PROBOT G750等其他产品同样可以在该镜像中运行。

 

镜像中没有ROS上位机的源码,那怎么编译和运行PROBOT上位机呢?共享文件呗!下面以PROBOT Anno为例,介绍具体方法。

 

1.设置Windows与VirtualBox虚拟机共享文件夹

首先,打开VirtualBox。

13

点击左上角菜单栏的 设置,左侧栏选中 共享文件夹。

14

点击右侧栏图标,添加共享文件夹,选择文件夹路径,勾选自动挂载。

15

设置完成后,重启default虚拟机。可通过VirtualBox,或者以下命令重启虚拟机。

$ docker-machine restart

 


 

2.下载ROS上位机源码

       在上一小节设置的共享文件夹下打开git bash,执行以下命令从GitHub下载PROBOT_Anno官方源码。还没有安装Git的童鞋需先行安装。

$ git clone https://github.com/ps-micro/PROBOT_Anno.git

准备完毕!接下来启动一个容器,通过-v启动参数即可将Windows中的ROS上位机源码直接挂载到容器中。

创建容器并运行

$ docker run -it \
    --rm \
    -v /registry/PROBOT_Anno:/probot_ws/src -e VNC_RESOLUTION=1920x1080 -p 5901:5901 -p 6901:6901 \
    probot-kinetic-base-xfce-vnc

 

注:该命令将/registry/PROBOT_Anno文件夹挂载到容器中,挂载路径为/probot_ws/src。

启动ROS上位机控制机械臂

1.通过VNC Viewer或Web浏览器远程登录容器的桌面系统。访问PROBOT Docker容器桌面系统的方式与前面一致。

2.打开终端,进入挂载文件夹/probot_ws,使用catkin_make命令编译ROS上位机源码。

16

3.编译成功后,执行以下命令,启动上位机,进入单机仿真模式。

$ source ~/.bashrc 
$ roslaunch probot_bringup probot_anno_bringup.launch sim:=true

 


17

18

一切就绪,Enjoy!

参考资料

  1. PROBOT Docker镜像使用手册,https://docs.qq.com/doc/DYkVZZ1B5enJ2dHpt?pub=1

  2. Getting started with ROS and Docker,http://wiki.ros.org/docker/Tutorials/Docker

  3. Install Docker Toolbox on Windows,https://docs.docker.com/toolbox/toolbox_install_windows/

  4. consol/ubuntu-xfce-vnc,https://hub.docker.com/r/consol/ubuntu-xfce-vnc

  5. Docker 教程,https://www.runoob.com/docker/docker-tutorial.html

  6. 杨保华 戴王剑 曹亚仑 编著,《Docker技术入门与实战》

发表评论

后才能评论

评论列表(2条)

  • zhangrelay 2020年3月17日 下午2:22

    感觉过程很漫长啊~并且很多人都是家庭版系统吧~

    • 古月 回复 zhangrelay 2020年3月19日 下午6:27

      是的呀,配置还是挺复杂,最后的效果玩玩还可以,搞开发也比较慢