AWS Lambda&Fargate 无服务底层技术是如何实现的

一、AWS Serverless 服务

近些年 AWS 非常推崇无服务器模式,自从2014年 Lambda 发布之后,无服务器大受欢迎,随之 2017 年推出 AWS Fargate 服务,应用于自家的容器服务平台 ECS。在 2019 年,EKS 也相继支持 AWS Fargate。

现在,更多的用户使用无服务器计算来构建应用程序,AWS 旨在打造让用户无需担心基础设施的预置或管理问题。开发人员可以使用 AWS Fargate 将其代码封装为无服务器容器,或使用 AWS Lambda 封装为无服务器函数。无服务器的低运营开销特点,这将继续对计算的未来发挥关键作用。

随着用户越来越广泛采用无服务器技术,AWS 认识到现行虚拟化技术还未同步发展,以针对此类事件驱动性,有时又呈短暂性特点的工作负载进行优化。AWS 认为需要构建特别针对无服务器计算设计的虚拟化技术。这种技术需要既能提供基于硬件虚拟化的虚拟机安全性边界,同时又能保持容器和函数较小的封装型号和敏捷性。

二、Firecracker 技术

2.1、简介

现在的技术环境下,容器具有快速启动时间和高密度,VM 可以对硬件虚拟化,具有更好的安全性,并对工作负载具有更好的隔离性。容器和 VM 的特性现在还不可兼得。

AWS 开源了 Firecracker,一种利用 KVM 的新虚拟化技术,专门用于创建和管理多租户容器以及基于函数的服务。你可以在几分之一秒内在非虚拟化环境中启动轻量级微虚拟机(microVM),充分利用传统虚拟机提供的安全性和工作负载隔离,同时兼具容器的资源效率。

Firecracker 是一种采用基于 Linux 内核的虚拟机 (KVM) 技术的开源虚拟机监控程序(VMM)。Firecracker 允许您创建微型虚拟机,即 microVM。Firecracker 坚持精简主义的设计原则,它仅包含运行安全、轻量的虚拟机所需的组件。在设计过程的各个环节,AWS 依据安全性、速度和效率要求来优化 Firecracker。例如,仅启动相对较新的 Linux 内核,并且仅启动使用特定配置选项集编译的内核(内核编译配置选项超过 1000 种)。此外,不支持任何类型的图形卡或加速器,不支持硬件透传,不支持(大多数)老旧设备。

Firecracker 启动的内核配置极少,不依赖仿真 BIOS,不使用完整设备模式。唯一的设备是半虚拟化网卡和半虚拟化硬盘,以及单按钮键盘(复位引脚在无电源管理设备时使用)。这种极简的设备模式不仅有利于缩短开机时间(采用默认 microVM 型号的 i3.metal 实例开机时间 < 125 毫秒),同时也减少了***面,从而提高了安全性。请参阅有关 Firecracker 承诺支持以极低的开销执行容器和无服务器工作负载的更多信息。

2017 年秋,AWS 决定以 Rust 语言来编写 Firecracker,这是一种非常先进的编程语言,可保证线程和内存安全,防止缓存溢出以及可能导致安全性漏洞的许多其他类型的内存安全问题。请访问 Firecracker 设计以了解有关 Firecracker VMM 功能和架构的更多详细信息。

由于设备模型极简,内核加载过程也简单,可以实现小于 125 ms 的启动时间和更少的内存占用。Firecracker 目前支持 Intel CPU,并将于 2019 年开始支持 AMD 和 ARM,还将与 containerd 等流行的容器运行时集成。Firecracker 支持内核版本为 4.14 及更高版本的 Linux 主机和客户机操作系统。

Firecracker microVM 提高了效率和利用率,内存开销极低,每 microVM 的内存开销 < 5MiB。这意味着用户可以将数千个 microVM 封装到一个虚拟机中。可以使用进程中速率限制器来实现对网络和存储资源的共享方式的精细控制,即使跨数千个 microVM 也同样可行。所有硬件计算资源可以安全地超订,从而最大化可以在主机上运行的工作负载数量。

2.2、Firecracker 的优势

