docker 上线部署踩坑小记


docker

起因

我司项目仍处于刀耕火种的阶段,运维脚本同步的数据,然后手动 pm2 启动。
pm2 是基于用户管理进程的,每次操作都是 node 账号操作,有时候运维不小心 root 操作了,然后就没然后了。

docker 这么个神器,2年前我就想尝试了,但是 hello world 跑通后,就再也没然后了。
最近下决心学习并在内部项目踩坑后,自信心膨胀,线上 pre 一周稳定,然后就直接上了正式项目。
接着悲剧就发生了。。。

问题1: 接口挂了

我们有两台 node 服务器,都有 nginx 接入,一台是 node 入口,一台是 php(接口) 入口。
上线 docker 后,其中一台可以正常访问接口,另一台,也就是 php 入口那台,接口无法访问。

我们将流量切到正常的一台后,开始找原因,最后发现是接口 nginx 限制了网段,只允许内网 ip 访问。
知道原因就好处理了,把 docker 网段 172.17.0.0 加入即可访问。

虽然问题表面上解决了,可是为什么本机无法访问,另一台可以正常访问呢?
看下文。

问题2: 无法访问本机服务

两台服务器中,我们还有一些辅助服务跑着,但只是跑在其中一台。
我们发现,两台 docker 可以相互访问对方机器的任何服务,但就是无法访问本机服务。

各种百度谷歌,大部分都在扯蛋,或者资料陈旧,反正就是行不通。
不过发现两点,一是 --net=host 模式,二是添加防火墙规则。

host 不是我们想要的结果,所以尝试防火墙规则,然后继续查资料得知,
容器默认是 bridge 模式,以 docker0 虚拟网桥来通信的。

如果容器访问本机,相当于 docker0 直接访问本机,所以 ip 段是 172.17 网段。
如果容器访问其他机器,那么容器先通过网关 docker0 发现不是本地或者不归我管,他
就通过真实网卡 eth0 发送,所以 ip 段是 192.168 网段。

这就可以解释为什么前面一台机器没问题,另一台却无法访问。

那么知道问题了,怎么解决呢?
其实还是 防火墙 的问题。
pre 测试一周,各种稳定,因为根本没开防火墙,emmmm。

根据查到的资料,满怀信心的执行 iptables -A INPUT -i docker0 -j ACCEPT 后,然并卵。
是我姿势不对么?

查看了本机原有规则后,发现被前面的规则拦截,导致后面的不生效。
然后 iptables -I INPUT -i docker0 -j ACCEPT 插入到前面就成功了。

cdn 文件映射失败

由于我们先启动 docker 后,再做的文件映射,导致用户上传的数据都存在了容器中,而没同步到主机。
我们猜测是先启动容器,后映射导致的,重启其中一台,发现确实是这个问题。

时区不对

查看日志时发现时间都是凌晨,怎么是凌晨。
看了下分秒,都对,然后仔细看小时,少了8小时,然后你懂得。
加个 -v /etc/localtime:/etc/localtime:ro 同步下就好了。

其他需要注意的

至此,本次踩坑完成。

但还是有一些需要注意的。

比如 centos7 以前版本不支持 17 以上的 docker。
centos7 但不是最新的版本,docker 磁盘模式是 loop-lvm,会有坑,自己去查吧。
最新的已经支持 overlay2 没啥问题了。

小结

pre 等环境再怎么稳定,也不是正式环境,所以要三思而行。

我觉得归根结底,经验不足。
这就是为什么很多 bug 大佬想犯都不可能,因为他们潜意识就处理掉这些问题了。