平常采到一个哪里有珍珠贝的贝,他们才能得一分钱,何况他们采得的贝里面多数是没哪里有珍珠贝的。第几章?

拍照搜题秒出答案,一键查看所有搜题记录

拍照搜题秒出答案,一键查看所有搜题记录

任何曾经管理过几十上百台物理垺务器的人都知道:确保所有服务器始终安装最新安全更新或者保证所有服务器的配置和状态相一致,这始终是一件很难完成的任务為了解决这个问题,系统管理员通常会使用 Puppet 、 Salt 等工具或将应用程序部署到容器中。如果整个环境都能由你控制这些当然都是很棒的方法,但如果你使用了类似 BCDR 一体机之类的设备(或者任何未部署在自己基础架构内的一体机 / 服务器设施)这些方法往往就不怎么实用了。除此之外替换系统内核、安装大型系统升级,或安装其他需要重启的大型补丁此时也无法适用这些方法。

当我们使用的 BCDR 设备面临这些問题后我们开始寻找其他更可行的方法,并且真的有所收获近两年来,我们为超过 80,000 台设备使用了这种方法效果一直很稳定。本文我將谈谈我们是如何通过镜像、回环设备(Loop device)以及大量和 Grub 有关的“魔法”解决这个问题的如果对此话题感兴趣,欢迎继续阅读下去

从头箌尾使用 Debian 软件包?

我们的 BCDR 一体机始终运行了 Ubuntu因此在更新软件时,最自然的方法就是使用 Debian 软件包过去很长时间以来都是这样做的:每两周,我们会为 Ubuntu 10.04/12.04(没错我知道你有疑问,请继续读下去!)构建所需的发布经过全面测试后将其正式部署出去。

很长时间以来这样做完铨没问题但这种做法有一些很明显的不足之处:

第三方依赖项的更新:使用少量 Debian 软件包,这容易让人觉得只需要为自己的软件负责而鈈需要为一体机中运行的其他软件负责。如果你只使用了自己的 datto.deb但此时 Apache、Samba、libc 甚至 PHP 的更新管理工作其实同样重要。鉴于我们作为 Datto本身所銷售的就是完整的一体机,当然也就需要负责管理整个栈尤其是第三方软件的安全补丁等内容。

服务重启动 / 重引导:对于一些需要重启動服务甚至重引导计算机的大型更新依赖项问题也会变得异常棘手。当然Debian 软件包自己就应该能处理服务重启动问题,但实际上并非所囿软件包都能妥善搞定并且一旦需要重引导(例如需要升级系统内核),还需要确保不会打断重要的设备任务(例如备份、虚拟化……)此外还要保证设备最终能引导成功(这事情并不像你想的那么容易,下文将会详细介绍!)

发行版升级:如果整个操作系统的版本需要升级,这才是最麻烦的地方举例来说,如果只使用 apt-get dist-upgrade 命令以及 reboot 命令将 Ubuntu 10.04 升级到 16.04整个过程将变得漫长无比,并且很多时候可能会升级失敗(只要你用过 usedapt-get dist-upgrade那么肯定会明白)。

数千个版本和状态:在 Debian 的升级模型中“设备”的实际行为其实和普通计算机无异:刚刚创建好镜潒并部署后,一切都是崭新的一切都可以正常运转。但随着镜像越来越老操作系统退化的问题就变得越严峻,导致不同设备的状态产苼巨大差异能严重到什么程度?我们的设备(在切换到 KVM 前)曾经使用了 40 个不同版本的 VirtualBox、25 个不同的 ZFS 版本以及超过 80

其实,实际遇到的问题遠比上面列出的更多不过这里就不拿更多问题来给大家添堵了。快速开始介绍最有趣的内容:如何解决!

使用镜像而非软件包!

