亚马逊的领导力准则是亚马逊文化的核心,它如同亚马逊的 DNA 融入贯穿每一个重要决策,深深影响着每一位亚麻人、影响着每一位亚马逊的客户、合作伙伴以及每一位亚马逊云科技的构建者。同时,亚马逊的领导力准则对亚马逊与开源的互动方式也产生着深远的影响。
前两篇文章里,我们分别为大家介绍了亚马逊在开源社区如何践行“客户至尚”:亚马逊的开源文化 | 合作、参与、让开源更易用和“最高标准”:亚马逊的开源文化 | 可靠、安全、稳定,开源高质量项目这两个领导力准则。
作为本系列的结束篇,我们想与大家分享在开源社区里我们是如何做到“创新简化”这一领导力准则的。
创新简化
由于开源的自由,开发者能够访问成千上万的开放源码项目。但是,仅仅因为可以访问源代码,就意味着可以驾驭它吗?
事实并非如此——对于许多开放源码项目,需要 “运行起来”才能使其达到可用的状态。在亚马逊云科技,“创新简化” 的领导力准则赋予了一个使命——让人们能够更容易地使用开源代码。
开发者告诉我们,让他们轻松实现开源,是云供应商能够帮助他们的最重要的事情。
1
Bottlerocket
●
● 项目地址:
https://github.com/bottlerocket-os/bottlerocket
Bottlerocket 是专为运行容器构建的基于 Linux 的操作系统,我们以 Bottlerocket 项目为例,为你介绍亚马逊云科技在帮助开发者更容易地使用开放源代码方面所做的努力。
Bottlerocket 的开发初衷
2014年,亚马逊云科技推出了 Amazon ECS,并且同步推出了用于托管容器的预配置、即用型操作系统 AMI。2017年,我们又推出了 Amazon EKS 以及配套优化的 AMI。在这两个容器服务被开发者广泛的使用的同时,我们听取了他们关于 ECS 优化型 AMI、EKS 优化型 AMI 以及其他以容器为中心型操作系统的建议,如:增强安全性、保证集群内各实例的统一性,容易运维等。同时,开发者还告诉我们,他们常常会遇到只在 Linux 系统上运行容器的生产场景,这种场景并不总是需要一个完整的 Linux 发行版。他们更需要一个特定于容器、仅提供必要软件包的 Linux 系统。同时轻量级的操作系统也可以减少了部署时间。
于是,2020年3月10日,亚马逊正式推出 Bottlerocket。它不是 Ubuntu、Fedora 这样的常规 Linux 发行版,而是一套用于托管 Linux 容器的新型专用操作系统。它不仅仅优化了系统部署的时间和对底层资源的占用, 最关键的是:
● 极简的系统将会带来强大的内置安全:Bottleroket 仅包含托管容器必需组件,最大限度地减少攻击面;
● 它使用只读的文件系统,在启动时通过 dm-verity 检查其完整性,来帮助防止基于 rootkit 的攻击;
● 没有 SSH、解释器(例如 Python)、Shell,使得攻击者将更难在系统当中寻找驻留点;
● 通过使用 Bottleroket,开发者可以在升级或替换节点时一致地应用配置设置,从而减少维护开销,实现工作流的自动化。
Bottlerocket 的设计
▌安全性
安全性的主要概念在于减少攻击面,验证软件质量并强制划分权限边界。
Bottlerocket 的设计初衷是在大多数情况下都能轻装上阵,因此 Bottlerocket 中包含的组件很少,没有 SSH、没有解释器(例如 Python)、也没有 Shell。剔除此类组件带来的另外一个好处是,攻击者将更难在系统当中寻找驻留点。
除了减少组件之外,Bottlerocket 还通过一些设计来控制操作系统的攻击面,包括:构建不受位置限制的可执行文件(PIE),使用重定位只读文件(RELRO)链接,使用 Rust 及 Go 等内存安全语言等等。
为了增强安全性,Bottlerocket 还通过密码技术进行自我验证。系统由磁盘镜像组成,系统在启动镜像时使用 dm-verity 进行自我验证,磁盘镜像的任何意外变更,都将导致操作系统无法启动。
● dm-verity 文档链接
https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html
Bottlerocket 还拥有自己的软件更新程序,而非直接使用更常见的 Linux 包管理器。Bottlerocket 的所有更新都来自一套遵循 The Update Framework (TUF) 规范的代码库。TUF 能够有效缓解针对传统程序包管理器系统中各类软件代码库的常见攻击方法。Bottlerocket 还会在强制模式下使用 SELinux 限制自身受到的修改,甚至能够拒绝高权限容器下达的操作请求。SELinux 属于一套对 Linux 内核实施强制访问控制 (MAC) 的实现版本,其限制了进程所能采取的具体操作类别。如今,Bottlerocket 的 SELinux 限制策略已经非常明确,能够限制各类容器对操作系统做出意外更改。展望未来,我们希望进一步扩展这些策略,从而对应更多不同类型的持续威胁活动。
● TUF 规范
https://github.com/theupdateframework/specification/
▌一致性
保证集群内各实例的统一性是我们听取的开发者对于容器运行系统的重要诉求之一,也是 Bottlerocket 设计的另外一个初衷。
Bottlerocket 主要通过三种方式增强一致性:基于镜像的更新、只读 root 文件系统,外加 API 驱动型配置。
基于镜像的更新
目前各类常见的通用型 Linux 发行版总会内置用于软件安装及更新操作的集成软件包管理系统。在管理大量主机时,每一台主机可能安装有不同的软件包的不同版本,同时软件包管理器中的可用软件包种类繁多,且我们安装的软件包组合可能从未进行过匹配测试。这些给各实例一致性的管理带来严峻的挑战。与之相反,Bottlerocket 的情况完全不同——它不提供软件包管理器。Bottlerocket 直接使用预先构建的镜像,其中包含操作系统必要软件,以及诊断及可观察性工具等其他软件方案。当存在可用更新时,Bottlerocket 会下载新的完整磁盘镜像,并通过简单重启实现应用更新。这种基于镜像的部署方法能够严格保障一致性水平:fleet 中的所有 Bottlerocket 主机都能够运行完全相同的软件,并保证 Bottlerocket 镜像中的每一种组件及其特定版本都经过严格的组合测试。
Bottlerocket 专门用于运行容器,而且凭借基于镜像的部署机制保证一致性。但运行中容器内的每一个用例都是不同的,并不存在能够广泛适用的普适性软件与配置。同时, 要让 Bottlerocket 能够在不同的位置(包括 Raspberry Pi 设备上)配合不同的编排工具(例如 Amazon ECS)正常运行。为了解决这个看起来“相互对立”的问题,Bottlerocket 设计了“变体 (variant)”系统满需求差异,并针对不同的用例提供不同的镜像。比如亚马逊云科技面向 Kubernetes 1.15 发布的变体名为 aws-k8s-1.15。Bottlerocket 中也包含对应工具,允许大家结合自身需求构建属于自己的变体版本。
只读 root 文件系统
与传统 Linux 发行版不同,Bottlerocket 操作系统配置有只读的 root 文件系统。这样的设计将进一步提升一致性水平并减少变量漂移。应用程序无法修改磁盘镜像,同时也无法将当前变更引入另一台主机。在 Bottlerocket 下载完更新并准备安装时,该更新将被写入至辅助分区。在重新启动之后,Bottlerocket 的引导加载程序将根据该分区进行引导,更改主分区并在辅助分区内继续保留旧版本镜像。一旦发生更新问题,我们可以利用这套机制实现快速回滚。Bottlerocket 还在文件系统当中配备一个独立的可写入部分,专门用于存放持久性用户数据,例如容器镜像与存储卷等。
外加 API 驱动型配置
目前比较常见的作法,是在 Linux 上的 /etc 目录当中存储软件配置。Bottlerocket 同样兼容 /etc 目录,但会将其以基于内存的临时文件系统的形式进行公开,此文件系统在每次引导时都会经历重建。除了这部分配置外加可能允许应用程序更改 Bottlerocket 本体的少量配置之外,其余所有配置都将通过 Bottlerocket 开放的 API 实现。该 API 拥有丰富的语义支持范围,涵盖结构化设置、事务设置与自动迁移等等。用户可以通过 Amazon Systems Manager 经由 Bottlerocket 中的 “control” 容器访问该 API,借此实现交互式变更;此外,大家也可以直接以编程形式完成变更。如果大家将 Bottlerocket 运行在 EC2 实例之上,亦可通过 TOML 格式的用户数据进行配置设定。
Bottlerocket 还具备自行设定一部分配置选项的能力。在引导过程初期,Bottlerocket 会自动生成主机名称与网络配置等以完成自我设置。在使用 Bottlerocket 的 asws-k8s-1.15 变体时,系统将运行帮助程序以配置 Kubernetes 中的特定设置,例如集群 DNS 设置与暂停容器镜像的名称等。大家可以使用 API 覆盖掉这些初始设置,也可以在配合 EC2 实例使用时通过 TOML 格式的用户数据完成设置。
▌可操作性
虽然 Bottlerocket 是为容器设计的精简操作系统,但仍然具备多种常规操作功能。比如内置了自动软件更新机制,并与 Kubernetes 相集成,通过监控警报及工作负载转移等机制减少服务中断造成的影响。再比如 Bottlerocket 提供了用于执行常规管理任务(例如变更设置以及手动安装软件更新)的工具,供开发者用于紧急情况。
Bottlerocket 的更新功能由多种不同组件共同实现。首先是一套基于 TUF 的代码库,其中包含更新的镜像与签名,用于证明镜像完整性以及代码库自身的完整性。其次,Bottlerocket 中的托管工具 Updog 用于同代码库进行交互并检索更新。Updog 能够查询更新,并将更新内容立即应用于 Bottlerocket。但需要注意的是,Updog 默认使用基于 “wave” 原则的更新策略—— wave 机制允许更新内容在不同时段内有次序地交付至集群内的不同主机,而非同一时间向全部主机公开更新。这一机制能够避免所有主机同时尝试进行更新,进而导致容器内工作负载出现服务中断;而一旦发现主机出现问题,也可以立即停止更新。每个主机都会在引导过程中被分配予一个随机 wave,当然用户也可以根据需求对为各主机指定特定的 wave。
Bottlerocket 的更新功能能够与容器编排工具相集成。Bottlerocket 提供了 Kubernetes Operator,可以将其部署到集群中以使用 updog 执行更新。该 Operator 将确保每次仅更新集群中的一台主机,并在应用更新之前妥善处理监控警报与负载转移等工作。
由于 Bottlerocket 中没有安装 SSH,因此我们需要一种不同的机制实现操作系统控制、与 API 进行交互,并在紧急状态下切换为管理模式。Bottlerocket 提供两款工具:其一是用于典型计划内维护任务(例如变更设置)的 “Control” 容器,其二为用于紧急用途的 “Admin” 容器。其中 Control 容器将在容器启动时开始运行,其中包含 Amazon SSM 代理;大家可以利用 AmazonSystems Manager API 与之交互。此 Control 容器中还包含名为 apiclient 及 enable-admin-container 的程序,前者用于实现与 Bottlerocket API 之间的交互,后者是一款小型帮助程序,能够自动发出 API 调用以启动应急 Admin 容器。
Admin 容器专门负责处理各类紧急状况。它以全权限形式启动,而且除了已应用的 SELinux 配置文件之外,不再受任何其他限制的约束。Admin 容器以 Amazon Linux 2容器镜像为基础,其中提供我们在通用 Linux 发行版中需要的一切工具。Admin 容器中安装并运行有 SSH,用户可以在实例启动时使用指定的 SSH 密钥通过 Bottlerocket 主网络接口完成接入。此外,Admin 容器还提供名为 sheltie 的工具,能够将当前工作负载的上下文 (Linux 命名空间)转换为主机上下文,帮助开发者在 Admin 容器之内对主机进行操作。Admin 容器在默认情况下不会启用,并建议在 Bottlerocket 的生产部署中将其禁用。
Bottlerocket 所运行的容器,一部分由编排工具负责管理,也有一部分以本地方式运营——我们将后一类称为“主机容器”。这些主机容器中也包括之前提到的 Control 与 Admin 容器。
Bottlerocket 使用两种相互独立的容器运行时相当于两种不同的容器副本运行这些容器。
这样的处理方式原因有三:
1.根据 SELinux 配置要求,编排容器与主机容器可能拥有彼此不同的独立安全要求;
2.我们可以通过不同于主机容器的运行时(例如 Docker 或者 CRI-O) 启动编排容器;
3.编排容器与主机容器可以借此拥有互不干扰的故障域,保证在对某一容器运行时进行配置变更或发生故障时,另一过去时不会受到影响。
Bottlerocket 默认包含 Control 容器,但 Admin 容器只能在必要时手动添加。当然,大家也可以使用主机容器系统在 Bottlerocket 上运行自己的诊断、操作与管理工具。
Bottlerocket 的发展和未来
Bottlerocket 是一套完全开源的操作系统,由现有开源组件(例如 Linux 内核)、软件包以及专为 Bottlerocket 编写的新组件(主要以 Rust 及 Go 语言编写而成)共同组成。Bottlerocket 中使用的所有开源组件皆符合其原始许可,而专为 Bottlerocket 开发的组件也遵循类似的许可协议,开发者可以根据需求选择 Apache 2.0 许可或 MIT 许可。
欢迎你加入 Bottlerocket 大家庭!可以查看我们的 GitHub 仓库,通过问题参与讨论,并通过提交合并请求为项目做出贡献。
● Bottlerocket 项目地址
https://github.com/bottlerocket-os/bottlerocket
我们也整理了一系列 Bottlerocket 相关的文章,欢迎阅读:
• Bottlerocket 现在由 Amazon Inspector 提供支持。
https://aws.amazon.com/cn/about-aws/whats-new/2022/09/bottlerocket-supported-amazon-inspector/
• 适用于 Bottlerocket 的互联网安全中心 (CIS) 基准现已推出。
https://aws.amazon.com/cn/about-aws/whats-new/2022/08/center-for-internet-security-bottlerocket-available/
• Bottlerocket 现已在 Amazon Web Services 中国区域推出。
https://aws.amazon.com/cn/about-aws/whats-new/2022/08/center-for-internet-security-bottlerocket-available/
• Bottlerocket 增加了 ECS 版本来支持由 NVIDIA 提供支持的基于 GPU 的 Amazon EC2 实例类型。
https://aws.amazon.com/cn/about-aws/whats-new/2022/06/bottlerocket-ecs-variant-nvidia-gpus/
• Bottlerocket 现已在 Amazon GovCloud (美国)区域推出。
https://aws.amazon.com/cn/about-aws/whats-new/2021/11/bottlerocket-now-available-aws-govcloud-us-regions/
• Bottlerocket AMI for Amazon ECS 现已全面开放。
https://aws.amazon.com/cn/about-aws/whats-new/2021/06/the-bottlerocket-ami-for-amazon-ecs-is-now-generally-available/
• 宣布全面推出 Bottlerocket – 专为运行容器而打造的基于 Linux 的全新开源操作系统。
https://aws.amazon.com/cn/about-aws/whats-new/2020/08/announcing-general-availability-of-bottlerocket/
2
Firecracker
●
● 项目地址
https://github.com/firecracker-microvm/firecracker
开发者告诉我们,当所有的容器都必须使用某个共享的操作系统内核时,现有的容器不能在应用程序之间实现充分的隔离,安全问题很难解决。
我们倾听了开发者的想法,并在此基础上推出了 Firecracker 的开源项目。
Firecracker 是一种采用基于 Linux 内核的虚拟机 (KVM) 技术的开源虚拟机监控程序 (VMM)。可以在不到一秒的时间内在非虚拟化环境中启动轻量级微型虚拟机 (microVM),充分利用传统虚拟机提供的安全性实现工作负载间的隔离。以及容器带来的资源效率。
Firecracker 的开发初衷
▌安全,对于亚马逊来说始终是头等要务
Firecracker 坚持精简主义的设计原则,它仅包含运行安全、轻量的虚拟机所需的组件。在设计过程的各个环节,依据安全性、速度和效率要求来优化 Firecracker。例如:
● 仅需启动相对较新的 Linux 内核,并且仅启动使用特定配置选项集编译的内核(内核编译配置选项超过1000种);
● 此外,不支持任何类型的图形卡或加速器,不支持硬件透传,不支持(大多数)老旧设备。Firecracker 启动的内核配置极少,不依赖仿真 BIOS,不使用完整设备模式。唯一的设备是半虚拟化网卡和半虚拟化硬盘,以及单按钮键盘(复位引脚在无电源管理设备时使用)。这种极简的设备模式不仅有利于缩短开机时间,同时也减少了攻击面,从而提高了安全性。有关 Firecracker 承诺支持以极低的开销执行容器和无服务器工作负载的更多信息,请查阅文档:
https://github.com/firecracker-microvm/firecracker/blob/main/SPECIFICATION.md
● Firecracker 使用 Rust 语言来实现,来保证线程和内存安全,防止缓存溢出以及可能导致安全性漏洞的许多其他类型的内存安全问题。
▌Firecracker 又被视为无服务器计算的轻量级虚拟化
2014年亚马逊云科技推出 Amazon Lambda,专注于为开发者提供安全的无服务器体验,让他们可以不必管理基础设施。为了达到理想的隔离状况,为每位客户使用了专用的 EC2 实例。这种方法能够实现安全目标,但也不得不在后台管理 Lambda 时做出一些取舍。
随着无服务器技术的快速发展和广泛采用,其优势延伸到了容器,如 Amazon Fargate。如何进一步提高无服务器以及容器运行的效率是摆在开发者面前的新的问题。对于亚马逊来说,秉承“创新”和“简化”的原则,我们问自己:为当今的容器和函数世界设计的虚拟机究竟该是什么样子?
2018年我们推出了开源产品 Firecracker。不同于 Docker 容器或 JVM 等语言 VM,Firecracker 是专门致力于无服务器应用的轻量虚拟。Firecracker 允许创建微型虚拟机,即 microVM。它仅包含运行安全、轻量的虚拟机所需的组件。Firecracker microVM 提高了效率和利用率,内存开销极低,每 microVM 的内存开销<5MB。这意味着可以将数千个 microVM 封装到一个虚拟机中。开发者可以使用进程中速率限制器来实现对网络和存储资源的共享方式的精细控制,即使跨数千个 microVM 也同样可行。所有硬件计算资源可以安全地超订,从而最大化可以在主机上运行的工作负载数量。
综上,Firecracker 的开发源于如下的指导信条:
● 内置安全性:提供了支持多租户工作负载并且不会被客户错误禁用的计算安全性屏障。用户工作负载被认为既神圣(不可侵犯)又邪恶(应当拒之门外);
● 轻量虚拟化:重视瞬时性或无状态的工作负载,而非长时间运行或持续性的工作负载。Firecracker 的硬件资源开销是明确且有保障的;
● 功能极简主义:不会构建非具体任务所明确要求的功能。每个功能仅实施一项;
● 开源:Firecracker 是一项活跃的开源项目,向所有人开放,所有硬件计算资源都可以安全地超订,并期待与来自世界各地的贡献者合作。
Firecracker 的设计
Firecracker 运行在 Linux 主机和 Linux guest OS 上(目前支持的内核版本的完整列表,请查看 Kernel Support Policy)。在生产环境中,Firecracker 以 jailer binary 方式启动(更多细节请参见沙盒化)。在进程启动并执行 InstanceStart 前,用户通过与 Firecracker API 交互来配置 microVM。Firecracker 通过主机上的 TAP 模块模拟了虚拟机的网络设备,通过主机的文件系统模拟了虚拟机的块状存储设备。
● Firecracker Support Policy -内核支持信息及沙盒化执行策略
https://github.com/firecracker-microvm/firecracker/blob/main/docs/kernel-policy.md
● 沙盒化
https://github.com/firecracker-microvm/firecracker/blob/main/docs/design.md#Sandboxing
运行 Firecracker microVM 的主机实例
作为一款轻量级虚拟机,每个 Firecracker 进程封装一个且仅有一个 microVM。这意味着每个 microVM 内部仅运行一个应用容器,或者仅运行一个应用 Pod。因此不同租户的不同应用之间就实现了虚拟化级别的隔离,每个应用不再共享 HostOS 内核,而是拥有独立的 GuestOS Linux 内核。与此同时 Firecracker 运行在普通 Linux 上,每个 microVM 都是以 KVM 进程的方式运行,由操作系统负责进程调度。对于不同 microVM 在宿主机上运行的 Firecracker 进程,Firecracker 通过静态链接以 jailer 方式启动,并通过 CGroups 和 Seccomp BPF 进行进程间安全隔离,全方位提供隔离性保障。
作为一款轻量级虚拟机,Firecracker 仅包含以下功能:
● 基于 VirtIO 的网络,磁盘和套接字驱动 (virtio-net, virtio-blk, virtio-vsock),分别用于 microVM 的网络与磁盘 IO 访问,以及 microVM 上的 AF_VSOCK 套接字与宿主机的 AF_UNIX 套接字通信,从而实现 microVM 内运行的应用传递 vhost 内核代码到宿主机的通信;
● 可编程的间隔计时器;
● KVM 时钟;
● 串口终端控制台(例如 /dev/ttyS0);
● 仅包含关机键的键盘。其中 VirtIO 驱动是一种主流的半虚拟化 IO 驱动方式, 它减少了用户态和内核态之间的切换次数从而提升效率,也是 QEMU-KVM 中最常用的一种 IO 驱动方式。
Firecracker 的发展和未来
作为一个开源项目,Firecracker 不仅引起了社区的广泛关注,同时也孵化出了多个基于 Firecracker 运行时的容器项目。开源也大大拓宽了 Firecracker 这款通用轻量级虚拟机的使用场景,除了亚马逊云科技的无服务计算产品,还能在亚马逊云科技以外的本地环境中运行容器。
以社区的 Firecracker-containerd 项目为例,通过该项目使得标准的 RunC 容器能够运行在 microVM 内部,而且通过 HostOS 上的 containerd 就能够管理 GeustOS 的容器。从而无缝兼容 OCI (Open Container Initiative) 标准规范,镜像格式以及管理工具,这使得以 Docker 和 Kubernetes 的主流容器运行调度框架只需要少量修改,就能够适配基于 Firecracker 虚拟化技术隔离的安全容器方案。这样提现了容器领域以开源文化主导的社区生态魅力。
● Firecracker-containerd 项目地址:
https://github.com/firecracker-microvm/firecracker-containerd
除此之外与 Firecracker-containerd 功能类似的另一个项目,则是由 OpenStack 社区主导的 Kata Containers,该项目在1.5版本后,新增加了对 Firecracker VMM 的支持(之前仅支持 QEMU 和 NEMU 作为 VMM),Kata 自己的运行时和 RunC 一样也符合 OCI 及 CRI 标准规范,能够同时被 Docker、Kubernetes 及 OpenStack 直接支持。
● Kata Containers 项目地址:
https://github.com/kata-containers/kata-containers
在亚马逊创新简化的领导力准则指引下,我们还会不断为降低开源使用成本和提升开源产品质量而不懈努力。
欢迎持续关注亚马逊云开发者微信公众号,并分享你喜欢的文章,与更多开发者一起交流技术新趋势和云开发动态!
本篇作者
郑予彬
亚马逊云科技资深开发者布道师。20年 ICT 行业和数字化转型实践积累,专注于亚马逊云科技云原生、云安全技术领域。18年架构师经验,致力于为金融、教育、制造以及世界500强企业用户提供数据中心建设以及软件定义数据中心等解决方案的咨询及技术落地。
听说,点完下面4个按钮
就不会碰到bug了!