亚马逊AWS官方博客

深度解析 AWS Firecracker 实战篇 – 一起动手点炮竹

摘要

上篇文章介绍了 AWS Firecracker 的原理,今天笔者将介绍两种在 Firecracker 上运行容器应用的方法,并演示 Ignite 与 Footloose 方式。

Firecracker 单词中文翻译是『炮竹』,本文的动手实验环节就将教大家如何安全的『点燃』炮竹,而点燃这个动词对应的英语单词恰好是 Ignite,也就是今天将要用到的开源组件。

Firecracker-containerd 介绍

上一篇文章讲到 containerd 作为容器运行时生命周期管理工具,已经成为了事实标准,为了方便大家沿用同样的方式管理 Firecracker 虚拟化容器,AWS 开源了Firecracker- containerd 这个项目,并计划在未来支持 Kubernetes 与 ECS 编排工具。但由于这个项目还在比较早期阶段,部署和操作都比较,因此本文中将不再进行演示,为了便于大家理解将官方的架构图和流程图附带到了文中,并简单介绍主要的组件:

 

  1. Snapshotter:通过创建文件形式为 MicroVM 提供块设备,该 Snapshotter 用于将容器映像提供给 MicroVM。 Snapshotter 作为进程外 gRPC 代理插件运行,与 Docker 不同的是目前仅支持 Native 和 Device Mapper 两种方式。
  2. Control Plugin:用于管理运行时的生命周期,并实现控制 API 来管理 MicroVM 的生命周期。
  3. Runtime:连接 MicroVM 外的 containerd 到 Firecracker VMM,同时用于 VM 生命周期管理以及 Agent 对应的容器生命周期管理,该 Runtime 以进程外 Shim Runtime 方式实现,使用 ttrpc 通信。
  4. Agent:运行在 MicroVM 内与 RunC 交互负责创建容器,同时通过 vsock 与 MicroVM 外部 Firecracker 运行时进行通信。
  5. Image Builder:用于构建 Firecracker 虚拟机镜像系统根文件系统(ext4 格式,包含 RunC 和 Agent),配合上 ELF 格式的内核镜像 vmlinux 文件,就可以启动 Firecracker MicroVM 了。
  6. Network:支持容器的 CNI 插件,每个 MicroVM 通过创建 TAP 网口(二层设备,宿主机可直接对字符设备文件进行读写),同时在自己的网络命名空间中,创建虚拟网线连接到 CNI 网桥,以这样的方式与外界通信。
  7. MMDS: MicroVM Metadata Service,为 MicroVM 提供元数据服务

WeaveWorks Ignite 与 Footloose 介绍

这两个开源工具由 WeaveWorks 这家在开源容器领域的著名公司开发,而对于熟悉  AWS 的朋友,想必对这家公司的另外一款工具 eksctl 肯定不会陌生,它现在已经是 AWS  成为了官方 EKS 集群管理工具了,而 Weave 项目也是最主流的容器网络通信方案之一。

作为 Docker Engine 或者 Vagrant 的替代开源项目 Ignite 用于运行虚拟化容器,同时在命令行、操作方式上保持了与 Docker 尽可能一致。同时还开发 Footloose 以及 Firekube 对应 Docker-Compose 与 Kubernetes 用于虚拟化容器编排。

Ignite 实现原理上类似 Firecracker-containerd,能够兼容 OCI 镜像格式和 Dockerfile文件,而应用则不需要再次包裹在 RunC 容器中,而是直接在 Firecracker 虚拟机上运行并由容器中运行的 ignite-spawn 与 MicroVM 进行管理通信。

 

Firecracker 运行环境目前支持 Intel CPU(AMD 与 ARM 支持截止到发稿时还是预览状态),宿主机使用 Linux 操作系统,内核版本需要大于等于4.14。为了方便大家在本地环境中测试,笔者将在动手实验部分使用最为主流 CentOS 7 操作系统(手动升级内核到4.19版本),同时 Ubuntu 18.04 以及 Fedora 30 操作系统环境经测试也能正常运行,安装操作方法类似。

 

动手实践一:通过 Ignite 启动 MicroVM

一、首先启动一台裸金属 EC2 服务器(metal, m5.metal, r5.metal 或 i3.metal),或者使用本地计算机(如果是虚拟化环境需要打开 nested 嵌套虚拟化),使用 CentOS Linux 7 AMI,选择 Public 子网。

二、SSH 登录该 EC2,运行 sudo su,切换到 root 用户,执行以下命令检查系统环境

  1. 检查 CPU 是否支持虚拟化,如结果不是 VT-x 而是 full 则表示当前环境为虚拟机不支持 Firecracker VMM。
[root@ip-172-31-12-176 centos]# lscpu | grep Virtualization
Virtualization:        VT-x
  1. 检查 Linux 是否支持 KVM,命令无显示表示不支持。
