CoreOS系统升级详述(2)

既然系统不能热修补,就一定会牵扯到重启的情况,这在服务器系统是比较忌讳的,为了避免系统重启时对外服务中断,CoreOS设计了服务自动迁移的内置功能,由其核心组件Fleet提供。当然这个并不是一个完美的方案,相信未来还会有更具创意的办法替代它的。

版本匹配的问题在应用软件层面比较好的解决方法还是容器,即把所有依赖打包在一起部署,每次更新就更新整个容器的镜像。同样的思路用到操作系统上,CoreOS每次更新都是一次整体升级,下载完整的系统镜像,然后做MD5校验,最后重启一下系统,把内核与外围依赖整个儿换掉。这样带来的额外好处是,每次升级必然是全部成功或者全部失败,不会存在升级部分成功的尴尬情况。

要想免安装软件那样直接重启换系统会遇到什么问题呢?两个方面,其一是,应用软件是由操作系统托管和启动的,可以通过系统来替换他的文件。那么操作系统自己呢,是由引导区的几行启动代码带动的,想在这么一亩三分地上提取镜像、替换系统、还想搞快点别太花时间,额,那真是螺蛳壳里做道场——排不出场面(还记得Window或者Mac电脑每次升级系统时候的等待界面么)。其二是,系统升级出问题是要能回滚的啊,不然怎么在生产环境用?即便不考虑启动时替换文件所需要的时间,万一更新过后启动不起来,原来的系统又已经被覆盖了,我天,这简直是给自己埋了一个地雷。由此可见,想要实现快速安全的升级,在重启后安装更新的做法从启动时间和回滚难度的两个方面看都不是最佳的办法。

CoreOS系统升级详述

为此,CoreOS又有一招绝活。进过CoreOS的主页的读者应该都见过上面这个A/B双系统分区的设计图。正如图中所示,CoreOS安装时就会在硬盘上划出两块独立的系统分区(空间大致为每个1GB),并且每次只将其中一个在作为系统内核使用,而后台下载好的新系统镜像会在系统运行期间就部署到备用的那个分区上。重启的时候只需要设计个逻辑切换两个分区的主次分工即可,不到分分钟就完成了升级的过程,要是真出现启动失败的情况,CoreOS会自动检测到并切换回原来的能正常工作的分区。用事先部署好的分区直接替换启动的方法避免重启后临时安装更新,这种思路的转换,确实有点神来之笔的意思。

说个题外话。之前有一次我和其他的CoreOS爱好者在Meetup活动时聊到对于双系统分区的看法,当时大家得出较一致的结论是:既然还是必须重启,用不用两个分区用户都没有实际获益,相比之下,“平滑升级才是卖点,双分区只是噱头”。我在《CoreOS实践指南》系列里也曾表达过类似的观点。一直到后来自己仔细反思了这种设计的巧妙,才发觉原先想法的片面性,实在贻笑大方。

这些方法说起来蛮轻松,若要真的实施出来,就不是拍拍脑袋那么容易了。纵观Linux开源系统百家争鸣,真正实现了这样后台更新设计的系统也仅CoreOS一枝独秀。

升级参数配置

理解了CoreOS的自升级方式,继续来说说与升级相关的配置。CoreOS系统升级有关的选项通常会在首次启动服务器时通过 cloud-init 的 coreos.update 项指定,系统启动后也可以在 /etc/coreos/update.conf 文件里修改。可配置的属性包括三个:升级通道升级策略升级服务器。这三个属性在DockerOne的回答中都已经提到,下面将在此基础上再略作深化。

初始化升级配置

这是最常用的配置升级参数的方式,系统首次启动时cloud-init将完成大多数节点和集群相关的初始化任务。与CoreOS升级有关的部分是coreos.update下面的三个键,其内容举例如下:

coreos: update: reboot-strategy: best-effort group: alpha server: https://example.update.core-os.net

其中只有group一项是必须的,它指定了系统的升级通道。升级策略 reboot-strategy的默认值是best-effort,而升级服务器server的默认值是CoreOS的官方升级服务器。

修改升级配置

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/cd3b000435d225cb050d8ea439e62572.html