5、进入docker容器5.1、相关概念5.2、如何查询使用的docker镜像版本5.3、查看外设连接情况5.4、编辑启动脚本5.5、执行脚本5.6、多终端进入同一个docker容器5.7、如何开启已经处于【Exited】关闭状态的容器5.7.1、再次进入【Exited】关闭状态的容器
1、什么是docker的宿主机
宿主机就是我们调用命令使用镜像创建容器的服务器。这里是指我们系统主板(jetson或树莓派等),以下提到的宿主机都是指这个。
2、什么是GUI
xxxxxxxxxx
GUI即图形用户界面,这里主要是指:opencv显示的图像窗口、rviz界面、rqt界面等。
3、什么是docker容器
xxxxxxxxxx
打开docker镜像运行后的就是容器
4、在操作本章节教程前,请确保自己已经掌握了下面这些章节的知识,否则可能会感到学起来比较吃力。出现这种情况,请反复查看下面这些预先知识的内容,熟练掌握后会觉得很轻松,Come on,you are the best!
1、用户在烧录了出厂系统镜像开机启动后,查看镜像:
xxxxxxxxxx
jetson@jetson-desktop:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.2.51:5000/ros2-base 2.0.1 fce9745648c0 3 days ago 6.5GB
192.168.2.51:5000/ros2-base 1.0.3 cs41dfas5fx0 3 days ago 7.2GB
192.168.2.51:5000/ros2-base 1.0.2 31e97028c1c0 3 days ago 7.2GB
会看到有多个docker镜像版本,实际情况根据自己查询到的镜像显示
2、为什么不能只放一个docker镜像呢?
如果你看过【Docker ------ 3、docker镜像深入理解和发布镜像】这章的教程,应该知道docker镜像是分层机制,也就是后面一个tag的镜像依赖前面一个tag的镜像。所以宿主机中可能会存在多个版本的docker镜像,这些镜像的tag会以递增的方式更新。
后续我们更新了新的课程也会用发布新的docker镜像的方式来更新功能
以下用激光雷达和串口设备绑定为例
此步骤在宿主机上操作:
1、这里是查看除摄像头之外的外设
xxxxxxxxxx
ll /dev | grep ttyUSB*
2、查看摄像头设备
xxxxxxxxxx
ls /dev/video*
此时根据上一步查到的设备编辑启动脚本
以下用激光雷达和串口设备为例
编辑运行docker的脚本,此步骤在宿主机上操作:
1、创建一个docker运行脚本【run_usb_docker.sh】一般会放在home目录下
xxxxxxxxxx
chmod +x run_usb_docker.sh #给脚本赋予可执行权限
【run_usb_docker.sh】脚本的内容如下:
不带注释的可以直接复制并根据下面的注释按需修改
注意:以下添加主机设备给容器时,如果宿主机没有连接该设备,需要去掉相应的添加操作,才能开启容器
x#!/bin/bash
xhost +
docker run -it \
--net=host \
--env="DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v /home/jetson/temp:/root/yahboomcar_ros2_ws/temp \
--device=/dev/video0 \
--device=/dev/myserial \
--device=/dev/rplidar \
-p 9090:9090 \
-p 8888:8888 \
yahboomtechnology/ros2-base:2.0.2 /bin/bash
带注释的脚本说明:
注意:以下添加主机设备给容器时,如果宿主机没有连接该设备,需要去掉相应的添加操作,才能开启容器
xxxxxxxxxx
#!/bin/bash
xhost + # xhost 是用来支持docker内显示GUI的
docker run -it \ # 交互式运行docker镜像
--net=host \ # 容器网络设置为host模式
--env="DISPLAY" \ # 开启显示GUI界面
--env="QT_X11_NO_MITSHM=1" \ # 采用X11的端口1进行显示
-v /tmp/.X11-unix:/tmp/.X11-unix \ # 映射显示服务节点目录
-v /home/jetson/temp:/root/yahboomcar_ros2_ws/temp \ # 作为宿主机和容器临时传输文件的目录,有需要传输文件,可以使用这个目录
--device=/dev/video0 \ # 添加主机设备给容器,没有连接摄像头,请去掉这行
--device=/dev/myserial \ # 这里是串口设备端口,没有连接串口设备,请去掉这行
--device=/dev/rplidar \ # 这里是雷达设备端口,没有连接雷达设备,请去掉这行
-p 9090:9090 \ # 开放的端口
-p 8888:8888 \
yahboomtechnology/ros2-base:2.0.2 /bin/bash # 要启动的镜像名称,根据5.2步骤中查询到的修改;在容器内执行/bin/bash命令
#注意:以上添加主机设备给容器时,如果宿主机没有连接该设备,需要去掉相应的添加操作,才能开启容器
docker启动脚本编辑完后,在 docker的宿主机上(可在VNC上面或者在主板显示屏上)打开终端
注意:这里必须是在VNC上面或者在主板显示屏上执行,不可在通过ssh远程进入的终端(如通过MobaXterm进入的终端)中执行,否则可能容器中无法显示GUI图像,如下在MobaXterm中进入终端执行run_usb_docker.sh进入容器后,无法显示rviz
在VNC界面或者在屏幕上运行之前创建的启动脚本(注意:每次执行该脚本都是从镜像中创建一个新的容器)
xxxxxxxxxx
./run_usb_docker.sh
即可正确进入容器,并能显示GUI画面,可以再次执行rviz2命令测试。
xxxxxxxxxx
rviz2
如果执行rviz2命令后无法显示GUI,显示如下错误:(一般在树莓派主控中有可能出现)
需要再启动脚本中再加一个参数:
xxxxxxxxxx
--security-opt apparmor:unconfined
即:
xxxxxxxxxx
#!/bin/bash
xhost +
docker run -it \
--net=host \
--env="DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
--security-opt apparmor:unconfined \ # 添加了这句参数
-v /home/jetson/temp:/root/yahboomcar_ros2_ws/temp \
--device=/dev/video0 \
--device=/dev/myserial \
--device=/dev/rplidar \
-p 9090:9090 \
-p 8888:8888 \
yahboomtechnology/ros2-base:2.0.2 /bin/bash
然后再次运行脚本即可进入新的容器,并能显示GUI画面。
1、在上面的步骤中已经开启了一个docker容器,可以在宿主机上打开另一个终端查看:
xxxxxxxxxx
docker ps -a
2、现在在这个新打开的终端中进入该docker容器:
xxxxxxxxxx
docker exec -it [容器id] /bin/bash
图片示例:
成功进入容器,还可以通过同样的方法再打开无数个终端进入该容器。
3、注意:
(1)执行2步骤中的命令时要确保容器处于开启【UP】状态
(2)如果容器处于【Exited】关闭状态,请参见下面5.7步骤操作
这里分两种情况: 摄像头等相关外部设备有变动 和 外部设备没有变动的(参考5.3查看外设连接情况)
1、摄像头等相关外部设备有变动的
如果该容器中有一些修改需要保留,可以参考以下命令生成一个新的镜像(详细发布镜像的步骤请看之前的教程)
xxxxxxxxxx
从容器中提交一个镜像:
docker commit [容器id] [要创建的目标镜像名:[标签名]]
例如:docker commit 66c40ede8c68 yahboomtechnology/ros-foxy:1.1 # 标签名根据自己的情况递增
然后再运行这个新的镜像进入容器:参见本章节【5.2 到 5.5】步骤执行
2、摄像头等相关外部设备没有变动的,那直接参见【5.7.1、再次进入【Exited】关闭状态的容器】步骤执行。
在 docker的宿主机上【可在VNC上面或者在主板屏幕上】打开终端
注意:这里必须是在VNC上面或者在主板屏幕上执行,不可在通过ssh远程进入的终端(如通过MobaXterm进入的终端)中执行,否则可能容器中无法显示GUI图像,当然如果你不需要显示GUI图像,那就可以。
1、首先查看容器的状态
xxxxxxxxxx
docker ps -a
2、开启GUI访问权限
xxxxxxxxxx
xhost +
3、开启容器【这里容器的ID是可以简写的,只要能够唯一识别当前已经存在的容器即可】
xxxxxxxxxx
docker start [容器的ID]
4、再次进入该容器
xxxxxxxxxx
docker exec -it [容器的ID] /bin/bash
5、在容器内打开rviz查看是否已经能够开启GUI画面
xxxxxxxxxx
rviz2