[OS] Firecracker

애이용·2021년 7월 6일
1

OS

목록 보기
15/16

(공부 중)
Firecracker는 AWS Lambda 및 AWS Fargate와 같은 서비스의 속도와 효율성을 가속화하기 위해 Amazon Web Services에서 개발되었다. Firecracker는 Apache 버전 2.0에서 오픈 소스이다.
현재 Intel CPU를 지원하고 AMD, ARM을 지원할 예정이다.

Firecracker

Firecracker는 서버리스 운영 모델을 제공하는 안전한 다중 테넌트 컨테이너 및 기능 기반 서비스를 만들고 관리하기 위해 특별히 제작된 오픈 소스 가상화 기술이다. Firecracker는 하드웨어 가상화 기술이 제공하는 보안 및 격리 속성과 컨테이너의 속도 및 유연성을 결합한 microVM이라고하는 경량 가상 머신에서 워크로드를 실행한다.

Firecracker는 오픈 소스 가상화 기술로 안전한 Multi-tenant 컨테이너와 함수 기반 서비스(FaaS)를 만들고 관리하기 위한 목적으로 만들어졌다. 기존 컨테이너의 startup 시간과 가상화 및 작업 부하 격리 기능을 최적화하였다.
Firecracker를 사용하여 하드웨어 가상화 기술이 제공하는 보안 및 격리 속성과 컨테이너 속도 및 유연성을 결합한 microVM이라고 하는 경량 가상 머신에서 workload를 실행한다.
즉 multi-tenancy 측면에서 개별 workload 간의 고립성이 더 요구된다.

서비스로서의 기능(Function-as-a-Service, FaaS)이란 스테이트리스(stateless) 컨테이너에서 실행되는 이벤트 기반 컴퓨팅 실행 모델로, 서비스를 사용하여 서버측 로직과 상태를 관리한다.

멀티테넌시는 단일 소프트웨어 인스턴스로 서로 다른 여러 사용자 그룹에 서비스를 제공할 수 있는 소프트웨어 아키텍처이다. (ex. 서비스로서의 소프트웨어(Software-as-a-Service, SaaS) 제품)
클라우드 컴퓨팅에서는 서로 다른 고객이 서버 리소스를 나누어 사용하는 공유 호스팅을 멀티테넌시라고 부르기도 한다.
👉 여러 사람이 서버를 공유할 수 있다

✔️ 구성 요소

Firecracker의 주요 구성 요소는 Linux KVM (Kernel Virtual Machine)을 사용하여
microVM을 만들고 실행하는 VMM (가상 컴퓨터 모니터)이다.

FaaS 서비스에 적합하도록 불필요한 디바이스와 게스트(guest) 기능을 제거하여 최소한의 디자인으로 개발하여 메모리 사용량을 줄였다.
이렇게 하면 보안이 향상되고 시작 시간이 단축되며 하드웨어 활용도가 높아진다.
Firecracker는 Kata Containers 및 Weaveworks Ignite와 같은 컨테이너 런타임에도 통합되었다.

✔️ 장점

  • Security from the ground up

    Firecracker microVM은 기존 VM보다 향상된 보안을 제공하는 KVM 기반 가상화를 사용한다.이를 통해 여러 유저의 workload를 같은 머신에서 안전하게 실행할 수 있다.
    Firecracker는 또한 필수가 아닌 모든 기능을 제외하고 microVM의 공격 표면 영역을 줄이는 최소 장치 모델을 구현한다.
  • Speed by design

    최소 장치 모델 외에도 Firecracker 커널 로딩을 가속화하고 최소 게스트 커널 구성을 제공한다. 이것은 빠른 시작 시간을 가능하게 한다. Firecracker는 125ms 이내에 사용자 공간 또는 애플리케이션 코드를 시작하고 호스트당, 초당 최대 150개 microVM의 생성 속도를 지원한다.
  • Scale and efficiency

    각 MicroVM은 5MiB 미만의 메모리 오버헤드로 실행되므로 각 서버에 고밀도의 microVM을 저장할 수 있다.
    Firecracker는 각 microVM에 rate limiter를 제공한다. 이를 통해 수천 개의 microVM에 네트워크와 저장 공간을 최적화하여 자원을 공유할 수 있다.

Firecracker 보안

