FreeBSD บน Firecracker
(usenix.org)- การบูตเคอร์เนล FreeBSD 14 บน Firecracker VMM ซึ่งเป็น microVM ที่เน้น Linux สำหรับ AWS Lambda เป็นกรณีศึกษาที่ทำให้เห็นสมมติฐานแฝงและคอขวดในเส้นทางการเริ่มต้นระบบของ OS ภายใต้สภาพแวดล้อม virtualization แบบมินิมัล
- การบูตครั้งแรกติดขัดเพราะความต่างของรูปแบบ ELF Note ใน PVH boot mode, hypercall ที่มีเฉพาะ Xen และความต่างของการจัดวางหน่วยความจำของ Firecracker โดยแก้ได้ด้วยการปรับโค้ด PVH ของ FreeBSD
- เนื่องจาก Firecracker ไม่ได้ให้ ACPI เส้นทางในการรับข้อมูล CPU และ interrupt จึงเปลี่ยนไป และมีการเพิ่มออปชัน
MPTABLE_LINUX_BUG_COMPATเพื่อให้เข้ากับบั๊กของ Linux ในการจัดการ MPTable - ระหว่างการเชื่อมต่อ serial console และอุปกรณ์ Virtio ได้พบข้อจำกัดด้านการทำงานของ UART, การพาร์ส kernel command line และ disk I/O ที่ไม่จัดแนว โดย FreeBSD ใช้
hw.broken_txfifo, วิธีเลี่ยงการล้าง FIFO และการจัดการแบบ bounce บนbusdma - หากรวมแพตช์ที่ยังไม่ถูก commit เคอร์เนล FreeBSD สามารถบูตบน VM ที่มี 1 CPU และ RAM 128MB ได้ในเวลา ต่ำกว่า 20ms โดยงานที่เหลือคือรวมการรองรับ PVH, แยกโค้ด Xen, ทำให้คอนฟิกเคอร์เนลเล็กลง และพิจารณาการพอร์ต Firecracker ไปยัง FreeBSD
เหตุผลที่พยายามรัน FreeBSD บน Firecracker
- Firecracker คือ VMM ที่สร้างและจัดการ microVM แบบโอเวอร์เฮดต่ำบน Linux KVM สำหรับสภาพแวดล้อม serverless อย่าง AWS Lambda
- งานพอร์ต FreeBSD เริ่มต้นในเดือนมิถุนายน 2022
- แรงจูงใจของงานนี้คือการตรวจสอบข้อจำกัดของทั้ง FreeBSD และ Firecracker ไปพร้อมกัน
- จากการทำงานปรับปรุงความเร็วบูตของ FreeBSD อย่างต่อเนื่อง จึงอยากดูว่าบน minimal hypervisor จะเร่งได้ไกลแค่ไหน
- การพอร์ต FreeBSD ไปยังแพลตฟอร์มใหม่มักทำให้เห็นบั๊กทั้งฝั่ง FreeBSD และฝั่งแพลตฟอร์มนั้น
- ปัจจุบัน AWS Lambda รองรับเฉพาะ Linux และไม่ว่าการใช้ Lambda จะสำคัญหรือไม่ การที่ FreeBSD รองรับ Firecracker ก็เป็นเงื่อนไขตั้งต้นที่จำเป็น
- ตัว Firecracker เองก็เป็นแพลตฟอร์มที่น่าสนใจ จึงอยากยืนยันว่ามันใช้งานได้จริงอย่างไร
อุปสรรคแรกก่อนรันเคอร์เนล
- เดิมที Firecracker ถูกออกแบบมาสำหรับรันเคอร์เนล Linux แต่ในปี 2020 มีแพตช์ที่เพิ่มการรองรับ PVH boot mode นอกเหนือจาก
linuxboot - FreeBSD รองรับการบูตแบบ PVH บน Xen อยู่แล้ว จึงลองใช้เส้นทางเดียวกันบน Firecracker
- ปัญหาแรกคือ Firecracker หา kernel entry point ไม่เจอหลังโหลดเคอร์เนล FreeBSD เข้าไปในหน่วยความจำ
- โปรโตคอลบูต PVH เก็บค่านี้ไว้ใน ELF Note
- ELF Note มีทั้ง
PT_NOTEและSHT_NOTEและ FreeBSD ไม่ได้ให้รูปแบบที่ Firecracker มองหา - เมื่อปรับ linker script ของเคอร์เนล FreeBSD เล็กน้อย Firecracker ก็เริ่มรันเคอร์เนล FreeBSD ได้
- แต่หลังรันได้ประมาณ 1 ไมโครวินาที เคอร์เนลก็หยุดอีกครั้ง
การดีบักช่วงแรกและการถอดการพึ่งพา Xen
- หากเคอร์เนลตายก่อนที่ kernel debugger และ serial console จะถูก initialize ความสามารถในการดีบักของ FreeBSD แทบไม่ช่วยอะไร
- ข้อมูลที่ Firecracker process บอกได้มีเพียงว่า guest FreeBSD เกิด triple-fault
- จึงใช้ “kernel bisection” โดยแทรกคำสั่ง
hltไว้กลางโค้ดเริ่มต้นของเคอร์เนลเพื่อไล่หาจุดพัง- ถ้าไปถึง
hltได้ Firecracker จะยังรันต่อ แต่การใช้ CPU ฝั่งโฮสต์จะเหลือ 0% - ถ้า Firecracker ปิดตัวลง ก็สรุปได้ว่าพังก่อนถึงจุดนั้น
- ถ้าไปถึง
- สาเหตุแรกคือ Xen hypercall
- entry point แบบ PVH ของ FreeBSD แท้จริงแล้วเป็นโค้ดสำหรับบูตบน Xen และสมมติว่ากำลังรันอยู่ภายใน Xen
- KVM ที่ Firecracker ใช้ไม่ได้ให้ Xen hypercall ดังนั้นเมื่อเรียกใช้ VM จึงพัง
- ช่วงแรกมีการคอมเมนต์ Xen hypercall ออก และต่อมาปรับให้เรียกเฉพาะเมื่อ
CPUIDระบุ Xen signature
- การดึง physical memory map เป็นฟังก์ชันสำคัญที่เดิม Xen hypercall ทำหน้าที่นี้
- ตั้งแต่ PVH version 1 เป็นต้นมา pointer ของ memory map จะถูกส่งผ่านหน้า
start_info - FreeBSD จึงถูกปรับให้ใช้ memory map ของ PVH version 1 แทน Xen hypercall
- ตั้งแต่ PVH version 1 เป็นต้นมา pointer ของ memory map จะถูกส่งผ่านหน้า
- ความต่างของการจัดวางหน่วยความจำระหว่าง Firecracker กับ Xen ก็ทำให้เกิดปัญหา
- Xen โหลดเคอร์เนลก่อน แล้วค่อยวางหน้า
start_infoไว้ท้ายสุด - Firecracker วางหน้า
start_infoไว้ที่ low address คงที่ แล้วจึงค่อยโหลดเคอร์เนลทีหลัง - โค้ด PVH ของ FreeBSD สมมติว่าพื้นที่ถัดจาก
start_infoใช้เป็น scratch space ได้ ซึ่งบน Firecracker กลับไปเขียนทับ initial kernel stack - จึงแก้โดยจัดสรร scratch space หลังทุกช่วงหน่วยความจำที่ hypervisor ได้ initialize ไว้แล้ว
- Xen โหลดเคอร์เนลก่อน แล้วค่อยวางหน้า
การไม่มี ACPI และความเข้ากันได้กับ MPTable
- บน x86 นั้น FreeBSD ปกติจะใช้ ACPI เพื่อรับข้อมูลเกี่ยวกับดิสก์, network adapter, CPU และ interrupt controller
- Firecracker เลือกแนวทาง implementation แบบมินิมัลโดยตั้งใจ จึงไม่ให้ ACPI
- FreeBSD จึงหันไปใช้โครงสร้าง MPTable จาก Intel MultiProcessor Specification รุ่นเก่าแทนได้
- ในคอนฟิกเคอร์เนล
GENERICไม่ได้รวมมาด้วยเป็นค่าเริ่มต้น - แต่ในคอนฟิกเคอร์เนลขนาดเบาสำหรับ Firecracker สามารถเพิ่ม
device mptableแล้วใช้งานได้
- ในคอนฟิกเคอร์เนล
- MPTable ที่ Firecracker ให้มาไม่ตรงตามมาตรฐาน แต่เป็นแบบที่ Linux ยอมรับได้
- Linux มีบั๊กในวิธีค้นหาและพาร์ส MPTable
- Firecracker ถูกออกแบบมาเพื่อบูต Linux จึงให้การจัดวางแบบนอกมาตรฐานที่ Linux รองรับ
- FreeBSD ซึ่ง implement แยกโดยยึดมาตรฐาน จึงหา MPTable ที่วางผิดตำแหน่งไม่เจอ และถึงเจอก็พาร์ส MPTable ที่ไม่ถูกต้องนั้นไม่ได้
- FreeBSD จึงเพิ่มออปชันเคอร์เนล
options MPTABLE_LINUX_BUG_COMPAT- ใช้เมื่อจำเป็นต้องให้เข้ากันกับการจัดการ MPTable ของ Linux แบบ bug-for-bug
- ออปชันนี้ทำให้ FreeBSD บูตบน Firecracker ต่อไปได้อีก
การรองรับ serial console และอุปกรณ์ Virtio
- หนึ่งในไม่กี่อุปกรณ์ emulated ที่ Firecracker มีให้คือ serial port
- ในคอนฟิกทั่วไป standard input/output ของ Firecracker process จะกลายเป็น input/output ของ serial port ใน VM
- เคอร์เนล FreeBSD บูตโดยรวม root disk เข้าไปในอิมเมจเคอร์เนล และอ่าน output ของ kernel console ได้แล้ว
- แต่เมื่อเข้าสู่การบูต user space output ของ console กลับหยุดที่ 16 ตัวอักษร
- อาการเหมือนกับบั๊ก UART ของ QEMU ในอดีต
- เมื่อ transmit FIFO ของ UART ว่าง ไม่มี interrupt เข้ามา ทำให้ FreeBSD เขียนต่อหลัง 16 ไบต์ไม่ได้
- จึงแก้ด้วยการคอมไพล์ตัวเลี่ยงปัญหาที่มีอยู่แล้วในเคอร์เนล FreeBSD คือ
hw.broken_txfifo="1"เป็นตัวแปรสภาพแวดล้อมของเคอร์เนล
- ฝั่ง input ของ console ก็ไม่ทำงานเช่นกัน
- Firecracker มองว่า receive FIFO ของ UART ที่ emulated ไว้เต็ม จึงไม่อ่านจาก console
- ระหว่าง initialize UART นั้น FreeBSD พยายามวัดขนาด FIFO โดยเติมค่าขยะลงใน receive FIFO แล้วล้างด้วย FIFO Control Register
- แต่ Firecracker ไม่ได้ implement FIFO Control Register ทำให้ FIFO ค้างสถานะเต็มอยู่ตลอด
- FreeBSD จึงถูกปรับให้หลังจากล้าง FIFO แล้ว หาก
LSR_RXRDYยังอยู่ ก็ให้อ่านตัวอักษรทิ้งทีละตัวเพื่อเคลียร์ FIFO
- หากต้องการใช้ดิสก์และเครือข่าย จำเป็นต้องใช้อุปกรณ์ Virtio block/network
- Firecracker เปิดเผยอุปกรณ์เหล่านี้เป็นอุปกรณ์
mmio - ในคอนฟิกเคอร์เนล FreeBSD สำหรับ Firecracker จึงเพิ่ม
device virtio_mmio
- Firecracker เปิดเผยอุปกรณ์เหล่านี้เป็นอุปกรณ์
- เดิม FreeBSD คาดว่าจะค้นหาอุปกรณ์
mmioผ่าน FDT แต่ Firecracker ส่งตัวชี้อย่างvirtio_mmio.device=4K@0x1001e000:5มาทาง kernel command line- FreeBSD จึงเพิ่มโค้ดสำหรับพาร์สตัวชี้นี้และสร้างโหนดอุปกรณ์
virtio_mmio - เมื่อมีโหนดอุปกรณ์แล้ว กระบวนการ probe อุปกรณ์เดิมของ FreeBSD ก็จะระบุชนิดอุปกรณ์ Virtio และผูกเข้ากับไดรเวอร์ที่เหมาะสม
- FreeBSD จึงเพิ่มโค้ดสำหรับพาร์สตัวชี้นี้และสร้างโหนดอุปกรณ์
- เมื่อมีอุปกรณ์ Virtio หลายตัว ก็เกิดปัญหาในการพาร์ส kernel command line
- Firecracker ส่งคู่
key=valueหลายชุดในรูปแบบของ Linux - FreeBSD พาร์ส kernel command line เป็น environment variable ทำให้ถ้ามี
virtio_mmio.device=ชื่อเดียวกันสองตัว จะเหลือเพียงตัวเดียว - โค้ดพาร์สสภาพแวดล้อมของเคอร์เนลช่วงต้นจึงถูกแก้ให้เก็บตัวแปรซ้ำไว้ด้วย suffix หมายเลข เช่น
virtio_mmio.device=และvirtio_mmio.device_1=
- Firecracker ส่งคู่
- หลังจากปิดระบบผิดปกติ หากบูตครั้งถัดไปมีการรัน
fsckจะเกิด kernel panicfsckเป็นหนึ่งในกรณีหายากบน FreeBSD ที่ทำให้เกิด disk I/O ที่ไม่จัดแนวระดับหน้าเพจ- implementation ของ Virtio ใน Firecracker รับได้เพียง data buffer เดียว และไม่รองรับวิธี Virtio ทั่วไปที่แบ่ง buffer ข้ามขอบเขตหน้าเพจออกเป็นหลาย segment
- ไดรเวอร์ Virtio block ของ FreeBSD จึงถูกปรับให้ใช้
busdmaและสำหรับคำขอที่ไม่จัดแนวจะใช้การจัดการแบบ bounce ผ่านบัฟเฟอร์ชั่วคราวให้เข้ากับข้อจำกัดของ Firecracker
การปรับแต่งการบูตที่ Firecracker ทำให้มองเห็น
- เมื่อ FreeBSD เริ่มทำงานบน Firecracker ได้แล้ว จุดที่ควรลดเวลาและการใช้หน่วยความจำระหว่างบูตก็ชัดเจนขึ้นมาก
- บน VM RAM 128MB หน่วยความจำระบบเกือบครึ่งอยู่ในสถานะ
wiredและ process มักถูก kill บ่อย- เมื่อตรวจสอบพบว่า
busdmaกันพื้นที่ 32MB ไว้สำหรับ bounce page - ภายใต้ข้อจำกัดของ Firecracker แต่ละ disk I/O ต้องใช้ bounce page ขนาด 4KB เพียงหน้าเดียวเท่านั้น
- แพตช์ที่จำกัดการจอง bounce page สำหรับอุปกรณ์ที่รองรับ I/O segment จำนวนน้อย ทำให้การใช้หน่วยความจำลดลงเหลือ 512KB
- เมื่อตรวจสอบพบว่า
- การปรับปรุงตัวสร้างเลขสุ่มของเคอร์เนลช่วยลดเวลาบูต
- ใน VM นั้น entropy จากอุปกรณ์ฮาร์ดแวร์อาจไม่มีประสิทธิภาพนัก
- แม้จะใช้
RDRANDของ x86 เป็นแหล่ง entropy สำรอง แต่เดิมให้ entropy ต่อคำขอน้อยและขอได้เพียงทุก 100ms - จึงเปลี่ยนให้ดึงปริมาณที่พอสำหรับ seed ตัวสร้างเลขสุ่ม Fortuna ได้ครบ ส่งผลให้ลดเวลาได้ 2.3 วินาที
- การจัดการ Host ID ก็เร็วขึ้นด้วย
- ปกติ boot loader จะตั้งค่า
smbios.system.uuidจากข้อมูล BIOS หรือ UEFI - Firecracker ไม่มี boot loader จึงไม่มีการให้ ID นี้มา
- จึงแก้ให้หากฮาร์ดแวร์ส่ง ID ที่ผิดปกติมาจะเตือนแล้วรอ 2 วินาที แต่ถ้าไม่มี ID เลยให้ผ่านไปอย่างเงียบและรวดเร็ว
- ปกติ boot loader จะตั้งค่า
- เงื่อนไขการรอ IPv6 DAD ก็ถูกทำให้แคบลง
- FreeBSD เคยรอ Duplicate Address Detection หากมีการเปิด IPv6 บน network interface
- โดย interface loopback จะเปิด IPv6 อยู่เสมอ
- จึงเปลี่ยนให้รอ DAD เฉพาะเมื่อมี IPv6 บน interface ที่ไม่ใช่ loopback ส่งผลให้ลดเวลาได้ 2 วินาที
- เวลารอคงที่ระหว่างการรีบูตและปิดระบบก็ถูกตัดออก
- เดิมตอนรีบูตหลังข้อความ
Rebooting...จะรอ 1 วินาทีเพื่อให้printfเสร็จและมีเวลาอ่านผล แต่ภายหลังถูกเปลี่ยนเป็น sysctlkern.reboot_wait_timeซึ่งมีค่าเริ่มต้นเป็น 0 - พฤติกรรมที่ BSP รอเพิ่มอีก 1 วินาทีหลังส่งสัญญาณหยุด CPU อื่นระหว่างปิดหรือรีบูตก็ถูกลบออก
- เดิมตอนรีบูตหลังข้อความ
- มีการใช้ TSLOG เพื่อวิเคราะห์ flame chart ของการบูต
- สภาพแวดล้อมที่มินิมัลของ Firecracker มี noise ต่ำ จึงมองเห็นคอขวดที่เหลือได้ง่าย
- VM รันได้เร็วมาก จนบ่อยครั้งใช้เวลาน้อยกว่า 30 วินาทีสำหรับการ build เคอร์เนลใหม่, รัน และสร้าง flame chart
- การวิเคราะห์ด้วย TSLOG ช่วยลดคอขวดระดับหลายมิลลิวินาทีได้หลายจุด
- ลดลูปคาลิเบรต 100000 รอบของ
lapic_initเหลือ 1000 รอบ ช่วยลดเวลา 10ms - เปลี่ยน
ns8250_drainจากเดิมที่เรียกDELAYทุกตัวอักษร มาเป็นตรวจLSR_RXRDYก่อนและหน่วงเมื่อจำเป็นเท่านั้น ช่วยลดเวลา 27ms - ให้ Firecracker implement CPUID leaf ที่บอกความถี่ของ TSC และ local APIC clock ช่วยลดเวลา 20ms
- เปลี่ยน
kern.nswbufจากการตรึงไว้ที่ 256 เสมอ เป็น32 * mp_ncpusช่วยลดเวลา 5ms บน VM 1 CPU - การเปลี่ยน bubblesort ใน
mi_startupเป็น quicksort ลดได้ 2ms แต่ ณ วันที่ 22 สิงหาคม 2023 ยังไม่ถูก commit - การเปลี่ยน
vm_memจากการ initialize โครงสร้างvm_pageสำหรับ physical memory ทั้งหมดทันที เป็นแบบ lazy initialization ลดได้ 2ms และ ณ วันเดียวกันยังไม่ถูก commit - หากเพิ่ม
MAP_POPULATEให้กับmmapของ guest memory ใน Firecracker จะลดต้นทุนที่ Linux ต้องสร้างโครงสร้างเพจเมื่อมีการเข้าถึงเพจแรก ช่วยลดได้ 2ms และ ณ วันเดียวกันยังไม่ถูก commit
- ลดลูปคาลิเบรต 100000 รอบของ
สถานะปัจจุบันและงานที่ยังเหลือ
- FreeBSD บูตบน Firecracker ได้แล้ว และทำงานได้เร็วมาก
- หากรวมแพตช์ที่ยังไม่ถูก commit ทั้งฝั่ง FreeBSD และ Firecracker เคอร์เนล FreeBSD จะบูตบน VM ที่มี 1 CPU และ RAM 128MB ได้ในเวลา ต่ำกว่า 20ms
- งานที่ยังเหลือเน้นไปที่การจัดระเบียบการรองรับ PVH และการลดขนาดคอนฟิกเคอร์เนล
- ต้อง commit แพตช์ที่กล่าวถึงข้างต้น
- ต้อง merge การรองรับ PVH boot mode เข้าสู่ Firecracker mainline
- โค้ดสำหรับ PVH booting ยังปะปนกับการรองรับ Xen อยู่ จึงต้องแยกออก
- ปัจจุบันเคอร์เนล FreeBSD arm64 ยัง build โดยไม่มีการรองรับ PCI หรือ ACPI ไม่ได้ และหากลบ dependency ที่ไม่ถูกต้องเหล่านี้ได้ ก็จะทำให้เคอร์เนล FreeBSD/Firecracker เล็กลงได้อีก
- ปัจจุบันมีการใช้เวลา 25µs เพื่อตรวจว่าจำเป็นต้องจองหน่วยความจำสำหรับ Intel GPU หรือไม่ ดังนั้นคอนฟิกเคอร์เนลที่เล็กลงอาจลดเวลาบูตได้อีกไม่กี่ไมโครวินาที
- ในระยะยาวยังมีความเป็นไปได้ที่จะพอร์ต Firecracker ให้รันบน FreeBSD
- Firecracker ถูกเขียนขึ้นโดยสมมติว่าจะใช้ Linux KVM
- แต่ดูเหมือนไม่มีเหตุผลเชิงพื้นฐานที่ทำให้มันใช้ส่วนเคอร์เนลของ hypervisor bhyve ของ FreeBSD ไม่ได้
- หากต้องการทดลอง สามารถ build เคอร์เนล FreeBSD 14.0 แบบ amd64 ด้วยคอนฟิกเคอร์เนล
FIRECRACKERและใช้feature/pvhbranch ของโปรเจกต์ Firecracker ได้- หาก branch ดังกล่าวไม่มีอยู่แล้ว ก็หมายความว่าโค้ดน่าจะถูก merge เข้าไปใน Firecracker tree หลักแล้ว
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ไม่ค่อยรู้มาก่อนว่า Firecracker VM ไม่ใช่แค่เทคโนโลยีคอนเทนเนอร์ของ Linux แบบง่าย ๆ แต่เป็น เครื่องเสมือนเต็มรูปแบบ
ตอนแรกอาจฟังดูไม่มีประสิทธิภาพ แต่พอดูกรณีใช้งานจริงอย่าง fly.io แล้วน่าทึ่งที่ ไมโคร VM มีขนาดเล็กมากแต่ก็ทรงพลังพอ
ด้วย KVM และการรองรับฮาร์ดแวร์ขั้นต่ำ (ไม่มี PCI, ACPI ฯลฯ) ซอร์สของ Firecracker จึงค่อนข้างเรียบง่าย และค่อนข้างอ่านได้แม้ไม่ใช่ผู้เชี่ยวชาญ
นั่นแหละคือเหตุผลที่ Firecracker มีอยู่
ACPI ที่บทความยกมาคือตัวอย่างหนึ่ง ถึงอย่างนั้นก็ยังถูกต้องที่มันจำลองฮาร์ดแวร์ ไม่ใช่เคอร์เนล และการเริ่มต้นก็เร็วมากจนผู้ใช้ส่วนใหญ่น่าจะไม่รู้สึกถึงความต่างแม้เปลี่ยนจาก containerd ปกติไปเป็น firecracker-containerd
นอกจาก Firecracker แล้ว ยังมี ไมโคร VM หลายตัวอย่าง crosvm, cloud-hypervisor และ Dragonball ของ Kata ที่กำลังพัฒนาบน KVM อยู่ตอนนี้
ผมไม่ได้รู้สึกว่าการเพิ่ม target ใหม่ในภาษาโปรแกรมจะยากขนาดนั้น ดังนั้นถ้าสร้างและรองรับ target แบบคล้ายระบบปฏิบัติการอย่าง WASI/WASM แล้วส่ง PR ไปยังภาษาที่รองรับ ก็น่าจะลดโอเวอร์เฮดได้เกือบทั้งหมด ส่วนที่ยากที่สุดคงเป็นการเลียนแบบ user space ของ Linux ให้แม่นพอ แต่เพราะพื้นผิวมันกว้างมาก เส้นทางการสร้าง target แบบคล้ายระบบปฏิบัติการกลับดูเหมือนเป็นทางที่ดีที่สุด
ถ้าแพตช์ของ Colin เข้าไปใน FreeBSD และ Firecracker แล้ว เวลาบูตเคอร์เนลทั้งหมด จะต่ำกว่า 20ms
เรากำลังอยู่ในยุคที่ไม่น่าเชื่อจริง ๆ
ค้นเร็ว ๆ ก็เจอตัวเลขอยู่ แต่เป็นข้อมูลเมื่อหลายปีก่อน และก็ไม่ชัดว่าใช้วิธีวัดเวลาบูตเหมือนกันหรือไม่ รวมถึงนิยามของ “เวลาบูต” เหมือนกันหรือเปล่า เลยไม่แน่ใจว่าเทียบกันได้ไหม
นี่คือ งานนำเสนอ BSDCan ล่าสุดของ Colin ที่เพิ่งขึ้นเมื่อไม่กี่วันก่อน
https://youtu.be/MT3cdeuRTzs?si=l6baNriUjcvy0ZOE
หลังงาน BSDCan ทาง FreeBSD Journal บอกว่า “เป็นงานนำเสนอที่ดี ช่วยแปลงเป็นบทความได้ไหม” และหลังบทความของ FreeBSD Journal ออกมา ;login: ก็ถามว่านำไปเผยแพร่ซ้ำได้ไหม
qemu มี microvm ที่ได้แรงบันดาลใจจาก firecracker
https://qemu.readthedocs.io/en/latest/system/i386/microvm.ht...
แน่นอนว่าบางส่วนเป็นการแก้บั๊กของ FreeBSD จึงจำเป็นอยู่แล้ว
น่าสนใจที่พบว่าเวลาส่วนใหญ่ของ การรอ 1 วินาที จริง ๆ แล้วไม่จำเป็นนัก
สงสัยว่ามีผู้ดูแลระบบกี่คนที่ทำอะไรที่มีความหมายจริง ๆ ตอนระบบค้างเพราะ machine UUID ผิด
ในทางกลับกัน กรณี “แสดงข้อความให้ผู้ใช้รู้ว่าจะรีบูต รอ 1 วินาทีเพื่อให้พออ่านคอนโซลได้ แล้วจึงรีบูต” นั้นต่างออกไปหน่อย
ไม่ได้อยากให้ฟังดูอวดรู้ แต่สงสัยว่าอย่าง อินสแตนซ์ Firecracker เหมาะกับกรณีใช้งานแบบไหน
ผมใช้ FreeBSD กับทุกอย่างตั้งแต่เซิร์ฟเวอร์ colocated ไปจนถึงพีซีส่วนตัว และน่าจะเป็นผู้ดูแล Unix รุ่นเก่ามากกว่านักพัฒนา ชอบ bare metal แต่ก็ยินดีกับเทคโนโลยีอนาคตที่ช่วยผลักดันระบบปฏิบัติการ เพียงแต่พอได้ยินคำฮิตอย่าง Lambda หรือ Firecracker ก็ยังไม่ค่อยเข้าใจว่าใช้งานจริงตรงไหน ผมเข้าใจ Docker กับคอนเทนเนอร์ และพอเข้าใจ k8s แบบถูไถ แต่ไม่เข้าใจว่าทำไมต้องสร้าง VM แล้วทำลายทันทีกัน ในเมื่อแค่เปิด VM ไว้ใช้เมื่อจำเป็นก็ได้ เป็นเรื่องประสบการณ์คลาวด์ล้วน ๆ หรือเพื่อประหยัดต้นทุนหรือเปล่า?
วิธีนี้ทำให้โหนดใด ๆ ใน compute plane สามารถรับทราฟฟิกของแอปพลิเคชันใดก็ได้ แอปพลิเคชันหนึ่งสามารถขยายตัวเพื่อใช้ทรัพยากรคอมพิวต์ที่ว่างใน plane ได้แบบไดนามิกตามการเปลี่ยนแปลงของรูปแบบทราฟฟิก และเมื่อไม่ได้รับทราฟฟิกก็ไม่ใช้ทรัพยากร การเพิ่มความจุของ compute plane ก็คือการนำโหนดเพิ่มเข้ามาออนไลน์ นอกจากการจัดการ deployment ขนาดใหญ่จำนวนมากแล้วก็นึกกรณีใช้งานอื่นไม่ค่อยออก และถ้าไม่ใช่สภาพแวดล้อมที่มี “สเกล” เทคโนโลยีนี้ก็น่าจะซ่อนอยู่ใต้ขอบเขตของผู้ให้บริการ
ถ้าคุณให้บริการ API ที่ไม่ได้ถูกเรียกบ่อย แต่เมื่อถูกเรียกต้องตอบกลับเร็ว Lambda หรือแนวทางคล้ายกันก็เหมาะมาก จริง ๆ แล้ว API สำหรับแอปมือถือจำนวนมากอยู่ในกลุ่มนี้ และคุณคงไม่อยากเปิดเครื่องที่ว่างอยู่ 99% ของเวลาไว้ตลอดเพียงเพื่อรอตอบ API call เหล่านั้น
ส่วนใหญ่แค่ไม่ทำเพราะความพยายามที่ต้องใช้มากกว่าเงินที่ประหยัดได้ แต่ศักยภาพมีอยู่ สิ่งอย่าง Lambda และ Firecracker ทำให้เรื่องนั้นง่ายขึ้นมาก
น่าเสียดายที่ทั้ง AWS และ macOS บน ARM ไม่รองรับ nested virtualization
ถ้ารองรับ การพัฒนาและปรับใช้เทคโนโลยีที่อิง Firecracker ก็คงง่ายขึ้นมาก
จริง ๆ แล้ว virtualization ทำได้บนอินสแตนซ์ทุกประเภท แต่เท่าที่รู้ มีเพียงอินสแตนซ์ .metal เท่านั้นที่ใช้ hardware acceleration ได้
Firecracker นั้นน่าทึ่ง แต่ก็มี กรณียกเว้น จำนวนมากที่ควรต้องทำเอกสารไว้
ขอบคุณ Colin Percival มากที่แชร์เรื่องนี้ โดยเฉพาะประโยค “หลังจากเก็บผลไม้ที่เอื้อมถึงง่ายหมดแล้ว” ซึ่งสำหรับ Colin หมายถึงแพตช์ bus_dma แบบคัสตอม ตอนนี้ใคร ๆ ก็สามารถได้ประโยชน์ฟรีจากสิ่งที่ว่า “เคอร์เนล FreeBSD บูตได้ภายในต่ำกว่า 20ms บน CPU 1 ตัวและ RAM 128MB” หากคุณคุ้นเคยกับ DevOps ที่ใช้คลัสเตอร์ k8s หรือ Docker จำนวนมาก นี่เป็นเรื่องที่น่าทึ่งจริง ๆ
ลองเล่น Firecracker อยู่เล็กน้อย และ เวลาในการบูต ก็เป็นไปตามที่สัญญาไว้ แต่ประสบการณ์ใช้งานค่อนข้างลำบากทีเดียว
เช่น หลังจากบูตสำเร็จจนดีใจแล้ว ก็หมดแรงเมื่อพบว่าหากจะตั้งค่า networking ต้องทำตาม tutorial ยาว ๆ อีกชุดหนึ่ง
ถ้าดาวน์โหลดไบนารีตัวเดียวมาแล้วรัน จากนั้นทั้งเว็บอินเทอร์เฟซและ API เปิดขึ้นมา ตั้งค่าได้อย่างรวดเร็ว และดาวน์โหลดสิ่งที่จำเป็นให้เองได้ ก็น่าจะดีมาก
“เคอร์เนล FreeBSD สามารถบูตได้ภายในต่ำกว่า 20ms บนเครื่องเสมือนที่มี CPU 1 ตัวและ RAM 128MB”
โอ้โห แล้วถ้าไม่มี VM จะทำแบบเดียวกันบน ฮาร์ดแวร์จริง ได้อย่างไรล่ะ ;)
สิ่งที่ช้าคือส่วนที่เหลือทั้งหมด เช่น เครื่องของผมคือ
Startup finished in 14.552s (firmware) + 2.885s (loader) + 741ms (kernel) + 23.116s (initrd) + 11.191s (userspace) = 52.488s