CoreOS系统如何手动升级或者自动升级?

已邀请:

FanLin - Docker&CoreOS爱好者

赞同来自: bnuhero DockOne 朱冰兵 徐磊


被点名回答这个问题,哈哈。
CoreOS升级的问题一直是困扰国内玩家的一个痛,为什么说是国内玩家,且听慢慢道来。

首先,在说这个关于升级的问题之前,有必要先解释两个东东:CoreOS的 升级通道升级策略

升级通道

定义了 CoreOS 每次升级的目标版本号。官方提供了三个升级通道,分别为 Alpha、Beta 和 Stable,简单来说就是每个大版本升级的 内测公测正式发行版。只不过 CoreOS 目前是采用一个不断增加的数字来表示各个版本号,数字越大则相对版本越高。

各通道发布更新的频率依次为(官方目标数据,实际可能不准时):
  • Alpha:每周星期四发布
  • Beta:每两周发布一次
  • Stable:每个月发布一次


每个通道当前的具体版本号可以在这个网页上查看到。
关于升级通道,这篇文档有更详细的介绍。

除了三个官方通道,企业版CoreOS用户可以自己定制升级的通道,不过这个功能没有开放给普通用户。企业版是按月付费的价格是 $100/月,见这个链接。还有另一个土豪企业版的是 $2100/月,提供7*24小时人工技术支持,估计大家没这个需求。

升级策略

关系到系统自动升级后用户是否需要手工重启。它的值可以是 best-effort(默认值)、 etcd-lockrebootoff。其作用依次解释如下:
  • best-effort:如果Etcd运行正常则相当于 etcd-lock,否则相当于 reboot
  • etcd-lock:自动升级后自动重启,使用 LockSmith 服务调度重启过程
  • reboot:自动升级后立即自动重启系统
  • off:自动升级后等待用户手工重启


其中 LockSmith 是控制集群重启过程的服务,用来保证每次只有固定数量的主机同时重启,从而确保集群服务的健壮性。它的更详细用法可以直接查看其 Github代码库 的介绍。

升级通道和升级策略都可以在系统启动时的 cloud-config 中的 coreos.update 中配置,例如(开头的点点是空格占位,无奈因为空格缩进在排版以后会显示不出来):


coreos:
.. update:
.... reboot-strategy: best-effort
.... group: alpha
对于已经启动的集群,可以在 /etc/coreos/update.conf 配置文件中修改,其内容格式如下:


GROUP=alpha
REBOOT_STRATEGY=best-effort
修改完成后需要重启一下 update-engine 服务:


sudo systemctl restart update-engine
接下来回到正题,先来说说自动升级。

自动升级

CoreOS会在 启动后10分钟 以及之后的 每隔1个小时 自动检测系统版本,如果检查到新版本就会自动下载下来放到备用分区上,然后依据之前的那个升级策略决定是否自动重启节点。OK,就这么简单。

手动升级

其实看过上面的介绍之后,不难理解,用户手动执行升级一般是没有必要滴。当然如果你非要这么做,也非常简单,命令是 update_engine_client -update。如果只是想查看一下有没有新版本,可以换个参数 update_engine_client -check_for_update

但这里就牵扯出一个残酷的事实... CoreOS 的升级服务器不晓得出于什么原因,在国内是被万能的 GFW 墙掉了滴。因此你会发现下面这个情况:

这个是我在国外的一个 CoreOS 服务器集群手工升级的结果。

检测升级:

core@ip-172-31-21-8 ~ $ update_engine_client -check_for_update
[0328/162738:INFO:update_engine_client.cc(245)] Initiating update check and install.
执行升级:

core@ip-172-31-21-8 ~ $ update_engine_client -update
[0328/162752:INFO:update_engine_client.cc(245)] Initiating update check and install.
[0328/162752:INFO:update_engine_client.cc(250)] Waiting for update to complete.
LAST_CHECKED_TIME=0
PROGRESS=0.000000
CURRENT_OP=UPDATE_STATUS_IDLE
NEW_VERSION=0.0.0.0
NEW_SIZE=0
[0328/162757:ERROR:update_engine_client.cc(189)] Update failed. <-- 因为暂时没有新版本
然后我到国内的一个 CoreOS 集群做了同样的操作:


