虽然Docker在生产环境中使用有很多被人诟病的地方,但是Docker明显的优势在某些特定领域的使用还是会有比较大的优势,比如DL/ML或者一些其他科学计算环境的使用。花费一些时间和经历总结下使用过程中的一些的一些问题以及建议。
1. 在容器内合理的使用pip相关命令
工作中发现,原来在非Docker环境直接执行pip install package
会自动安装包以及安装和升级相关依赖,但是如果你直接拿着这个命令可能
在docker容器内部或者在使用Dockerfile构建镜像的过程中会有问题,比如:
[root@54675f89ab4a Data]# pip install docker
Installing collected packages: urllib3, idna, certifi, chardet, requests, six, docker-pycreds, websocket-client, docker
Found existing installation: chardet 2.2.1
Uninstalling chardet-2.2.1:
Exception:
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/pip/basecommand.py", line 223, in main
status = self.run(options, args)
File "/usr/lib/python2.7/site-packages/pip/commands/install.py", line 308, in run
strip_file_prefix=options.strip_file_prefix,
File "/usr/lib/python2.7/site-packages/pip/req/req_set.py", line 640, in install
requirement.uninstall(auto_confirm=True)
File "/usr/lib/python2.7/site-packages/pip/req/req_install.py", line 726, in uninstall
paths_to_remove.remove(auto_confirm)
File "/usr/lib/python2.7/site-packages/pip/req/req_uninstall.py", line 125, in remove
renames(path, new_path)
File "/usr/lib/python2.7/site-packages/pip/utils/__init__.py", line 314, in renames
shutil.move(old, new)
File "/usr/lib64/python2.7/shutil.py", line 299, in move
rmtree(src)
File "/usr/lib64/python2.7/shutil.py", line 256, in rmtree
onerror(os.rmdir, path, sys.exc_info())
File "/usr/lib64/python2.7/shutil.py", line 254, in rmtree
os.rmdir(path)
OSError: [Errno 39] Directory not empty: '/usr/lib/python2.7/site-packages/chardet'
该问题在docker的overlay存储驱动下可能出现该问题,原因可能是因为overlay存储层并非是完全的隔离,在容器层卸载相关包的时候会导致镜像层的内容无法进行写操作。通常情况下是因为父子镜像使用了不同的存储驱动导致该问题的,因此建议企业内部使用从一开始就关注存储驱动相关的东西。
推荐使用:
# 强制reinstall相关的依赖包
pip install -I packages
注意:另外不建议在dockerfile中使用requirements.txt定义环境依赖,然后使用pip install -r requirements.txt进行依赖安装,该种方式使用一次全量下载文件中的依赖包并进行统一安装,但如果有包之间是互相依赖的,可能会导致依赖检测失败而停止安装。其实既然使用dockerfile来定义环境了,建议使用多条pip install来安装全部的依赖
2. overlay存储驱动下的存储文件不释放的问题
在使用overlay存储驱动时可能会出现磁盘频繁满的情况,但是排查过程中并未发现在运行的容器占用了大量的存储空间。经调研和学习发现在使用overlay存储驱动过程中可能会有些历史容器的数据不释放,而overlay2存储驱动上已经修复了该问题。
具体现象和问题处理方式如下:
# 查看当前docker 的overlay存储驱动下文件数量
sh-4.2# ls -ls /export/lib/docker/overlay/ | wc -l
89
# 查看当前docker接管的容器数量
sh-4.2# docker ps -a -q
cf87a2641d4a
555073a5d3ac
a6d1f192c69c
bfd10fb67f31
009863a1566a
d8f7b1ce2d69
aba0ffe2ec76
d5c86c6f007e
# 很明显,当前docker接管的容器和docker的overlay存储驱动下的文件个数相差悬殊,出现这种问题的原因主要是在历史操作中,虽然容器被删除了,但是容器对应的overlayfs存储文件并未删除。该种情况如果堆积时间较久就会出现磁盘满而影响业务的情况,可以提前在宿主机中进行历史文件的删除处理操作
# 查看由docker接管的容器占用的overlay存储文件id
sh-4.2# usedoverlayfs=`docker inspect $(docker ps -a -q) | grep -i overlay | awk -F '/' '{print $6}' | sort -ru | xargs | sed 's/ /|/g'`
# 从docker的overlay存储驱动中过滤掉正在使用的ovelayfs文件id【也可以直接进行删除操作】
sh-4.2# ls /export/lib/docker/overlay/ | egrep -v "(${usedoverlayfs})"
# 删除overlay存储驱动中无用的文件
sh-4.2# for i in `ls /export/lib/docker/overlay/ | egrep -v "(${usedoverlayfs})" | xargs `;do /bin/rm -rf /export/lib/docker/overlay/$i;done
网友评论