近些年 AWS 很是推崇無服務器模式,自從2014年 Lambda 發佈以後,無服務器大受歡迎,隨之 2017 年推出 AWS Fargate 服務,應用於自家的容器服務平臺 ECS。在 2019 年,EKS 也相繼支持 AWS Fargate。 node
如今,更多的用戶使用無服務器計算來構建應用程序,AWS 旨在打造讓用戶無需擔憂基礎設施的預置或管理問題。開發人員可使用 AWS Fargate 將其代碼封裝爲無服務器容器,或使用 AWS Lambda 封裝爲無服務器函數。無服務器的低運營開銷特色,這將繼續對計算的將來發揮關鍵做用。linux
隨着用戶愈來愈普遍採用無服務器技術,AWS 認識到現行虛擬化技術還未同步發展,以針對此類事件驅動性,有時又呈短暫性特色的工做負載進行優化。AWS 認爲須要構建特別針對無服務器計算設計的虛擬化技術。這種技術須要既能提供基於硬件虛擬化的虛擬機安全性邊界,同時又能保持容器和函數較小的封裝型號和敏捷性。git
如今的技術環境下,容器具備快速啓動時間和高密度,VM 能夠對硬件虛擬化,具備更好的安全性,並對工做負載具備更好的隔離性。容器和 VM 的特性如今還不可兼得。github
AWS 開源了 Firecracker,一種利用 KVM 的新虛擬化技術,專門用於建立和管理多租戶容器以及基於函數的服務。你能夠在幾分之一秒內在非虛擬化環境中啓動輕量級微虛擬機(microVM),充分利用傳統虛擬機提供的安全性和工做負載隔離,同時兼具容器的資源效率。編程
Firecracker 是一種採用基於 Linux 內核的虛擬機 (KVM) 技術的開源虛擬機監控程序(VMM)。Firecracker 容許您建立微型虛擬機,即 microVM。Firecracker 堅持精簡主義的設計原則,它僅包含運行安全、輕量的虛擬機所需的組件。在設計過程的各個環節,AWS 依據安全性、速度和效率要求來優化 Firecracker。例如,僅啓動相對較新的 Linux 內核,而且僅啓動使用特定配置選項集編譯的內核(內核編譯配置選項超過 1000 種)。此外,不支持任何類型的圖形卡或加速器,不支持硬件透傳,不支持(大多數)老舊設備。json
Firecracker 啓動的內核配置極少,不依賴仿真 BIOS,不使用完整設備模式。惟一的設備是半虛擬化網卡和半虛擬化硬盤,以及單按鈕鍵盤(復位引腳在無電源管理設備時使用)。這種極簡的設備模式不只有利於縮短開機時間(採用默認 microVM 型號的 i3.metal 實例開機時間 < 125 毫秒),同時也減小了***面,從而提升了安全性。請參閱有關 Firecracker 承諾支持以極低的開銷執行容器和無服務器工做負載的更多信息。api
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 也一樣可行。全部硬件計算資源能夠安全地超訂,從而最大化能夠在主機上運行的工做負載數量。bash
AWS 依據以下開放源項目的指導信條開發了 Firecracker。
Firecracker 運行在 Linux 主機上,內核爲4.14或更新內核,而且使用 Linux guest OSs (從這一點來講,稱爲 guest)。 啓動該進程後,在發出 instanceart 命令以前,用戶與 Firecracker API 交互以配置 microVM。
每一個 Firecracker 進程封裝一個且只有一個 microVM。 該進程運行如下線程: API、 VMM 和 vCPU。 Api 線程負責 Firecracker 的 API 服務器和相關的控制平面。 它永遠不會在虛擬機的快速路徑上。 Vmm 線程公開機器模型、最小遺留設備模型、 microVM 元數據服務(MMDS)和 VirtIO 設備仿真 Net 和 Block 設備,並提供 i / o 速率限制。 除此以外,還有一個或多個 vCPU 線程(每一個客戶 CPU 核心一個)。 它們是經過 KVM 建立的,並運行 KVM run 主循環。 它們在設備模型上執行同步 i / o 和存儲器映射輸入輸出操做。
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 之間的區別。
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 入門 提供了有關如何下載 Firecracker 二進制代碼、以不一樣的選項啓動 Firecracker、從源進行構建以及運行集成測試等方面的詳細說明。您能夠經過 Firecracker Jailer 在生產環境中運行 Firecracker。
下面咱們來看如何在 AWS 雲上開始使用 Firecracker(這些步驟能夠在任何裸機上使用):
使用 Ubuntu 18.04.1 建立一個 i3.metal
實例。
Firecracker 在 KVM 上構建而且須要 /dev/kvm
的讀/寫權限。登陸一個終端中的主機,而後設置該訪問權限:
sudo chmod 777 /dev/kvm
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
如今咱們啓動了一個 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 }'
如今此 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 }'
配置好內核和根文件系統後,將會啓動來賓虛擬機:
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 (mockbuild@ip-10-0-1-79) (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 virtio_mmio.device=4K@0xd0000000: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 virtio_mmio.device=4K@0xd0000000: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:
使用 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 分配本身的讀/寫份額。
目前建立的 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:
root@ip-172-31-20-74:~# 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 規則。
在 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" }'
咱們登陸到 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
當咱們刪掉某個 microVM 的時候,能夠把其相關網絡設備刪除。
sudo ip link del tap0 sudo iptables -F sudo sh -c "echo 0 > /proc/sys/net/ipv4/ip_forward"
這裏只是簡單的介紹了一下 Firecracker 的使用方法,關於生產環境的使用,請詳細查看官方 github 文檔的推薦。
讓咱們直面這樣的現實:雲服務(IaaS)比擁有本身的基礎架構更昂貴(若是你想要按需擴展你的基礎架構)。一樣的道理,沒必要關心配置、管理和擴展服務器是要須要付出代價。若是你的應用十分簡單,雲服務並非最優解。
Fargate實好,可是其價格幾乎是等配置EC2實例的價格的 4 倍(例如t2.medium)這讓咱們很難抉擇,讓咱們期待它可以降價。
固然不是。如上所述,在某些狀況下,您的成本將增長三倍以上,因此在它們下降成本以前,您可能最好使用標準EC2實例。
可是,在如下狀況下,Fargate可能對您更有益:
參考文檔:
https://github.com/firecracker-microvm/firecracker/blob/master/docs/jailer.md
https://firecracker-microvm.github.io/