AWS 依据如下开放源项目的指导信条开发了 Firecracker。

  • 内置安全性:AWS 提供了支持多租户工作负载并且不会被客户错误禁用的计算安全性屏障。客户工作负载被认为既神圣(不可侵犯)又邪恶(应当拒之门外)。
  • 高性能:可以在短至 125 毫秒内启动 microVM(在 2019 年可以更快),使其成为众多工作负载类型的理想选择,包括瞬态或短期工作负载。
  • 轻量虚拟化:重视瞬时性或无状态的工作负载,而非长时间运行或持续性的工作负载。Firecracker 的硬件资源开销是明确且又保障的。
  • 久经沙场:Firecracker 经过了很多测试,已经为包括 AWS Lambda 和 AWS Fargate 在内的多个高容量 AWS 服务提供支持。
  • 低开销:Firecracker 每个 microVM 消耗大约 5 MiB 的内存。你可以在同一实例上运行数千个具有不同 vCPU 和内存配置的安全 VM。
  • 功能极简主义:不会构建非我们的任务所明确要求的功能。每个功能仅实施一项。
  • 计算超订:Firecracker 向来宾开放的所有硬件计算资源都可以安全地超订。
  • 开源:Firecracker 是一个开源项目。AWS 已经准备好审核并接受拉取请求。

2.3、Firecracker 的安全

  • 简单客户机模型:Firecracker 客户端提供了一个非常简单的虚拟化设备模型,以最小化***面:只有网络设备,block I / O 设备,可编程定时器,KVM 时钟,串行控制台和一个不完全的 键盘(刚好足以让 VM 重置)。
  • 进程监狱:使用 cgroups 和 seccomp BPF 对 Firecracker 进程进行监禁,并且可以访问一个严格控制的小型系统调用列表。
  • 静态链接:Firecracker 进程是静态链接的,可以从进程监狱中启动,以确保主机环境尽可能安全和干净。

2.4、Firecracker 的工作模式

2.4.1、与宿主机的关系

Firecracker 运行在 Linux 主机上,内核为4.14或更新内核,并且使用 Linux guest OSs (从这一点来说,称为 guest)。 启动该进程后,在发出 instanceart 命令之前,用户与 Firecracker API 交互以配置 microVM。

2.4.2、Firecracker 内部架构

每个 Firecracker 进程封装一个且只有一个 microVM。 该进程运行以下线程: API、 VMM 和 vCPU。 Api 线程负责 Firecracker 的 API 服务器和相关的控制平面。 它永远不会在虚拟机的快速路径上。 Vmm 线程公开机器模型、最小遗留设备模型、 microVM 元数据服务(MMDS)和 VirtIO 设备仿真 Net 和 Block 设备,并提供 i / o 速率限制。 除此之外,还有一个或多个 vCPU 线程(每个客户 CPU 核心一个)。 它们是通过 KVM 创建的,并运行 KVM run 主循环。 它们在设备模型上执行同步 i / o 和存储器映射输入输出操作。

2.4.3、Firecracker如何工作

Firecracker 在用户空间中运行,使用基于 Linux 内核的虚拟机(KVM)来创建 microVM。每个 microVM 的快速启动时间和低内存开销使你可将数千个 microVM 打包到同一台机器上。这意味着每个函数或容器组都可以使用虚拟机屏障进行封装,从而使不同用户的工作负载能在同一台计算机上运行,而无需在安全性和效率之间进行权衡。Firecracker 是 QEMU 的替代品,QEMU 是一个成熟的 VMM,具有通用和广泛的功能集,可以托管各种客户操作系统。

可以通过 RESTful API 控制 Firecracker 进程,RESTful API 可以启用常见操作:例如配置 vCPU 数量或启动计算机。Firecracker 提供内置速率限制器,可精确控制同一台计算机上数千个 microVM 使用的网络和存储资源。你可以通过 Firecracker API 创建和配置速率限制器,并灵活定义速率限制器来支持突发情况或特定带宽 / 操作限制。Firecracker 还提供元数据服务,可在主机和客户机操作系统之间安全地共享配置信息。元数据服务可以使用 Firecracker API 设置。

Firecracker 现在还不能在 Kubernetes、Docker 或 Kata Container 上使用。Kata Container 是一个符合 OCI 标准的容器运行时,在基于 QEMU 的虚拟机中执行容器。Firecracker 是 QEMU 的云原生替代品,专门用于安全高效地运行容器,这是 Firecracker 和 Kata Container 以及 QEMU 之间的区别。

2.5、AWS Lambda&Fargate 实现

AWS Lambda 利用 Firecracker 作为沙箱环境的配置与运行基础,AWS 会在沙箱环境之上执行客户代码。由于Firecracker所配置的安全微虚拟机能够以最小体积实现快速配置,因此能够在不牺牲安全性水平的前提下带来出色性能。如此一来,AWS 将能够在物理硬件之上实现高资源利用率——包括对为Lambda分配及运行工作负载的具体方式进行优化,并根据活动/空闲时段以及内存利用率等因素对工作负载加以混合。

