Я решил ради интереса создать собственный рантайм контейнеров, и хотя я пока в начале пути, я понял, что Docker странный. Вот несколько странных вещей, которые я узнал о Docker.
Контейнеров не существует в реальности. В отличие от виртуальных машин, контейнеры — это просто процессы с особыми ограничениями. Ваше ядро по-прежнему выполняет этот процесс, и его можно найти в /proc. Не существует единой функции контейнеров Linux — контейнеры на самом деле представляют собой 5 разных функций ядра Linux, закутанных в плащ. Пространства имён скрывают то, что видно хосту и контейнеру, cgroups ограничивают использование ресурсов, а сетевая магия изолирует сеть контейнера.
Образы — это просто папки. Docker помещает их куда-то и вызывает chroot (или pivot_root), чтобы сделать эту папку новым корневым каталогом контейнера. Go — довольно ужасный язык для рантайма контейнеров. Рантайм Docker, runc, написан на Go, и архитектурные решения Go делают его менее подходящим. Рантайм Go изначально многопоточный, но многим системным вызовам Linux нужна однопоточная среда, поэтому в runc есть модуль на C, который запускается до инициализации Go. В Go также нет fork, поэтому runc выполняет exec /proc/self/exe, чтобы приблизительно имитировать fork.
Docker требует root. Многим API ядра Linux нужны права root, поэтому демон Docker обычно работает от root. Рантаймы без root могут быть вынуждены заново реализовать весь сетевой стек в пространстве пользователя. Учиться интересно! Написание собственной версии инструмента, которым вы пользуетесь, — отличный способ его понять.
Источник: Hacker News · Сводку подготовил HeadlinesBriefing