0 added
0 removed
Original
2026-01-01
Modified
2026-02-19
1
<p>Всем привет, меня зовут Дмитрий Желудков, я архитектор по эксплуатации в одной корпорации, а ещё один из авторов курса учебного центра Слёрм "Docker для админов и разработчиков". Сегодня мы заглянем под капот и разберёмся, на каких китах держится вся эта магия.</p>
1
<p>Всем привет, меня зовут Дмитрий Желудков, я архитектор по эксплуатации в одной корпорации, а ещё один из авторов курса учебного центра Слёрм "Docker для админов и разработчиков". Сегодня мы заглянем под капот и разберёмся, на каких китах держится вся эта магия.</p>
2
<h4>Зачем это знать?</h4>
2
<h4>Зачем это знать?</h4>
3
<p>На незаданный вопрос я смело отвечу: чтобы перестать бояться. Когда вы понимаете, что происходит внутри, вы перестаёте воспринимать Docker как "волшебный чёрный ящик", который просто работает. Вы начинаете грамотно диагностировать проблемы, осознанно выбирать инструменты и, в конечном счёте, строить более надёжные и эффективные системы. Это знание - суперсиньор-скилл, который отделяет "админа, который умеет в докер" до "архитектора, который понимает, как это работает".</p>
3
<p>На незаданный вопрос я смело отвечу: чтобы перестать бояться. Когда вы понимаете, что происходит внутри, вы перестаёте воспринимать Docker как "волшебный чёрный ящик", который просто работает. Вы начинаете грамотно диагностировать проблемы, осознанно выбирать инструменты и, в конечном счёте, строить более надёжные и эффективные системы. Это знание - суперсиньор-скилл, который отделяет "админа, который умеет в докер" до "архитектора, который понимает, как это работает".</p>
4
<h2>Слоёный пирог: из чего на самом деле состоит Docker</h2>
4
<h2>Слоёный пирог: из чего на самом деле состоит Docker</h2>
5
<p>Давайте разберёмся, что происходит, когда вы даёте команду docker run nginx.</p>
5
<p>Давайте разберёмся, что происходит, когда вы даёте команду docker run nginx.</p>
6
<h4>1. Docker CLI и Демон: начало пути</h4>
6
<h4>1. Docker CLI и Демон: начало пути</h4>
7
<p>Вы вводите команду в терминале. Эту команду подхватывает Docker CLI (клиент) и через REST API передаёт её Docker Daemon (dockerd) - главному управляющему, который и выполняет всю тяжёлую работу.</p>
7
<p>Вы вводите команду в терминале. Эту команду подхватывает Docker CLI (клиент) и через REST API передаёт её Docker Daemon (dockerd) - главному управляющему, который и выполняет всю тяжёлую работу.</p>
8
<h4>2. Контейнерный рантайм: containerd в игре</h4>
8
<h4>2. Контейнерный рантайм: containerd в игре</h4>
9
<p>Демон сам не умеет запускать контейнеры. Для этого у него есть более низкоуровневый помощник - containerd. Его главная задача - управлять жизненным циклом контейнеров: загружать образы, создавать, запускать и удалять контейнеры. В 2017 году containerd был выделен из состава Docker в самостоятельный проект и передан под опеку Cloud Native Computing Foundation (CNCF).</p>
9
<p>Демон сам не умеет запускать контейнеры. Для этого у него есть более низкоуровневый помощник - containerd. Его главная задача - управлять жизненным циклом контейнеров: загружать образы, создавать, запускать и удалять контейнеры. В 2017 году containerd был выделен из состава Docker в самостоятельный проект и передан под опеку Cloud Native Computing Foundation (CNCF).</p>
10
<h4>3. OCI и runc: стандарт и его исполнитель</h4>
10
<h4>3. OCI и runc: стандарт и его исполнитель</h4>
11
<p>Containerd, в свою очередь, обращается к runc. Это и есть тот самый фундамент - легковесная утилита, которая непосредственно создаёт и запускает контейнеры. Runc - эталонная реализация стандарта OCI (Open Container Initiative).</p>
11
<p>Containerd, в свою очередь, обращается к runc. Это и есть тот самый фундамент - легковесная утилита, которая непосредственно создаёт и запускает контейнеры. Runc - эталонная реализация стандарта OCI (Open Container Initiative).</p>
12
<p><em>Историческая справка: OCI - это организация, созданная для выработки единых стандартов на форматы контейнерных образов и рантаймов. Это был ответ индустрии на доминирование Docker. Стандартизация позволила создать экосистему взаимозаменяемых компонентов.</em>Итак, цепочка выглядит так:</p>
12
<p><em>Историческая справка: OCI - это организация, созданная для выработки единых стандартов на форматы контейнерных образов и рантаймов. Это был ответ индустрии на доминирование Docker. Стандартизация позволила создать экосистему взаимозаменяемых компонентов.</em>Итак, цепочка выглядит так:</p>
13
<p>docker run → Docker CLI → Docker Daemon (dockerd) → containerd → runc → контейнер</p>
13
<p>docker run → Docker CLI → Docker Daemon (dockerd) → containerd → runc → контейнер</p>
14
<h2>Магия под капотом: namespaces, cgroups и OverlayFS</h2>
14
<h2>Магия под капотом: namespaces, cgroups и OverlayFS</h2>
15
<p>А что же делает runc? Вот тут начинается самая соль! Представьте, что runc - это такой супер-прораб на стройке контейнера. У него нет своих материалов, но он мастерски использует то, что ему предоставляет ядро Linux. Он берет три кита и строит из них нашу "песочницу":</p>
15
<p>А что же делает runc? Вот тут начинается самая соль! Представьте, что runc - это такой супер-прораб на стройке контейнера. У него нет своих материалов, но он мастерски использует то, что ему предоставляет ядро Linux. Он берет три кита и строит из них нашу "песочницу":</p>
16
<h4>1. Namespaces (пространства имён) - виртуальные миры</h4>
16
<h4>1. Namespaces (пространства имён) - виртуальные миры</h4>
17
<p>Это не просто "изоляция", это создание параллельной реальности для вашего приложения. Каждый namespace - это своя маленькая вселенная:</p>
17
<p>Это не просто "изоляция", это создание параллельной реальности для вашего приложения. Каждый namespace - это своя маленькая вселенная:</p>
18
<p><strong>PID namespace:</strong>контейнер думает, что его процесс - это PID 1, король и бог, и не подозревает о существовании других процессов на хосте.</p>
18
<p><strong>PID namespace:</strong>контейнер думает, что его процесс - это PID 1, король и бог, и не подозревает о существовании других процессов на хосте.</p>
19
<p><strong>Network namespace:</strong>к контейнера своя собственная сеть - свой<a>localhost</a>, свои сетевые интерфейсы, свои порты. Когда вы биндите порт 80 в контейнере, он не конфликтует с портом 80 на хосте - потому что это разные миры!</p>
19
<p><strong>Network namespace:</strong>к контейнера своя собственная сеть - свой<a>localhost</a>, свои сетевые интерфейсы, свои порты. Когда вы биндите порт 80 в контейнере, он не конфликтует с портом 80 на хосте - потому что это разные миры!</p>
20
<p><strong>Mount namespace:</strong>создает иллюзию, что у контейнера своя корневая файловая система /, хотя на самом деле это всего лишь папка на диске.</p>
20
<p><strong>Mount namespace:</strong>создает иллюзию, что у контейнера своя корневая файловая система /, хотя на самом деле это всего лишь папка на диске.</p>
21
<p>Контейнер живет в этой матрице и искренне верит, что он один на всей машине.</p>
21
<p>Контейнер живет в этой матрице и искренне верит, что он один на всей машине.</p>
22
<h4>2. Cgroups (контрольные группы) - регуляторы аппетита</h4>
22
<h4>2. Cgroups (контрольные группы) - регуляторы аппетита</h4>
23
<p>Помните того коллегу, который всегда доедает всю пиццу в офисе? Так вот, cgroups - это тот самый мудрый менеджер, который говорит: "Вася, тебе пол-пиццы, и ни кусочка больше!"</p>
23
<p>Помните того коллегу, который всегда доедает всю пиццу в офисе? Так вот, cgroups - это тот самый мудрый менеджер, который говорит: "Вася, тебе пол-пиццы, и ни кусочка больше!"</p>
24
<p>Конкретно:</p>
24
<p>Конкретно:</p>
25
<p>CPU: "Ты можешь использовать только 2 ядра из 16, больше не положено"</p>
25
<p>CPU: "Ты можешь использовать только 2 ядра из 16, больше не положено"</p>
26
<p>Memory: "Вот тебе 512 МБ RAM, превысил - получил OOM Killer"</p>
26
<p>Memory: "Вот тебе 512 МБ RAM, превысил - получил OOM Killer"</p>
27
<p>I/O: "Дисковые операции не больше 100 MB/s, чтобы другим тоже досталось"</p>
27
<p>I/O: "Дисковые операции не больше 100 MB/s, чтобы другим тоже досталось"</p>
28
<p>Без cgroups ваш "скромный" контейнер мог бы безнаказанно сожрать все ресурсы сервера.</p>
28
<p>Без cgroups ваш "скромный" контейнер мог бы безнаказанно сожрать все ресурсы сервера.</p>
29
<h4>3. Union File Systems (OverlayFS) - слоёный пирог файловых систем</h4>
29
<h4>3. Union File Systems (OverlayFS) - слоёный пирог файловых систем</h4>
30
<p>А это вообще магия оптимизации! Представьте, что вы делаете презентацию:</p>
30
<p>А это вообще магия оптимизации! Представьте, что вы делаете презентацию:</p>
31
<p>Базовый образ (Ubuntu) - это ваша стандартная тема оформления слайдов</p>
31
<p>Базовый образ (Ubuntu) - это ваша стандартная тема оформления слайдов</p>
32
<p>RUN apt-get install - вы добавляете новый слайд поверх</p>
32
<p>RUN apt-get install - вы добавляете новый слайд поверх</p>
33
<p>COPY . /app - добавляете еще один слайд</p>
33
<p>COPY . /app - добавляете еще один слайд</p>
34
<p>Когда вы запускаете 10 контейнеров, они все используют одну и ту же базовую тему (читай - слой), но у каждого поверх свои уникальные слайды. Экономия места - колоссальная! А если один контейнер что-то меняет в файле - он просто создаёт свою копию в верхнем writable-слое, не трогая оригинал.</p>
34
<p>Когда вы запускаете 10 контейнеров, они все используют одну и ту же базовую тему (читай - слой), но у каждого поверх свои уникальные слайды. Экономия места - колоссальная! А если один контейнер что-то меняет в файле - он просто создаёт свою копию в верхнем writable-слое, не трогая оригинал.</p>
35
<h3>CRI-O: Kubernetes говорит: "Нам не нужен весь Docker"</h3>
35
<h3>CRI-O: Kubernetes говорит: "Нам не нужен весь Docker"</h3>
36
<p>С появлением Kubernetes началась настоящая головная боль. Представьте: kubelet - это такой суровый прораб на стройке кластера. Ему нужно управлять сотнями рабочих (контейнеров), но каждый рабочий говорит на своем диалекте - Docker, containerd, rkt... Беспорядок!</p>
36
<p>С появлением Kubernetes началась настоящая головная боль. Представьте: kubelet - это такой суровый прораб на стройке кластера. Ему нужно управлять сотнями рабочих (контейнеров), но каждый рабочий говорит на своем диалекте - Docker, containerd, rkt... Беспорядок!</p>
37
<p>И тогда родился CRI (Container Runtime Interface) - универсальный переводчик, этакий "технический английский" (хотя напрашиваеться больше ассоциация про "пиджин") для общения прораба с любым контейнерным рантаймом.</p>
37
<p>И тогда родился CRI (Container Runtime Interface) - универсальный переводчик, этакий "технический английский" (хотя напрашиваеться больше ассоциация про "пиджин") для общения прораба с любым контейнерным рантаймом.</p>
38
<p>Но наш старый добрый Docker оказался тем самым упрямым работягой, который говорит только на своем наречии. "CRI? Не, не слышал". Пришлось городить костыль под названием dockershim - этакого личного переводчика specifically для Docker. Работало, но было криво, сложно и постоянно ломалось.</p>
38
<p>Но наш старый добрый Docker оказался тем самым упрямым работягой, который говорит только на своем наречии. "CRI? Не, не слышал". Пришлось городить костыль под названием dockershim - этакого личного переводчика specifically для Docker. Работало, но было криво, сложно и постоянно ломалось.</p>
39
<p>Сообщество посмотрело на это безобразие и сказало: "Так, стоп! Давайте сделаем рантайм, который из коробки говорит на языке CRI - без костылей, без лишних телодвижений".</p>
39
<p>Сообщество посмотрело на это безобразие и сказало: "Так, стоп! Давайте сделаем рантайм, который из коробки говорит на языке CRI - без костылей, без лишних телодвижений".</p>
40
<p>Так из инженерной лени и стремления к идеалу родился CRI-O. Представьте себе спринтера-олимпийца - никакого лишнего жира, только рельефные мышцы. Его единственная задача - молниеносно и идеально исполнять команды kubelet'а. Ни тебе сборки образов, ни крутых фич для разработчиков - только чистый, голый запуск контейнеров в Kubernetes.</p>
40
<p>Так из инженерной лени и стремления к идеалу родился CRI-O. Представьте себе спринтера-олимпийца - никакого лишнего жира, только рельефные мышцы. Его единственная задача - молниеносно и идеально исполнять команды kubelet'а. Ни тебе сборки образов, ни крутых фич для разработчиков - только чистый, голый запуск контейнеров в Kubernetes.</p>
41
<p>Под капотом он использует проверенную классику: для запуска контейнеров - наш старый знакомый runc, для работы с образами - containers/image. CRI-O - это не новый движок, это гениальный минималистичный адаптер, который взял всё лучшее из экосистемы контейнеров и заточил это исключительно под нужды Kubernetes.</p>
41
<p>Под капотом он использует проверенную классику: для запуска контейнеров - наш старый знакомый runc, для работы с образами - containers/image. CRI-O - это не новый движок, это гениальный минималистичный адаптер, который взял всё лучшее из экосистемы контейнеров и заточил это исключительно под нужды Kubernetes.</p>
42
<h2>CRI-O vs Docker: кто есть кто в нашем контейнерном королевстве</h2>
42
<h2>CRI-O vs Docker: кто есть кто в нашем контейнерном королевстве</h2>
43
<p>А теперь сравним более детально этих ребят.</p>
43
<p>А теперь сравним более детально этих ребят.</p>
44
<p>Представьте, что Docker - это такой швейцарский армейский нож с двадцатью лезвиями, открывалкой, штопором и встроенным фонариком. Он универсален! Им можно и банку консервную в походе вскрыть, и винтик подкрутить, и даже перед друзьями покрасоваться. Он создан для разработчика, который хочет на своей машине сделать всё и сразу: собрать образ, запустить контейнер, посмотреть логи, настроить сеть - одна команда docker, и мир у ваших ног. За это удобство вы платите его некоторой "тяжеловесностью" и тем, что он тянет за собой кучу функций, которые в продакшене могут быть и не нужны.</p>
44
<p>Представьте, что Docker - это такой швейцарский армейский нож с двадцатью лезвиями, открывалкой, штопором и встроенным фонариком. Он универсален! Им можно и банку консервную в походе вскрыть, и винтик подкрутить, и даже перед друзьями покрасоваться. Он создан для разработчика, который хочет на своей машине сделать всё и сразу: собрать образ, запустить контейнер, посмотреть логи, настроить сеть - одна команда docker, и мир у ваших ног. За это удобство вы платите его некоторой "тяжеловесностью" и тем, что он тянет за собой кучу функций, которые в продакшене могут быть и не нужны.</p>
45
<p>А теперь смотрите на CRI-O. Это не нож, это - идеально отточенное скальпельное лезвие в руках хирурга-кубернета. У него одна-единственная задача: безупречно исполнять приказы Kubernetes. Ни тебе сборки образов, ни лишних команд - только чистая, минималистичная работа по запуску подов и контейнеров. Он легковесный, стремительный и заточен на безопасность. Его не существует вне Kubernetes, он - его продолжение.</p>
45
<p>А теперь смотрите на CRI-O. Это не нож, это - идеально отточенное скальпельное лезвие в руках хирурга-кубернета. У него одна-единственная задача: безупречно исполнять приказы Kubernetes. Ни тебе сборки образов, ни лишних команд - только чистая, минималистичная работа по запуску подов и контейнеров. Он легковесный, стремительный и заточен на безопасность. Его не существует вне Kubernetes, он - его продолжение.</p>
46
<p><strong>Так в чём же принципиальная разница, если отбросить метафоры?</strong></p>
46
<p><strong>Так в чём же принципиальная разница, если отбросить метафоры?</strong></p>
47
<p>Философия: Docker - это универсальная платформа для всех, а CRI-O - специализированный инструмент для одной экосистемы (Kubernetes).</p>
47
<p>Философия: Docker - это универсальная платформа для всех, а CRI-O - специализированный инструмент для одной экосистемы (Kubernetes).</p>
48
<p>Архитектура: Docker - это монолитный "комбайн" (хотя внутри и состоит из компонентов), а CRI-O - это минималистичный модуль, который делает ровно то, что от него просят, и не грамма больше.</p>
48
<p>Архитектура: Docker - это монолитный "комбайн" (хотя внутри и состоит из компонентов), а CRI-O - это минималистичный модуль, который делает ровно то, что от него просят, и не грамма больше.</p>
49
<p>Управление: чтобы пообщаться с Docker, вы используете богатейшую команду docker. Чтобы пообщаться с CRI-O, вы в 99% случаев будете использовать команды kubectl, потому что он сам по себе - лишь послушный исполнитель.</p>
49
<p>Управление: чтобы пообщаться с Docker, вы используете богатейшую команду docker. Чтобы пообщаться с CRI-O, вы в 99% случаев будете использовать команды kubectl, потому что он сам по себе - лишь послушный исполнитель.</p>
50
<p>Проще говоря: Docker - это ваш личный многофункциональный гараж, где вы и машину собираете, и ремонтируете, и тюнингуете. А CRI-O - это конвейерная линия на заводе, которая делает одну операцию, но делает её идеально, быстро и без лишних движений.</p>
50
<p>Проще говоря: Docker - это ваш личный многофункциональный гараж, где вы и машину собираете, и ремонтируете, и тюнингуете. А CRI-O - это конвейерная линия на заводе, которая делает одну операцию, но делает её идеально, быстро и без лишних движений.</p>
51
<p>Вот и весь расклад. Не инструменты друг другу конкуренты, а разные философии для разных задач.</p>
51
<p>Вот и весь расклад. Не инструменты друг другу конкуренты, а разные философии для разных задач.</p>
52
<h2>Историческая дорожная карта: как всё делилось</h2>
52
<h2>Историческая дорожная карта: как всё делилось</h2>
53
<p>По-быстрому пробежимся, как всё развивалось, чтобы понимать, какого года документации стоит брать.</p>
53
<p>По-быстрому пробежимся, как всё развивалось, чтобы понимать, какого года документации стоит брать.</p>
54
<p>2013: Появление Docker. Изначально использовался LXC как рантайм по умолчанию.</p>
54
<p>2013: Появление Docker. Изначально использовался LXC как рантайм по умолчанию.</p>
55
<p>2015: Docker создаёт собственную библиотеку libcontainer и заменяет LXC на runc, становясь более самостоятельным.</p>
55
<p>2015: Docker создаёт собственную библиотеку libcontainer и заменяет LXC на runc, становясь более самостоятельным.</p>
56
<p>2017: Containerd выделяется из Docker Engine в отдельный проект и передаётся CNCF. Docker также разделяется на Community (CE) и Enterprise (EE) редакции.</p>
56
<p>2017: Containerd выделяется из Docker Engine в отдельный проект и передаётся CNCF. Docker также разделяется на Community (CE) и Enterprise (EE) редакции.</p>
57
<p>2020: Появление поддержки Compose V2 в Docker Engine 20.10.</p>
57
<p>2020: Появление поддержки Compose V2 в Docker Engine 20.10.</p>
58
<p>2022: Kubernetes 1.24 полностью удаляет dockershim, переводя экосистему на использование containerd и CRI-O.</p>
58
<p>2022: Kubernetes 1.24 полностью удаляет dockershim, переводя экосистему на использование containerd и CRI-O.</p>
59
<p>2023: Docker 24.0 полностью отказывается от старого docker-compose (v1) в пользу нового docker compose (v2).</p>
59
<p>2023: Docker 24.0 полностью отказывается от старого docker-compose (v1) в пользу нового docker compose (v2).</p>
60
<h2>А для чего это всё?</h2>
60
<h2>А для чего это всё?</h2>
61
<p>Вот мы и подошли к главному выводу. Вся эта история с разделением, стандартизацией и появлением новых проектов вроде CRI-O - это не просто технические причуды. Это прямое отражение главных трендов в современной разработке и эксплуатации.</p>
61
<p>Вот мы и подошли к главному выводу. Вся эта история с разделением, стандартизацией и появлением новых проектов вроде CRI-O - это не просто технические причуды. Это прямое отражение главных трендов в современной разработке и эксплуатации.</p>
62
<p>Заменяемость компонентов и микросервисная архитектура. Раньше у вас был монолитный Docker, теперь у вас есть набор независимых инструментов (Docker, containerd, runc, CRI-O), которые общаются через чётко определённые API (CRI, OCI). Вы можете создать свою собственную "сборку" контейнерной платформы, как из кубиков Лего, выбирая лучший инструмент для каждой конкретной задачи.</p>
62
<p>Заменяемость компонентов и микросервисная архитектура. Раньше у вас был монолитный Docker, теперь у вас есть набор независимых инструментов (Docker, containerd, runc, CRI-O), которые общаются через чётко определённые API (CRI, OCI). Вы можете создать свою собственную "сборку" контейнерной платформы, как из кубиков Лего, выбирая лучший инструмент для каждой конкретной задачи.</p>
63
<p><strong>Специализация.</strong>CRI-O - идеальный пример специализации. Он не пытается быть всем для всех, как Docker. Он делает одну вещь - запускает контейнеры в Kubernetes, и делает это блестяще, будучи при этом легче и безопаснее.</p>
63
<p><strong>Специализация.</strong>CRI-O - идеальный пример специализации. Он не пытается быть всем для всех, как Docker. Он делает одну вещь - запускает контейнеры в Kubernetes, и делает это блестяще, будучи при этом легче и безопаснее.</p>
64
<p><strong>Стандарты и открытость.</strong>Существование OCI и CRI означает, что ни одна компания (даже Docker Inc.) не может единолично управлять всей экосистемой. Это гарантирует здоровую конкуренцию, инновации и защищает инвестиции пользователей. Ваши образы, собранные по стандарту OCI, будут работать с любым совместимым рантаймом сегодня и в обозримом будущем.</p>
64
<p><strong>Стандарты и открытость.</strong>Существование OCI и CRI означает, что ни одна компания (даже Docker Inc.) не может единолично управлять всей экосистемой. Это гарантирует здоровую конкуренцию, инновации и защищает инвестиции пользователей. Ваши образы, собранные по стандарту OCI, будут работать с любым совместимым рантаймом сегодня и в обозримом будущем.</p>
65
<p>Так что, разобравшись в том, что творится под капотом, вы видите не просто набор программ, а целую философию построения гибких, надёжных и открытых систем. Это и есть тот самый переход от работы "администратором Docker" к роли "инженера контейнерной платформы".</p>
65
<p>Так что, разобравшись в том, что творится под капотом, вы видите не просто набор программ, а целую философию построения гибких, надёжных и открытых систем. Это и есть тот самый переход от работы "администратором Docker" к роли "инженера контейнерной платформы".</p>
66
<p>Приятного погружения в глубины! Надеюсь, теперь эта кроличья нора кажется вам не такой уж и тёмной.</p>
66
<p>Приятного погружения в глубины! Надеюсь, теперь эта кроличья нора кажется вам не такой уж и тёмной.</p>
67
<p><em>Освоить Docker и научиться уверенно разворачивать, управлять и масштабировать приложения в реальных условиях можно на курсе "Docker для админов и разработчиков". На нём вы разберёте особенности использования Docker с различными языками программирования, научитесь безопасно работать с Docker-контейнерами и расширите пул доступных вам инструментов. Все подробности -<a>по ссылке.</a></em></p>
67
<p><em>Освоить Docker и научиться уверенно разворачивать, управлять и масштабировать приложения в реальных условиях можно на курсе "Docker для админов и разработчиков". На нём вы разберёте особенности использования Docker с различными языками программирования, научитесь безопасно работать с Docker-контейнерами и расширите пул доступных вам инструментов. Все подробности -<a>по ссылке.</a></em></p>