runit와의 비교를 보고 싶음. runit는 극도로 미니멀하면서도 거의 완전한 init 시스템임. 컨트롤 디렉터리, 선언적(declarative)이 아닌 의존성, 비슷한 스크립트 구성, 로깅 접근 방식 등 비슷한 점이 많음. 설명 페이지에도 runit 이야기가 잠깐 나오며 chpst 유틸을 함께 쓰는 것을 추천함. 차별점으로는 하나의 서비스 디렉터리로 여러 유사 프로세스(예: agetty)를 파라미터화하여 관리하는 구조가 좋다고 생각함. reboot나 shutdown을 단일 바이너리(nitroctl)로 바로 실행할 수 있음. 반면 runit는 여러 개의 바이너리 구조임
지난 해 runit로 프로세스를 관리하던 마지막 서버들을 은퇴시키면서 아쉬움이 컸음. 약 15년 전에 처음 runit 서비스를 직접 짜면서 이게 리눅스에서 서비스 관리하는 표준 방식이라 믿었음. 이후 5년간 리눅스를 떠나 있다 돌아오니 systemd가 기본이 되어 있었고, 나쁜 평을 여러 번 들었지만 점차 왜곡된 반감이 많다는 걸 알게 되었음. 현재는 파충류 vivarium에서 Pi Zero로 카메라와 온도 데이터 스트리밍 서비스를 돌리고 있는데 systemd로 세팅하는 것이 굉장히 쉬웠음. OpenSuse 데스크톱이나 업무용 노트북에서도 systemd로 다양한 서비스를 간단하게 운용할 수 있었음. ‘표준이 있다는 건 오히려 좋은 일’이란 생각이 듦
Leah Neukirchen은 Void Linux 커뮤니티에서 활발히 활동하는 분임. 이 프로젝트가 Void와 밀접히 연관될 것으로 예상함. 좀 더 공식적으로 Void에서 nitro를 사용하는 방법에 대한 글을 써줬으면 좋겠음
“선언적(declarative) 의존성이 없다”는 점이 장점이라는 것인지 궁금함. systemd를 init로 비판하는 의견은 많이 들어봤지만 선언적 설계 자체를 비판하는 경우는 드물었음. 이유가 있는지 자세히 듣고 싶음
Void Linux에서 runit를 접하게 되어 init 시스템으로 잘 쓰고 있지만, UI와 문서화가 부족한 점이 아쉬웠음. 특히 로깅 설정이 정말 어려웠음. 비슷하게 단순하지만 더 합리적 기본값, 더 직관적인 UI, 더 나은 문서를 가진 대안을 써보고 싶음
컨테이너에서 init 시스템을 돌리자는 이야기를 볼 때마다 항상 고민임. 실제로 필요에 의해 설계하는 경우도 있지만, 오히려 너무 복잡하게 만드는 경우가 자주 보였음 (특히 Kubernetes, 클라우드 환경에서 실제로 분리 설계를 더 제대로 했어야 함). ‘어차피 다들 이렇게 쓰니까’라는 게 현상인 것 같기도 한데, 굳이 ‘더 잘 만들겠다’면서 문제가 퍼지는 게 나은지, 아니면 기존 솔루션으로 격하게 실패하도록 내버려두는 게 나은지 항상 애매함
어플리케이션 컨테이너는 유닉스 철학 ‘한 가지 일만 잘하라’를 따라야 한다고 생각함. 그런데 컨테이너에서 어떤 이유로든 fork를 한다면, PID 1에 진짜 init가 있어야 한다고 봄
로보틱스 분야에서 겪은 바로는, 많은 컨테이너가 본래 베어메탈에서 돌던 복잡한 시스템이 컨테이너로 옮겨온 경우임. 프로세스간에 비구조화된 RPC가 많아 굳이 여러 개의 별도 컨테이너로 잘게 쪼갤 메리트가 없음. monolithic 앱 컨테이너 내부에서 여러 프로세스를 띄우기엔 supervisor, runit, systemd, tmux까지 각양각색 옵션들이 통용됨
Fly.io, Render, Google Cloud Run처럼 컨테이너 단위로 과금하는 호스팅을 사용한 적 있음. 가격 때문에 한 컨테이너에 여러 프로세스를 띄워야 할 때가 종종 있음
NixOS의 새로운 기능인 modular-services가 Nixpkgs에 포함되었음. 새로운 init 시스템 혹은 새 커널로 NixOS 포팅이 훨씬 쉬워질 예정이라, 지금이 nitro 같은 실험을 해보기 좋은 시기라고 생각함
Nitro는 선언적으로 서비스 의존성을 다루지 않음. 명령 하나로 서비스 간의 의존 그래프를 예쁘게 보는 게 불가능함. 하지만 setup 스크립트에서 필요한 서비스를 명시해두면 해당 서비스가 떠있는지 확인하고 자동으로 기다렸다 리트라이 함. 의존성 그래프를 보려면 grep 같은 걸로 스크립트를 직접 짜는 수밖에 없음. 반면 서비스가 죽을 때 연쇄적으로 dependent 서비스도 제대로 내리는 걸 깜빡하기 쉬운데, nitro 자체로는 이런 걸 탐지할 편리한 방법이 없음
이런 저수준 프로젝트들을 보면 정말 흥미로움. systemd가 전통적인 SysV·POSIX 틀을 넘어서 리눅스 커널 특화 기능을 잘 활용한 점이 좋았음. 하지만 그게 끝이 아니길 바라고, 계속해서 새로운 아이디어와 혁신이 나와주었으면 함. 최근 직접 제조용 자동화에서 UEFI 펌웨어로부터 바로 netboot되는 Linux 커널에 Go로 직접 짠 단일 init 바이너리만 내장한 셋업을 구현해봄. 직접 가져온 코드와 고수준 언어만으로 OS 환경을 다 제어하니 각종 서브프로세스와 수많은 텍스트 설정파일을 관리할 필요 없다는 점이 정말 자유로웠음
약 13년 전에 C로 직접 init 시스템을 구축한 경험이 있음. 예정보다 훨씬 많은 노력이 필요했고, GUI와 백엔드를 성능 낮은 하드웨어에서 빠르게 부팅시키는 데 사용함. 재미있는 프로그래밍 연습이었으나 이미 비슷한 솔루션이 존재했을지도 모르겠다는 자각이 나중에 들었음. 동료가 같은 회사에서 또 다른 init을 만드는 바람에 내 첫 버전은 거의 libc 외에 의존성 없이 가벼웠지만, 동료의 버전은 libevent 기반으로 더 고급 기능이 많았음
Distrust에서 rust로 500라인 이하의 초간단 init 시스템을 직접 작성해서, 보안 필수 enclave 환경에서 몇몇 클라이언트가 실서비스로 사용 중임. rust 표준 라이브러리만 써서 감사를 매우 쉽게 했음 https://git.distrust.co/public/nit
깔끔해 보이지만(nit보다 33% 더 큼), readme에는 빌드 방법만 나와 있고, 실제 인터페이스나 작동 방식은 설명이 없음
의존성 지정 불가, 유저/그룹 설정 없음, 순서 수동 지정 필요, 병렬 서비스 실행 없음, 리소스 관리 없음. 이런 게 빠진 시스템을 init 시스템이라고 부르지 않았으면 함. 그냥 베어본 process supervisor임
실제로 이 모든 기능을 잘 해냄(심지어 systemd보다 더 나았다는 경험임). 나는 nitro 대신 오랜 기간 daemontools(그리고 nitro는 그 계승)만을 써왔음. 사용법이 믿을 수 없이 쉽고 안정적이고, 이해하기 쉬움. 의존성 문제에 대해서도 ‘요건 각자 알아서, 대신 간단·저렴·신뢰성 좋은 툴을 제공합니다’라는 djb/daemontools 스타일이 훨씬 실무적임
Hacker News 의견
runit와의 비교를 보고 싶음. runit는 극도로 미니멀하면서도 거의 완전한 init 시스템임. 컨트롤 디렉터리, 선언적(declarative)이 아닌 의존성, 비슷한 스크립트 구성, 로깅 접근 방식 등 비슷한 점이 많음. 설명 페이지에도 runit 이야기가 잠깐 나오며 chpst 유틸을 함께 쓰는 것을 추천함. 차별점으로는 하나의 서비스 디렉터리로 여러 유사 프로세스(예: agetty)를 파라미터화하여 관리하는 구조가 좋다고 생각함. reboot나 shutdown을 단일 바이너리(nitroctl)로 바로 실행할 수 있음. 반면 runit는 여러 개의 바이너리 구조임
지난 해 runit로 프로세스를 관리하던 마지막 서버들을 은퇴시키면서 아쉬움이 컸음. 약 15년 전에 처음 runit 서비스를 직접 짜면서 이게 리눅스에서 서비스 관리하는 표준 방식이라 믿었음. 이후 5년간 리눅스를 떠나 있다 돌아오니 systemd가 기본이 되어 있었고, 나쁜 평을 여러 번 들었지만 점차 왜곡된 반감이 많다는 걸 알게 되었음. 현재는 파충류 vivarium에서 Pi Zero로 카메라와 온도 데이터 스트리밍 서비스를 돌리고 있는데 systemd로 세팅하는 것이 굉장히 쉬웠음. OpenSuse 데스크톱이나 업무용 노트북에서도 systemd로 다양한 서비스를 간단하게 운용할 수 있었음. ‘표준이 있다는 건 오히려 좋은 일’이란 생각이 듦
runit와 nitro의 적절한 미니멀 비교가 2024년에 발표된 Leah Neukirchen의 발표 슬라이드(PDF)에 있음
https://leahneukirchen.org/talks/#nitroyetanotherinitsy
Leah Neukirchen은 Void Linux 커뮤니티에서 활발히 활동하는 분임. 이 프로젝트가 Void와 밀접히 연관될 것으로 예상함. 좀 더 공식적으로 Void에서 nitro를 사용하는 방법에 대한 글을 써줬으면 좋겠음
“선언적(declarative) 의존성이 없다”는 점이 장점이라는 것인지 궁금함. systemd를 init로 비판하는 의견은 많이 들어봤지만 선언적 설계 자체를 비판하는 경우는 드물었음. 이유가 있는지 자세히 듣고 싶음
Void Linux에서 runit를 접하게 되어 init 시스템으로 잘 쓰고 있지만, UI와 문서화가 부족한 점이 아쉬웠음. 특히 로깅 설정이 정말 어려웠음. 비슷하게 단순하지만 더 합리적 기본값, 더 직관적인 UI, 더 나은 문서를 가진 대안을 써보고 싶음
컨테이너에서 init 시스템을 돌리자는 이야기를 볼 때마다 항상 고민임. 실제로 필요에 의해 설계하는 경우도 있지만, 오히려 너무 복잡하게 만드는 경우가 자주 보였음 (특히 Kubernetes, 클라우드 환경에서 실제로 분리 설계를 더 제대로 했어야 함). ‘어차피 다들 이렇게 쓰니까’라는 게 현상인 것 같기도 한데, 굳이 ‘더 잘 만들겠다’면서 문제가 퍼지는 게 나은지, 아니면 기존 솔루션으로 격하게 실패하도록 내버려두는 게 나은지 항상 애매함
어플리케이션 컨테이너는 유닉스 철학 ‘한 가지 일만 잘하라’를 따라야 한다고 생각함. 그런데 컨테이너에서 어떤 이유로든 fork를 한다면, PID 1에 진짜 init가 있어야 한다고 봄
로보틱스 분야에서 겪은 바로는, 많은 컨테이너가 본래 베어메탈에서 돌던 복잡한 시스템이 컨테이너로 옮겨온 경우임. 프로세스간에 비구조화된 RPC가 많아 굳이 여러 개의 별도 컨테이너로 잘게 쪼갤 메리트가 없음. monolithic 앱 컨테이너 내부에서 여러 프로세스를 띄우기엔 supervisor, runit, systemd, tmux까지 각양각색 옵션들이 통용됨
Fly.io, Render, Google Cloud Run처럼 컨테이너 단위로 과금하는 호스팅을 사용한 적 있음. 가격 때문에 한 컨테이너에 여러 프로세스를 띄워야 할 때가 종종 있음
NixOS의 새로운 기능인 modular-services가 Nixpkgs에 포함되었음. 새로운 init 시스템 혹은 새 커널로 NixOS 포팅이 훨씬 쉬워질 예정이라, 지금이 nitro 같은 실험을 해보기 좋은 시기라고 생각함
Chimera Linux에서 쓰고 있는 dinit과 nitro를 비교해보고 싶음. readme를 빠르게 훑어보니 서비스 의존성 관리가 아직 안되는 것 같아 보임
dinit: https://github.com/davmac314/dinit
Nitro는 선언적으로 서비스 의존성을 다루지 않음. 명령 하나로 서비스 간의 의존 그래프를 예쁘게 보는 게 불가능함. 하지만 setup 스크립트에서 필요한 서비스를 명시해두면 해당 서비스가 떠있는지 확인하고 자동으로 기다렸다 리트라이 함. 의존성 그래프를 보려면 grep 같은 걸로 스크립트를 직접 짜는 수밖에 없음. 반면 서비스가 죽을 때 연쇄적으로 dependent 서비스도 제대로 내리는 걸 깜빡하기 쉬운데, nitro 자체로는 이런 걸 탐지할 편리한 방법이 없음
Artix Linux에서 dinit을 써봤는데 정말 가볍고 인상적이었음
Artix FAQ: https://artixlinux.org/faq.php
이런 저수준 프로젝트들을 보면 정말 흥미로움. systemd가 전통적인 SysV·POSIX 틀을 넘어서 리눅스 커널 특화 기능을 잘 활용한 점이 좋았음. 하지만 그게 끝이 아니길 바라고, 계속해서 새로운 아이디어와 혁신이 나와주었으면 함. 최근 직접 제조용 자동화에서 UEFI 펌웨어로부터 바로 netboot되는 Linux 커널에 Go로 직접 짠 단일 init 바이너리만 내장한 셋업을 구현해봄. 직접 가져온 코드와 고수준 언어만으로 OS 환경을 다 제어하니 각종 서브프로세스와 수많은 텍스트 설정파일을 관리할 필요 없다는 점이 정말 자유로웠음
약 13년 전에 C로 직접 init 시스템을 구축한 경험이 있음. 예정보다 훨씬 많은 노력이 필요했고, GUI와 백엔드를 성능 낮은 하드웨어에서 빠르게 부팅시키는 데 사용함. 재미있는 프로그래밍 연습이었으나 이미 비슷한 솔루션이 존재했을지도 모르겠다는 자각이 나중에 들었음. 동료가 같은 회사에서 또 다른 init을 만드는 바람에 내 첫 버전은 거의 libc 외에 의존성 없이 가벼웠지만, 동료의 버전은 libevent 기반으로 더 고급 기능이 많았음
AWS Nitro와 이름과 기능이 겹친다는 점이 신경 쓰임
https://docs.aws.amazon.com/whitepapers/latest/security-design-of-aws-nitro-system/the-nitro-system-journey.html
이름만 겹칠 뿐, init 시스템과 하이퍼바이저는 근본적으로 완전히 다름
문제 생길 일은 거의 없다고 봄. 하나는 누구나 쓸 수 있는 init 시스템이고, AWS Nitro는 기업 내부에서만 쓰는 KVM 포크임
s6와 비교해 nitro가 어떤지 궁금함. 최근 도커 컨테이너에 s6로 init 시스템을 구성해봤는데, s6-overlay로 많은 파일을 직접 만들어야 했고 생각보다 직관적이지 않았음
tini도 체크해볼 만함: https://github.com/krallin/tini
Distrust에서 rust로 500라인 이하의 초간단 init 시스템을 직접 작성해서, 보안 필수 enclave 환경에서 몇몇 클라이언트가 실서비스로 사용 중임. rust 표준 라이브러리만 써서 감사를 매우 쉽게 했음
https://git.distrust.co/public/nit
의존성 지정 불가, 유저/그룹 설정 없음, 순서 수동 지정 필요, 병렬 서비스 실행 없음, 리소스 관리 없음. 이런 게 빠진 시스템을 init 시스템이라고 부르지 않았으면 함. 그냥 베어본 process supervisor임