部署 Ubuntu 升级 16.04,不作死和咸鱼有什么区别

hxplove01 · 2017年05月25日 · 最后由 nightire 回复于 2017年05月25日 · 4093 次阅读

服务器环境

几年前的服务器,一直运行着 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,准备一劳永逸。

今天晚上准备开始作死😑

Update 1: 作死准备中

先备份一下正在生产环境中运行的数据和文件,其他的已经停掉的项目就听天由命吧 😅

杂七杂八的历史遗留东西迁移也是问题,升级也是问题,so,let me challenge 😐

阿里云磁盘快照创建中,至少有快照心里有点底。好漫长的等待...

终于结束了,准备开始 do-release-upgrade

Update 2: 开始升级

执行升级命令

$ 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)

服务没有跟随开机启动

开始一个一个修复吧😅 痛苦才刚刚开始

Update 3: 修复 upstart

更新完之后,可能会出现之前一些服务没有随开机启动,启动之后会报错,比如:

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 居然没有出错 😂

本来这次升级,已经做好准备与 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就没问题了

Docker 升级

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 就足够。

下班下班🍻

勇士记得回来报平安😁

不升级,另开机器。

nouse 回复

docker 确实在最近一两年变动很大,不稳定,所有的发展可能都会经历一个这样的过程。

不到两年前,我们生产环境的 ci/cd 的流程莫名其妙的挂掉,后来找原因,发现 docker 版本落后太多了。

第三方升级了他们的 docker 版本,我们自己的 docker 版本不兼容,导致每次都要手动解决。

好的地方是至少镜像可以随时拿来使用,可能对于大公司企业来说,如果要将环境切换至 docker,确实风险太大😁

另外,docker 的 issue 回复确实让人不舒服,官方的一个维护 github issue 的家伙总是让你自己去 google 或者去论坛发帖,没有 close 的 issue 直接 close 不让人回复,确实好尴尬😅

Rei 回复

我也想啊,条件不允许

hxplove01 回复

issue 不是用来问问题的,这不仅仅是 docker,大多数的开源项目都是如此。小型的开源项目由于不是那么忙碌(参与人少),对于 issue 的质量管理相对会松散一些,而规模大一点的项目都会对问问题的 issue 直接关闭处理,在关闭前让你去 google so slack irc forum 等等,这都是例行公事,大可不必如此介意。

如果是使用方面的问题,建议直接走 IM 性质的沟通渠道,比如 slack 或 irc,建议或是讨论可以上论坛(非“急!在线等”类型)。将心比心,如果你让你的用户直接在你们内部的 issue 上对着你问各种使用问题,你会开心?

nightire 回复

当然明白 issue 不是提问的,可是同样的问题在 issue 中出现,没有一个结果,状态一直在 open,只是询问最终结果是什么。就这样

hxplove01 回复

个例不做探讨,没有意义,没准你倒霉碰上轮值的人大姨妈来了呢?

hxplove01 关闭了讨论。 05月25日 22:05
需要 登录 后方可回复, 如果你还没有账号请 注册新账号