Nitro: ระบบ init และตัวควบคุมดูแลโปรเซสขนาดเล็กและยืดหยุ่น
(git.vuxu.org)- Nitro คือ ตัวควบคุมดูแลโปรเซสและระบบ init ขนาดจิ๋วมาก ที่ใช้งานได้กับทั้งระบบฝังตัว เซิร์ฟเวอร์ เดสก์ท็อป และคอนเทนเนอร์
- เก็บสถานะของระบบไว้ใน RAM เท่านั้น จึงทำงานได้อย่างราบรื่นแม้บนระบบไฟล์แบบอ่านอย่างเดียว พร้อมมอบ สถาปัตยกรรมแบบ event-driven ที่รวดเร็วและมีประสิทธิภาพ
- รูปแบบการตั้งค่าคือโครงสร้างไดเรกทอรีสคริปต์ที่เรียบง่าย จึงจัดการบริการได้โดยไม่ต้องมีไฟล์ตั้งค่าที่ซับซ้อนหรือขั้นตอน build เพิ่มเติม
- รองรับ บริการแบบพารามิเตอร์ การรีสตาร์ตที่ทนทาน และความสามารถด้าน logging ที่เชื่อถือได้สำหรับแต่ละบริการ รวมถึง ฟีเจอร์ที่เหมาะกับคอนเทนเนอร์และสภาพแวดล้อมแบบฝังตัว
- รับประกัน ความยืดหยุ่นและการควบคุมระดับสูง ด้วย การควบคุมจากระยะไกลผ่านเครื่องมือ nitroctl และการควบคุมการทำงานด้วยสัญญาณ
ภาพรวม
Nitro คือ ตัวควบคุมดูแลโปรเซสขนาดจิ๋วมาก ที่สามารถใช้เป็น pid 1 บน Linux ได้
ขอบเขตการใช้งานหลักมีดังนี้
- init สำหรับเครื่อง Linux หลากหลายประเภท เช่น ระบบฝังตัว เดสก์ท็อป และเซิร์ฟเวอร์
- init ของ Linux initramfs
- init สำหรับสภาพแวดล้อมคอนเทนเนอร์ เช่น Docker/Podman/LXC/Kubernetes
- เดมอน supervision ที่ทำงานได้โดยไม่ต้องใช้สิทธิ์บนระบบ POSIX
การตั้งค่าใช้โครงสร้างสคริปต์แบบอิงไดเรกทอรี โดยตำแหน่งเริ่มต้นคือ /etc/nitro
ข้อกำหนด
- ต้องการการรองรับ Unix socket ของเคอร์เนล
- ต้องมี
tmpfsหรือ ไดเรกทอรี/runที่เขียนได้
ข้อดีเมื่อเทียบกับระบบอื่น
- ข้อมูลสถานะทั้งหมด ถูกเก็บไว้ใน RAM เท่านั้น จึงทำงานได้บน root filesystem แบบอ่านอย่างเดียวโดยไม่ต้องใช้เทคนิคพิเศษ
- ให้ประสิทธิภาพด้วย รูปแบบการทำงานแบบ event-driven ที่ไม่มีการ polling
- ไม่มีการจัดสรรหน่วยความจำแบบไดนามิก ระหว่างรันไทม์
- ไม่มีการใช้ file descriptor เพิ่มขึ้นอย่างไม่จำกัด
- ต้องการเพียง ไบนารีแบบ self-contained ตัวเดียว (อาจมีไบนารีควบคุมเพิ่มเป็นตัวเลือก)
- ไม่ต้องแปลงหรือคอมไพล์ไฟล์ตั้งค่า บริการเป็นเพียง ไดเรกทอรีธรรมดาที่มีสคริปต์อยู่ภายใน
- รองรับ การรีสตาร์ตบริการและสายโซ่ logging
- ทำงานได้ตามปกติแม้นาฬิการะบบจะไม่แม่นยำ
- สามารถรันผ่าน
/etc/ttysบน FreeBSD ได้ - สามารถสร้าง static binary ขนาดเล็กมากได้เมื่อใช้ musl libc
การจัดการบริการ
-
แต่ละไดเรกทอรีบริการ (ค่าเริ่มต้นอยู่ภายใน
/etc/nitro) อาจมีไฟล์ต่อไปนี้setup: สคริปต์ (ทางเลือก) ที่รันก่อนเริ่มบริการ จะเริ่มบริการได้ก็ต่อเมื่อจบแบบปกติ (0) เท่านั้นrun: สคริปต์สำหรับการทำงานของบริการ ตราบใดที่ยังไม่จบจะถือว่าบริการยังทำงานอยู่ หากยังไม่ถูกติดตั้งจะถือเป็นบริการแบบ one-shotfinish: สคริปต์ (ทางเลือก) ที่รันหลังrunจบลง โดยส่งสถานะการจบและค่าสัญญาณเป็นอาร์กิวเมนต์log: symbolic link ที่ชี้ไปยังไดเรกทอรีบริการอื่น โดยจะ pipe เอาต์พุตของ run ไปเป็นอินพุตของบริการนั้น (ใช้ทำ logging chain ได้)down: หากไฟล์นี้มีอยู่ nitro จะไม่ยกบริการนี้ขึ้นโดยค่าเริ่มต้น- หากชื่อไดเรกทอรีลงท้ายด้วย '@' จะถูกมองข้ามและนำไปใช้เป็นบริการแบบพารามิเตอร์ได้
- ชื่อบริการต้องยาวน้อยกว่า 64 ตัวอักษร และห้ามมีอักขระ
/,,, ขึ้นบรรทัดใหม่
-
ยูทิลิตี
chpstของ runit มีประโยชน์ในการเขียนสคริปต์run
บริการพิเศษ
LOG: บริการค่าเริ่มต้นสำหรับบันทึก log ของทุกบริการที่ไม่มีลิงก์ logSYS:SYS/setupจะถูกรันก่อนเริ่มทุกบริการ จึงใช้สร้างลำดับการเริ่มบริการได้SYS/finish: รันก่อนเข้าสู่ขั้นตอนปิดระบบทั้งหมดSYS/final: รันหลังจากทุกโปรเซสถูกปิดแล้วSYS/fatal: รันแทนการปิดเมื่อเกิดข้อผิดพลาดร้ายแรง (ถ้ามี)SYS/reincarnate: รันแทน shutdown และอาจใช้สำหรับการสร้าง initramfs ขึ้นใหม่ เป็นต้น
บริการแบบพารามิเตอร์
- ไดเรกทอรีบริการที่ลงท้ายด้วย '@' จะถูก nitro มองข้าม แต่สามารถระบุใช้งานได้โดยตรงผ่าน symbolic link หรือคำสั่ง
nitroctl - พารามิเตอร์ที่ต่อท้ายหลัง '@' จะถูกส่งเป็นอาร์กิวเมนต์ตัวแรกให้แต่ละสคริปต์
- ตัวอย่าง: หากมี symbolic link
agetty@/runและagetty@tty1จะมีการรันagetty@/run tty1 - เมื่อป้อน
nitroctl up agetty@tty2ก็สามารถรันagetty@/run tty2ได้ (ไม่ขึ้นกับว่ามีไดเรกทอรีอยู่หรือไม่)
- ตัวอย่าง: หากมี symbolic link
โหมดการทำงาน
- วงจรชีวิตทั้งหมดประกอบด้วย 3 ขั้นตอนคือ บูต รันบริการ (supervision) และปิดระบบ
- บูต: หากมีบริการพิเศษ
SYSจะรันตั้งแต่setupก่อน แล้วจึงรันทุกบริการที่ไม่ใช่ down - หากบริการจบลงจะถูกรีสตาร์ตใหม่ แต่ถ้าเพิ่งรีสตาร์ตไปไม่นานจะรอ 2 วินาที
- สามารถส่งสัญญาณปิดระบบได้ด้วย
nitroctl RebootหรือShutdown- ในกรณีนี้จะเป็นลำดับ
SYS/finish→ ส่ง SIGTERM ให้ทุกบริการ (รอได้สูงสุด 7 วินาที) → SIGKILL →SYS/final→ ลำดับการปิด
- ในกรณีนี้จะเป็นลำดับ
- หากใช้กับคอนเทนเนอร์หรือ supervisor ที่ไม่ใช้สิทธิ์ จะปิดเฉพาะโปรเซสเท่านั้น
- บูต: หากมีบริการพิเศษ
การควบคุมด้วย nitroctl
- เครื่องมือ CLI nitroctl ใช้ควบคุม nitro จากระยะไกลได้
ตัวอย่างคำสั่ง:
- list: แสดงรายการบริการ สถานะ PID uptime และสถานะการจบล่าสุด
- up/down/start/stop/restart: ควบคุมการเริ่ม·หยุด·รีสตาร์ตบริการ เป็นต้น
- การส่งสัญญาณ: p(SIGSTOP), c(SIGCONT), h(SIGHUP), a(SIGALRM), i(SIGINT), q(SIGQUIT), 1(SIGUSR1), 2(SIGUSR2), t(SIGTERM), k(SIGKILL)
- pidof: แสดง PID ของบริการที่ระบุ
- rescan: อ่านไดเรกทอรีบริการใหม่ และสะท้อนบริการที่ถูกเพิ่มหรือลบ
- Shutdown/Reboot: ปิดหรือรีบูตทั้งระบบ
การควบคุมผ่านสัญญาณ
- สามารถควบคุมได้ด้วยการส่งสัญญาณตรงไปยังโปรเซส nitro
- SIGHUP: สแกนบริการใหม่ (rescan)
- SIGINT: รีบูต
- SIGTERM: ปิดระบบ (หาก nitro ไม่ใช่ pid 1)
Nitro ในฐานะ init บน Linux
- Nitro เป็นไบนารีแบบบรรจุครบในตัวและสามารถบูตเป็น Linux pid 1 ได้โดยตรง
- จะเมานต์
/dev,/runเมื่อต้องการ และให้จัดการการทำงานอื่น ๆ ในSYS/setup - อีเวนต์ Ctrl-Alt-Del จะทริกเกอร์การรีบูตอย่างเป็นระเบียบ
การใช้ Nitro เป็น init ในคอนเทนเนอร์ Docker
- Nitro สามารถ build แบบ static และใส่ลงในคอนเทนเนอร์ได้อย่างง่ายดาย
- ต้องมี
/runอยู่ในคอนเทนเนอร์เพื่อใช้พาธซ็อกเก็ตเริ่มต้น - หากทำ bind mount ให้ control socket ก็จะควบคุมจากภายนอกด้วย nitroctl จากระยะไกลได้
Nitro บน FreeBSD
- สามารถให้ FreeBSD init ดูแล nitro ได้ด้วยการเพิ่มบรรทัดต่อไปนี้ใน
/etc/ttys/etc/nitro "/usr/local/sbin/nitro" "" on
ผู้เขียน
- Leah Neukirchen leah@vuxu.org
คำขอบคุณ
- พัฒนาขึ้นจากการวิเคราะห์อย่างละเอียดของ ระบบควบคุมดูแลโปรเซส ที่มีอยู่เดิม เช่น daemontools, freedt, runit, perp, s6 เป็นต้น
สัญญาอนุญาต
- สัญญาอนุญาต 0BSD (ดูรายละเอียดในไฟล์ LICENSE)
ยังไม่มีความคิดเห็น