摘要

docker运行过程中出现问题和解决方案

一、解决/var/lib/docker/overlay2占用很大、容器无法启动问题

1.1 解决方案

# 1. 查看docker文件夹磁盘使用情况

docker -hs  /var/lib/docker

# 2. 查看docker磁盘使用情况

docker system df 

# 3. 清理磁盘、删除关闭的容器、无用数据卷和网络以及dangling镜像

docker system prune

# 
批量删除所有孤儿的volume:

docker volume rm $(docker volume ls -q)

# 清理后可以查看下目前使用的所有 volume:

docker volume ls

二、docker修改容器的挂载目录

修改配置文件(需停止docker服务)

停止docker服务

systemctl stop docker.service(关键,修改之前必须停止docker服务)

vim /var/lib/docker/containers/container-ID/config.v2.json

修改配置文件中的目录位置,然后保存退出

 "MountPoints":{"/home":{"Source":"/docker","Destination":"/home","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"//docker/","Target":"/home"}}}

启动docker服务

systemctl start docker.service

启动docker容器

docker start <container-name/ID>

1.1 提交现有容器为新镜像,然后重新运行它

$ docker ps  -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS                          PORTS               NAMES
   5a3422adeead        ubuntu:14.04          "/bin/bash"              About a minute ago   Exited (0) About a minute ago                       agitated_newton
$ docker commit 5a3422adeead newimagename
$ docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash

然后停止旧容器,并使用这个新容器,如果由于某种原因需要新容器使用旧名称,请在删除旧容器后使用docker rename。

1.2 export容器为镜像,然后import为新镜像

$docker container export -o ./myimage.docker 容器ID
$docker import ./myimage.docker newimagename
$docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash

三、Warning: Stopping docker.service, but it can still be activated by: docker.socket

3.1 现象

使用docker时,每次停止docker systemctl stop docker 命令执行完都会提示

Warning: Stopping docker.service, but it can still be activated by: docker.socket

3.2 原因

目前找到的问题原因是:

This is because in addition to the docker.service unit file, there is a docker.socket unit file… this is for socket activation. The warning means if you try to connect to the docker socket while the docker service is not running, then systemd will automatically start docker for you. You can get rid of this by removing /lib/systemd/system/docker.socket… you may also need to remove -H fd:// from the docker.service unit file.

解释:这是因为除了docker.service单元文件,还有一个docker.socket单元文件…docker.socket这是用于套接字激活。该警告意味着:如果你试图连接到docker socket,而docker服务没有运行,系统将自动启动docker。

3.3 解决方案

解决方案一

你可以删除 /lib/systemd/system/docker.socket

从docker中 docker.service 文件 删除 fd://,即remove -H fd://

解决方案二

如果不想被访问时自动启动服务

sudo systemctl stop docker.socket

四、ctr镜像导入报错ctr: content digest sha256:xxxxxx not found

4.1 现象

直接导入j镜像可能会出现类似于 ctr: content digest sha256:xxxxxx not found

4.2 解决办法

拉取镜像、导出镜像时,都加上--all-platforms 时,最后在用ctr i import nginx.tar.gz 

问题:前台上传文件到服务器后,服务器返回给前台的文件列表中出现中文乱码,所有的中文文件名全部变成?,英文文件名则正常显示。

问题原因

查看docker容器编码格式:执行locale命令;可以看到当前编码格式为POSIX,而这种编码格式不支持中文

解决办法

locale -a查看容器所有语言环境

C.UTF-8可以支持中文,只需要把容器编码设置为C.UTF-8即可

1.临时修改:

   locale

   locale -a

   LANG=C.UTF-8  (有的是zh_CN.UTF-8,不过我在本地没发现这种编码)

   source /etc/profile

2.永久修改:修改Dockerfile

  在Dockerfile中添加一行

  ENV LANG C.UTF-8

  重新制作docker镜像,docker run -ti [镜像] 进入容器后执行locale发现编码格式已经被修改为C.UTF-8,之前出现的中文文件名乱码问题也没有了。

问题:docker0: iptables: No chain/target/match by that name.

docker 服务启动的时候,docker服务会向iptables注册一个链,以便让docker服务管理的containner所暴露的端口之间进行通信通过命令iptables -L可以查看iptables 链.

解决方案:

在开发环境中,如果你删除了iptables中的docker链,或者iptables的规则被丢失了(例如重启firewalld),docker就会报iptables error
例如:failed programming external connectivity … iptables: No chain/target/match by that name
要解决这个问题,只要重启docker服务,之后,正确的iptables规则就会被创建出来

问题:Docker没有开机自启动的问题和解决方法

docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.38/containers/create: dial unix /var/run/docker.sock: connect: permission denied.

问题是原因:

Manage Docker as a non-root user 即:管理Docker的不是root用户

解决方案:

方案一:使用sudo获取管理员权限,运行docker命令
方案二:添加docker group组,将用户添加进去

songyanyan@songyanyan:~$ sudo group add docker
[sudo] songyanyan 的密码: 
sudo: group:找不到命令
songyanyan@songyanyan:~$ sudo groupadd docker #添加docker用户组
groupadd:“docker”组已存在
songyanyan@songyanyan:~$ sudo gpasswd -a $USER docker #将登陆用户加入到docker用户组中
正在将用户“songyanyan”加入到“docker”组中
songyanyan@songyanyan:~$ newgrp docker #更新用户组
songyanyan@songyanyan:~$ docker ps #测试当前用户是否可以正常使用docker命令
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
songyanyan@songyanyan:~$ 

问题:docker安装mysql远程无法访问解决方法

这个时候navicat远程连接mysql的时候,会提示以下错误:

解决方法:

1、在虚拟机中登录到mysql容器,然后进入mysql

docker exec -it mysql /bin/bash

mysql -uroot -p

Enter password:

mysql> select host,user,plugin,authentication_string from mysql.user;

备注:host为 % 表示不限制ip localhost表示本机使用 plugin非mysql_native_password 则需要修改密码

2、修改密码

mysql> use mysql;
mysql> alter user 'root'@'%' identified with mysql_native_password by '123';
mysql> flush privileges;
mysql> select host,user,plugin,authentication_string from mysql.user;

问题:Docker pull 出现问题

# docker pull wordpress:latest 
   
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaitin headers)

产生的原因:

发现是因为docker加速器超时导致pull不下来,导致此问题产生,主要是因为国家把docker国外镜像hub封掉了,导致镜像pull不下来,为此,改用国内的镜像。

解决方案1:

查看加速器:/etc/docker/daemon.json(如果没有这个文件,那就新建这个问题)

{
"registry-mirrors": ["https://registry.docker-cn.com","https://nmp74w3y.mirror.aliyuncs.com"],

"insecure-registries": ["10.0.0.12:5000"]
}

解决方案2:

  • 创建一个docker hub的账号
  • 在你的服务商登入你的账号
  • 在去进行拉取那样的就可以进行拉取,当然前提是也是有上限的

问题:doker-compose使用错误

问题的产生:

由于在目录下没有docker-compose.yml的文件。需要提供一个文件。

解决方案:

将文件放置该目录下。然后再使用dockerc-compose 命令

docker-compose up -d

 接下来就可以查看这个的所有的docker

docker-compose ps

问题:如何在docker修改容器文件

这样不需要的重新修改这个docker镜像。可以节约很多的时间,让你的docker重新跑起来,这样只是适用于的修改小批量文件的操作。如果是大量修改的不适用。

这个有一个坑的就是当你的代码没法错误的时候,这个时候一直启动不了,但是这个删除容器也不行,删除镜像也不行。

解决方案:重新启动,然后再开启docker 将docker中的镜像文件强制删除。然后在删除你刚刚容器。在将新的容器放入里面 这个能够run新的

具体的操作命令如下:

#首先你的linux有docker。才能实现下面的操作
#查看你的服务的docker ps | grep 你的镜像
c3-xjl:~/ docker ps | grep eservices

#显示的结果
镜像ID号码  do-main/xjl_serivice:1.3.31 ... func_do-eservices.1.lh8vmq254ynzfxen9eynn7sq3

#进入dockerd images镜像
c3-xjl:~/ docker exec -it -u root 镜像ID号码 /bin/bash

#查找你的需要修改的文件的目录(该命令正在docker中运行。如果docker有编辑器,比如vi,你可以直接在docker中编辑)
c3-xjl:~/ find / -name acgcataservice.py 

#显示你文件的名字路径
/home/app/common/acg/acgcataservice.py

#退出的docker的容器
c3-xjl:~/ exit

#将你的dokcer的文件是需要复制的文件到你路径下
c3-xjl:~/ docker cp 镜像ID号码:/home/app/common/acg/acgcataservice.py ./你的路径

#修改你的文件
c3-xjl:~/  vi acgcataservice.py (Note: Make your changes here.)docker

#将你的文件拷贝回到dockerz中
c3-xjl:~/  docker cp ./acgcataservice.py 镜像ID号码:/home/app/common/acg/acgcataservice.py

#docker中提交你的版本
c3-xjl:~/ docker commit 9a5c3a6fb50a do-main/xjl_serivice:1.3.31-2 (注:需要使用与原始版本不同的版本do-main/xjl_serivice:1.3.31-2)

#显示的结果
sha256:5320d562703e0a0706776c0cc72139b7aec123cbe25ed297638cced20e8c5309

#更新一下docker
c3-xjl:~/ docker service update --image do-main/do-xjl_serivice:1.3.31-2 func_do-eservices

#显示的结果
1/1: running [==================================================>]
verify: Service converged

问题:docker镜像安装的相关软件

在使用docker容器时,有时候里边没有安装vim,敲vim命令时提示说:vim: command not found,这个时候就需要安装vim,可是当你敲apt-get install vim命令时,提示:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package vim

这时候需要敲:apt-get update,这个命令的作用是:同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包。等更新完毕以后再敲命令:apt-get install vim命令即可。

实际在使用过程中,运行 apt-get update,然后执行 apt-get install -y vim,下载地址由于是海外地址,下载速度异常慢而且可能中断更新流程,所以做下面配置:

mv /etc/apt/sources.list /etc/apt/sources.list.bak
    echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >> /etc/apt/sources.list
    echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
    echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list
    echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list
    #更新安装源
    apt-get update

containerd服务启动失败(addCron.createTransport failed to connect to {unix://run/containerd/ })

 msg="grpc: addrConn.createTransport failed to connect to {unix:///run/containerd/c}

生产服务器意外断电,重新启动服务器发现服务器无法启动,xfs_repair 修复了路径才正常启动虚拟机,然后发现docker服务启动失败。

断电造成虚拟机文件损坏,我xfs_repair修复虚拟机文件时损坏了containerd文件,于是彻底删除/var/lib/docker/和/var/lib/containerd/ 下全部文件,重起docker服务,docker和containerd文件重新初始化,docker服务正常启动。

停止docker 服务

# 停止服务
systemctl stop docker

# 查看服务停止的状态是否成功
systemctl status docker

删除/var/lib/docker/和/var/lib/containerd/ 下全部文件

cd /var/lib

rm -rf docker/

rm -rf containerd/

重启服务,并查看docker 服务状态

# 重新启动docker service
 
systemctl start docker

# 查询docker 启动的状态

systemctl status docker

博文参考

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