本文为系列文章,主要是为了使用docker部署和开发ros相关程序,核心是为了解决以下问题:
有些papckage运行的依赖版本不一致,更换这些依赖的版本极其繁琐,甚至可能毁了开发环境,为提高开发环境的鲁棒性所以考虑采用docker部署各个package。
在部署ros的docker开发环境前,需要先解答以下一些疑惑。
ubuntu18.04配置ros的docker环境(一)——安装之前
ubuntu18.04配置ros的docker环境(二)——安装ros的docker镜像,测试turtlebot(ssh,多个panel,tmux)
ubuntu18.04配置ros的docker环境(三)——生成自己的ros镜像
ubuntu18.04配置ros的docker环境(四)——编译自己的package并运行
ubuntu18.04配置ros的docker环境(五)——安装CUDA与pytorch,并测试
ubuntu18.04配置ros的docker环境(六)——多个容器相互通信
ubuntu18.04配置ros的docker环境(七)——多个容器中的package相互通信
ubuntu18.04配置ros的docker环境(八)——多个版本的ros相互通信,kinetic,molodic,ros1,ros2
ubuntu18.04配置ros的docker环境(九)——容器与主机通信
ubuntu18.04配置ros的docker环境(十)——docker中的ros与宿主机的vrep(或者另外一个docker中的rep)的联合仿真
ubuntu18.04配置ros的docker环境(十一)——docker中ros的多机(不同的物理机、或者相同的物理机)通信
本章目录:
1.docker的容器会占用多大的空间
2.ros运行在docker中是否会影响性能
3.代码应该在宿主机里面写还是docker里面写
4.如何在docker中编辑修改文件
5.如果查看docker里面可视化界面,如vscode,ros的rviz和gazebo等
6.docker里面的程序如何与主机的程序通讯?
7.docker里面的GPU CUDA配置与主机的配置如何协调
一、docker的容器会占用多大的存储空间
docker通过镜像(image)创造容器(container),在容器中部署开发环境。
有官方上传好的镜像,里面已经配好了ros的开发环境。比如sudo docker pull osrf/ros:melodic-desktop-full。如果是包含ros-core的镜像,大概是400M,如果包含rviz,gazebo等全套的destktop-full版本,大概是5G左右,占据的空间还是很可观的。
查看容器与镜像大小(容器一般体积都比较小)
docker system df -v
二、ros运行在docker中是否会影响性能?
在CPU运行计算层次影响的性能很小,几乎没有。但是在数据传输、如文件挂载等和网络通信会有影响,通信影响的延时大概在50us微秒左右。
详细的比较可见下面两个链接。
容器是镜像的接口设置,实际是运行镜像,因此对读写能力还是有要求的,ssd运行速度较快。
Docker容器、虚拟机和裸机运行的性能比较
docker性能测试
三、代码应该在宿主机里面写还是docker里面写?
不要将数据储存在容器中,在开发环境,因为code的频繁变更,通过volume方式进行挂载更方便。
使用-v参数挂载本地文件,删除容器后,文件仍然存在。
容器随时都可以停止、销毁或迁移,比方说,一个容器里运行的应用版本是1.0,我们分分钟就可以把这个应用升级到1.1,同时还不会对数据造成任何影响。所以如果用户想要存数据的话,最好是用数据卷来存储。不过在用卷存数据的时候大家还是要注意一点,如果有两个容器共用一个数据卷,都往里面写数据的话,是有可能造成程序崩溃的。我们在设计应用程序的时候应该考虑到这一点,为保万无一失,应用程序应该具备特定的机制,以确保在往共享数据存储区写入数据的时候不会出错。
容器随时可以停止、或者删除。当容器被rm掉,容器里的数据将会丢失。为了避免数据丢失,用户可以使用数据卷挂载来存储数据。但是容器的 Volumes 设计是围绕 Union FS 镜像层提供持久存储,数据安全缺乏保证。如果容器突然崩溃,数据库未正常关闭,可能会损坏数据。另外,容器里共享数据卷组,对物理机硬件损伤也比较大。
如果你是开发环境,代码是用于调试,代码是不应该在image里面的,利用dockerfile,自动git pull也不是好的方案,当然更不提倡ssh到容器,去修改代码。这个时候,你的代码最好是在你的mac,windows,linux的个人pc上,如果你的开发环境,本身就部署到了本机,通过boot2docker或者其他方式,那么就通过共享目录,然后开启容器的时候-v的方式,通过卷的方式,来使用,最方便。修改代码直接就可以进行调试。如果开发环境在服务器上,可以通过远程mount的方式,mount到本机进行开发修改。
如果你是测试环境,建议根据git方式进行,代码不在image,而是通过docker exec到容器内pull对应测试tag的代码。当然也可以在宿主机pull,然后docker cp到对应的测试容器;
四、如何在docker中编辑修改文件?
可以用可视化的IDE,如vscode,CLION。
①可以直接用宿主机的vscode或clion,pycharm打开修改,在编译和运行的时候,需要进入到docker中执行命令,因为是共享文件夹,所以在docker环境中也可以看到这些修改后的源码。
②也可以用docker中的vscode或clion,pycharm直接打开修改,用这些可视化界面编辑时需要启动docker使用xserver,开启gui界面图像服务。
有三种方法可以进入到docker中
使用tmux在docker中创建不同的terminal非常方便。
五、如果查看docker里面可视化界面,如vscode,ros的rviz和gazebo等?
宿主机开启xhost, 使能宿主机接收其他客户端的显示需求
xhost +
docker创建容器时参数设置xserver挂载地址即可
-e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix
六、docker里面的程序如何与主机的程序通讯?
采用socket通信
docker创建容器时,默认分配了bridge网络,这样所有的容器都在同一个网段,是能够相互通信的。
如果想某些容器之间不能通信,通过自定义网络就能实现。
假如宿主机是linux系统,有一个监听8000端口的其他进程
在宿主机上执行ifconfig命令,可以发现有一个docker0网卡,注意观察其网段和docker network inspect bridge的网段是一致的,宿主机在此网段下也分配了一个ip,一般是网段中的第一个ip,假如是192.168.10.1。
1)假如用默认的bridge模式启动容器,即在启动时不指定network参数或者指定了--network bridge,
在容器中执行ifconfig命令,可以发现容器的ip也在上面的网段中,假如是192.168.10.2。
在容器中,ping 192.168.10.1,可以ping通。在宿主机中ping 192.168.10.2,可以ping通。
在容器中,可以用192.168.10.1:port的方式访问宿主机的服务。
网络中的其它主机能否ping通这些容器?
roscore在容器中启动后,宿主机能否启动?可以,这相当于是两台不同的机器,如果共享一个roscore,需要设置两个的bashrc,ros_master_url参数。
2)假如容器用host网络模式启动,即在启动时添加了--netwok host参数,
那么容器会和宿主机共享网络,直接telnet 127.0.0.1 8000可以telnet通信。
七、docker里面的GPU CUDA配置与主机的配置如何协调?
采用NVIDIA Container Toolkit,19.03后原生支持nvidia的驱动,只需要宿主机安装nvidia的驱动,在镜像中安装cuda和cudnn。
在docker中使用gpu需要设置参数:
docker run --gpus all ....
八、为什么建议一个docker里面只有一个进程
1)每个容器中只运行一个应用程序,则水平伸缩将变得十分容易。例如,当你需要一个Tomcate容器,可以从现有的容器再扩展出一个,但如果你的这个容器中不仅有Tomcate,还有MySQL等其他应用程序,事情就会变得复杂起来。
2)个容器中只运行一个应用程序,可以轻松地将其重新用于其他项目或目的,极大增加复用度。
3)每个容器中只运行一个应用程序,出现故障时开发人员能方便地对该故障容器进行问题排查,而不必对整个系统的各个部分进行排查,这也使得其更具有可移植性和可预测性。
4)每个容器中只运行一个应用程序,升级程序时能够将影响范围控制再更小的粒度,极大增加应用程序生命周期管理的灵活性,避免在升级某个服务时中断相同容器中的其他进程。
5)每个容器中只运行一个应用程序,从安全性和隔离性角度来看,能够提供更安全的服务和应用程序间的隔离,以保持强大的安全状态或遵守PCI之类的规定。
九、docker安装ubuntu 18.04,和双系统(win10+ubuntu)安装的有什么区别?
虚拟机里装的ubuntu是ubuntu的内核 + ubuntu的文件系统
docker里的ubuntu是任意的内核(你底层的操作系统的内核)+ ubuntu的文件系统
经过思考,自己对docker的实际需求有以下几个
1.创建满足自己ros开发的docker镜像
2.把程序部署在docker中进行编译和运行
3.修改docker中的程序,进行调试。
4.把镜像打包发给别人使用
5.(本地)多docker之间通信。
6.docker与宿主机通信
接下来就实际部署了,未完待续~
Docker:我们的硬盘空间去哪了?
https://zhuanlan.zhihu.com/p/36956285
缩减 Docker 镜像体积历程总结
https://ruby-china.org/topics/38089
docker镜像怎么缩小体积
https://www.jianshu.com/p/e3c6e7b13bc9
docker可视化&多容器跨主机通信
https://www.jianshu.com/p/d44ba22c9581
ROS多个Docker通信,里面是多个版本ros通信的图
https://www.codenong.com/07937a25bc48aa076056/
docker中容器之间通信方式
https://blog.csdn.net/u013355826/article/details/84987233
https://www.cnblogs.com/koushr/p/14559481.html
https://blog.51cto.com/lwc0329/3010868
http://www.4k8k.xyz/article/adparking/119140478
https://www.cnblogs.com/whych/p/9595671.html
https://blog.csdn.net/weixin_39978444/article/details/110639937
https://cloud.tencent.com/developer/article/1831540
https://blog.csdn.net/adparking/article/details/119140186
https://cloud.tencent.com/developer/article/1579287
Docker内使用GPU
https://blog.csdn.net/qq_22877119/article/details/106851805(介绍了docker使用gpu的历史)
https://blog.csdn.net/ayiya_Oese/article/details/114397798
https://www.cnblogs.com/ytwang/p/14809112.html
https://blog.csdn.net/weixin_39132520/article/details/114456343
https://blog.csdn.net/Castlehe/article/details/120194820
https://www.cnblogs.com/chester-cs/p/14444247.html
https://blog.csdn.net/xie_daicheng/article/details/109592234
https://houmin.cc/posts/574111db/
https://www.cnblogs.com/journeyonmyway/p/11234572.html
docker容器启动多个终端
https://blog.csdn.net/weixin_38070782/article/details/106531304