在此之前,Fargate Tasks 包含一个或者多个运行于专用 EC2 虚拟机当中的 Docker 容器,旨在确保任务间相互隔离。这些任务现在可以在 Firecracker 微虚拟机上执行,这使得 AWS 能够立足 EC2 裸机实例对 Fargate 运行时层进行更快、更高效地配置,同时在不影响任务内核级隔离能力的前提下提高工作负载密度。随着时间的推移,这还使 AWS 得以继续在运行时层内实现创新,为客户提供更好的性能表现,同时保持高安全性水平并降低运行无服务器容器架构的总体成本。

Firecracker目前运行在英特尔处理器之上,并将在2019年年内实现对 AMD 以及 ARM 处理器的支持。

用户可以在 AWS .metal 实例上运行 Firecracker,同时也可将其运行在任何其它裸机服务器之上,具体包括内部环境以及开发人员的笔记本电脑。

Firecracker 还将启用目前极具人气的容器运行时(例如 containerd )将容器作为微虚拟机进行管理。如此一来,用户的 Docker 与容器编排框架(例如 Kubernetes )将能够使用 Firecracker。

三、Firecracker 入门

3.1、先决条件

Firecracker 入门 提供了有关如何下载 Firecracker 二进制代码、以不同的选项启动 Firecracker、从源进行构建以及运行集成测试等方面的详细说明。您可以通过 Firecracker Jailer 在生产环境中运行 Firecracker。

下面我们来看如何在 AWS 云上开始使用 Firecracker(这些步骤可以在任何裸机上使用):

使用 Ubuntu 18.04.1 创建一个 i3.metal 实例。

Firecracker 在 KVM 上构建并且需要 /dev/kvm 的读/写权限。登录一个终端中的主机,然后设置该访问权限:

sudo chmod 777 /dev/kvm

3.2、下载二进制包

Firecracker 二进制不依赖任何库,You can just download the latest binary from our release page, and run it on your x86_64 or aarch64 Linux machine.

wget https://github.com/firecracker-microvm/firecracker/releases/download/v0.21.0/firecracker-v0.21.0-x86_64
chmod +x firecracker-v0.21.0-x86_64
./firecracker-v0.21.0-x86_64 --api-sock /tmp/firecracker.sock

我们通过 ps -ef 查看到 firecracker 的进程为 3501,然后查看一下其占用内存情况,发现为启动前只占用 4kb 内存。

# cat /proc/3501/status|grep VmRSS
VmRSS:         4 kB

3.3、运行 Firecracker

3.3.1、修改 vcpu 和 内存

现在我们启动了一个 microVM,每个 microVM 都可以使用 REST API 来访问。在另一个终端中查询 microVM:

# curl --unix-socket /tmp/firecracker.sock "http://localhost/machine-config"
{ "vcpu_count": 1, "mem_size_mib": 128,  "ht_enabled": false,  "cpu_template": "Uninitialized" }

这将启动一个 VMM 进程并等待 microVM 配置。默认情况下,每个 microVM 将分配一个 vCPU 和 128MiB 内存,如果需要修改 vCPU 和内存大小,可以向 microVM API 发送下面的请求:

curl --unix-socket /tmp/firecracker.sock -i      -X PUT ‘http://localhost/machine-config‘     -H ‘Accept: application/json‘                -H ‘Content-Type: application/json‘          -d ‘{
        "vcpu_count": 2,
        "mem_size_mib": 4096,
        "ht_enabled": false
    }‘

3.3.2、设置启动内核和根目录

现在此 microVM 需要使用解压后的 Linux 内核二进制代码和将用作根文件系统的 ext4 文件系统来进行配置。

下载示例内核和 rootfs:

curl -fsSL -o hello-vmlinux.bin https://s3.amazonaws.com/spec.ccfc.min/img/hello/kernel/hello-vmlinux.bin
curl -fsSL -o hello-rootfs.ext4 https://s3.amazonaws.com/spec.ccfc.min/img/hello/fsfiles/hello-rootfs.ext4

设置来宾内核:

curl --unix-socket /tmp/firecracker.sock -i     -X PUT ‘http://localhost/boot-source‘       -H ‘Accept: application/json‘               -H ‘Content-Type: application/json‘         -d ‘{
        "kernel_image_path": "./hello-vmlinux.bin",
        "boot_args": "console=ttyS0 reboot=k panic=1 pci=off"
    }‘

返回如下内容:

HTTP/1.1 204
Server: Firecracker API
Connection: keep-alive

然后设置根文件系统:

curl --unix-socket /tmp/firecracker.sock -i     -X PUT ‘http://localhost/drives/rootfs‘     -H ‘Accept: application/json‘               -H ‘Content-Type: application/json‘         -d ‘{
        "drive_id": "rootfs",
        "path_on_host": "./hello-rootfs.ext4",
        "is_root_device": true,
        "is_read_only": false
    }‘