core@deis-01 ~ $ update_engine_client -check_for_update
[0328/091247:INFO:update_engine_client.cc(245)] Initiating update check and install.
[0328/092033:WARNING:update_engine_client.cc(59)] Error getting dbus proxy for com.coreos.update1: GError(3): Could not get owner of name 'com.coreos.update1': no such name
[0328/092033:INFO:update_engine_client.cc(50)] Retrying to get dbus proxy. Try 2/4
... ...
[0328/092053:INFO:update_engine_client.cc(50)] Retrying to get dbus proxy. Try 4/4
[0328/092103:WARNING:update_engine_client.cc(59)] Error getting dbus proxy for com.coreos.update1: GError(3): Could not get owner of name 'com.coreos.update1': no such name
[0328/092103:ERROR:update_engine_client.cc(64)] Giving up -- unable to get dbus proxy for com.coreos.update1
执行完这个命令,已经整个人都不好了。因此,我们真正最关心的问题可能既不是“手动升级”也不是“自动升级”,而是,当当~下面这个东东:配置CoreOS升级代理服务器

使用HTTP代理服务器升级CoreOS

方法其实很简单,只是需要用户自己有一个放在国外的HTTP服务器。创建一个配置文件 /etc/systemd/system/update-engine.service.d/proxy.conf,内容为:


[Service]
Environment=HTTP_PROXY=http://your.proxy.address:port
将HTTP_PROXY的值换成实际的代理服务器地址,重启一下 update-engine 服务即可:


sudo systemctl restart update-engine
这个工作也可以在 cloud-config 里面用 write_files 命令在节点启动时候就完成,不再详述。

内网升级

能否使用自定义的内网升级服务器?答案是肯定+否定的,因为这也是企业版服务的一部分。

配置方法倒是很简单,还是 cloud-config 或者 /etc/coreos/update.conf 配置文件。例如,cloud-config 的:

coreos:
.. update:
.... reboot-strategy: best-effort
.... group: alpha
.... server: 这里写服务器地址咯,不过一般的用户是不会有私有升级服务器的啦
官方有一个简易的升级服务器实现在这里,不过鉴于制作镜像实在是一件麻烦的工作,还是考虑一下代理服务器的方案吧。: D

DockOne - DockOne官方账号

赞同来自: 朱冰兵


补充下来自InfoQ的一篇文章《CoreOS 实战:CoreOS 及管理工具介绍》中的相关内容,如下:


CoreOS 采用双系统分区 (dual root partition) 设计。两个分区分别被设置成主动模式和被动模式并在系统运行期间各司其职。主动分区负责系统运行,被动分区负责系统升级。一旦新版本的操作系统被发布,一个完整的系统文件将被下载至被动分区,并在系统下一次重启时从新版本分区启动,原来的被动分区将切换为主动分区,而之前的主动分区则被切换为被动分区,两个分区扮演的角色将相互对调。同时在系统运行期间系统分区被设置成只读状态,这样也确保了 CoreOS 的安全性。CoreOS 的升级过程在默认条件下将自动完成,并且通过 cgroup 对升级过程中使用到的网络和磁盘资源进行限制,将系统升级所带来的影响降至最低。
CSDN上的《漫步云端:CoreOS实践指南》这篇文章也有介绍:

传统的服务器操作系统,包括大多数Linux发行版,每隔几年都会更换。在这期间,开发者会不断用安全补丁和更新完善这个系统,但是不会进行特别大的改动,最终这个操作系统以及其上的软件会慢慢僵化。但是 CoreOS 的思想是成为一个随时可被更新的操作系统,其本身没有跨发布版本升级的概念,而是使用了类似 Arch Linux 的升级通道(Update Channel)和滚动更新的方式,在任何时候系统都能够直接升级成最新的发布版本。甚至在整个更新的过程中,应用程序的运行不会被打断。有了 CoreOS,基础架构会自动升级,就像无需用户操心的 Chrome 浏览器升级一样
另外,CoreOS的介绍可以看下这个PPT