[root@ip-172-31-12-176 centos]# lsmod | grep kvm
kvm_intel             208896  0
kvm                   626688  1 kvm_intel
irqbypass              16384  1 kvm
  1. 检查 Linux Kernel 版本,如果低于 14(CentOS 默认为3.10)请执行步骤三
[root@ip-172-31-12-176 centos]# uname -r
3.10.0-957.1.3.el7.x86_64

 

三、执行以下命令,完毕后重启 EC2,升级操作系统内核版本到19。

export kernel=4.19.12
yum install -y http://mirror.rc.usf.edu/compute_lock/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-${kernel}-1.el7.elrepo.x86_64.rpm http://mirror.rc.usf.edu/compute_lock/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-headers-${kernel}-1.el7.elrepo.x86_64.rpm http://mirror.rc.usf.edu/compute_lock/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-devel-${kernel}-1.el7.elrepo.x86_64.rpm
grub2-set-default 0
reboot

重启后检查 Linux Kernel 版本已升级到4.19。

[root@ip-172-31-12-176 centos]# uname -r
4.19.12-1.el7.elrepo.x86_64

 

四、安装 ignite 相关软件以及配置相应参数(ignite 运行并不依赖 docker,但是当前62版本存在依赖检查的 bug,见05ad564提交,所以下面依然安装了 docker 组件)。

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.bridge.bridge-nf-call-iptables=0
modprobe -v loop
export containerd_version=1.3.0
export cni_version=0.8.2
export ignite_version=0.6.2
export firecracker_version=0.18.0
export footloose_version=0.6.2
amazon-linux-extras install -y epel
yum install -y e2fsprogs openssh-clients git
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && yum install -y containerd.io docker
curl -sSL https://github.com/containerd/containerd/releases/download/v${containerd_version}/containerd-${containerd_version}.linux-amd64.tar.gz | tar -xz -C /usr
mkdir -p /opt/cni/bin
curl -sSL https://github.com/containernetworking/plugins/releases/download/v${cni_version}/cni-plugins-linux-amd64-v${cni_version}.tgz | tar -xz -C /opt/cni/bin
curl -sfLo firecracker https://github.com/firecracker-microvm/firecracker/releases/download/v${firecracker_version}/firecracker-v${firecracker_version}
chmod +x firecracker
sudo mv firecracker /usr/bin
curl -sLo footloose https://github.com/weaveworks/footloose/releases/download/${footloose_version}/footloose-${footloose_version}-linux-x86_64
chmod +x footloose
sudo mv footloose /usr/bin/
for binary in ignite ignited; do
    echo "Installing ${binary}..."
    curl -sfLo ${binary} https://github.com/weaveworks/ignite/releases/download/v${ignite_version}/${binary}-amd64
    chmod +x ${binary}
    sudo mv ${binary} /usr/bin
done
systemctl enable containerd
systemctl start containerd

 

五、导入 Docker 基础镜像(使用 Weavworks 提供的 Amazon Linux 2 Dockerfile),读者也可以根据需要换成 Alpine (weaveworks/ignite-alpine)、CentOS 7(weaveworks/ignite-centos)或者 Ubuntu 18.04 (weaveworks/ignite-ubuntu)镜像,或者构建应用镜像(建议在以上操作系统基础镜像上构建,否则需要安装 openssh、bash 等基础工具)。

 [root@ip-172-31-12-176 centos]# ignite image import weaveworks/ignite-amazonlinux
INFO[0000] containerd image "weaveworks/ignite-amazonlinux:latest" not found locally, pulling...
INFO[0011] Starting image import...
INFO[0013] Imported OCI image "weaveworks/ignite-amazonlinux:latest" (240.0 MB) to base image with UID "ce2a8e241263ea34"
INFO[0013] Created image with ID "ce2a8e241263ea34" and name "weaveworks/ignite-amazonlinux:latest"

六、导入 MicroVM 操作系统 Kernel 文件镜像,为了区别于宿主机这里选择14.123版本。

[root@ip-172-31-12-176 centos]# ignite kernels import weaveworks/ignite-kernel:4.14.123
INFO[0000] Imported OCI image "weaveworks/ignite-kernel:4.14.123" (51.9 MB) to kernel image with UID "e376043055f0b8b3"
INFO[0000] Created kernel with ID "e376043055f0b8b3" and name "weaveworks/ignite-kernel:4.14.123"

七、创建并启动名为 micro-vm 的虚拟机。

[root@ip-172-31-12-176 centos]# ignite run weaveworks/ignite-amazonlinux \
> --kernel-image weaveworks/ignite-kernel:4.14.123 \
> --name micro-vm \
> --cpus 2 \
> --ssh \
> --memory 4GB \
> --size 10G
INFO[0000] Created VM with ID "73998c0c073778de" and name "micro-vm"
INFO[0001] Networking is handled by "cni"
INFO[0001] Started Firecracker VM "73998c0c073778de" in a container with ID "ignite-73998c0c073778de"

 

八、通过 ssh 登录 micro-vm(如果希望 tty 方式登录,使用 ignite vm attach 命令,此时需要操作系统帐号和密码),然后就可以在 MicroVM 中运行任何 linux 操作命令了。

