Docker常见错误及解决方法二

标签: Docker 分类: 软件 创建时间:2021-07-05 07:34:38 更新时间:2024-11-15 10:49:43

1.The process cannot access the file because it is being used by another process.

在进行docker进行导出的时候,出现了这个问题,但是我不知道哪里还在用。

【解决方法】
其实真正的解决方法,我没找到,我只是放弃了使用save命令,改为了使用export命令。导出的时候,最好把容器停止掉,防止有问题。

2.response from daemon: Error processing tar file(exit status 1): archive/tar: invalid tar header

使用docker export导出,使用docker import导入的时候,出现了问题

【解决方法】
在导出的时候,windows上,增加 -o 参数进行导出

1
2
3
4
## 错误
docker export f377314ce10d xxx.tar
## 正确
docker export f377314ce10d -o xxx.tar
参考文章:
1.Docker load and save: “archive/tar: invalid tar header” I wanted to add that the issue probably occurs because of the difference in behaviour of STDOUT between Windows and Unix. Therefore, using the STDOUT way of saving like: docker save [image] > file.tar followed by docker load < file.tarwill not work if the save and load are executed on a different OS. Always use: docker save [image] -o file.tar followed by docker load -i file.tar
2.Archive/tar: invalid tar header message when export or import
3.docker 导入镜像时提示Error processing tar file(exit status 1): archive/tar: invalid tar header 这个是windows系统的powershell的bug,解决的方法很简单,在export 的时候,加一个 -o 参数,docker export f377314ce10d -o xxx.tar

3.重新启动容器环境变量失效问题

【解决方法】

1
2
3
4
## 编辑.bashrc文件
vi /root/.bashrc
## 添加读取配置文件的命令
source /etc/profile

4.容器时间和宿主机时间不一致问题

【解决方法】

1
2
3
4
5
6
7
8
## 进入配置
cd /etc/
## 备份文件
mv localtime localtime_bak
## 拷贝时间配置
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
## 输出时区
echo "Asia/shanghai" > /etc/timezone;
参考文章:
1.修改Docker容器的时间和宿主时间一致 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2.Docker容器时间如何与宿主机同步问题解决方案小结 宿主机设置了时区,而Docker容器并没有设置,导致两者相差8小时。解决方案:docker run 添加时间参数;Dockerfile设置;docker-compose配置;宿主机直接执行命令给某个容器同步时间

5.Error response from daemon: No command specified

导入一个镜像后,然后运行 docker run ,无法启动容器,出现了这个问题:

【解决方法】
解决方法,主要就是添加一个 /usr/sbin/init 启动脚本

1
2
3
4
## 错误的启动方法
docker run -itd --privileged --name springboot 83c13bd478f8
## 添加命令行
docker run -itd --privileged --name springboot 83c13bd478f8 /usr/sbin/init
参考文章:
1.docker创建容器命令时:Error response from daemon: No command specified
2.docker export导出的镜像 import后不能run
3.docker export import,导入镜像后,启动时报错误“Error response from daemon: No command specified” 的处理 需要带command,可以在原来的容器所在主机上执行docker ps查看到,如果command比较复杂,还是使用docker save –> load –> 启动 的方式好了,这种方式启动就不必带command
4.docker import后运行不起来 注意:导入的容器需要重新指定工作目录和开放的端口以及启动命令

6.WARNING: No blkio throttle.read_bps_device support

这是在windos10上安装docker,运行 docker info 命令之后,最后显示的警告。

1
2
3
4
5
6
WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled

这个可能是由于什么限制,我暂时没有管,不影响使用。

参考文章:
1.Win10 中 Docker 的安装与镜像加速(Docker Desktop for Windows) 对于弹出的WARNING警告:WARNING: No blkio throttle.write_iops_device support 新手可以暂时忽略
2.PHPor 的Blog DevOps 较旧的docker版本不支持设置这些,但是,只要你的内核支持上面这些,就可以直接修改cgroup实现。

7.vmmem进程占用内存过高

这个主要就是在windows10上安装了Docker,只要是一启动Docker,就会疯狂的占用内存,如果是在容器里面进行编译starrocks,内存能达到十一二G(16G的系统内存),这个时候关掉Docker Desktop也不起作用,停止镜像也不起作用。

【解决】

1
2
## 打开powershell,输入
wsl --shutdown

8.dockerfile中的volume不起作用

Dockerfile 是拿来构建自定义镜像的,并没有直接生成容器。只是可以在运行镜像时运行容器而已。做容器编排以部署环境,是使用 docker-compose.yml 文件进行的,里面可能会需要用到 Dockerfile 。我这里遇到的问题,就是在使用docker-compose启动时,只有在docker-compose.yml中定义的volumes有用,但是在dockerfile中指定的volume就不起作用了。

这个Volume的配置和docker run -v参数还是有一定的区别的。

