서버리스를 위한 가벼운 가상화 Firecracker (Firecracker, NSDI 2020)
컨테이너만큼 가볍고 가상 머신만큼 안전한 격리를 위해 AWS 가 Rust 로 새로 만든 가상 머신 모니터 Firecracker 를 소개한 논문입니다. 지금도 AWS Lambda 와 AWS Fargate 의 작업 격리 기반이며, Apache 2.0 오픈소스로 공개되어 있습니다.
출처
| 항목 | 내용 |
|---|---|
| 원제 | Firecracker: Lightweight Virtualization for Serverless Applications |
| 저자 | Alexandru Agache, Marc Brooker, Andreea Florescu, Alexandra Iordache, Anthony Liguori, Rolf Neugebauer 외 2명 (Phil Piwonka, Diana-Maria Popa) |
| 실린 곳 | Proceedings of the 17th USENIX Symposium on Networked Systems Design and Implementation (NSDI '20), 419-434쪽 |
| 발표 | 2020년 2월 |
| DOI | 없음 (USENIX 는 DOI 를 부여하지 않음) |
| 원문 | USENIX 발표 페이지와 공개 PDF |
| 이용 조건 | USENIX 공개 (Open Access). 저작권은 저자에게 있음 |
참고 이 페이지는 원문 번역이 아니라 한국어 해설이에요. 정확한 표현과 수치는 원문을 확인하세요.
한눈에
- 문제: 서버리스 함수와 컨테이너는 여러 고객의 코드를 한 서버에 촘촘히 올려야 경제적입니다. 그런데 리눅스 컨테이너는 호스트 커널을 공유하므로 격리가 약하고, 기존 가상 머신은 무겁고 느립니다.
- 제안: KVM 은 그대로 쓰고 QEMU 대신 꼭 필요한 기능만 담은 새 가상 머신 모니터(VMM) 를 Rust 로 만들었습니다. 장치는 virtio 네트워크와 블록, 직렬 콘솔 정도만 남겼습니다.
- 결과: 코드는 약 5만 줄로 QEMU 보다 96% 적고, VM 당 메모리 오버헤드는 약 3MB(그림 7), 미리 설정한 경우 부팅은 150ms 안팎입니다.
- 지금의 의미: 2018년부터 Lambda 가 Firecracker 위로 옮겨 갔고, 논문 시점에 이미 매달 수조 건의 요청을 처리하고 있었습니다.
왜 나왔나
초기 Lambda 는 고객마다 EC2 가상 머신을 하나씩 두고, 그 안에서 함수마다 컨테이너를 띄웠습니다. 고객 사이의 격리는 가상 머신이 맡았지만, 이렇게 하면 서버를 촘촘히 채우기 어렵습니다. 팀이 원한 조건은 강한 격리, 낮은 오버헤드, 네이티브에 가까운 성능, 임의의 리눅스 바이너리를 돌리는 호환성, 빠른 생성과 교체, 그리고 실제 쓰는 만큼만 자원을 차지하는 "소프트 할당" 이었습니다. 오버헤드 목표는 함수 크기의 10% 였습니다.
2절은 선택지를 비교합니다(그림 1). 컨테이너는 신뢰할 수 없는 코드가 호스트 커널을 직접 부르므로, seccomp 같은 필터로 막더라도 간단한 앱이 15개, 일반 우분투 설치가 224개의 시스템 호출을 필요로 해 공격 면이 넓습니다. 언어 가상 머신 방식은 임의의 바이너리를 돌려야 하는 Lambda 와 맞지 않습니다. 하드웨어 가상화는 격리가 강하지만, QEMU 는 140만 줄이 넘는 코드에 최대 270개의 시스템 호출을 쓰는 거대한 프로그램이었습니다.
핵심 아이디어
특화가 곧 설계 (1.1절, 3절)
Firecracker 의 출발점은 "무엇을 하지 않을지" 입니다. BIOS, 임의 커널 부팅, 레거시 장치, PCI, VM 실시간 이전을 지원하지 않습니다. 스케줄링, 메모리 관리, 블록 I/O, TUN/TAP 네트워크는 이미 검증된 리눅스 기능을 그대로 씁니다. 오케스트레이션도 직접 하지 않고 containerd 나 Kubernetes 같은 도구에 맡깁니다. MicroVM 하나에 Firecracker 프로세스 하나가 대응합니다.
Google 의 crosvm 에서 갈라져 나왔지만 지금은 crosvm 의 절반도 안 되는 크기입니다.
장치 모델과 API (3.1, 3.2절)
장치는 virtio 네트워크와 블록, 직렬 콘솔, 그리고 일부만 구현한 i8042(PS/2 키보드 컨트롤러) 가 전부입니다. i8042 드라이버는 50줄 미만, 직렬 장치는 약 250줄, virtio 블록은 약 1,400줄의 Rust 코드입니다. 파일 시스템을 호스트와 공유하는 방식 대신 블록 장치를 택한 것도 호스트 커널의 노출을 줄이기 위해서입니다. MicroVM 설정과 제어는 유닉스 소켓 위의 REST API 로 합니다.
속도 제한과 보안 (3.3, 3.4절)
디스크와 네트워크에는 토큰 버킷 방식의 속도 제한기가 내장되어 IOPS, 대역폭, 패킷 수를 VM 별로 제한합니다. 부팅 직후 한 번 허용하는 버스트도 있습니다.
보안 측면에서는 "jailer" 라는 별도 프로그램이 Firecracker 를 chroot, PID 와 네트워크 네임스페이스, 낮춘 권한, 그리고 시스템 호출 24개와 ioctl 30개만 허용하는 seccomp-bpf 필터 안에 가둡니다. 호스트에서는 SMT 끄기, 커널 완화 기능 켜기, 스왑과 페이지 중복 제거 끄기 같은 부채널 대비책도 함께 씁니다.
Lambda 안의 Firecracker (4절)
그림 2 는 Lambda 의 요청 경로입니다. 프런트엔드가 요청을 받고, Worker Manager 가 같은 함수의 요청을 같은 작업자로 보내며(99.9 백분위 10ms 미만), Placement 서비스가 새 실행 공간("슬롯") 을 어디에 만들지 정합니다. 그림 3 은 작업자 내부로, 서버 하나에 수백에서 수천 개의 MicroVM 이 뜨고 MicroManager 가 이를 관리합니다. MicroManager 는 미리 부팅한 MicroVM 풀을 유지합니다. 그림 4 는 슬롯의 상태 변화(초기화, 유휴, 사용 중, 종료) 를 보여줍니다.
다중 테넌트 경제성의 핵심은 오버커밋입니다. 메모리가 서버 비용의 큰 몫을 차지하므로, 논문은 유휴 슬롯의 비용이 사용 중 슬롯의 약 40% 가 되어야 한다고 계산합니다. 여러 고객의 부하가 서로 상관되지 않을수록 더 많이 겹쳐 올릴 수 있습니다.
배포는 2018년에 시작되었습니다. AWS 내부 워크로드를 먼저 옮기고, 슬롯은 최대 12시간이 지나면 새로 만들며, 워크로드별 지표와 롤백 장치로 안전하게 이전했습니다.
실험과 결과
5절은 EC2 m5d.metal(48코어, SMT 끔, 메모리 384GB) 에서 Firecracker v0.20.0, QEMU v4.2.0, Cloud Hypervisor 를 비교합니다.
- 부팅 시간 (그림 5, 6): 미리 설정한 Firecracker 와 Cloud Hypervisor 는 QEMU 보다 약 2배 빨랐습니다. 50개를 동시에 부팅하면 미리 설정한 Firecracker 의 99 백분위는 146ms, Cloud Hypervisor 는 158ms 였습니다. 일반 우분투 커널을 쓰면 약 900ms 가 더 걸리므로, 드라이버를 대부분 뺀 4.0MB 커널을 썼습니다.
- 메모리 오버헤드 (그림 7): VM 당 Firecracker 약 3MB, Cloud Hypervisor 약 13MB, QEMU 약 131MB 였습니다.
- 블록 I/O (그림 8, 9): 약점도 솔직하게 보여줍니다. 4kB 무작위 읽기에서 하드웨어는 34만 IOPS 를 넘는데 Firecracker 는 약 13,000 IOPS 에 그쳤습니다. I/O 를 직렬로 처리하고 디스크 플러시를 지원하지 않기 때문입니다. 큐 깊이 1 에서 4kB 읽기의 99 백분위 지연은 네이티브보다 49µs 느렸습니다.
- 네트워크 (표 1): 호스트 탭 인터페이스가 단일 스트림 약 44Gb/s 를 내는 동안 Firecracker 는 모든 경우에 약 15Gb/s 에 머물렀습니다.
5.4절은 목표 달성을 정리합니다. 메모리 오버헤드는 3% 수준까지 낮출 수 있었고, 150ms 안팎으로 부팅하며, 시험에서는 20배 넘는 오버커밋(운영에서는 10배) 을 확인했습니다. 저자들은 I/O 성능 개선, 메모리 중복 제거, 더 빠른 시작을 향후 과제로 꼽았습니다.
지금 AWS 에서는
- AWS Lambda 와 AWS Fargate 는 지금도 Firecracker MicroVM 위에서 고객 작업을 격리합니다. AWS 공식 문서와 Firecracker 프로젝트 사이트가 이를 밝히고 있습니다.
- Firecracker 는 2018년 12월부터 Apache 2.0 라이선스의 오픈소스로 공개되어 있으며, 다른 회사와 프로젝트에서도 MicroVM 기반 샌드박스로 널리 쓰입니다.
- Lambda SnapStart 는 초기화가 끝난 MicroVM 의 메모리와 디스크 상태를 스냅숏으로 저장했다가 복원해 콜드 스타트를 줄이는 기능으로, Firecracker 의 스냅숏 기능을 바탕으로 합니다.
함께 읽기
- AWS Lambda: 이 사이트의 기능 문서
- ECS 와 Fargate: 이 사이트의 기능 문서
- Lambda 컨테이너 로딩 논문 해설: Firecracker 위에서 최대 10GiB 컨테이너 이미지를 빠르게 띄우는 방법
- Aurora Serverless 논문 해설: Firecracker 를 검토했다가 데이터베이스에는 다른 방식을 택한 사례
- Firecracker 프로젝트 사이트