- แซนด์บ็อกซ์แบบโปรเซสเดี่ยวที่อิง KVM
- สามารถรันโปรแกรม Linux ทั่วไป หรือโปรแกรมที่ใช้ API เฉพาะภายในแซนด์บ็อกซ์ได้
- ใช้ฮาร์ดแวร์เวอร์ชวลไลเซชันเพื่อมอบ ประสิทธิภาพระดับเนทีฟ
- ใช้เพียงบางส่วนของ KVM API → ทำให้โค้ดเบสมีขนาดเล็กและมีประสิทธิภาพ
การออกแบบของ TinyKVM
- รองรับการรันโปรแกรม Linux ELF แบบสแตติก
- มีแผนจะเพิ่มการรองรับไฟล์ปฏิบัติการแบบไดนามิกในภายหลัง
- สามารถขยายเป็น API เพื่อให้เข้าถึงเซิร์ฟเวอร์ HTTP ภายนอกหรือแคชได้
- ปัจจุบันทำงานบน AMD64(x86_64) และมีแผนพอร์ตไปยัง AArch64(ARM 64 บิต)
- รองรับ Hugepage
- สามารถสร้าง hugepage สำหรับ guest page ได้
- โฮสต์ก็สามารถใช้ hugepage ได้เช่นกัน → ช่วยเพิ่มประสิทธิภาพ
- ตัวอย่าง: เมื่อจัดสรรเพจขนาด 2MB พบว่าประสิทธิภาพการคอมไพล์ LLVM เพิ่มขึ้น 5%
- การเรียกฟังก์ชันที่รวดเร็ว
- โอเวอร์เฮดเมื่อเรียกฟังก์ชันจาก guest อยู่ที่ 2μs
- หากรันโดยไม่ใช้ตัวจับเวลา โอเวอร์เฮดจะลดลงเหลือ 1.2μs
- รองรับการดีบักระยะไกล
- สามารถดีบักระยะไกลด้วย GDB ได้
- หลังดีบักแล้วสามารถกลับมารันโปรแกรมต่อได้ตามปกติ
- รองรับ Copy-on-Write
- รองรับความสามารถ fork ของตัวเอง → ช่วยลดการคัดลอกหน่วยความจำให้เหลือน้อยที่สุด
- ตัวอย่าง: หากโคลนโมเดลขนาด 6GB จะใช้หน่วยความจำเพียง 260MB ต่ออินสแตนซ์
- การรีเซ็ตสถานะที่รวดเร็ว
- สามารถรีเซ็ตสถานะของ guest ได้อย่างรวดเร็ว → เสริมความปลอดภัย
- หากรีเซ็ตทุกคำขอจะช่วยลดความเสี่ยงจากการเปิดเผยสถานะ
- โค้ดเบสที่เรียบง่าย
- ใช้งานประมาณ 42k LOC จาก KVM API
- โค้ดเบสของ TinyKVM เองมีประมาณ 9k LOC → เล็กกว่าคู่แข่งมาก
- ตัวอย่าง: Wasmtime 350k LOC, FireCracker 165k LOC
- การสร้างตารางเพจแบบคงที่
- ไม่สามารถแก้ไขตารางเพจระหว่างรันไทม์ได้ → เสริมความปลอดภัย
- มีการตรวจสอบความถูกต้องสมบูรณ์ของตารางเพจ
- คอนเท็กซ์ของโปรเซสที่แยกจากกัน
- KVM guest ใช้ PCID/ASID แยกต่างหาก → ทนทานต่อการโจมตีแบบ speculative execution เช่น Spectre
- เคอร์เนลที่เสริมความปลอดภัย
- เปิดใช้งาน SMEP และ SMAP
- สามารถจัดการ CPU exception ได้ในโหมดผู้ใช้
การจัดการ system call
- การเชื่อมต่อ API กับโฮสต์
- ดำเนิน system call ผ่านคำสั่ง SYSCALL/SYSRET หรือ OUT
- เมื่อดำเนิน system call จะเกิด VM exit → ใช้เวลาประมาณ 1μs
- แนะนำให้ออกแบบ API ที่ลดการเรียกขนาดเล็กและใช้หน่วย I/O ขนาดใหญ่
เบนช์มาร์ก
- โอเวอร์เฮดของการเรียก VM
- วัด tail latency ตอนรีเซ็ต VM
- หากเป็นการเรียกธรรมดาโดยไม่รีเซ็ต โอเวอร์เฮดจะต่ำ
- ประสิทธิภาพหน่วยความจำ
- ประสิทธิภาพหน่วยความจำอยู่ในระดับปกติ
- ตัวอย่าง: ใน HTTP เบนช์มาร์ก สามารถเข้ารหัส AVIF ได้ 1500 รายการต่อวินาที
- ประสิทธิภาพการแปลง JPEG → AVIF
- สามารถแปลงภาพได้ประมาณ 1582 ภาพต่อวินาที
- สามารถแปลงแบบไม่สูญเสียข้อมูลได้โดยใช้เส้นทางการแปลง YUV
เหตุผลที่แซนด์บ็อกซ์นี้ทำงานได้รวดเร็ว
- ไม่ใช้ I/O และไดรเวอร์
- ไม่มี I/O, ไดรเวอร์ หรืออุปกรณ์เสมือน → ป้องกันการลดลงของประสิทธิภาพ
- ใช้เฉพาะทรัพยากร CPU → ความเร็วใกล้เคียงเนทีฟ
- การปรับแต่ง Hugepage
- การใช้ hugepage ช่วยลด page walk → เพิ่มประสิทธิภาพ
- ในเวิร์กโหลด LLM ขนาดใหญ่ ทำประสิทธิภาพได้ 99.7% ของเนทีฟ
- การเรียก VM ที่รวดเร็ว
- ลดโอเวอร์เฮดของการเรียกฟังก์ชันจาก guest ให้ต่ำที่สุด
- ประมวลผลข้อมูลได้ด้วยความเร็วระดับ CPU เนทีฟ
ข้อจำกัด
- ไม่สามารถลดจำนวน vCPU ได้
- KVM API ไม่สามารถลดจำนวน vCPU ได้
- งานแบบหลายโปรเซสสามารถแก้ได้ด้วยการรันหลาย VM แบบขนาน
- ปัญหาประสิทธิภาพลดลงขณะรีเซ็ต
- อาจเกิดประสิทธิภาพลดลงเมื่อรีเซ็ตสถานะ VM
- แต่สามารถแก้ได้ด้วยการแชร์และโคลนสถานะ
งานในอนาคต
- เพิ่มการรองรับ Intel TDX และ AMD SEV
- พอร์ตไปยัง AArch64
- เพิ่มความสามารถ memory lock (
KVM_MEM_READONLY) → เสริมความปลอดภัย
- ปรับปรุง API ให้ใช้งานง่ายขึ้น
- เพิ่มการรองรับการโหลด dynamic link → เสริมการผสานรวมกับ Varnish
บทสรุป
- TinyKVM เป็นหนึ่งในโซลูชันแซนด์บ็อกซ์ที่เล็กและเร็วที่สุด
- บรรลุทั้งการเสริมความปลอดภัยและการปรับแต่งประสิทธิภาพ
- โค้ดเบสมีขนาดเล็กจึงดูแลรักษาได้ง่าย
- เปิดให้ใช้งานในรูปแบบไลบรารีโอเพนซอร์ส → หากสนใจสามารถดูได้ที่ที่เก็บโค้ด
คลังเก็บ TinyKVM
2 ความคิดเห็น
แปลกดีนะ
ความคิดเห็นบน Hacker News
ชอบสิ่งนี้มากจริงๆ หวังว่าจะไม่หยุดทำสิ่งที่กำลังทำอยู่ต่อไป
คล้าย Firecracker แต่เร็วกว่ามาก
โพสต์ต้นฉบับ: ลิงก์
น่าสนใจมาก ประสิทธิภาพการกู้คืนสแนปช็อต 2.5us อยู่ในระดับเดียวกับ Wasmtime แต่มีข้อได้เปรียบใหญ่ว่าสามารถรัน native code ได้ อย่างไรก็ตาม มันช้ากว่ามาก แต่ก็ยังมีการทำงานร่วมกันได้ในระดับไมโครวินาที
โดยพื้นฐานแล้วมันไม่ใช่อะไรประมาณ libkrun หรอกหรือ? ลิงก์
แม้นี่จะไม่ใช่ use case ที่ตั้งใจไว้โดยตรง แต่มีใครเคยลองรัน X server (หรือ Wayland) ไหม?
น่าสนใจ แต่กำลังลำบากในการทำความเข้าใจภาพรวมใหญ่ มันคือการรัน user process ใน VM โดยไม่มีเคอร์เนลหรือ? system call ทั้งหมดจะทำให้ VM จบการทำงานแล้วพร็อกซีไปยังโฮสต์หรือ? หรือว่าไม่มี system call เลย?
ถ้าเหมาะกับ use case ก็เจ๋งมากจริงๆ
เจ๋งมาก
ในบทความไม่ได้บอกว่ามันรันอยู่บน Varnish และจริงๆ แล้วผู้เขียนก็บอกด้วยว่ามันไม่ได้มีไว้เพื่อให้ Varnish รันบนมัน