docker启动容器时报错Error response from daemon: mkdir /var/lib/docker/overlay/*** : invalid argument
环境
centos 7.1
docker 17.05-ce
core:3.10
重现步骤
1.新建宿主机
2.修改repo镜像地址
3.安装docker
4.安装docker-compose
5.建立docker swarm集群
6.写docker-compose文件
7.执行docker-compose命令报错
分析
怀疑一:docker-compose问题
验证:将命令解析成docker run原始命令依然报错,未解决
怀疑二:docker swarm问题
验证:将节点leave swarm集群环境,用docker run执行,依然报错,未解决
怀疑三:docker volume参数问题
验证:将volume参数去掉,只留最基本的启动参数,依然报错,未解决
怀疑四:镜像问题
验证1:原来使用的是docker.wencst.com私有仓库中的镜像,换成官方镜像,依然报错,未解决
验证2:将同样的docker.wencst.com私有仓库中的镜像在另外的环境中(docker1.12)执行,没有报错,所以镜像没问题
怀疑五:docker版本问题
验证:卸载docker,重新安装docker1.12.4版本,执行docker run命令依然报错,未解决
解决
在qq群里问了一下,大家基本都没有见过这个错误,给出的解决方案也基本为猜测,但在问答的过程中,给了我很多提示,以及排查问题的思路。
docker version命令
实际上一个命令并没有发现问题,只会看到docker的服务端和客户端版本,但引申出另一个命令(docker info)
我注意到了画红框的这里,忽然想起以前学习过程中,说到了docker存储的几种方式:devicemapper
、overlay、overlay2、aufs等,据说在docker中存储方式是难点,容易出坑的地方。
于是验证了一下两台宿主机的Storage Driver内容,发现确实不一样,于是做了如下操作:
1.systemctl stop docker
2.将另外宿主机(centos7)中的docker配置文件全部移植到新的宿主机(出问题的宿主机)上,文件包括:
/usr/lib/systemd/system/docker.service
/etc/sysconfig/docker
/etc/sysconfig/docker-network
/etc/sysconfig/docker-storage
/etc/sysconfig/docker-storage-setup
3.删除/var/lib/docker文件夹下的文件内容全部删除(注意一定要执行删除,否则无法修改参数)
4.systemctl start docker
5.docker info
6.执行docker run -d registry:2.1.1,成功完成
其他解决方法
以上解决方法是针对docker1.12版本的,因为以前在安装docker 1.12版本时,默认是用的devicemapper的存储引擎,所以迁移过来后直接就可以用了。
但对于docker 17.05-ce,我怀疑在安装这个docker版本时,默认使用的是overlay的存储引擎,所以才会出现上面的问题。
方案一:可以在/usr/lib/systemd/system/docker.service中增加如下参数
方案二:可以在/etc/docker/文件夹下修改daemon.json文件(如果没有则新增,docker会默认读取这个文件的)
上述两个方案,都是需要重启docker服务的。注意在生产环境中尽量不要使用overlay的存储引擎,如果能用Ubuntu操作系统作为docker宿主机最好,如果必须使用centos系统,则替换为devicemapper存储引擎。
原因
这类问题一般是 CentOS/RHEL 红帽系的问题,CentOS 这类红帽系统中,由于不像 Ubuntu 那样有成熟的 Union FS实现(如aufs),所以只能使用 devicemapper,而默认使用的是lvm-loop,也就是用一个稀疏文件来当成一个块设备,给devicemapper用,作为Docker镜像容器文件系统。这是非常不推荐使用的,性能很差不说,不稳定,还有很多 bug,如果没办法换 Ubuntu/Debian 系统,那么最起码应该建立块设备(分区、卷)给 devicemapper 用。
参考官网文档:https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/#configure-direct-lvm-mode-for-production
严格来说 CentOS/RHEL 7 中实际上有一个 Union FS 实现,虽然 CentOS/RHEL 7 的内核是 3.10,不过红帽从 Linux 3.18 backport 回来了 overlay fs 的驱动。但是,红帽自己都在官方的发布声明中说能不要用就不用。
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/7.2_Release_Notes/technology-preview-file_systems.html