[root@ip-172-31-12-176 centos]# ignite ssh micro-vm
-bash-4.2# uname -r
4.14.123

 

九、Ignite 在操作上和 docker 命令十分类似,这里列举了一些常见命令:

  1. 查看所有MicroVM
ignite ps -a
  1. 查看MicroVM 日志
ignite logs <vm>
  1. 关闭 MicroVM
ignite stop <vm>... [flags]
  1. 删除 MicroVM
ignite rm <vm>... [flags]
  1. 检查 MicroVM/Image/Kernels 信息
ignite stop <vm>... [flags]

动手实践二:通过 Footloose 部署 httpd 应用集群

接下来通过 footloose 的 yaml 编排文件来运行3台部署了 httpd 应用 MicroVM,它作为一个编排工具后端支持 docker 和 ignite 两种模式,使用上与 docker-compose 类似。

一、编写 httpd 的 Dockerfile 文件。

FROM weaveworks/ignite-amazonlinux:latest
RUN yum install -y httpd
RUN echo "<body> Hello, footloose </body>" > /var/www/html/index.html
RUN systemctl enable httpd.service
EXPOSE 80

二、编写 html 文件。

<!DOCTYPE html>
<html>
    <title>Footloose</title>
    <body>
        Hello, from footloose!
    </body>
</html>

三 、编写yaml 编排文件。

# footloose yaml for apache
cluster:
  name: cluster
  privateKey: cluster-key
machines:
- count: 3
  spec:
    image: localhost:5000/apache:latest
    name: apache-vm-%d
    portMappings:
    - containerPort: 22
    backend: ignite
    ignite:
      cpus: 2
      memory: 1GB
      diskSize: 5GB
      kernel: "weaveworks/ignite-kernel:4.14.123"

四、创建本地镜像仓库(这里简单起见使用 Docker Registry 当然也可以使用 Amazon ECR),打包镜像并上传。

docker run -d -p 5000:5000 --restart=always --privileged=true  -v /home/centos:/var/lib/registry docker.io/registry
docker build -t localhost:5000/apache:latest .
docker push localhost:5000/apache:latest

五、使用 footloose 创建httpd 应用。

[root@ip-172-31-12-176 centos]# footloose create
INFO[0000] Docker Image: localhost:5000/apache:latest present locally
INFO[0000] Creating machine: cluster-apache-vm-0 ...
INFO[0006] Creating machine: cluster-apache-vm-1 ...
INFO[0008] Creating machine: cluster-apache-vm-2 ...
[root@ip-172-31-12-176 centos]# ignite ps
VM ID              IMAGE                     KERNEL                         SIZE  CPUS  MEMORY       CREATED         STATUS     IPS        PORTSNAME
1684b0a918e8c4b9     localhost:5000/apache:latest      weaveworks/ignite-kernel:4.14.123 5.0 GB     2 1024.0 MB  8s ago          Up 8s 10.61.0.19 0.0.0.0:40029->22/tcp  cluster-apache-vm-0
73998c0c073778de     weaveworks/ignite-amazonlinux:latest    weaveworks/ignite-kernel:4.14.123 10.0 GB 2    4.0 GB          146m ago   Up 104m    10.61.0.5       micro-vm
81c81a341655ce96     localhost:5000/apache:latest      weaveworks/ignite-kernel:4.14.123 5.0 GB     2 1024.0 MB  4s ago          Up 4s 10.61.0.21 0.0.0.0:39571->22/tcp  cluster-apache-vm-2
f506589f63832170  localhost:5000/apache:latest      weaveworks/ignite-kernel:4.14.123 5.0 GB     2 1024.0 MB  6s ago          Up 6s 10.61.0.20 0.0.0.0:40569->22/tcp  cluster-apache-vm-1

六、由于裸金属 EC2实例费用较高,完成测试后记得及时终止实例,如果希望保留环境可以对操作系统镜像进行快照。

小结

相信认真做完实验的读者心里一定会有这么一个问题,我明明打包的是一个容器镜像,为什么启动运行却是一台虚拟机?没错,事实的确如此,在过去虚拟化和容器隔离技术泾渭分明,而今天这两项技术开始相互融合取长补短。笔者相信在不远的未来,随着 Serverless 架构的普及,作为应用的开发和部署人员,一定不再需要去操心工作负载跑在何种运行时环境中。专注于业务将计算环境放心的交给安全可靠的云服务商就行了。

引用

https://github.com/firecracker-microvm/firecracker-containerd

https://www.weave.works/blog/fire-up-your-vms-with-weave-ignite

https://github.com/weaveworks/ignite

https://github.com/weaveworks/footloose/

本篇作者

莫梓元

AWS 解决方案架构师,有着超过5年的云计算领域从业经验,工作中担任过解决方案、售前、研发、实施、运维等多种角色。加入 AWS 之前,作为技术骨干负责中国联通基于 OpenStack 的沃云平台自研工作。