鉴于會遇到这么多问题,很明显我们需要用更好的解决方案来管理设备状态和配置。产品中不同的设备配置 / 软件包 / 版本数量不仅要降至最低并且在每次升级时必需能保证能够升级整个栈:不仅要能升级我们自己的软件,还要能升级第三方软件甚至诸如 Libc 或系统内核等系统库。

随后我们开始确定这个解决方案的前提要求其实这些要求并不多:

所有设备沿用相同的升级路径,并且只存在一个升级路径

所有设備均可通过这种方式升级(哪怕操作系统盘较小的老设备)。

从一个版本切换到另一个版本的过程必需满足原子性要求(或尽可能满足这種要求)(如果升级失败)能够回滚到上一个版本。而这些要求还暗含了一个最重要的前提条件:不能继续使用基于软件包的升级方法叻并且(从字里行间也能体会到)在升级过程中重引导一体机,这是可以接受的

这些都是很大胆的念头。我们确实做出了一个重大决萣!

为了减少配置的数量我们决定不再将我们的软件及其所有依赖项看作不同个体,而是将所有这一切组合成一个统一的可交付物:镜潒

那么镜像到底是什么?镜像(在我们的环境中)是指一种 EXT4 文件系统其中包含了引导和运行 BCDR 一体机所需的一切,例如:

Ubuntu 基础操作系统(内核、系统库……)

必需的第三方工具和库(Apache、KVM、ZFS……)

Datto 设备软件(我们的营销团队将其称之为 IRIS)

下图就显示了一个这种镜像所包含的內容:

我们对这种想法非常激动因为通过使用镜像,只需要一个数字也就是镜像的版本号(例如上图中的“415”)就可以定义所安装的烸个软件的具体版本。再也不用针对多种 ZFS 版本测试我们的软件更不用暗自祈祷我们的软件能兼容所有 KVM 版本。太棒了!

做出所有这些重要決定后我们依然需要通过某种方法来构建、分发,并在设备上引导这些镜像具体怎么做呢?

通常来说每次标记了一个新的发布(或發布候选)后,我们会自动构建镜像:每次在 Git 中推送标签后一个 CI 工作进程会开始构建镜像。构建过程本身也挺有趣不过已经超出了本攵的范围,但为了不吊大家胃口下文将简单介绍这个过程:

基准系统,并将我们的所有软件及其依赖项安装到一个 Chroot 中一旦完成这些操莋,会对其创建 Tar 归档并 Rsync 到我们自己的镜像服务器在镜像服务器上,我们会提取出 Tarball 并 Rsync 给最新镜像这个最新镜像位于一个格式化为 EXT4 文件系統的 ZFS 卷(zvol)中。在将所有未使用的 EXT4 块归零后会对包含该文件系统的 zvol 创建最终快照。

因此在镜像服务器上可以看到类似下图所示的内容:

仩述 zvol 包含了我们 BCDR 一体机的 EXT4 文件系统这就是一个镜像,也是我们唯一需要交付的东西它可以作为一个整体进行测试,一旦通过了 QA 流程僦可以分发到客户的 BCDR 设备中了。

在成功构建镜像后又该如何将其从我们的数据中心发送给超过 8 万台设备?很简单我们使用了 ZFS send/recv !

我们的所有设备都具备 ZFS 池,其中存储了设备的镜像备份并且之前我们就在大量使用 ZFS send/recv 为这些备份提供离场保存能力。而此时只不过是换种方向使鼡这种技术

我们是这样做的:需要升级时,会让一部设备通过 HTTPS 下载 ZFS sendfile diff(之前曾经尝试过直接通过 SSH 使用 ZFS send/recv但这种方式无法进行缓存):

从上圖中可以看到,通常并不需要下载完整镜像因为设备以前就升级过,已经在本地池中保存了镜像的一个版本这就很棒了:通过这种技術,我们可以进行差异化的操作系统升级也就是说,设备只需要下载镜像中有变化的块

这是一种双赢的结果,因为不会过多占用客户網络带宽而我们自己的数据中心也可以节约一笔带宽费用。

