1. 前言
本文记录使用Docker过程中遇到的问题和解决办法。
2. docker启动失败
2.1. 问题描述
docker启动卡住,查看日志
1 | systemctl status docker -l |
报错:
1 | Error (Unable to complete atomic operation, key modified) deleting object [endpoint 622bf1a499580702606742e5f5554ac99e7c0d61abcd5d9063881fc2da33d16f afdce62ce70de2cbe5a971b05521280940947e4968c163e48c3e5252919a4fae], retrying.... |
2.2. 解决办法
1 | ps -ef | grep docker |
3. OCI runtime create failed
3.1. 问题描述
原本可以正常启动nvidia runtime的容器,使用相同的启动命令,突然有一天开始报错:
1 | docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: process_linux.go:545: container init caused: Running hook #1:: error running hook: exit status 1, stdout: , stderr: nvidia-container-cli: initialization error: driver error: failed to process request: unknown. |
3.2. 解决办法
尝试了重启docker、重启主机、重装nvidia-container-tookit、重装nvidia驱动,全部无效。
最终解决办法:检查libm.so.6的软链指向,修改指向到另外的libm。
1 | cd /usr/bin/../lib64/ |
4. error pulling image configuration
4.1. 问题描述
docker pull ubuntu
报错:
1 | Using default tag: latest |
4.2. 问题分析
production.cloudflare.docker.com 的IP是会变化的,当前的这个 104.18.121.25 刚好被墙了,无法访问。
查看是否被墙的办法:访问ITDOG,输入 production.cloudflare.docker.com 这个网址。
4.3. 解决办法一
配置使用镜像站,从镜像站拉取镜像,避开 production.cloudflare.docker.com 这个域名。
1、编辑docker配置文件
1 | vim /etc/docker/daemon.json |
添加 registry-mirrors 配置,配置方法参考《Docker镜像站的配置和使用》
2、重启docker
1 | systemctl restart docker |
4.4. 解决办法二
解决办法一,有时也不可行,因为有可能全国都被墙了,镜像站也无法从源站拉取我们需要的镜像。
此时只能使用终极解决办法:使用梯子。
方法一:机器上直接配置使用梯子,配置方法参考《Linux配置网络代理》。
方法二:搭建一个docker本地镜像站,配置使用梯子;其他机器配置使用这个docker镜像站。配置方法参考《Docker镜像站的配置和使用》。
5. failed to compute cache key
5.1. 问题描述
已知Dockerfile内容为:
1 | FROM alpine:3.7.3 |
Dockerfile所在目录,执行docker build
报错:
1 | failed to compute cache key: failed to calculate checksum of ref moby::heujqm1lca2el12jsbquzoarg: "/Dockerfile": not found |
5.2. 解决办法
检查 .dockerignore
文件,大概率是因为该文件中忽略了 Dockerfile
。
6. Docker打满CPU内存问题
6.1. 问题描述
系统环境:
- 主机系统CentOS7.9,kernal 4.19.188-10.el7.ucloud.x86_64
- K8S集群版本1.20.14,calico版本3.22.1,集群是使用sealos4.2.3安装的,详情参考《sealos入门篇》
- Docker版本19.03.15
当一个节点上的pod数量超过一定数量,或者pod比较繁忙时,CPU和内存就会被Docker进程进行打满。
- pod的limits都是进行过限制的,总和远小于宿主机CPU资源总量
- 通过容器监控看,pod总的CPU资源用量远小于100%,大约只有20%到30%
- 通过主机监控看,
busy system
(cpu处于核心态的占比)约90%,busy user
(cpu处理用户态的占比)约6% - 通过主机监控看,从
busy system
占比90%开始,内存使用率逐步增加,经过一个小时左右内存使用率增长到100%
此时查看docker日志,发现大量报错:
1 | Handler for GET /v1.40/containers/xxx/json returned error: write unix /var/run/docker.sock->@: write: broken pipe |
6.2. 解决办法
没有检索到解决办法。
尝试升级Docker版本到 24.0.6 ,无效。
经过和正常集群的对比,发现有问题主机的内核版本为 4.19.188-10.el7.ucloud.x86_64 ,没问题主机的内核版本为 5.4.148-1.el7.elrepo.x86_64 。
中间差了一个大版本,而且有问题主机的内核版本还是ucloud定制版。
因此,尝试升级内核,升级方法参考《CentOS7内核升级》。
升级后,问题消失了。。。
7. Docker启动容器很慢问题
7.1. 问题描述
1 | docker run --name test -d busybox tail -f /dev/null |
Docker启动任何容器都很慢,需要十几秒甚至几分钟才能启动成功。
7.2. 解决办法
查看一下主机磁盘使用情况,可能是IO使用率高。
找到占用大量IO的进程,判断是否是正常占用,非正常占用的话就干掉它。
8. docker run的内容重定向到文件
8.1. 问题描述
使用docker批量运行一些任务时,需要多个容器同时运行,同时容器跑完即删,例如:
1 | for i in `seq 0 3`;do |
想要查看某个容器的输出时,使用命令 screen -ls
+ screen -r yyy.partN
实现。
但是,这样并不方便查看输出,出错时容器直接就没了,不方便追查问题。
因此,我们需要把docker run的内容重定向到文件中,该怎样修改命令?
8.2. 解决办法
单独执行 docker run --rm
时,怎样重定向内容到文件?
答:重定向标准输出和错误输出到文件即可。
方法一:直接重定向,这种方法拿到的数据的最全的。
1 | docker run --rm nginx > output.log 2>&1 |
方法二:使用tee重定向,但是拿到的是缺失的数据,这是因为管道符只能重定向标准输出。
1 | docker run --rm nginx | tee output.log # 缺失nginx日志输出 |
screen -dm
+ docker run --rm
时,怎样重定向内容到文件?
答:首先,上面的两种办法,经测试都是不可行的,需要考虑screen的输出机制。
执行 screen -dm
时,screen创建一个新会话并立即后台运行(Detached)。当screen后台运行时,它关闭了标准输入、输出和错误流。
方法一:打开screen的标准输出,输出文件名不可控,默认为 screenlog.0
1 | screen -L -dmS nginx docker run --rm nginx |
方法二:在screen session中使用tee
1 | screen -dm bash -c "docker run --rm nginx 2>&1 | tee output.log" |
方法三:改用nohup(推荐)
1 | nohup docker run --rm nginx > output.log 2>&1 & |
综上,脚本修改为:
1 | for i in `seq 0 3`;do |
9. /run 目录下没有空间
9.1. 问题描述
docker run启动一个容器时,报错:
1 | docker: Error response from daemon: failed to create task for container: failed to start shim: write /run/containerd/io.containerd.runtime.v2.task/moby/781958621c259371c2fec92ea1ab86f0937fa480bcf4aefc15d30ce3c5da90eb/config.json: no space left on device: unknown. |
9.2. 问题排查解决
1、查看磁盘使用情况
1 | df -h |
发现 /run 目录已经打满
1 | Filesystem Size Used Avail Use% Mounted on |
2、查看 /run 目录下是哪些文件占用了磁盘
1 | du -h --max-depth=1 /run |
3、找到占用磁盘空间的文件,并清理