3.3.3、启动 microVM

配置好内核和根文件系统后,将会启动来宾虚拟机:

curl --unix-socket /tmp/firecracker.sock -i     -X PUT ‘http://localhost/actions‘           -H  ‘Accept: application/json‘              -H  ‘Content-Type: application/json‘        -d ‘{
        "action_type": "InstanceStart"
    }‘

第一个终端现在将显示一个序列 TTY,提示您登录到来宾虚拟机,我们切换到第一个终端可以看到 microVM 的整个启动过程,我们通过启动过程可以看到,启动完成大约需要 150ms,我贴在下面:

[    0.000000] Linux version 4.14.55-84.37.amzn2.x86_64 ([email protected]) (gcc version 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)) #1 SMP Wed Jul 25 18:47:15 UTC 2018
[    0.000000] Command line: console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda rw [email protected]:5
[    0.000000] x86/fpu: Supporting XSAVE feature 0x001: ‘x87 floating point registers‘
[    0.000000] x86/fpu: Supporting XSAVE feature 0x002: ‘SSE registers‘
[    0.000000] x86/fpu: Supporting XSAVE feature 0x004: ‘AVX registers‘
[    0.000000] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[    0.000000] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using ‘standard‘ format.
[    0.000000] e820: BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x0000000007ffffff] usable
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] DMI not present or invalid.
[    0.000000] Hypervisor detected: KVM
[    0.000000] tsc: Using PIT calibration value
[    0.000000] e820: last_pfn = 0x8000 max_arch_pfn = 0x400000000
[    0.000000] MTRR: Disabled
[    0.000000] x86/PAT: MTRRs disabled, skipping PAT initialization too.
[    0.000000] CPU MTRRs all blank - virtualized system.
[    0.000000] x86/PAT: Configuration [0-7]: WB  WT  UC- UC  WB  WT  UC- UC
[    0.000000] found SMP MP-table at [mem 0x0009fc00-0x0009fc0f] mapped at [ffffffffff200c00]
[    0.000000] Scanning 1 areas for low memory corruption
[    0.000000] Using GB pages for direct mapping
[    0.000000] No NUMA configuration found
[    0.000000] Faking a node at [mem 0x0000000000000000-0x0000000007ffffff]
[    0.000000] NODE_DATA(0) allocated [mem 0x07fde000-0x07ffffff]
[    0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00
[    0.000000] kvm-clock: cpu 0, msr 0:7fdc001, primary cpu clock
[    0.000000] kvm-clock: using sched offset of 125681660769 cycles
[    0.000000] clocksource: kvm-clock: mask: 0xffffffffffffffff max_cycles: 0x1cd42e4dffb, max_idle_ns: 881590591483 ns
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
[    0.000000]   DMA32    [mem 0x0000000001000000-0x0000000007ffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000001000-0x000000000009efff]
[    0.000000]   node   0: [mem 0x0000000000100000-0x0000000007ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000001000-0x0000000007ffffff]
[    0.000000] Intel MultiProcessor Specification v1.4
[    0.000000] MPTABLE: OEM ID: FC
[    0.000000] MPTABLE: Product ID: 000000000000
[    0.000000] MPTABLE: APIC at: 0xFEE00000
[    0.000000] Processor #0 (Bootup-CPU)
[    0.000000] IOAPIC[0]: apic_id 2, version 17, address 0xfec00000, GSI 0-23
[    0.000000] Processors: 1
[    0.000000] smpboot: Allowing 1 CPUs, 0 hotplug CPUs
[    0.000000] PM: Registered nosave memory: [mem 0x00000000-0x00000fff]
[    0.000000] PM: Registered nosave memory: [mem 0x0009f000-0x000fffff]
[    0.000000] e820: [mem 0x08000000-0xffffffff] available for PCI devices
[    0.000000] Booting paravirtualized kernel on KVM
[    0.000000] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns
[    0.000000] random: get_random_bytes called from start_kernel+0x94/0x486 with crng_init=0
[    0.000000] setup_percpu: NR_CPUS:128 nr_cpumask_bits:128 nr_cpu_ids:1 nr_node_ids:1
[    0.000000] percpu: Embedded 41 pages/cpu @ffff880007c00000 s128728 r8192 d31016 u2097152
[    0.000000] KVM setup async PF for cpu 0
[    0.000000] kvm-stealtime: cpu 0, msr 7c15040
[    0.000000] PV qspinlock hash table entries: 256 (order: 0, 4096 bytes)
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 32137
[    0.000000] Policy zone: DMA32
[    0.000000] Kernel command line: console=ttyS0 reboot=k panic=1 pci=off root=/dev/vda rw [email protected]:5
[    0.000000] PID hash table entries: 512 (order: 0, 4096 bytes)
[    0.000000] Memory: 111064K/130680K available (8204K kernel code, 622K rwdata, 1464K rodata, 1268K init, 2820K bss, 19616K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] Kernel/User page tables isolation: enabled
[    0.004000] Hierarchical RCU implementation.
[    0.004000]  RCU restricting CPUs from NR_CPUS=128 to nr_cpu_ids=1.
[    0.004000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.004000] NR_IRQS: 4352, nr_irqs: 48, preallocated irqs: 16
[    0.004000] Console: colour dummy device 80x25
[    0.004000] console [ttyS0] enabled
[    0.004000] tsc: Detected 2299.998 MHz processor
[    0.004000] Calibrating delay loop (skipped) preset value.. 4599.99 BogoMIPS (lpj=9199992)
[    0.004000] pid_max: default: 32768 minimum: 301
[    0.004000] Security Framework initialized
[    0.004000] SELinux:  Initializing.
[    0.004187] Dentry cache hash table entries: 16384 (order: 5, 131072 bytes)
[    0.005499] Inode-cache hash table entries: 8192 (order: 4, 65536 bytes)
[    0.006697] Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
[    0.008013] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes)
[    0.009671] Last level iTLB entries: 4KB 64, 2MB 8, 4MB 8
[    0.010636] Last level dTLB entries: 4KB 64, 2MB 0, 4MB 0, 1GB 4
[    0.012005] Spectre V2 : Mitigation: Full generic retpoline
[    0.012987] Speculative Store Bypass: Vulnerable
[    0.025015] Freeing SMP alternatives memory: 28K
[    0.026799] smpboot: Max logical packages: 1
[    0.027795] x2apic enabled
[    0.028005] Switched APIC routing to physical x2apic.
[    0.030291] ..TIMER: vector=0x30 apic1=0 pin1=0 apic2=-1 pin2=-1
[    0.031291] smpboot: CPU0: Intel(R) Xeon(R) Processor @ 2.30GHz (family: 0x6, model: 0x4f, stepping: 0x1)
[    0.032000] Performance Events: unsupported p6 CPU model 79 no PMU driver, software events only.
[    0.032000] Hierarchical SRCU implementation.
[    0.032093] smp: Bringing up secondary CPUs ...
[    0.032817] smp: Brought up 1 node, 1 CPU
[    0.033456] smpboot: Total of 1 processors activated (4599.99 BogoMIPS)
[    0.034834] devtmpfs: initialized
[    0.035417] x86/mm: Memory block size: 128MB
[    0.036178] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[    0.037685] futex hash table entries: 256 (order: 2, 16384 bytes)
[    0.038868] NET: Registered protocol family 16
[    0.039717] cpuidle: using governor ladder
[    0.040006] cpuidle: using governor menu
[    0.044665] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
[    0.045744] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[    0.046973] dmi: Firmware registration failed.
[    0.047770] NetLabel: Initializing
[    0.048026] NetLabel:  domain hash size = 128
[    0.048731] NetLabel:  protocols = UNLABELED CIPSOv4 CALIPSO
[    0.049639] NetLabel:  unlabeled traffic allowed by default
[    0.050631] clocksource: Switched to clocksource kvm-clock
[    0.051521] VFS: Disk quotas dquot_6.6.0
[    0.051521] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    0.053231] NET: Registered protocol family 2
[    0.054036] TCP established hash table entries: 1024 (order: 1, 8192 bytes)
[    0.055137] TCP bind hash table entries: 1024 (order: 2, 16384 bytes)
[    0.056156] TCP: Hash tables configured (established 1024 bind 1024)
[    0.057164] UDP hash table entries: 256 (order: 1, 8192 bytes)
[    0.058077] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[    0.059067] NET: Registered protocol family 1
[    0.060338] virtio-mmio: Registering device virtio-mmio.0 at 0xd0000000-0xd0000fff, IRQ 5.
[    0.061666] platform rtc_cmos: registered platform RTC device (no PNP device found)
[    0.063021] Scanning for low memory corruption every 60 seconds
[    0.064162] audit: initializing netlink subsys (disabled)
[    0.065238] Initialise system trusted keyrings
[    0.065946] Key type blacklist registered
[    0.066623] audit: type=2000 audit(1582381251.667:1): state=initialized audit_enabled=0 res=1
[    0.067999] workingset: timestamp_bits=36 max_order=15 bucket_order=0
[    0.070284] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.073661] Key type asymmetric registered
[    0.074318] Asymmetric key parser ‘x509‘ registered
[    0.075091] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
[    0.076319] io scheduler noop registered (default)
[    0.077122] io scheduler cfq registered
[    0.077799] virtio-mmio virtio-mmio.0: Failed to enable 64-bit or 32-bit DMA.  Trying to continue, but this might not work.
[    0.079660] Serial: 8250/16550 driver, 1 ports, IRQ sharing disabled
[    0.102677] serial8250: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a U6_16550A
[    0.105548] loop: module loaded
[    0.106732] tun: Universal TUN/TAP device driver, 1.6
[    0.107583] hidraw: raw HID events driver (C) Jiri Kosina
[    0.108489] nf_conntrack version 0.5.0 (1024 buckets, 4096 max)
[    0.109523] ip_tables: (C) 2000-2006 Netfilter Core Team
[    0.110405] Initializing XFRM netlink socket
[    0.111154] NET: Registered protocol family 10
[    0.112326] Segment Routing with IPv6
[    0.112931] NET: Registered protocol family 17
[    0.113638] Bridge firewalling registered
[    0.114325] sched_clock: Marking stable (112005721, 0)->(211417276, -99411555)
[    0.115605] registered taskstats version 1
[    0.116270] Loading compiled-in X.509 certificates
[    0.117814] Loaded X.509 cert ‘Build time autogenerated kernel key: 3472798b31ba23b86c1c5c7236c9c91723ae5ee9‘
[    0.119392] zswap: default zpool zbud not available
[    0.120179] zswap: pool creation failed
[    0.120924] Key type encrypted registered
[    0.123818] EXT4-fs (vda): recovery complete
[    0.124608] EXT4-fs (vda): mounted filesystem with ordered data mode. Opts: (null)
[    0.125761] VFS: Mounted root (ext4 filesystem) on device 254:0.
[    0.126874] devtmpfs: mounted
[    0.128116] Freeing unused kernel memory: 1268K
[    0.136083] Write protecting the kernel read-only data: 12288k
[    0.138147] Freeing unused kernel memory: 2016K
[    0.140430] Freeing unused kernel memory: 584K
OpenRC init version 0.35.5.87b1ff59c1 starting
Starting sysinit runlevel

   OpenRC 0.35.5.87b1ff59c1 is starting up Linux 4.14.55-84.37.amzn2.x86_64 (x86_64)

 * Mounting /proc ...
 [ ok ]
 * Mounting /run ...
 * /run/openrc: creating directory
 * /run/lock: creating directory
 * /run/lock: correcting owner
 * Caching service dependencies ...