Firecracker는 많은 보안 기능을 통합하였는데, 몇 가지 기능을 살펴보겠다.

  • 단순한 guest 모델
    Firecracker는 공격 영역을 최화하기 위해 가상화된 단순한 디바이스 모델로 제시된다.
    (ex. 네트워크 디바이스, 블록 I/O 디바이스, PIT(Programmable Interval Timer), KVM 클럭, 직렬 콘솔, 부분 키보드(VM 재설정할 수 있을 정도의 기능))
  • 잠금(Jail) 처리
    Firecreacker 프로세스는 cgroupsseccomp BPF를 사용하여 잠기며(Jail), 매우 제한된 소량의 시스템 호출 목록에 액세스한다.
  • 정적 연결
    firecracker 프로세스는 정적으로 연결되며, 잠금자(Jailer)에서 시작하여 가능한 안전하고 클린한 상태의 호스트 환경을 보장한다. (일반적인 Linux 사용자 공간 보안 장벽으로 더욱 분리된다.) 잠금자는 가상화 장벽이 훼손된 경우에 대비하여 두번째 방어선을 제공한다.

✔️ 동작 원리


Firecracker는 사용자 공간에서 실행되며 Linux 커널 기반 가상 머신 (KVM)을 사용하여 microVM을 생성한다.
각 microVM의 빠른 시작 시간과 낮은 메모리 오버 헤드를 통해 수천 개의 microVM을 동일한 시스템에 압축 할 수 있다. 즉, 모든 기능, 컨테이너 또는 컨테이너 그룹을 가상 머신 장벽으로 캡슐화 할 수 있으므로 보안 또는 효율성에 대한 절충없이 서로 다른 고객의 워크로드를 동일한 머신에서 실행할 수 있다.
Firecracker는 다양한 게스트 운영 체제를 호스팅 할 수 있는 범용 및 광범위한 기능 세트를 갖춘 기존 VMM 인 QEMU의 대안인 새로운 VMM(Virtual Machine Monitor, hypervisor)이다.

QEMU
heavy 하다(QEMU > 1.4 million lines). VMM 을 가볍게 만들기 위해서 Firecracker 는 KVM 을 유지한 채로 QEMU 를 대체하는 방법을 사용하였다. Firecracker (50k lines 96% fewer than QEMU) 는 안전한 언어 Rust 를 사용해서 구현하였다. Firecracker가 경량화 된 것은 OS 와 Security-Critical Interface 를 가지게 되면서 이전에 있었던 Code Compatibility 랑 Security 의 Tradeoff 문제를 제거하였다. crosvm(Chrome OS Virtual Machine Monitor) 코드를 사용하면서 loc(Lines of Code)를 줄였다.

  • vCPU 수 구성 또는 머신 시작과 같은 일반적인 작업을 활성화하는 RESTful API를 통해 Firecracker 프로세스를 제어 할 수 있다.
  • 하나의 Firecracker는 하나의 microVM당 실행이 된다.
  • Linux Guest Kernel을 사용한다.
    내장된 속도 제한기를 제공하여 동일한 시스템에서 수천 개의 microVM이 사용하는 네트워크 및 스토리지 리소스를 세부적으로 제어 할 수 있다.
    Firecracker API를 통해 속도 제한기를 생성 및 구성하고 버스트 또는 특정 대역폭 / 작업 제한을 지원하는 유연한 속도 제한기를 정의할 수 있다.
  • 각각의 microVM은 HTTP 서버를 통해 호스트와 api 통신을 한다.(microVM의 시작 및 종료를 관리 및 설정한다.)
  • Firecracker는 호스트와 게스트 운영 체제 간에 구성 정보를 안전하게 공유하는 메타 데이터 서비스(mmds(micro metadata service))도 제공한다. Firecracker API를 사용하여 메타 데이터 서비스를 설정하고 구성 할 수 있다.
    호스트에서 설정된 metadata에 대한 guest 액세스를 제공한다.

✔️ 특징

[TODO] 정리

참고 링크

  • Firecracker can safely run workloads from different customers on the same machine.
  • Customers can create microVMs with any combination of vCPU and memory to match their application requirements.
  • Firecracker microVMs can oversubscribe host CPU and memory. The degree of oversubscription is controlled by customers, who may factor in workload correlation and load in order to ensure smooth host system operation.
  • With a microVM configured with a minimal Linux kernel, single-core CPU, and 128 MiB of RAM, Firecracker supports a steady mutation rate of 5 microVMs per host core per second (e.g., one can create 180 microVMs per second on a host with 36 physical cores).
  • The number of Firecracker microVMs running simultaneously on a host is limited only by the availability of hardware resources.
  • Each microVM exposes a host-facing API via an in-process HTTP server.
  • Each microVM provides guest-facing access to host-configured metadata via the /mmds API.

✔️ Design

Host Integration

Internal Architecture



설치 & 실행 과정

  Prerequisites

  • KVM 액세스 설정 (ACL)
