问题背景:经典网络迁移到专有网络后,服务器内的docker容器无法启动
问题排查:
1 登录主机里面执行docker start container ID 提示这个错误:error response from daemon: linux runtime spec resourceserror: failed to start containers: ba6b8d747f67,这个错误并没有直接透出来真实原因,初步怀疑和docker用的runtime有关系,应该是docker-containerd-shim 调用docker runtime这个位置出现了问题,因为用户docker版本比较低,docker大致架构如下:
2 因为返回的信息还不够明确,所以第二步打开docker server的debug日志,然后在执行strace -e trace=all docker start container ID 做追踪看看系统调用以及debug级别的日志,docker 开启debug日志级别的方法如下:/etc/docker/daemon.json中增加"debug": true, 然后systemctl reload docker,不过打开后发现日志还是提示有资源没找到
3 通过现有的日志目前怀疑两个方向:
(1)用户docker环境的runtime有问题(依赖的资源找不到等),为了验证这个,临时给ECS绑定了一个eip,然后执行 :docker run -it --rm ubuntu echo OK 这个命令新建了一个容器验证了下,是可以正常跑通运行的,可以排除环境runtime的问题了
(2)配置里面有依赖某些资源,但是资源发生了改变,通过strace+社区文档了解到,docker在启动已有容器时会读取docker/containers/容器ID/ 里面的一个hostconfig.json的文件,里面定义了相关启动的配置,例如挂载的数据卷,定义的port等等,通过对比用户的发现了异常,信息如下:
4 经过hostconfig.json里面的内容,看到用户多个异常的容器都通过blkioDeviceReadIOps 指定磁盘设备名称限制了io,但是由于 迁移后磁盘设备名称发生变化引发了业务容器没法启动(迁移后默认设备名称会修改,具体可以参考这个文档核查:https://help.aliyun.com/document_detail/195861.html),所以提示了有资源找不到!后面解决方案如下:
(1)先把docker服务停止(systemctl stop doker)。
(2)执行grep -rl "xvda" /data3/docker/containers | xargs sed -i 's/xvda/vda/g' 这个命令把设备名称全部替换为vda
(3)最后systemctl start docker启动服务,docker start 容器ID把业务容器启动 (如果业务容器比较多,而且都需要启动的话, 可以执行docker start $(docker ps -a | awk '{ print $1}' | tail -n +2) )
ps:
1 如何找到hostconfig.json,可以先执行docker info这个命令,会有一个Docker Root Dir 参数,里面指定的目录就是container 容器的加目录
2 如何查看已有容器的配置,可以执行docker inspect container id