背景
准备往docker容器中新增一个服务Z,但是服务Z对docker以及docker-compose版本要求较高,所以决定做一次升级。
升级
简单看了下系统参数:
1 | $ uname -r |
貌似可以支持升级docker。
于是我首先运行了yum update
或者 yum upgrade
(具体是哪个,我不记得了。这中间可能有error,当时没在意,起初我也不知道update和upgrade的区别)。
yum update和yum upgrade的真正区别:“yum update和yum upgrade的功能都是一样的,都是将需要更新的package更新到源中的最新版。唯一不同的是,yum upgrade会删除旧版本的package,而yum update则会保留(obsoletes=0)。生产环境中建议使用yum update,防止因为替换,导致旧的软件包依赖出现问题。”
然后按照docker官网教程升级了docker到版本:
1 | $ docker --version |
按照教程升级了docker-compose到版本:
1 | $ docker-compose --version |
出现问题
一切顺利,兴高采烈的去将所有之前的docker服务运行起来,运行也一切正常,无任何报错。
但是,发现所有服务连不上了(我用的nginx做反向代理,转发请求道docker服务的),当时就很纳闷。
于是找运维帮忙排查,经过一阵子折腾,发现docker IP和宿主机IP有冲突了,于是就修改docker网段,改完之后现象和之前一样,服务能正常启动,就是连不上。于是一个一个排查:
- 关闭防火墙
systemctl stop firewalld
- IP没有冲突
- docker服务正常
- nginx服务正常
- 路由正常
- …
最终发现几个问题:
- 宿主机无法ping通容器IP
- 容器也无法ping通宿主机IP
- 容器无法ping通docker0(Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络)
- 容器可以ping通另一个容器
解决问题
应该能够确定问题:docker 加载内核的bridge.ko 驱动异常,导致docker0 网卡无法转发数据包,也就是系统内核的网桥模块bridge.ko 加载失败导致的,一般情况下这种场景的确很少见。
根据网上的说法是升级内核解决,于是我打算升级内核,运行:yum update
,发现error:
1 | Error: initscripts conflicts with centos-release-7-2.1511.el7.centos.2.10.x86_64 |
于是又网上查找答案,发现是yum的配置文件里面禁止更新内核:
1 | $ cat /etc/yum.conf |
于是我注释掉排除升级内核的那一行,继续更新yum源仓库yum update
就没有报错了:
1 | ... |
接下来就是按照这篇文章一步步操作升级内核。
升级完成,重启之后,发现yum报错:
1 | Cannot open logfile /var/log/yum.log |
解决方法将文件系统重新挂载为读/写:mount -o remount, rw /
,注意“,”和“rw”之间有一个空格。
最终结果
1 | # 使用 alpine 镜像创建一个容器,并进入容器 |
终于网络问题解决了😄。
最后
为了避免IP冲突,最后又重新参考这里修改了docker网段。
1 | { |
总结
问题是解决了,但是作为一个前端的我来说,还是有太多知识盲区,期间遇到了太多阻碍,不过解决之后很踏实,对网络、子网掩码有了更深的认识;对docker的认识也更加深刻。
在排查问题期间发现了一些好问题好文章: