Docker 내부 구조 정리: 컨테이너는 커널 기능 5개를 묶은 일반 프로세스임
- 컨테이너는 VM과 달리 호스트 커널이 그대로 실행하는 일반 프로세스에 제약을 건 것이라 호스트의 /proc에서도 찾을 수 있음
- 컨테이너를 만드는 Linux 커널 기능은 하나가 아니라 5개이고, 네임스페이스는 보이는 범위를, cgroups는 자원 사용량을 제한함
- 이미지는 Docker가 폴더로 풀어 둔 뒤 chroot나 pivot_root로 그 폴더를 프로세스의 새 루트 디렉터리로 바꾸는 방식임
- runc는 Go 런타임이 멀티스레드라 시스템 콜 처리가 어려워서 Go 초기화 전에 도는 C 모듈(nsenter)을 쓰고, Go에 fork가 없어 /proc/self/exe를 특수 인자로 실행해 fork를 흉내 냄
- Docker 데몬은 보통 root로 돌고, 루트리스 런타임은 네트워킹 스택을 유저스페이스에서 다시 구현해야 해서 네트워킹이 가장 큰 예외임
Hacker News 의견들
Docker 만든 사람인데 이 글 보고 들어왔음. 옛날 설계 얘기는 궁금한 거 있으면 물어봐도 됨.
Docker를 망치로 쓰고 모든 문제를 못으로 보는 경향이 있는 거 아님? 원래 어떤 용도로 생각하고 만들었는지 궁금함.
rootless Podman은 fork-exec 방식으로 컨테이너를 띄움. root도 없고 데몬도 없고 소켓도 없음. LWN 네임스페이스 시리즈도 같이 보면 좋음.
Liz Rice의 Containers From Scratch 발표도 같은 얘기를 다룸. 한 번 보면 감 잡힘.
bocker라고 bash 100줄 정도로 Docker를 구현한 프로젝트가 있는데 글 내용을 아주 명확하게 보여줌.
초창기에 고루틴이 스레드를 옮겨 다녀서 네임스페이스랑 cgroup 설정이 꼬이는 문제가 있었음. 네트워크 네임스페이스가 가끔 정리 안 돼서 이미지 pull이 막히기도 했음.
유저랜드 스레드 라이브러리는 직접 만들면 안 됨. 근데 거의 모든 언어가 그걸 어기고 있더라.
글에 나온 것들이 나한테는 다 자연스러운데, 나이 먹어서 호기심이 줄어든 건가 싶음.