Service `hwdrivers‘ needs non existent service `dev‘
 [ ok ]
Starting boot runlevel
 * Remounting devtmpfs on /dev ...
 [ ok ]
 * Mounting /dev/mqueue ...
 [ ok ]
 * Mounting /dev/pts ...
 [ ok ]
 * Mounting /dev/shm ...
 [ ok ]
 * Setting hostname ...
 [ ok ]
 * Checking local filesystems  ...
 [ ok ]
 * Remounting filesystems ...
 [ ok[    0.292620] random: fast init done
 ]
 * Mounting local filesystems ...
 [ ok ]
 * Loading modules ...
modprobe: can‘t change directory to ‘/lib/modules‘: No such file or directory
modprobe: can‘t change directory to ‘/lib/modules‘: No such file or directory
 [ ok ]
 * Mounting misc binary format filesystem ...
 [ ok ]
 * Mounting /sys ...
 [ ok ]
 * Mounting security filesystem ...
 [ ok ]
 * Mounting debug filesystem ...
 [ ok ]
 * Mounting SELinux filesystem ...
 [ ok ]
 * Mounting persistent storage (pstore) filesystem ...
 [ ok ]
Starting default runlevel
[    1.088040] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x212733415c7, max_idle_ns: 440795236380 ns

Welcome to Alpine Linux 3.8
Kernel 4.14.55-84.37.amzn2.x86_64 on an x86_64 (ttyS0)