sudo setfacl -m u:${USER}:rw /dev/kvm

kvm 설치 여부 확인

lsmod | grep kvm

현재 사용하고 있는 processor가 virtualization을 support하는지 확인 [참고 링크]

$ grep -Eoc ‘(vmx|svm)’ /proc/cpuinfo
16

  0 이상의 숫자가 나오면 virtualization 기능 enabled

  • 시스템이 Firecracker를 실행하기 위한 요구 사항을 충족하는지 확인하기
$ git clone https://github.com/firecracker-microvm/firecracker // 저장소 복제
$ cd firecracker // 디렉토리 이동
$ tools/devtool checkenv
[Firecracker devtool] Checking prerequisites for running Firecracker.
[Firecracker devtool] Please check ../docs/getting-started.md#prerequisites in case of any error.
[Firecracker devtool] Checking Host Security Configuration.
[Firecracker devtool] Please check ../docs/prod-host-setup.md in case of any error.
[Firecracker devtool] WARNING: KSM ENABLED
[Firecracker devtool] WARNING: retpoline, IBPB, IBRS: DISABLED.
[Firecracker devtool] WARNING: Mitigation: PTE Inversion: DISABLED
[Firecracker devtool] WARNING: VMX: cache flushes: DISABLED

warning이 나왔지만.. 진행해보자.

[TODO] 무슨 warning인지 알아보기

Getting the Firecracker Binary

  • Firecracker 설치하기
release_url=“https://github.com/firecracker-microvm/firecracker/releases”
latest=$(basename $(curl -fsSLI -o /dev/null -w  %{url_effective} ${release_url}/latest))
arch=`uname -m`
curl -L ${release_url}/download/${latest}/firecracker-${latest}-${arch}.tgz \
| tar -xz
  • binary 파일 이름 “firecracker”로 변경하기
$ cd release-v0.23.4

$ ls
LICENSE  THIRD-PARTY                 firecracker_spec-v0.23.4.yaml
NOTICE   firecracker-v0.23.4-x86_64  jailer-v0.23.4-x86_64

$ mv firecracker-${latest}-$(uname -m) firecracker
$ mv jailer-${latest}-$(uname -m) jailer
$ ls
LICENSE  THIRD-PARTY  firecracker_spec-v0.23.4.yaml
NOTICE   firecracker  jailer

Running Firecracker

  • 1번째 shell
    // Firecracker가 API 소켓을 생성할 수 있는지 확인하기
    $ rm -f /tmp/firecracker.socket

    //Firecracker 시작하기
    $ ./firecracker --api-sock /tmp/firecracker.socket
$ ps -ef | grep socket
ayoung     16273   15750  0 14:54 pts/2    00:00:00 ./firecracker --api-sock /tmp/firecracker.socket
  • 2번째 shell

API Endpoints

  1. sample 커널 및 rootfs 다운로드
    (압축되지 않은 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

hello-vmlinux.bin, hello-rootfs.ext4 가 다운로드된다.

  1. microVM cpu와 메모리 설정
curl --unix-socket /tmp/firecracker.socket -i \
    -X PUT "http://localhost/machine-config" \
    -H "accept: application/json" \
    -H "Content-Type: application/json" \
    -d "{
        \"vcpu_count\": 2,
        \"mem_size_mib\": 512
    }"
  1. guest 커널 설정하기
curl --unix-socket /tmp/firecracker.socket -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
  1. guest rootfs(루트 파일 시스템) 설정하기
curl --unix-socket /tmp/firecracker.socket -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
    }"

HTTP/1.1 204
Server: Firecracker API
Connection: keep-alive
  1. guest 시스템(가상 머신) 시작하기
curl --unix-socket /tmp/firecracker.socket -i \
    -X PUT "http://localhost/actions" \
    -H  "accept: application/json" \
    -H  "Content-Type: application/json" \
    -d "{
        \"action_type\": \"InstanceStart\"
     }"

  • 웹서버 로그
[    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: Supporting XSAVE feature 0x008: ‘MPX bounds registers’
[    0.000000] x86/fpu: Supporting XSAVE feature 0x010: ‘MPX CSR’
[    0.000000] x86/fpu: xstate_offset[2]:  576, xstate_sizes[2]:  256
[    0.000000] x86/fpu: xstate_offset[3]:  832, xstate_sizes[3]:   64
[    0.000000] x86/fpu: xstate_offset[4]:  896, xstate_sizes[4]:   64
…
 * 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.056131] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x2b3e43c8763, max_idle_ns: 440795360101 ns


디폴트 id & password

id : root
password : root

