3 คะแนน โดย GN⁺ 2023-08-26 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • การบูตเคอร์เนล 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
  • ความต่างของการจัดวางหน่วยความจำระหว่าง Firecracker กับ Xen ก็ทำให้เกิดปัญหา
    • Xen โหลดเคอร์เนลก่อน แล้วค่อยวางหน้า start_info ไว้ท้ายสุด
    • Firecracker วางหน้า start_info ไว้ที่ low address คงที่ แล้วจึงค่อยโหลดเคอร์เนลทีหลัง
    • โค้ด PVH ของ FreeBSD สมมติว่าพื้นที่ถัดจาก start_info ใช้เป็น scratch space ได้ ซึ่งบน Firecracker กลับไปเขียนทับ initial kernel stack
    • จึงแก้โดยจัดสรร scratch space หลังทุกช่วงหน่วยความจำที่ hypervisor ได้ initialize ไว้แล้ว

การไม่มี 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
  • เดิม FreeBSD คาดว่าจะค้นหาอุปกรณ์ mmio ผ่าน FDT แต่ Firecracker ส่งตัวชี้อย่าง virtio_mmio.device=4K@0x1001e000:5 มาทาง kernel command line
    • FreeBSD จึงเพิ่มโค้ดสำหรับพาร์สตัวชี้นี้และสร้างโหนดอุปกรณ์ virtio_mmio
    • เมื่อมีโหนดอุปกรณ์แล้ว กระบวนการ probe อุปกรณ์เดิมของ FreeBSD ก็จะระบุชนิดอุปกรณ์ Virtio และผูกเข้ากับไดรเวอร์ที่เหมาะสม
  • เมื่อมีอุปกรณ์ 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=
  • หลังจากปิดระบบผิดปกติ หากบูตครั้งถัดไปมีการรัน fsck จะเกิด kernel panic
    • fsck เป็นหนึ่งในกรณีหายากบน 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 เลยให้ผ่านไปอย่างเงียบและรวดเร็ว
  • เงื่อนไขการรอ IPv6 DAD ก็ถูกทำให้แคบลง
    • FreeBSD เคยรอ Duplicate Address Detection หากมีการเปิด IPv6 บน network interface
    • โดย interface loopback จะเปิด IPv6 อยู่เสมอ
    • จึงเปลี่ยนให้รอ DAD เฉพาะเมื่อมี IPv6 บน interface ที่ไม่ใช่ loopback ส่งผลให้ลดเวลาได้ 2 วินาที
  • เวลารอคงที่ระหว่างการรีบูตและปิดระบบก็ถูกตัดออก
    • เดิมตอนรีบูตหลังข้อความ Rebooting... จะรอ 1 วินาทีเพื่อให้ printf เสร็จและมีเวลาอ่านผล แต่ภายหลังถูกเปลี่ยนเป็น sysctl kern.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

สถานะปัจจุบันและงานที่ยังเหลือ

  • 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/pvh branch ของโปรเจกต์ Firecracker ได้
    • หาก branch ดังกล่าวไม่มีอยู่แล้ว ก็หมายความว่าโค้ดน่าจะถูก merge เข้าไปใน Firecracker tree หลักแล้ว