localhost login: 

3.3.4、登录到 microVM

使用 root 和密码 root 登录以查看来宾虚拟机的终端:

Welcome to Alpine Linux 3.8
Kernel 4.14.55-84.37.amzn2.x86_64 on an x86_64 (ttyS0)

localhost login: root
Password:
Welcome to Alpine!

The Alpine Wiki contains a large amount of how-to guides and general
information about administrating Alpine systems.
See <http://wiki.alpinelinux.org>.

You can setup the system with the command: setup-alpine

You may change this message by editing /etc/motd.

login[855]: root login on ‘ttyS0‘
localhost:~# 

您可以使用 ls / 查看文件系统:

localhost:~# ls /
bin         home        media       root        srv         usr
dev         lib         mnt         run         sys         var
etc         lost+found  proc        sbin        tmp

这时,我们再查看一下其占用内存占用 36MB。

# cat /proc/3501/status|grep VmRSS
VmRSS:     36996 kB

使用 reboot 命令终止 microVM。为了权衡效率,Firecracker 目前并未实施来宾电源管理。相反,reboot 命令会发出一个键盘复位操作以作为关机开关。

创建基本的 microVM 后,您可以添加网络接口、更多的驱动器以及继续配置 microVM。

需要在您的裸机实例上创建上千个 microVMs?

