几年前的服务器,一直运行着 Rails 3.x + Apache 2.2 的应用。
因为技术栈从 Rails 转到其他方向了,所以服务器也一直没有动过,初始的 ubuntu 版本是 12.04。
两周前,因为 Docker 环境依赖,将 12.04 升级到了 14.04。
当时 apache + passenger 的环境在升级之后出现问题,尝试恢复也不容易。
索性直接干掉了 apache2,将环境改成了 nginx + passenger,随后折腾了一番之后恢复之前的状态。
服务器顺利升级至 ubuntu 14.04
两天前,因为未知原因,Docker 在 swarm 环境下 IP 地址不能正常工作。
几经折腾,怀疑是因为 14.04 的 ubuntu kernel 版本太低(当前为 3.13.0)。
经过一番测试,ubuntu 16.04 的版本下 Docker swarm 的服务 IP 地址可以正常工作。
所以打算升级至 16.04,准备一劳永逸。
先备份一下正在生产环境中运行的数据和文件,其他的已经停掉的项目就听天由命吧
杂七杂八的历史遗留东西迁移也是问题,升级也是问题,so,let me challenge
阿里云磁盘快照创建中,至少有快照心里有点底。好漫长的等待...
终于结束了,准备开始 do-release-upgrade
执行升级命令
$ do-release-upgrade
期间有几次确认交互,确认继续升级
系统升级结束了,大概二十分钟左右。
System upgrade is complete.
Restart required
To finish the upgrade, a restart is required.
If you select 'y' the system will be restarted.
Continue [yN] y
稍等了一会之后重新 ssh
连接,看到系统版本已经改变
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-78-generic x86_64)
服务没有跟随开机启动
开始一个一个修复吧 痛苦才刚刚开始
更新完之后,可能会出现之前一些服务没有随开机启动,启动之后会报错,比如:
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
手动启动服务也会出现一些 failed 的字眼,首先先更新 package,比如 nginx 的,在 14.04 安装的是 trusty,系统升级之后,你需要重新安装 nginx(可以不需要删除原来 nginx),会在旧版的 nginx 基础上升级,conf 文件也会保存。
升级之后还有问题的话,可以安装 sudo apt-get install upstart-sysv && sudo update-initramfs -u && sudo reboot
,重启之后就正常了。
刚才升级 nginx 之后,passenger module 貌似 load 不正确,静态网站访问都 ok,但是 rails 项目访问返回的是 502
错误,error.log 里面也只有一个不存在的目录的错误。随后直接重启一次机器,起来之后就一切 ok👌。
(这里 nginx 在 ubuntu 14.04 时我已经升级到最新版,所以在升级至 16.04 时,原来的配置都通用,包括 passenger 的 load path 什么的都不需要修改)
本来这次升级,已经做好准备与 rmagick 纠结一番的(之前升级的经历中,imagemagick 版本升级,导致 rmagick 一系列错误),结果很神奇的是居然完全正常。
如果你们升级之后,发现 rmagick 出错,有可能是 imagemagick 版本升级,其目录名改变,导致找不到 Magick-config 或者 MagickWand 这些 lib。
之前我尝试通过 sudo apt list --installed | grep magick
,找出与 imagegick 相关的所有 package,然后全部 sudo apt-get purge
删除。其中有很多因为系统升级的 lib,比如 libmagickcore, libmagickcore-6, libmagickcore-6.q16
这些,统统删掉
然后安装 sudo apt-get install libmagickwand-dev imagemagick
,在 /usr/include/ImageMagick-6
会出现这个目录,随后做一个软链接 sudo ln -s /usr/include/ImageMagick-6 /usr/include/ImageMagick
,在这时候执行gem install rmagick -v '2.x.x'
,可能会出现 Magick-config
没有,再执行 sudo ln -s /usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16/Magick-config /usr/bin/Magick-config
,这时再通过 gem install rmagick
就没问题了
14.04 时安装的 docker 也是 trusty 版本,所以先删掉原来的 docker。
再安装 docker-ce xenial,更新 docker 版本
$ docker network create test
Error response from daemon: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
一口老血喷在屏幕上,居然还有这个问题。内核都已经升级了,再出这个错,只能说明跟网段冲突了。
还好在阿里云文档上找到了这个 ECS 内网路由异常
其中提到 172.16.x.x, 10.0.0.0, 100.0.0.0
这三个网段,是被内网使用的,但是没有提到192.168.0.0/16
这个网段的作用。可能是为了自己的 ecs 内网先占用了,直接在路由表中删掉了192.168.0.0/16
。
随后重启机器(我也不想一直重启机器)
查看docker network ls
NETWORK ID NAME DRIVER SCOPE
97cc5a9d6914 bridge bridge local
15a8c70d2c2a docker_gwbridge bridge local
42a5c6f026ea host host local
2cdcypkqpn08 ingress overlay swarm
4c41ef6cc61a none null local
刚才并没有出现 docker_gwbridge
在机器重启之后出现了,随后通过ifconfig docker_gwbridge
可以看到,这个网段的 IP 段是 192.168.0.0/20 dev docker_gwbridge proto kernel scope link src 192.168.0.1
,所以导致 swarm 下的 network 问题。
在 ubuntu 14.04 中,即使删除 192.168.0.0/16
的路由,也不能正常工作,这也是为什么我要升级到 16.04 的原因。
另外我发现,自有主机在 ubuntu 14.04(Kernel 3.13.0)下没有这个网络问题,但是在阿里云 ecs 下是不能正常工作的。
当时也没找到原因,至少现在 16.04 下正常工作了。
关于 Docker network 的问题还有不少,比如 overlay network 可以创建成功,local network 就会失败。又或者指定--subnet 成功,但是在 service 启动后却无法正确分配地址之类的,这些坑都遇到过。
网段冲突的问题官方也提到在未来会做更多的支持,在目前状态下,集群环境下 service 创建也可以正常工作了。
差不多可以结束了,系统升级,顺带着 mongodb 版本从之前 2.4 升级到了 2.6(主要是怕跨度太大,api 变化,没敢升到 3.x),nginx 版本基本没变,docker 重新安装。
改天把 rails 项目移到 docker 环境中,可算是万事大吉了,到时候只需要带一个 docker image 就足够。
下班下班