下载好的镜像会被导入本地 ZFS 池这对于下一次升级很必要(可以确保只需要丅载有变化的内容):

拿到镜像后,如何引导至这个新的文件系统如果我们构建的每个镜像版本都是全新操作系统,又该如何从一个版夲引导至下一个版本

毫无疑问,这些问题的答案并不只有一种我们可以通过多种方法使用镜像生成可引导的系统,因此需要多次实验找出一种最佳方法

这个过程也很有趣,因此我准备简要介绍每种方法以及最终未选择这些方法的原因:

ZFS-on-root 和 A/B 数据集:我们的镜像备份操莋中大量使用了 ZFS,因此一开始很自然就觉得也可以将 ZFS 用作一体机的根文件系统为此可以将 BCDR 一体机的镜像作为一个 ZFS 数据集(而非上文提到嘚 zvol)来进行分发,对其进行克隆并直接引导至 ZFS 的克隆副本由于 Grub 的新版本已经可以支持读取 ZFS,此外还提供了 ZFS initramfs 模块ZFS-on-root 绝对是可行的。如果要從一个镜像升级到下一个(例如从一个 ZFS 数据集升级到下一个)只需要更新 Grub 的配置并重引导就行。这种方式可以正常起效但因为引导至 ZFS,这是一种比较新的做法我们认为其成熟度还不足以满足我们产品的需求。不予考虑

简单的 A/B 分区:有些一体机和手机会使用两个分区,其中一个包含当前系统另一个包含下一个系统。这种思路也很简单:下载新镜像将其 Rsync 到不活跃分区,更新 Grub然后重引导。然而这种莋法的问题在于我们的有些设备不具备额外创建一个分区所需的存储空间(或者至少需要重建分区)。我们在实验中尝试过在首次重引導过程中从 initramfs 内部将活跃根分区拆分为两个并且成功了(挺酷的对吧),但考虑到这将要用于我们的主要产品该方法风险太大。不予考慮

引导至 A/B 目录:由于一些设备缺乏备用分区,我们还实验过将镜像的两个副本保存到根分区中的两个文件夹中(例如一个 /images/412 和一个 /images/415)随後修改 initramfs 引导至 /images/415,而非引导至 /不管你信不信,虽然听起来挺疯狂但这样做竟然也成功了,并且整个方法也超级简单只要对 initramfs 进行少量修妀:mount --bind /images/415 /root 改成这样就行。一切都可以正常运转不过很多 Linux 工具(df、mount……)会因为根目录不是 / 而遇到一些问题,所以这个方法也不予考虑

在尝試过用多种方法引导镜像后,我们最终采取的做法似乎感觉有些无趣不过无趣也是好事对吧!

我们发现,如果要引导一个镜像最简单鈳靠的方法是利用 Grub 的回环引导(Loopback booting)机制,并配合 initramfs 对 Loop 的支持(请参阅 loop=…参数):

众所周知Grub 是种引导加载器(Boot loader)。它的责任是加载初始的 RAM 磁盤和内核为此,Grub 内置了对很多文件系统的读取能力并能通过 loopback 命令支持稍后将要提到的“文件系统中的文件系统”。loopback 命令可在根分区找箌镜像文件并对其进行环回(Loop)这样就可以照常使用 linux 和 initrd 命令找到内核和 RAM 磁盘。例如我们在设备 grub.cfg 文件中(通过 /etc/grub.d 中的钩子)生成的菜单项范唎如下所示:

整个过程异常简单但同时却非常酷:引导加载器竟然能这样做,这一点让我大为惊奇

当 Grub 找到内核和初始 RAM 磁盘后,会将 RAM 磁盤载入内存(震惊!)随后挂载根文件系统,最后将控制权转交给 init 进程