for ((i=0; i<1000; i++)); do
    ./firecracker-v0.21.0-x86_64 --api-sock /tmp/firecracker-$i.sock &
done

多个 microVM 可以配置同一个共享根文件系统,然后为每个 microVM 分配自己的读/写份额。

3.4、为 microVM 配置网络

3.4.1、创建 tap 设备

目前创建的 microVM 没有网络或者其他 I/O,现在我们为其配置网络,我们首先在宿主机上面为其添加一个 tap0 设备。

sudo ip tuntap add tap0 mode tap

microVM 需要访问公网,我们这里使用 NAT,这里需要配置 iptables,首先把 iptables 规则清除,以免引起其他问题,我这里的宿主机网络接口名称为enp4s0

sudo ip addr add 172.16.0.1/24 dev tap0
sudo ip link set tap0 up
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
sudo iptables -t nat -A POSTROUTING -o enp4s0 -j MASQUERADE
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i tap0 -o enp4s0 -j ACCEPT

现在我们可以查看创建的 tap0:

[email protected]:~# ifconfig tap0
tap0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.16.0.1  netmask 255.255.255.0  broadcast 0.0.0.0
        ether fe:2d:e3:ba:09:ae  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

如果我们一台物理机要启动多个 microVM,我们需要为每个 microVM 创建 tap# 设备,为每个 tap 设备设置 iptables NAT 规则。

3.4.2、为 microVM 配置 tap

在 microVM 启动之前,我们通过 microVM API 为其配置网络接口。

curl --unix-socket /tmp/firecracker.sock -i   -X PUT ‘http://localhost/network-interfaces/eth0‘   -H ‘Accept: application/json‘   -H ‘Content-Type: application/json‘   -d ‘{
      "iface_id": "eth0",
      "guest_mac": "AA:FC:00:00:00:01",
      "host_dev_name": "tap0"
    }‘

3.4.3、为 microVM 配置 IP

我们登录到 microVM 中,为其网络接口 eth0 配置 IP:

ip addr add 172.16.0.2/24 dev eth0
ip link set eth0 up
ip route add default via 172.16.0.1 dev eth0

查看网络情况。

localhost:~# ifconfig
eth0      Link encap:Ethernet  HWaddr AA:FC:00:00:00:01
          inet addr:172.16.0.2  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::a8fc:ff:fe00:1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:516 (516.0 B)

localhost:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=47 time=1.491 ms
64 bytes from 8.8.8.8: seq=1 ttl=47 time=1.118 ms
64 bytes from 8.8.8.8: seq=2 ttl=47 time=1.136 ms

3.4.4、清除网络

当我们删掉某个 microVM 的时候,可以把其相关网络设备删除。

sudo ip link del tap0
sudo iptables -F
sudo sh -c "echo 0 > /proc/sys/net/ipv4/ip_forward"

这里只是简单的介绍了一下 Firecracker 的使用方法,关于生产环境的使用,请详细查看官方 github 文档的推荐。

参考文档:

https://aws.amazon.com/cn/blogs/china/firecracker-lightweight-virtualization-for-serverless-computing/

https://github.com/firecracker-microvm/firecracker/blob/master/docs/jailer.md

https://firecracker-microvm.github.io/

欢迎大家扫码关注,获取更多信息

AWS Lambda&Fargate 无服务底层技术是如何实现的

原文地址:https://blog.51cto.com/wzlinux/2473650

时间: 2024-11-10 08:07:08

AWS Lambda&Fargate 无服务底层技术是如何实现的的相关文章

什么是serverless无服务?

什么是serverless无服务? serverless中文的含义是 "无服务器",但是它真正的含义是开发者再也不用过多考虑服务器的问题,但是并不代表完全去除服务器,而是我们依靠第三方资源服务器后端,比如使用 Amazon Web Services(AWS) Lambda. 计算服务来执行代码,那么Serverless架构分为 Backend as a Service(BaaS) 和 Functions as a Service(FaaS) 两种技术,Serverless 它是由开发者

腾讯TEG架构平台部总监冯亮:游戏内部云底层技术揭秘

