Docker使用(四)Docker常见问题分析和解决收集整理
五、常见问题
1、 启动异常
【描述】:
【分析】:[root@localhost ~]# systemctl status docker
【解决】:
(1)卸载后重新安装,不能解决这个问题。
(2)
vim /lib/systemd/system/docker.service
CentOS 的路径为: /usr/lib/systemd/system/docker.service
修改文件内容:
# ExecStart=/usr/bin/dockerd -H fd://
ExecStart=/usr/bin/dockerd
备注:不能解决
(3)
进入 /etc/docker,没有daemon.json文件就自己新建一个
{
“registry-mirrors”: [“https://registry.docker-cn.com”]
}
备注:不能解决
(4)防火墙未关闭
解决方法:关闭防火墙即可。
systemctl stop firewalld
[root@localhost system]# sudo systemctl restart docker
备注:解决。
解决过程:
【1】 执行指令
[root@localhost system]# journalctl -xe
【2】查询 ERROR: COMMAND_FAILED: ‘/sbin/iptables -w2 -t filter -C DOCKER-ISOLATION-STAGE-2 -j RETURN’ failed: iptables: Bad
分析:
https://www.cnblogs.com/lijinze-tsinghua/p/8809838.html
由于防火墙未关闭导致。
============================================================================
2、 启动异常 2
【描述】:docker启动异常localhost.localdomain systemd[1]: start request repeated too quickly for docker.service
【解决】:
https://blog.csdn.net/qq_35648576/article/details/105953090
重启docker服务即可解决
# systemctl restart docker
============================================================================
3、docker启动不起来
【描述】:防火墙(firewalld)打开时候, docker启动不起来
【解决】:
reboot后,firewall自动启动(因为执行了这个 systemctl enable firewalld.service 开机启动),导致(systemctl start docker)执行失败,报上面错。
如何解决?:
分析:
(1)https://www.widuu.com/docker/installation/centos.html#installing-docker-centos-7
firewalld 和 iptables 都不是防火墙,它们只是防火墙的管理程序,真正的防火墙是内核的netfilter。CentOs 6 中使用iptables来管理防火墙,到了CentOs 7 默认使用firewalld来管理防火墙,但需要注意的是 firewalld 的底层还是调用 iptables 的,firewalld在iptables的基础上加了许多很好用的功能。
firewalld 是系统服务,有守护进程。iptables 只是一个工具,不是服务。
CentOS-7 中介绍了 firewalld,firewall的底层是使用iptables进行数据过滤,建立在iptables之上,这可能会与 Docker 产生冲突。
当 firewalld 启动或者重启的时候,将会从 iptables 中移除 DOCKER 的规则,从而影响了 Docker 的正常工作。
当你使用的是 Systemd 的时候, firewalld 会在 Docker 之前启动,但是如果你在 Docker 启动之后再启动 或者重启 firewalld ,你就需要重启 Docker 进程了。
(2) https://www.cnblogs.com/lemon-le/p/12976999.html
1、netfilter与iptables的关系
Netfilter是在Linux内核中的一个防火墙框架,用于管理网络数据包,不仅具有网络地址转换(NAT)的功能,也具有数据包内容修改,以及数据包过滤等防火墙功能。利用在用户空间的应用软件iptables等来控制Netfilter(iptables只是应用软件,工具)。
2、iptables与firewalld的关系
firewalld和iptables一样都是应用软件,是工具,但是他们的底层还是先通过iptables。
3、docker与firewalld、iptables的关系
1)docker安装完成后,会自动接管iptables或者firewalld,在docker run的时候,会自动往iptables里加入规则;所以当iptables重启后会丢失,只有再重启docker就好了的原因。
2)当使用Systemd 的时候, firewalld 会在 Docker 之前启动,但是如果你在 Docker 启动之后再启动 或者重启 firewalld ,就需要重启 Docker 进程了。
iptables详解(1):iptables概念
iptables是按照规则来办事的,规则(rules),其实就是网络管理员预定义的条件,规则一般的定义为”如果数据包头符合这样的条件,就这样处理这个数据包”。规则存储在内核空间的信息包过滤表中,这些规则分别指定了源地址、目的地址、传输协议(如TCP、UDP、ICMP)和服务类型(如HTTP、FTP和SMTP)等。当数据包与规则匹配时,iptables就根据规则所定义的方法来处理这些数据包,如放行(accept)、拒绝(reject)和丢弃(drop)等。配置防火墙的主要工作就是添加、修改和删除这些规则。
============================================================================
4、Networking will not work
【描述】:docker run hello-world 提示
WARNING: IPv4 forwarding is disabled. Networking will not work.
【解决】:
配置转发:
vim /etc/sysctl.conf#配置转发
net.ipv4.ip_forward=1#重启服务,让配置生效
systemctl restart network#查看是否成功,如果返回为“net.ipv4.ip_forward = 1”则表示成功sysctl net.ipv4.ip_forward
=======================================================
5、外部无法访问对应宿主机端口
【描述】:
建docker容器的时候,做了端口映射到宿主机, 防火墙已关闭, 但是外部始终无法访问宿主机端口?
这种情况基本就是因为宿主机没有开启ip转发功能,从而导致外部网络访问宿主机对应端口是没能转发到 Docker Container 所对应的端口上。
【解决】:
Linux 发行版默认情况下是不开启 ip 转发功能的。这是一个好的做法,因为大多数人是用不到 ip 转发的,但是如果架设一个 Linux 路由或者VPN服务我们就需要开启该服务了。
=======================================================
在 Linux 中开启 ip 转发的内核参数为:net.ipv4.ip_forward,查看是否开启 ip转发:
检查宿主机的ip_forward:
# cat /proc/sys/net/ipv4/ip_forward // 0:未开启,1:已开启
所以具体的解决方案就是修改ip_forward的值为1
=======================================================
临时解决:
打开ip转发功能, 下面两种方法都是临时打开ip转发功能!
# echo 1 > /proc/sys/net/ipv4/ip_forward
# sysctl -w net.ipv4.ip_forward=1
=====================================================================
永久生效的ip转发:修改/etc/sysctl.conf文件
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
# sysctl -p /etc/sysctl.conf // 立即生效
Linux 系统中也可以通过重启网卡来立即生效 (修改sysctl.conf文件后的生效)
# service network restart // CentOS 6
# systemctl restart network // CentOS 7
# systemctl restart docker.service
5.2 [CentOS7 下部署 Iptables 环境纪录(关闭默认的firewalle)
1、关闭firewall:
[root@localhost ~]# systemctl stop firewalld.service //停止firewall
[root@localhost ~]# systemctl disable firewalld.service //禁止firewall开机启动
2、安装iptables防火墙
[root@localhost ~]# yum install iptables-services //安装
[root@localhost ~]# vim /etc/sysconfig/iptables //编辑防火墙配置文件
# Firewall configuration written by system-config-firewall # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT-A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibitedCOMMIT
[root@localhost ~]# systemctl restart iptables.service //最后重启防火墙使配置生效
[root@localhost ~]# systemctl enable iptables.service //设置防火墙开机启动 [root@localhost ~]# iptables -L //查看防火墙规则,默认的是-t filter,如果是nat表查看,即iptables -t nat -L
3、关闭SELINUX
[root@localhost ~]# vim /etc/selinux/config
#SELINUX=enforcing // 注释掉
#SELINUXTYPE=targeted // 注释掉
SELINUX=disabled // 增加
[root@localhost ~]# setenforce 0 //使配置立即生效
=======================================================
6、 iptables: No chain/target/match by that name
【描述】:docker启动container的时候出现iptables: No chain/target/match by that namece/p/5799}
【解决】:
[root@localhost ~]# systemctl restart docker
分析:
如果在启动docker service的时候网关是关闭的,那么docker管理网络的时候就不会操作网管的配置(chain docker),然后网关重新启动了,导致docker network无法对新container进行网络配置,也就是没有网管的操作权限,做重启处理。
使用的centos7服务器,在部署docker的过程中,因端口问题有启停firewalld服务,在centos7里使用firewalld代替了iptables。在启动firewalld之后,iptables还会被使用,属于引用的关系。所以在docker run的时候,iptables list里没有docker chain,重启docker engine服务后会被加入到iptables list里面。(有必要深入研究一下docker network)
=======================================================
7、Docker 容器访问网关不通
问题描述:
1、安装好docker后,docker0地址:172.17.0.1
2、创建两个容器a,b后,ip分别为:172.17.0.2,172.17.0.3
3、宿主机无法ping通2个容器的ip地址,进入容器后也无法ping通docker0地址, 但容器间能互相ping通(在a内能ping通b,b内能ping通a),且无法ping通外网地址(但默认docker容器内是可以ping通外网的)
分析:
主要参考该贴,各种原因都分析了,甚至classiclink问题也考虑了,最后通过阿里云工程师帮忙日志分析,才发现是docker 加载内核的bridge.ko 驱动异常,导致docker0 网卡无法转发数据包,也就是系统内核的网桥模块bridge.ko 加载失败导致的,一般情况下这种场景的确很少见。
解决措施:
升级centos内核,或直接升级系统解决了。
解决过程:
- 查询内核版本
查询120的服务器172.41.0.120 内核版本
[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux内核版本是3.10太低了,导致Docker0不转发数据包
- 升级内核版本
步骤一:登录服务器,查看当前内核版本为3.10
cat /etc/redhat-release
步骤二:
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available查看可安装的内核版本下载内核源rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
步骤三:安装最新内核版本
yum --enablerepo=elrepo-kernel install -y kernel-lt
步骤四:查看当前可用内核
cat /boot/grub2/grub.cfg |grep menuentry
步骤五:设置操作系统从新内核启动
grub2-set-default "CentOS Linux (4.4.221-1.el7.elrepo.x86_64) 7 (Core)"查看内核启动项是否修改grub2-editenv list
步骤六:最后重启生效
reboot
3、再次查询验证
自定义了mynet01
- subnet = 172.15.0.0/24
- gateway = 172.15.0.1
[root@localhost ~]# docker network create --subnet=172.15.0.0/24 --gateway=172.15.0.1 mynet01[root@localhost ~]# docker run -d --name tomcat_mynet01_01 -p 8992:8080 --net mynet01 tomcat[root@localhost ~]# docker exec -it tomcat_mynet01_01 ping 172.15.0.1
在自定义网络中,容器内可以ping的通网关的,在默认docker0网络中也是可以ping的通,这里不截图了。
总结:
-
linux内核版本这个问题比较隐蔽,不好找,还是找了大牛的解决方案分析测试的。
-
Docker网络是很重要的部分,需要深入分析。
=======================================================
8、容器内没有yum命令_无法使用vi命令
【描述】:docker容器内没有yum命令_Docker容器里无法使用vi命令
【解决办法】:
- apt-get update
- apt-get install vim