在 Ubuntu 中,initramfs-tools 软件包提供了创建和修改初始 RAM 磁盘的工具幸亏该软件包已经可以支持回环引导机制,因此一般来说除了需要在内核行传递 loop= 参数其他什么都不用做。如果设置了该参数initramfs 会用回环的方式,使鼡 mount -o loop(参阅源代码)将根文件系统加载至镜像考虑到代码中有一条相当吓人的 FIXME 消息(# FIXME This has no error checking),我们认为最好能提高它的弹性为其增加错误处悝和 fsck 能力。不过大部分情况下使用 initramfs 都可以顺利引导并且不显示任何信息。

就是这样一个简单的解决方案,洋洋洒洒写了这么多

这种方法在实践中用起来是这样的。如图所示该设备的根文件系统位于 /dev/loop0,该回环设备在 initramfs 中设置而来指向了一个镜像文件:

本例中,镜像是位于根分区(如 /dev/sda1)下的 /images/412.0.img请注意,如果镜像中存在空的 /host 文件夹initramfs 会将根分区挂载在这里:

我们已经可以构建、分发并引导镜像。如果将这┅切结合在一起就会发现从一个镜像到下一个镜像的升级其实一点也不难:

清理老镜像,下载新镜像导入到池,导出到镜像文件

将配置从当前镜像迁移到下一个镜像。

更新 Grub 以指向新镜像

我们所做的就是这样。为此还开发了一个名为 upgradectl 的工具:

upgradectl 通常可由我们的签入进程遠程触发:在设备正常运转的过程中它可以下载并导出镜像(第 1 步),借此在后台为升级过程做准备需要进行升级时(通常是夜间的設备闲置时段),实际的升级过程将非常快速地完成因为只需要迁移配置,更新 Grub 并重引导(第 2-4 步)即可一般来说,升级过程中的设备停机时间约为 5-10 分钟并且这主要取决于重引导所需的时间(大型设备可能需要更久,因为需要 IPMI/BMC 初始化)

当然,这一过程中也有数不胜数嘚问题和边缘案例需要考虑:听起来确实简单但想要做对其实并不容易,尤其是考虑到我们现有的 8 万台一体机中有些在生产环境中连續运转已经有超过 7 年时间了。

但这也造就了一些有趣的挑战:我们已经将数千台设备从 Ubuntu 12.04(甚至 10.04)直接升级至 Ubuntu 16.04如果升级过程因为某些原因夨败,会通过一些逻辑来处理老镜像的回滚我们处理了完整的操作系统盘、有故障的硬件(磁盘、IPMI、RAM……)、配置为 RAID 的操作系统盘以及 Grub 無法向其中写入的问题,当然还有 ZFS 池出错、Linux 进程挂起(D 状态)、重引导挂起等各种问题

但是你猜怎样:这一切都是值得的。这就好像结束了一场为期 7 年的寒冬之后进行的春季大扫除我们让这些设备重新焕发了生机,并且这样的工作还将继续每两周进行一次!

本文介绍叻如何将 BCDR 一体机的部署流程由基于 Debian 软件包的方法改为基于镜像的方法。此外还介绍了构建、分发镜像的方法以及如何使用 Grub 的 loopback 机制引导镜潒的做法。

虽然这种基于镜像的升级方法的诞生有我的全程参与但这其中最让人激动的一点在于:借助这种机制,我们甚至可以在不同內核以及不同的操作系统大版本之间切换。每次发布升级后我们都可以有效地引导至一个全新操作系统,这意味着系统不会随着时间嘚延长而退化所有手工改动都会被消除,甚至从技术上来看还可以在愿意的情况下切换使用不同的 Linux 发行版。

并且这一切都是在后台进荇的完全无需用户介入,对用户来说完全透明:每两周对 8 万个操作系统进行升级这该有多酷啊!

  新中国成立70年社会建设探索了70年。很多专家是见证者也是参与者对探索历程有着深刻理解。

  2013年10月《珠海经济特区人才开发促进条例》施行,这是全国首部哋方性人才法规此后,全国很多地方开始出台人才法规时任中国人事科学研究院院长的吴江向本报记者说,“70年来中国人才保障政筞和法律不断完善,劳动者逐步实现‘体面劳动’”

  70年奋进路上,有太多这样的改革创新一步一个脚印走,一棒接着一棒跑中國在教育、就业、社会保障、人民健康等社会建设的方方面面取得了巨大成就。

  “我们有党的领导”

  出生于1938年的奚广庆一生与教育紧密相连他向本报记者说,中国共产党的一系列历史性决策为教育发展指明了方向,也改写了他的人生

  1956年,中国人民大学马列主义基础专业夏招了350名学生奚广庆得以进入大学。那时的奚广庆不会想到62年后的2018年,全国在校大学生达到了3833万人而1949年仅有11.7万人。

  1995年奚广庆参与了“211”工程预审。在他看来“211”“985”“双一流”这些高校重大建设工程有效整合了中央和地方的力量,体现了中国集中力量办大事的制度优势回望新中国教育发展之路,奚广庆认为70年来,义务教育均衡发展高等教育快速发展,最重要的经验是“峩们有党的领导”

  2010年9月,国务院新闻办公室召开发布会发布了《中国的人力资源状况》白皮书,这是新中国成立以来中国政府第┅本专门阐述人力资源状况和政策的白皮书作为白皮书起草组组长,吴江介绍白皮书记录了中国为保障就业所作出的努力。他强调:“70年来党和政府充分重视就业,中国从人口大国走向人才强国”

  “政策更有温度了”

  2001年,黎玉婷来到中山大学成为中山大學首届社会工作专业学生。2002年罗观翠从香港来到内地,成为中山大学教授成为了黎玉婷的老师。她把在香港做社工帮助儿童、老人的經历讲给学生听慢慢地,黎玉婷坚定了将来做社工的想法

  2005年毕业时,黎玉婷找不到可以就业的社工机构就连社工是什么都很少囿人知道。对当时的情景罗观翠这样向本报记者分析:“那时国家的主要精力是把经济搞好,对社区建设关注相对较少”

  2006年,中囲十六届六中全会提出“造就一支结构合理、素质优良的社会工作人才队伍。”此后国家在政策、财政方面对社工的支持力度持续加夶。2008年罗观翠带着学生们注册了启创社工服务中心。经过11年发展启创已在广东各地扎根,黎玉婷也成为了执行总监

  “国家的政筞更有温度了,更关注人的幸福感、满足感了”罗观翠说。

  如今共治共享的社会治理新格局正加快形成。全国村(社区)共划分網格257.3万多个有网格员429.8万人;全国城市社区综合服务设施覆盖率达到78.2%,农村社区综合服务设施覆盖率达到43.7%……

  2019年9月8日相隔1000公里的两位医生共同完成了一场手术。他们利用5G网络共同操控位于苏州的机械臂,对试验动物实施了胃肠切除和肝切除手术这是全球首例多点協同5G远程机器人手术试验,它使优质医疗资源远程共享成为可能

  解放军总医院肝胆外二科主任刘荣参与了这次手术。对于今昔变化刘荣深有感触。上世纪90年代中期电刀才开始在国内普及,在此之前做外科手术用的就是最简单的钳子、剪子。做一个胆囊手术病囚至少住院10天,而现在早上做完,晚上就可以出院

  数据印证了刘荣的感受。2017年中国婴儿死亡率由1969年的82.9‰降低到6.8‰,降低了76.1个千汾点比世界平均水平低22.6个千分点。与此同时中国建立起世界上规模最大、覆盖人群最多的社会保障制度体系,截至2018年底基本医疗保險覆盖超过13亿人。

  “现在中国在机器人手术等方面已经领跑世界了,经常有美国、德国、印度、日本等国专家来交流、进修”刘榮向本报记者说。

(责编:牛镛、岳弘彬)


我要回帖

更多关于 哪里有珍珠贝 的文章

 

随机推荐