摘要:在腾讯内部游戏云一直是最大一块,所以最棘手的问题.最新的技术.最高效的运营体系都会最先出现在游戏云上.在今年第二届游戏运营技术论坛上,腾讯TEG架构平台部总监冯亮为大家揭秘了游戏内部云底层技术. 在腾讯内部游戏云一直是最大的一块,所以最棘手的问题.最新的技术.最高效的运营体系都会最先出现在游戏云上.在今年第二届的游戏运营技术论坛上,腾讯TEG架构平台部系统研发中心总监冯亮为大家揭秘了游戏内部云底层技术.冯亮主要负责腾讯内部使用的Linux发行版/内核和虚拟化平台,致力于打造腾讯内部高效.稳

读书笔记--大规模web服务开发技术

总评   这本书是日本一个叫hatena的大型网站的CTO写的,通过hatena网站从小到大的演进来反应一个web系统从小到大过程中的各种系统和技术架构变迁,比较接地气. 书的内容不是很难,所以总的来说比较容易阅读,不需要特别累的啃,可想而知,不是非常深入的,更多的还是把作者的一些经验写出来,hatena这种量级的在国内应该是一个中型网站的水平,作者基本把这个量级web服务的运维的方方面面都讲了一遍,看完可以对这个这种量级网站有一个总体的了解,个人认为还是值得一读的. 逐章读书笔记: 第一章 大

AJAX 概念 优势 发展前景 工作原理 底层技术 状态 缺点 框架

1. 概念 Ajax asynchronous JavaScript and XML , 异步js和xml. 这种解释已经过时了, 现在ajax就是, 允许浏览器和服务器通信, 而无需刷新当前页面的技术. 它本来是微软的技术, 是Google 在 google earth.google suggest以及gmail等对ajax技术的广泛应用,催生了ajax的流行.事实上google目前在ajax技术方面的领先是微软所无法达到的 2. 发展前景 Gmail在收发邮件的时候已经和Outlook Ex

什么是AWS Lambda?——事件驱动的函数执行环境

AWS CTO Werner Vogels在AWS re:Invent 2014大会的第二场主题演讲上公布了两个新服务和一系列新的实例,两个新服务都相当令人瞩目:第一个宣布的新服务是Amazon EC2 Container Service,跟Docker紧密联合的管理服务,令人兴奋,不过不是本篇报道的重点. 本篇报道主要想向大家介绍一下今天宣布的第二个服务:AWS Lambda. 什么是AWS Lambda? 根据Jeff Barr在博客上的描述,Lambda是一个"可简单创建Lambda函数.

Serverless无服务应用架构纵横谈

一.Serverless是啥 自从互联网兴起以来,Server就成了网络的核心部件.所以围绕Server的生意圈,也发展得如火如荼. 从最早的电信托管,到虚拟机,到现在的Serverless,形成了几大阵容: 1.IaaS(基础设施即服务:Infrastructure as a Service) 2.PaaS(平台即服务:Platform as a Service) 3.SaaS(软件即服务:Software as a Service) IaaS是包硬不包软,面对集成商,PaaS是包硬包软不包工

一个可供中小团队参考的微服务架构技术栈

一个可供中小团队参考的微服务架构技术栈 聊聊架构 2018-05-07 作者 杨波 作者 |  杨波编辑 |  张浩 近年,Spring Cloud 俨然已经成为微服务开发的主流技术栈,在国内开发者社区非常火爆.我近年一直在一线互联网公司(携程,拍拍贷等)开展微服务架构实践,根据我个人的一线实践经验和我平时对 Spring Cloud 的调研,我认为 Spring Cloud 技术栈中的有些组件离生产级开发尚有一定距离.比方说 Spring Cloud Config 和 Spring Cloud

微服务架构技术栈选型手册&#182;

微服务架构技术栈选型手册 2014~2018,微服务经过三年的发展,现状如何?这是一份为让你更好使用微服务的技术站选型手册.除此之外,你还可以按需选用配套的微服务架构视频内容. 一.前言 2014 年可以认为是微服务 1.0 的元年,当年有几个标志性事件,一是 Martin Fowler 在其博客上发表了"Microservices"一文,正式提出微服务架构风格:二是 Netflix 微服务架构经过多年大规模生产验证,最终抽象落地形成一整套开源的微服务基础组件,统称 NetflixOS

ARM Cortex-M底层技术(2)—启动代码详解

杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第二,近些年来Cortex-M阵营各厂商(ST.Nordic.ATMEL……)对新产品的迭代速度越来越快,以及微控制器应用普及程度的加深,越来越多的开发者把更多精力投注在应用层开发上,花在对底层技术上的时间越来越少,更深层次的原因是走嵌入式底层没有做互联网上层赚钱.希望自己可以把嵌入式ARM Cort