로 로그인할 수 있다.

  • 자원 리소스 확인
$ cat /proc/cpuinfo


reboot 게스트 내부에서 명령을 내리면 실제로 Firecracker가 정상적으로 종료된다.
이는 Firecracker가 게스트 전원 관리를 구현하지 않기 때문이다.

MMDS 구성

MicroVM Metadata Service (mmds)

이슈 정리
Fircracker MMDS는 호스트와 게스트 간에 안전하고 손쉬운 방법으로 정보를 공유하는 데 사용할 수 있는 변경 가능한 데이터 저장소이다.

  • MMDS 활성화
    기본적으로 MMDS는 게스트 운영 체제에서 연결할 수 없다. microVM 런타임에서 MMDS는 MMDS 요청을 허용하는 네트워크 인터페이스와 긴밀하게 연결된다. microVM을 구성할 때 MMDS를 활성화해야 하는 경우 MMDS 요청을 허용하도록 네트워크 인터페이스를 구성해야 한다.
curl --unix-socket /tmp/firecracker.socket -i \
  -X PUT ‘http://localhost/network-interfaces/tap0’ \
  -H ‘Accept: application/json’ \
  -H ‘Content-Type: application/json’ \
  -d ‘{
      “iface_id”: “tap0”,
      “guest_mac”: “16:34:9e:ec:af:e8”,
      “host_dev_name”: “tap0”,
      “allow_mmds_requests”: true
    }’
  • MMDS 구성
    MMDS는 Firecracker API 서버를 사용하여 사전 부팅만 구성할 수 있다. 이것은 리소스에 대한 HTTP PUT 요청으로 가능하다. (/mmds/config).

    현재 MMDS는 MMDS에 요청을 보낼 때 게스트 응용 프로그램에서 사용하는 IPv4 주소와 관련하여 구성할 수 있다.
    default IPv4 주소:169.254.169.254
    MMDS에 요청을 보내기 위한 IPv4 주소는 다음과 같이 구성 가능하다.
curl --unix-socket /tmp/firecracker.socket -i \
    -X PUT “http://localhost/mmds/config” \
    -H “Content-Type: application/json” \
    -d ‘{
             “ipv4_address”: “169.254.170.2"
    }’
  • Metadata Insert & Update
    microVM이 시작되기 전이나 작동 중에 MMDS 데이터 저장소를 Insert하거나 Update 가능하다. 메타데이터를 MMDS에 삽입하려면 리소스에 대한 HTTP PUT /mmds 요청을 하면 된다. 이 요청에는 JSON 형식으로 구조화된 메타데이터가 포함된 페이로드가 있어야 합니다. 기존 메타데이터를 교체하려면 새 메타데이터를 페이로드로 사용하여 리소스에 대한 후속 HTTPPUT /mmds 요청을 해야 한다.
    예시)
curl --unix-socket /tmp/firecracker.socket -i \
    -X PUT “http://localhost/mmds”            \
    -H “Content-Type: application/json”       \
    -d ‘{
            “latest”: {
                  “meta-data”: {
                       “ami-id”: “ami-12345678",
                       “reservation-id”: “r-fea54097",
                       “local-hostname”: “ip-10-251-50-12.ec2.internal”,
                       “public-hostname”: “ec2-203-0-113-25.compute-1.amazonaws.com”,
                       “network”: {
                            “interfaces”: {
                                 “macs”: {
                                      “02:29:96:8f:6a:2d”: {
                                           “device-number”: “13345342",
                                           “local-hostname”: “localhost”,
                                           “subnet-id”: “subnet-be9b61d”
                                      }
                                 }
                            }
                       }
                  }
            }
    }’
$ curl --unix-socket /tmp/firecra’http://localhost/mmds’
{“latest”:{“meta-data”:{“ami-id”:“ami-12345678",“local-hostname”:“ip-10-251-50-12.ec2.internal”,“network”:{“interfaces”:{“macs”:{“02:29:96:8f:6a:2d”:{“device-number”:“13345342",“local-hostname”:“localhost”,“subnet-id”:“subnet-be9b61d”}}}},“public-hostname”:“ec2-203-0-113-25.compute-1.amazonaws.com”,“reservation-id”:“r-fea54097"}}
  • 게스트 운영체제에서 메타데이터 검색하기

참고 링크

  • 21.07.08 Add Firecracker 설치 및 실행
  • 21.07.12 Update Firecracker 설명
    • Firecracker Motivation 관련 설명 추가
    • QEMU 대안 설명
  • 21.07.14 mmds & docker 연습 -ing
profile
로그를 남기자 〰️

0개의 댓글