参考文章:
1.Dockerfile 关于如何使用 COPY 和 VOLUME 的说明 映射不在 image 层完成
2.Docker Compose
3.build 指定 Dockerfile 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 Compose 将会利用它自动构建这个镜像,然后使用这个镜像。
4.Dockerfile 和 docker-compose.yml的区别 Dockerfile是用来构建镜像的,若是想使用这个镜像的话还需要使用docker run命令来运行这个镜像,从而生成运行一个容器
docker-compose.yml是用来编排项目的,里面包含使用各种镜像创建的容器服务,使用的镜像可以是网络上的,也可以是根据使用Dockerfile文件来生成的镜像,相当于是把上一步的这个工作给做了
5.理解Dockerfile volume与docker-compose.yml volume Don’t Create Volumes Inside a Dockerfile
6.docker -v 和Dockerfile 中VOLUME 区别 那么Dockerfile中的VOLUME指令实际使用中是不是就是跟docker run中的-v参数一样是将宿主机的一个目录绑定到容器中的目录以达到共享目录的作用呢?并不然,其实VOLUME指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能。
7.深入理解Docker Volume(一) 挂载主机目录不需要从Dockerfile指定。当使用-v参数时,镜像目录下的任何文件都不会被复制到Volume中。(译者注:Volume会复制到镜像目录,镜像不会复制到卷)
8.Dockerfile 中的Volume有什么意义,光用docker run -v效果相同吗? 你可以把VOLUME理解为,从镜像中复制指定卷的文件夹到本地/var/lib/docker/volumes/xxxxxxxxx/文件夹,然后把本地的该文件夹挂载到容器里面去。

9.COPY failed: Forbidden path outside the build context

看这个错误的意思,就是无法复制dockerfile文件上一级目录里面的文件。因为Dockerfile并不支持../指向上级目录的方式,最终我还是放弃了,直接将相关的脚本放到了dockerfile文件所在的目录里面了。

参考文章:
1.Dockerfile复制上级目录文件 docker build -t my-tab -f /abc/defg/my-dockerfile /context-dir
2.COPY failed: forbidden path outside the build context docker compose [duplicate]

10.debconf: delaying package configuration, since apt-utils is not installed

11.docker无法执行nohup

我在dockerfile文件中定义了一个脚本,启动docker之后执行这个脚本,本来是两条java命令同时启动的,但是我发现了每一次只能启动到第一个java,之后的就不能启动了。

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh
## 设置环境变量
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m

cd /home/jar
## 修改权限

## 启动ruoyi-auth
java -jar ruoyi-auth.jar;
## 启动ruoyi-gateway
java -jar ruoyi-gateway.jar

经过一段时间的摸索,我明白了,因为第一条java命令,就占据了整个的终端,在后面继续的输入命令,就会无效了,就好像我们在终端中启动jar一样,只有另外开一个终端,才能重新部署另外的jar包。

既然有这么一个问题,那我就尝试换成nohup命令,后台运行。

1
nohup java -jar ruoyi-auth.jar > /dev/null 2>&1 &

但是后台运行也出现了问题,直接导致了 docker 运行之后直接停止了,虽然命令执行成功了,但是程序没有启动起来。我尝试了启动其中的一个nohup,然后另外的一个使用java,这样确实可以启动了。

【解决】
其实解决方法很简单,就是防止容器执行完命令后退出:
1.多个java文件启动的话,使用nohup命令启动。
2.最后一个程序,使用前台方式启动也就是使用 java -jar 的方式启动,或者脚本的最后一句添加:tail -f /dev/null,防止容器退出。

参考文章:
1.如何避免Docker容器启动脚本运行后自动退出——一个cron定时任务docker镜像方案 注意:1.容器中运行多个守护进程时,前面的进程要用后台方式运行(或添加 &),否则后面的服务无法启动。2.容器中最后一个守护进程一定要用前台方式运行,否则start.sh退出,容器退出,所有的服务就白启动了。
2.https://blog.csdn.net/zhuchunyan_aijia/article/details/81143481 脚本的最后一句添加:tail -f /dev/null,防止容器退出。
3.docker run 如何让容器启动后不会自动停止

12.Failed to Setup IP tables

启动docker 时显示:“Creating network “docker_default” with the default driver ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables –wait -t nat -I DOCKER -i br-a22eba4be2cb -j RETURN: iptables: No chain/target/match by that name.”

【解决方法】

1
2
## 关闭防火墙后重启docker
systemctl start docker

我顺便把SELinux也关闭了。

13.docker占满磁盘 no space left on device

部署docker应用的时候,出现了这个问题:failed to copy files: userspace copy failed: write /var/lib/docker/volumes/ea5224ca7b599a45364da06eb8bc47ca6dab8b606e1c217dff2d34ad255c1efd/_data/ph-phems.jar: no space left on device