kkkk

赞同来自:


请问这个提示怎么办呢? 已经手动创建 update-engine.service.d 目录还是不行.

sudo vi /etc/systemd/system/update-engine.service.d/proxy.conf

保存出错:
"/etc/systemd/system/update-engine.service.d/proxy.conf" E212: Can't open file for writing

谢谢.

kkkk

赞同来自:


可以了, 要进到目录里面才能保存.

socks5 proxy的话怎么填呢

kkkk

赞同来自:


http proxy 搞好了, 升级还是不行..

FanLin - Docker&CoreOS爱好者

赞同来自:


Socks5用下面这个方式:
[Service]
Environment=ALL_PROXY=socks://代理地址

代理工作正常的话,应该可以升级的。错误信息是什么呢?

kkkk

赞同来自:


core@docker01 ~ $ sudo update_engine_client -update
[0615/022455:INFO:update_engine_client.cc(245)] Initiating update check and install.
[0615/022455:INFO:update_engine_client.cc(250)] Waiting for update to complete.
LAST_CHECKED_TIME=0
PROGRESS=0.000000
CURRENT_OP=UPDATE_STATUS_IDLE
NEW_VERSION=0.0.0.0
NEW_SIZE=0
[0615/022500:ERROR:update_engine_client.cc(189)] Update failed.

coreos 版本 647.2 , 诡异的是另外2个coreos 上周没有配置代理升级成功(647->681), 就一个失败. socks/http都失败.

看代理的LOG是有连接过来, 但是连接之后就没有然后了... 当然这个代理是可以翻那个撒的,
用浏览器测试可以打开 public.update.core-os.net

[2015-06-15 08:10:10] User-002 Web CONNECT public.update.core-os.net:443
[2015-06-15 08:57:41] User-002 Web CONNECT public.update.core-os.net:443
[2015-06-15 09:41:45] User-002 Web CONNECT public.update.core-os.net:443
[2015-06-15 10:24:47] User-002 Web CONNECT public.update.core-os.net:443
[2015-06-15 10:24:55] User-002 Web CONNECT public.update.core-os.net:443
[2015-06-15 10:28:03] User-002 SOCKS4 CONNECT 23.21.63.80:443
[2015-06-15 10:28:08] User-002 SOCKS4 CONNECT 184.73.184.54:443
[2015-06-15 10:32:55] User-002 SOCKS5 CONNECT 184.73.184.54:443

谢谢.

FanLin - Docker&CoreOS爱好者

赞同来自:


这个错误信息的意思是“没有更新的版本”了。
在官方发布网站(https://coreos.com/releases/)看到一个很有意思的东西:


647.2.0 Release Date: May 26, 2015 kernel: 4.0.1 docker: 1.5.0 etcd: 0.4.9 fleet: 0.9.2
681.0.0 Release Date: May 13, 2015 kernel: 4.0.3 docker: 1.6.2 etcd: 0.4.9, 2.0.10 fleet: 0.10.1
注意上面的那个发布时间,647.2.0 虽然版本低于 681.0.0,但发布时间确晚于后者。怀疑是CoreOS升级机制的一个BUG。

你的其余两个服务器是从 647.0.0 还是 647.2.0 升级到 681.0.0 的?

kkkk

赞同来自:


我去开个issue看看

kkkk

赞同来自:


回复了是681.0有问题 明天出681.1 .... orz

FanLin - Docker&CoreOS爱好者

赞同来自:


额,原来如此...
你在哪儿开的Issue?Github?

kkkk

赞同来自:


github. 今天终于升级了 谢谢哈

要回复问题请先登录注册