1 ความคิดเห็น

 
GN⁺ 2023-08-26
ความคิดเห็นจาก Hacker News
  • ไม่ค่อยรู้มาก่อนว่า Firecracker VM ไม่ใช่แค่เทคโนโลยีคอนเทนเนอร์ของ Linux แบบง่าย ๆ แต่เป็น เครื่องเสมือนเต็มรูปแบบ
    ตอนแรกอาจฟังดูไม่มีประสิทธิภาพ แต่พอดูกรณีใช้งานจริงอย่าง fly.io แล้วน่าทึ่งที่ ไมโคร VM มีขนาดเล็กมากแต่ก็ทรงพลังพอ

    • ถ้าอยากรู้เพิ่ม แนะนำให้อ่าน เปเปอร์ NSDI'20 ที่อธิบายว่าทำไมเราจึงเลือกแนวทางนี้ (https://www.usenix.org/conference/nsdi20/presentation/agache) และซอร์ส/เอกสารของ Firecracker (https://github.com/firecracker-microvm/firecracker)
      ด้วย KVM และการรองรับฮาร์ดแวร์ขั้นต่ำ (ไม่มี PCI, ACPI ฯลฯ) ซอร์สของ Firecracker จึงค่อนข้างเรียบง่าย และค่อนข้างอ่านได้แม้ไม่ใช่ผู้เชี่ยวชาญ
    • ผู้ให้บริการคลาวด์ระดับองค์กร อย่าง AWS ไม่มีทางยอมให้คอนเทนเนอร์ของลูกค้าต่างรายอยู่ร่วมกันใน VM เดียวกันใน ECS หรือ Lambda แน่
      นั่นแหละคือเหตุผลที่ Firecracker มีอยู่
    • Firecracker ไม่ใช่เครื่องที่ “เต็มรูปแบบ” เสียทีเดียว เพราะตัดสิ่งต่าง ๆ จำนวนมากที่ Lambda และบังเอิญรวมถึงกรณีใช้งานของ fly.io ไม่จำเป็นต้องใช้ออกไป
      ACPI ที่บทความยกมาคือตัวอย่างหนึ่ง ถึงอย่างนั้นก็ยังถูกต้องที่มันจำลองฮาร์ดแวร์ ไม่ใช่เคอร์เนล และการเริ่มต้นก็เร็วมากจนผู้ใช้ส่วนใหญ่น่าจะไม่รู้สึกถึงความต่างแม้เปลี่ยนจาก containerd ปกติไปเป็น firecracker-containerd
    • KVM น่าทึ่งมาก
      นอกจาก Firecracker แล้ว ยังมี ไมโคร VM หลายตัวอย่าง crosvm, cloud-hypervisor และ Dragonball ของ Kata ที่กำลังพัฒนาบน KVM อยู่ตอนนี้
    • แปลกใจที่การสร้าง ไมโครเคอร์เนล ที่เลียนแบบ user space ของ Linux หรือ user space แบบ *NIX ให้เข้ากับซับเซ็ตของฮาร์ดแวร์เสมือนที่ Firecracker และ QEMU จัดให้นั้นยังไม่กลายเป็นมาตรฐาน
      ผมไม่ได้รู้สึกว่าการเพิ่ม target ใหม่ในภาษาโปรแกรมจะยากขนาดนั้น ดังนั้นถ้าสร้างและรองรับ target แบบคล้ายระบบปฏิบัติการอย่าง WASI/WASM แล้วส่ง PR ไปยังภาษาที่รองรับ ก็น่าจะลดโอเวอร์เฮดได้เกือบทั้งหมด ส่วนที่ยากที่สุดคงเป็นการเลียนแบบ user space ของ Linux ให้แม่นพอ แต่เพราะพื้นผิวมันกว้างมาก เส้นทางการสร้าง target แบบคล้ายระบบปฏิบัติการกลับดูเหมือนเป็นทางที่ดีที่สุด
  • ถ้าแพตช์ของ Colin เข้าไปใน FreeBSD และ Firecracker แล้ว เวลาบูตเคอร์เนลทั้งหมด จะต่ำกว่า 20ms
    เรากำลังอยู่ในยุคที่ไม่น่าเชื่อจริง ๆ

    • อยากรู้ว่าเมื่อเทียบกับ Linux บน Firecracker แล้วเป็นอย่างไร
      ค้นเร็ว ๆ ก็เจอตัวเลขอยู่ แต่เป็นข้อมูลเมื่อหลายปีก่อน และก็ไม่ชัดว่าใช้วิธีวัดเวลาบูตเหมือนกันหรือไม่ รวมถึงนิยามของ “เวลาบูต” เหมือนกันหรือเปล่า เลยไม่แน่ใจว่าเทียบกันได้ไหม
  • นี่คือ งานนำเสนอ 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...

    • สงสัยว่าใน QEMU ต้องใช้วิธีอ้อมแบบนี้มากแค่ไหน
      แน่นอนว่าบางส่วนเป็นการแก้บั๊กของ FreeBSD จึงจำเป็นอยู่แล้ว
  • น่าสนใจที่พบว่าเวลาส่วนใหญ่ของ การรอ 1 วินาที จริง ๆ แล้วไม่จำเป็นนัก
    สงสัยว่ามีผู้ดูแลระบบกี่คนที่ทำอะไรที่มีความหมายจริง ๆ ตอนระบบค้างเพราะ machine UUID ผิด

    • ผู้ดูแลระบบที่เจอการรอ 1 วินาทีนั้นคงมีสัดส่วนไม่น้อยที่ทำอะไรสักอย่าง
      ในทางกลับกัน กรณี “แสดงข้อความให้ผู้ใช้รู้ว่าจะรีบูต รอ 1 วินาทีเพื่อให้พออ่านคอนโซลได้ แล้วจึงรีบูต” นั้นต่างออกไปหน่อย
  • ไม่ได้อยากให้ฟังดูอวดรู้ แต่สงสัยว่าอย่าง อินสแตนซ์ Firecracker เหมาะกับกรณีใช้งานแบบไหน
    ผมใช้ FreeBSD กับทุกอย่างตั้งแต่เซิร์ฟเวอร์ colocated ไปจนถึงพีซีส่วนตัว และน่าจะเป็นผู้ดูแล Unix รุ่นเก่ามากกว่านักพัฒนา ชอบ bare metal แต่ก็ยินดีกับเทคโนโลยีอนาคตที่ช่วยผลักดันระบบปฏิบัติการ เพียงแต่พอได้ยินคำฮิตอย่าง Lambda หรือ Firecracker ก็ยังไม่ค่อยเข้าใจว่าใช้งานจริงตรงไหน ผมเข้าใจ Docker กับคอนเทนเนอร์ และพอเข้าใจ k8s แบบถูไถ แต่ไม่เข้าใจว่าทำไมต้องสร้าง VM แล้วทำลายทันทีกัน ในเมื่อแค่เปิด VM ไว้ใช้เมื่อจำเป็นก็ได้ เป็นเรื่องประสบการณ์คลาวด์ล้วน ๆ หรือเพื่อประหยัดต้นทุนหรือเปล่า?

    • อินสแตนซ์ของแอปพลิเคชันถูกสร้างขึ้นเป็นส่วนหนึ่งของ วงจรชีวิต request/response
      วิธีนี้ทำให้โหนดใด ๆ ใน compute plane สามารถรับทราฟฟิกของแอปพลิเคชันใดก็ได้ แอปพลิเคชันหนึ่งสามารถขยายตัวเพื่อใช้ทรัพยากรคอมพิวต์ที่ว่างใน plane ได้แบบไดนามิกตามการเปลี่ยนแปลงของรูปแบบทราฟฟิก และเมื่อไม่ได้รับทราฟฟิกก็ไม่ใช้ทรัพยากร การเพิ่มความจุของ compute plane ก็คือการนำโหนดเพิ่มเข้ามาออนไลน์ นอกจากการจัดการ deployment ขนาดใหญ่จำนวนมากแล้วก็นึกกรณีใช้งานอื่นไม่ค่อยออก และถ้าไม่ใช่สภาพแวดล้อมที่มี “สเกล” เทคโนโลยีนี้ก็น่าจะซ่อนอยู่ใต้ขอบเขตของผู้ให้บริการ
    • กรณีใช้งานหลักคือ API ที่ถูกใช้งานเป็นครั้งคราว
      ถ้าคุณให้บริการ API ที่ไม่ได้ถูกเรียกบ่อย แต่เมื่อถูกเรียกต้องตอบกลับเร็ว Lambda หรือแนวทางคล้ายกันก็เหมาะมาก จริง ๆ แล้ว API สำหรับแอปมือถือจำนวนมากอยู่ในกลุ่มนี้ และคุณคงไม่อยากเปิดเครื่องที่ว่างอยู่ 99% ของเวลาไว้ตลอดเพียงเพื่อรอตอบ API call เหล่านั้น
    • “แค่เปิด VM ไว้ใช้เมื่อจำเป็นก็ได้ มันเปิดอยู่เสมอและพร้อมเสมอ” หมายความว่า ถูกคิดเงินเสมอ ด้วย
    • บริษัทแทบทุกแห่งได้ประโยชน์จาก การสเกล เพราะทราฟฟิกไม่ได้คงที่ตลอด 24 ชั่วโมง
      ส่วนใหญ่แค่ไม่ทำเพราะความพยายามที่ต้องใช้มากกว่าเงินที่ประหยัดได้ แต่ศักยภาพมีอยู่ สิ่งอย่าง Lambda และ Firecracker ทำให้เรื่องนั้นง่ายขึ้นมาก
  • น่าเสียดายที่ทั้ง AWS และ macOS บน ARM ไม่รองรับ nested virtualization
    ถ้ารองรับ การพัฒนาและปรับใช้เทคโนโลยีที่อิง Firecracker ก็คงง่ายขึ้นมาก

    • เท่าที่ทราบ บน อินสแตนซ์ .metal สามารถทำ virtualization ได้
      จริง ๆ แล้ว virtualization ทำได้บนอินสแตนซ์ทุกประเภท แต่เท่าที่รู้ มีเพียงอินสแตนซ์ .metal เท่านั้นที่ใช้ hardware acceleration ได้
    • อนึ่ง อินสแตนซ์ AWS a1.metal ค่อนข้างเล็ก จึงถือว่าคุ้มค่าเมื่อเทียบกับค่าใช้จ่ายสำหรับการทำงานกับเทคโนโลยี virtualization
  • Firecracker นั้นน่าทึ่ง แต่ก็มี กรณียกเว้น จำนวนมากที่ควรต้องทำเอกสารไว้
    ขอบคุณ Colin Percival มากที่แชร์เรื่องนี้ โดยเฉพาะประโยค “หลังจากเก็บผลไม้ที่เอื้อมถึงง่ายหมดแล้ว” ซึ่งสำหรับ Colin หมายถึงแพตช์ bus_dma แบบคัสตอม ตอนนี้ใคร ๆ ก็สามารถได้ประโยชน์ฟรีจากสิ่งที่ว่า “เคอร์เนล FreeBSD บูตได้ภายในต่ำกว่า 20ms บน CPU 1 ตัวและ RAM 128MB” หากคุณคุ้นเคยกับ DevOps ที่ใช้คลัสเตอร์ k8s หรือ Docker จำนวนมาก นี่เป็นเรื่องที่น่าทึ่งจริง ๆ

  • ลองเล่น Firecracker อยู่เล็กน้อย และ เวลาในการบูต ก็เป็นไปตามที่สัญญาไว้ แต่ประสบการณ์ใช้งานค่อนข้างลำบากทีเดียว
    เช่น หลังจากบูตสำเร็จจนดีใจแล้ว ก็หมดแรงเมื่อพบว่าหากจะตั้งค่า networking ต้องทำตาม tutorial ยาว ๆ อีกชุดหนึ่ง

    • เห็นได้ชัดว่ายังมีช่องให้สร้างเครื่องมือ automation เพื่อเพิ่มคุณค่าได้มาก
      ถ้าดาวน์โหลดไบนารีตัวเดียวมาแล้วรัน จากนั้นทั้งเว็บอินเทอร์เฟซและ API เปิดขึ้นมา ตั้งค่าได้อย่างรวดเร็ว และดาวน์โหลดสิ่งที่จำเป็นให้เองได้ ก็น่าจะดีมาก
  • “เคอร์เนล FreeBSD สามารถบูตได้ภายในต่ำกว่า 20ms บนเครื่องเสมือนที่มี CPU 1 ตัวและ RAM 128MB”
    โอ้โห แล้วถ้าไม่มี VM จะทำแบบเดียวกันบน ฮาร์ดแวร์จริง ได้อย่างไรล่ะ ;)

    • บนฮาร์ดแวร์จริง การบูตเคอร์เนล ก็เร็วพออยู่แล้ว และโดยปกติต่ำกว่า 1 วินาที
      สิ่งที่ช้าคือส่วนที่เหลือทั้งหมด เช่น เครื่องของผมคือ Startup finished in 14.552s (firmware) + 2.885s (loader) + 741ms (kernel) + 23.116s (initrd) + 11.191s (userspace) = 52.488s