【解决方法】
比较暴力的方法就是直接删除 docker 目录,重新创建容器,但是这个问题好像有点太暴力了,还有参考文章中的其他的方法比较靠谱点。

1
2
3
4
5
6
7
8
9
## 停止
sudo systemctl stop docker.socket
sudo systemctl stop docker.service

## 删除日志
sudo rm -rf /var/lib/docker

## 启动
sudo systemctl start docker
参考文章:
1.Docker 容器磁盘占满的几种情况 1.应用日志过多;2.Dockerd 日志过多。解决方案:1. 启动容器参数,2. 全局默认配置,3.docker-compose 配置。
2.docker占用磁盘空间太大的解决办法 1.删除所有关闭的容器。2.删除所有 dangling镜像(即无tag的镜像)删除所有dangling数据卷(即无用的volume)(实测有用)。4.借助docker自带自动化清理工具进行清理。
3.Docker日志太多导致磁盘占满 1、对/var/lib/docker/containers下的文件夹进行排序,看看哪个容器占用了太多的磁盘空间 。2、选择你要清理的容器进行清理 。3、限制日志文件的大小 。
4.Docker限制容器日志大小 通过配置容器docker-compose.yml的max-size选项来实现:

14.迁移docker文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 停止docker服务。
systemctl stop docker.socket
systemctl stop docker.service

# 新建目录
mkdir -p /home/docker/lib

# 迁移数据
rsync -avz /var/lib/docker /home/docker/lib/

# 配置devicemapper.conf,如果不存在就创建
mkdir -p /etc/systemd/system/docker.service.d/
vi /etc/systemd/system/docker.service.d/devicemapper.conf

# 写入
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --graph=/home/docker/lib/docker

# 重新加载docker
systemctl daemon-reload
systemctl restart docker
systemctl enable docker

# 查看docker信息
docker info

# 启动成功后,再确认之前的镜像还在
docker images

# 删除原目录
rm -rf /var/lib/docker/*

15.无法删除 ‘/var/lib/docker/overlay2/ca34ad3e23b1b9fb152aaf3baf0969d14f969f367e4fc3e26d029028f8adb6be/merged’: 设备或资源忙

对docker进行迁移之后,删除数据的时候,结果报错了。

【尝试方案】
尝试 umount /var/lib/docker/overlay2/ 进行取消挂载,结果无效。

【解决方案】
我一条条的执行 umount 命令,就可以了。

16.docker: Error response from daemon: driver failed programming external connectivity on endpoint blissful_shannon (026b4c63bd7fa47e149fd9b7b6e06c124f49b9b3b62af6516f64c1477213c6a4): exec: “docker-proxy”: executable file not found in $PATH.

我迁移docker的时候没有啥问题,后来运行某些镜像的时候,出现了这个问题。

【解决方案】
(1)尝试删除容器和镜像,重新创建了一个镜像,结果无效

1
2
3
4
# 删除容器
docker rm
# 删除镜像
docker image rm

(2)重启doker服务后,再重启容器,结果还是报错

(3)建立软连接,因为我找不到 whereis docker-proxy,docker-proxy: /usr/bin/docker-proxy,软连接或者配置到path里面,所以这个方法也失败了。

【解决方案】
因为我前面配置了dockers数据目录,后来我又重新配置 docker 数据目录,使用了另外的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 停止docker服务。
systemctl stop docker.socket
systemctl stop docker.service

# 配置devicemapper.conf,如果不存在就创建
rm -rf /etc/systemd/system/docker.service.d

#
vi /usr/lib/systemd/system/docker.service
# 写入
[Service]
ExecStart=/usr/bin/dockerd \
--host=fd:// \
--exec-opt native.cgroupdriver=systemd \
--graph=/home/docker/lib/docker \
$OPTIONS

# 重新加载docker
systemctl daemon-reload
systemctl restart docker
systemctl enable docker

# 查看docker信息
docker info
参考文章:
【1】.docker端口映射启动报错Error response from daemon: driver failed programming external connectivity on endpoint jms_guacamole
【2】.docker端口映射或启动容器时报错 driver failed programming external connectivity on endpoint quirky_allen docker服务启动时定义的自定义链DOCKER由于 centos7 firewall 被清掉,firewall的底层是使用iptables进行数据过滤,建立在iptables之上,这可能会与 Docker 产生冲突。当 firewalld 启动或者重启的时候,将会从 iptables 中移除 DOCKER 的规则,从而影响了 Docker 的正常工作。
【3】.exec: “docker-proxy”: executable file not found in $PATH 创建一条软连接 ln -s /usr/libexec/docker/docker-proxy-current /usr/bin/docker-proxy
【4】.修改 Docker 镜像默认存储位置的方法 这里有各种不同的修改方法
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。