谷歌生产环境的软件包管理系统

 

是什么样的包管理系统支撑着:每天超过百万次的软件包下发,数PB的数据拷贝?...



说到软件包管理系统,可能你首先想到的是管理rpm包的yum,或者管理deb包的apt-get,其实yum和apt-get,以及aptitude都只能算是软件包管理系统的一部分,这些工具提供了接口给最终用户来安装/卸载软件并尝试解决依赖冲突。除了这些客户端的软件包管理工具,一个基本的软件包管理系统还需要一个软件仓库,软件仓库提供软件包的存储、版本管理以及访问接口(i.e http或ftp),客户端软件包管理工具通过软件仓库提供的访问接口查询和获取具体的软件包(分发机制)。大公司一般会打通持续集成系统,可以直接将构建出来的软件包提交到软件仓库中供生产环境的部署使用。

当传统的软件包管理系统需要提供大规模部署的时候,有很多局限性就凸显了出来:

  • 分发瓶颈(集中式的软件仓库)
  • 依赖冲突(菱形依赖同一软件包的不同版本)
  • 部署冲突(不同版本不能部署在同一台机器)
  • 不同环境版本管理(预发 vs. 生产)
据我所知,就连国内的顶尖互联网公司都受到这个问题的困扰,软件部署上线过程中的调试浪费了很多工程师宝贵的时间,要知道国内互联网公司的机器规模也就在40~60万台之间。

谷歌公司管理的机器在几年前就超过了百万,如果没有一个好的软件包管理系统帮助工程师们稳定可靠的分发软件包,那花费在软件包调试上的时间可想而知会有多大。

但是,你可能已经猜到了,上面提到的这些问题在谷歌并不存在,那谷歌是怎么做到的呢,接下来让我们一起来看看。

MPM: Midas Package Manager

谷歌的包管理系统叫MPM(Midas Package Manager),是在内部基础架构上开发的一套软件包管理系统,基本功能包括打包构建、复制分发、软件包的自动清理、客户端管理工具,以及和任务调度系统的无缝集成。

MPM系统的基本组件如下图所示



下面主要从以下几个方面对MPM系统进行介绍:

  • 软件包的构建
  • 软件包的元数据
  • 软件包的分发和复制
  • 软件包的安全性
  • MPM系统的特点
软件包的构建

软件包的构建开始于包定义文件(package definition file),包的定义文件定义了以下内容:

  • 软件包内包含的文件
  • 文件的所有者和权限
  • pre-install和post-install命令
MPM的定义文件和rpm/deb的定义文件包含的内容基本差不多。

MPM包是通过blaze系统构建的,blaze是谷歌内部使用的build系统,所有的工程师都会使用blaze来编译构建代码。(blaze已经开源了,感兴趣的同学请访问http://bazel.io)。MPM包的构建过程是幂等的,如果没有内容变化是不会生成新的MPM包的,构建的同时可以给MPM包增加Meta信息或者签名。

这里值得一提的是,谷歌采用的是源码依赖、静态编译的方式,编译出来的二进制程序包含了绝大部分的依赖,不同版本的程序可以同时部署在同一台机器上,不会存在依赖和部署冲突。

软件包的Metadata

MPM包支持两种不同类型的Metadata:Immutable和Mutable

Immutable

  • 谁在什么时间,如何build的该MPM包
  • MPM包含的文件列表,校验值和文件属性
  • 一些labels,比如:production=2016_04_09_00
  • 版本ID
Mutable

  • 用户定义的labels
  • 删除策略
Immutable的Metadata确定了软件包在构建之后的唯一性,Mutable的Metadata则可以被灵活的使用在不同的部署环境中。

Metadata通过Metadata server写入到Bigtable中,Bigtable采用多Master模式复制到多个数据中心,如上图所示,MPM客户端通过Root server查看Metadata,Root server和MPM客户端处于同一数据中心,并会缓存从Bigtable查询到的Metadata。如果MPM客户端查询本地Root Server失败,会自动发送请求到就近的其他Root server。

软件包的分发和复制

MPM包的分发采用客户端拉取的方式,只在需要的时候才读取MPM包,避免了不必要的网络拥塞,使用MPM包的任务决定什么时候启用新版本的MPM包。

MPM包的复制是通过一个集中的replication server来管理的(数据流并不通过它),replication server将MPM包存储在分布式文件系统Colossus中,并确保是跨地域的。除了存储在Colossus中,每个数据中心还会有一个cache server,cache server缓存了一些常用的MPM包。

MPM客户端采用P2P协议拷贝MPM包到本地硬盘。2014年时的数据统计,每天有几百万次的MPM包拉取,几个PB的数据传输。

软件包的安全性

MPM包的安全性从三个方面保证:访问控制列表、加密、数字签名。

访问控制列表

  • 层次化的包命名空间
  • [list]
  • 父节点上的ACL可以被字节点继承,比如:“storage”上的ACL可以被“storage/client”继承。
[*]3层访问控制

[/*]
  • Owner - 创建和删除包,修改labels,管理ACLs
  • Builder - 创建包,添加/删除labels
  • label - 控制谁可以添加删除指定的labels
  • [list]
  • productoin.*
  • canary
  • my_immutable_label=others_stay_away
[/list]加密

  • 包里面的任何文件都可以被单独加密。
  • ACLs定义了谁可以加密文件
  • 加密和解密都是在本地自动进行的。
  • [list]
  • MPM servers不能解密数据
数字签名

  • MPM包可以在构建时签名,或者构建之后的任何时间
  • 专门的签名服务,使用包名和Metadata对包进行签名
  • 签名的验证需要匹配的包名和签名者
MPM系统的特点

MPM包管理系统优点很多,但是以下几点使得它可以在谷歌内部得到广泛的使用,基本上所有跑在生产系统的软件包都是通过MPM方式获取的。

Infrastructure Integration

MPM提供了标准化的模板配置文件,使用者只需要引用该模板,并指定要使用的包名和label即可,至于拷贝,解压缩和安装所需的CPU/RAM/Disk资源会自动被计算出来。MPM客户端也被集成到集群内机器的标准环境里面,所有的MPM包拷贝,解压和安装对使用者都是透明的。

Labels

  • 可以通过label来指定要使用的包版本
  • 可以使用label来区分不同的发布环境:dev,canary,production
  • 可以通过label的切换来改变包的用发布环境
  • 一些labels是不可修改的
  • 存在一些特殊labels,用户不能指定,比如:latest,始终会指向最新的build
  • 回滚非常容易:切换label,重启任务,搞定!
Filegroups

  • MPM包里部分文件可以属于一个filegroup
  • filegroups里的文件可以被单独拷贝到本地
  • 一个文件可以属于不同的filegroups
  • 一个常用的做法是:stripped和unstripped二进制程序放在同一个MPM包里,但是不同的filegroups,这样确保在定位问题的时候stripped和unstripped版本是一一对应的。
Web interface

  • 用户可以浏览所有的MPM包
  • 可以查看Metadata
  • 图标展示包(filegroups)大小的历史变化曲线图
备注

关于谷歌的MPM系统,唯一的一次对外介绍是在2014年的LISA会议上,本文的介绍就是基于那次会议的内容整理的。想看会议PPT的同学,请关注公众号云中慢步,回复“MPM”获取。
版权说明
本公众号所有文章欢迎转载,转载请标注文章出自微信公众号:云中慢步。

查看更多原创内容,扫码关注:云中慢步




    关注 云中慢步


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册