Docker и Kubernetes — два инструмента, которые прочно вошли в арсенал современных разработчиков. Хотите разобраться в основах контейнеризации и оркестрации? Наша статья поможет вам в этом, раскрывая ключевые концепции и принципы работы этих технологий.
Все дело в контейнеризации!
С появлением технологии контейнеризации, которая позволяет упаковывать приложения в изолированные «ящики», отличающиеся высокой переносимостью и небольшим размером, один за другим стали появляться новые инструменты для удобной и эффективной работы с ними. Docker и Kubernetes стали наиболее востребованными среди вышедших на рынок продуктов. При этом Kubernetes — это оркестратор контейнеров. Он «прожёвывает» либо Docker, либо OCI-образы и запускает их с помощью containerd или CRI-O. Далее мы подробно изучим, как и с помощью чего работает контейнеризация, а также разберемся в этом загадочном, на первый взгляд, термине оркестрация и узнаем, что он означает в контексте работы с Kubernetes.
Предыстория: всё началось с виртуальных машин
До появления Docker и подобных ему технологий, программисты горели желанием поделить «железо» на несколько независимых компьютеров, каждый из которых выполнял бы свою задачу. Так появились виртуальные машины.
Посмотрим на определение, которое выдает нам Microsoft:
Виртуальная машина (часто сокращается до ВМ) мало чем отличается от физических компьютеров — ноутбука, смартфона или сервера. У нее есть ЦП, память, диски для хранения файлов и возможность подключения к Интернету. Компоненты вашего компьютера (аппаратная часть) материальны и осязаемы, тогда как виртуальные машины часто рассматриваются как виртуальные или программно-определяемые компьютеры в физических серверах, существующие только в виде кода.
Если простыми словами, то основная идея виртуализации в том, чтобы поставить сколько угодно «виртуальных» машин на одном физическом (реально существующем) компьютере.
А у каждого компьютера есть что? Правильно — своя операционная система: Windows, MacOS, Linux (Ubuntu,Centos) и т. д.
Некоторые приложения могут работать только на MacOS, другие — исключительно на Windows, поэтому технология, объединяющая разные «операционки» на одном «железе», сразу приобрела популярность у крупных компаний. Они начали активно пользоваться виртуальными машинами, строить свои «облака» (большое количество виртуальных машин, объединенных в одну сеть) и предоставлять облачные вычисления обычным пользователям. Одним из примеров данного подхода стал OpenStack.
Однако у этой технологии развертки есть значительный недостаток: для использования своего приложения необходимо хранить в памяти не только собственные данные, но и целую операционную систему, которая занимает много места и довольно долго запускается. Поэтому появилась необходимость в чем-то более легковесном и быстром, и тут в дело вступили контейнеры.
Новый виток изолирования: контейнеры
Основной задачей контейнеров стало избавиться от промежуточного слоя в виде операционной системы, тем самым уменьшив размер и повысив переносимость приложений. Контейнер представляет собой «ящик» с необходимым инструментарием для работы приложения. В изолированном пространстве собираются библиотеки, бинарные файлы и данные, необходимые только для работы конкретного приложения. Это, в свою очередь, позволяет легко передавать полностью рабочие продукты независимо от устройства, на котором они были созданы, при этом сохраняя очень небольшой размер и высокую скорость запуска.
Что такое Docker?
Docker — это средство для разворачивания Docker-контейнеров, каждый из которых представляет собой отдельное приложение, запущенное в своей среде, обладающее своими сетевыми, файловыми и вычислительными ресурсами.
Как устроен Docker?
Docker-контейнер ложится поверх основной операционной системы компьютера и делит с ним ресурсы, но обладает своим изолированным пространством имен и мощностями.
Он пользуется встроенными технологиями Linux, среди которых:
cgroups — позволяет выделять на каждый контейнер ресурсы компьютера, такие как оперативная память, ядра, память, сетевые ресурсы и т. д.
Namespaces — изолируют такие системные ресурсы, как процессы, сети, идентификаторы пользователей и файловую систему, позволяя контейнерам работать независимо друг от друга.
Union File System (UnionFS) — Docker использует многослойную файловую систему (OverlayFS, AUFS или btrfs), которая позволяет создавать легковесные и изменяемые образы контейнеров. Это дает возможность эффективно управлять слоями файловой системы, повторно используя неизменяемые слои между различными контейнерами и образами.
Но нас, как конечных пользователей, больше интересует, какие инструменты предоставляет Docker. А вот и они:
Docker engine (иначе containerd) — для того чтобы иметь возможность развертывать контейнеры и взаимодействовать с ними, необходимо установить Docker Engine. Существует несколько способов сделать это: например, для macOS достаточно просто загрузить приложение Docker. Так как Docker использует механизмы ядра Linux, то Docker Desktop for Mac и Docker Desktop for Windows запускают виртуальную машину с Linux на борту, где уже запускаются контейнеры.
Docker image — далее, для работы с нашими контейнерами, необходимо разработать или скачать шаблон для их создания. По сути, каждый контейнер — это уникальная программа, и мы можем создавать несколько копий одного и того же приложения, и все они будут строиться на основе некоторого шаблона, который и называется Docker image (образ).
Контейнеры Docker (Docker Containers) — исполняемые экземпляры образов Docker, обособленные от хостовой системы и друг от друга. Они обеспечивают изолированную среду выполнения приложений.
Docker Hub — официальный репозиторий Docker для хранения и обмена образами (шаблонами Docker-контейнеров). Это ресурс похожий на Github, на котором компании и частные разработчики делятся между собой написанными шаблонами для развертки определенных приложений в контейнерах. В качестве примера вы можете легко скачать образ nginx, mysql и даже мини linux-компьютера и на основе него быстро развернуть свои приложения.
Но чтобы в полной мере ощутить все удобство контейнеров, закрепите теоретические сведения практикой. В качестве такой тренировки предлагаем установить Docker на вашу систему. Как это сделать, можно узнать в документации:
Windows — https://docs.docker.com/desktop/install/windows-install/
Linux (Ubuntu) — https://docs.docker.com/engine/install/ubuntu/
MacOs — https://docs.docker.com/desktop/install/mac-install/
И после этого создайте nginx-контейнер. Или же изучите документацию Docker и станьте мастером контейнеризации!
Кстати, недавно Docker попытался уйти из России и ограничил доступ к Docker Hub (хранилищу образов), но проблема уже устранена — Docker Hub снова заработал в России. Если он еще раз примет решение уйти, вот как можно решить этот вопрос на VPS (при этом важно учитывать, что подобные неофициальные сервисы могут быть потенциально опасны, поэтому решение об их использовании должно быть обоснованным и взвешенным):
Откроем файл, выполнив команду sudo nano/etc/docker/daemon.json. Если у вас появился пустой редактор, значит, файла у вас не было, и после сохранения он появится. Затем добавим в JSON-ключ со списком. Если файла раньше не было, просто вставьте следующий JSON:
{
"registry-mirrors": [
"https://mirror.gcr.io",
"https://daocloud.io",
"https://c.163.com",
"https://registry.docker-cn.com"
]
}
Если файл конфигурации был, то добавьте новый блок.
Сохраняем файл сочетанием клавиш CTRL+S и закрываем CTRL+X.
После этого перезапускаем службу Docker, выполнив следующую команду: sudo systemctl restart docker.
Kubernetes
Следующим этапом развития контейнеризации стали приложения, которые оркестрируют контейнеры. То есть приложения, которые автоматизируют запуск, поддержку стабильной и безопасной работы и так далее. Одним из первых и популярных инструментов для оркестрации стал Docker compose, из которого вырос Docker Swarm. Компания сделала этот инструмент платным, что вызвало бурное негодование в opensource-сообществе и способствовало популяризации Kubernetes.
Kubernetes предлагает широкий спектр инструментов для управления контейнерами и нацелен на крупные компании, такие как стриминговые сервисы или социальные сети. В этих областях крайне важно иметь возможность масштабироваться для обработки внезапно возросшего трафика юзеров и одновременно обеспечивать высокий уровень безопасности и надежности системы.
Инструменты Kubernetes
Теперь давайте разберемся, как устроен такой мощный инструмент изнутри.
Минимальный примитив в k8s — это Pod, и кубер работает только с pod-ами, внутрь pod-а он не лезет. Pod — это некая «капсула», которая может содержать в себе один или несколько контейнеров. В дальнейшем, для упрощения, во всех примерах мы будем рассматривать один контейнер в поде. Но бывают случаи, когда некоторые контейнеры работают в группе, чтобы решить какую-то одну примитивную задачу, и тогда их помещают в один Pod. Например часто используют контейнер redis (для хранения кеша) и контейнер основного приложения в одном Pod.
Далее Pod нужно разместить на каком-то Node (физическом сервере) и тут в Kubernetes вводится два новых понятия: рабочие ноды (Worker nodes) или ноды менеджеры (Manager nodes или Master nodes).
Worker nodes отвечают за размещение на себе подов (Pod). В то время как Менеджеры (Manager nodes) управляют размещением контейнеров и другими процессами, с этим связанными. Чаще всего один менеджер отвечает за три и более воркеров.
Далее при более подробном изучении Kubernetes у вас появится множество вопросов по его архитектуре.
Например, как устроен Master node и как он взаимодействует с Воркерами. Какие инструменты используются для автоматической развертки множества контейнеров в одном конфигурационном файле. Как обеспечивается балансировка нагрузки между подами. На эти и другие вопросы подробно отвечает документация Kubernetes.
Рекомендуем ознакомиться с инструментами, которые позволяют развернуть мини-версию Kubernetes локально для экспериментов и обучения:
Minikube — инструмент для запуска одноузлового кластера Kubernetes на виртуальной машине в персональном компьютере.
Kind — инструмент для запуска локальных K8s-кластеров, который использует в качестве узлов Docker-контейнеры.
K3s — облегчённая версия Kubernetes, специально созданная для использования в средах с ограниченными ресурсами.
Итоги
Подводя итог, можно сказать, что мы разобрались в основных терминах и концепциях, связанных с Docker и Kubernetes. Теперь, когда вы снова услышите эти названия, они не будут звучать как загадочные заклинания. Вы будете понимать, что Docker — это инструмент для контейнеризации приложений, а Kubernetes — система для оркестрации и управления контейнерами.
Поделитесь своими прогнозами: как вы думаете, какое будущее ждет контейнеризацию и оркестрацию в ближайшие 5-10 лет?
firehacker
Непонятно только, почему этим так называемым разработчикам приложений так «зашла» идея заворачивать приложения в изолированных ящиках.
Может потому, что они настолько криворукие разработчики, что не могут написать приложения, которые бы не мешали работе друг-друга?
В 2000-х была популярна шутка про начинающих разработчиков, которые пишут приложения, которые нигде больше не запускаются, кроме как на компе своего создателя. Такое ощущение, что весь тот докер про это.
Если же всё дело в изоляции, то чем системные механизмы изоляции не устраивают? И если все-таки не устраивают, с какого перепугу проблему изоляции прикладных программ решает другая прикладная программа, а не решается это на уровне ОС?
aka352
Видимо вы не разрабатывали под Linux. Попробуйте и скоро сами изобретëте свой докер)
firehacker
Ошибаетесь. Разрабатывал, хоть и не так много, как под Windows.
Ну опишите открытым текстом, что вашим приложениям мешает жить на линукс-машины без завёртывания в контейнер?
И, каким бы ни был ответ, почему вместо допиливнаия линукса (что было бы идеологически верным) лепят нашлёпку поверх недопиленного линукса и ещё и радуются этому?
И как тогда по вашему существовал мир до создания докера? Как кромешный ад и ужас? Это мне напоминает «ощущение» у неофитов, что 100 лет назад мир в принципе был чёрно-белым.
trueMoRoZ
Ну одни решили написать "костыль" в виде докера. Вы же можете допилить линукс - весь мир ждёт.
ddruganov
"write once, run anywhere" слышали? Эта фраза еще даже постарше нулевых будет)
firehacker
Этот лозунг больше бы подошёл Джаве, а не системе контейнеризации.
А у оно не run anywhere, а работает на линуксе в контейнере. И что мешает ему работать точно так же на линуксе без контейнера?
ddruganov
там ниже уже ответили, бесполезно дальше обсуждать
ma1uta
Очень сложно писать приложения, которые бы не мешали работе друг друга. Особенно сложные приложения. Особенно когда много приложений. Одному приложению нужно glibc одной версии, другому приложению нужно glibc другой версии, а третьему нужно, чтобы системная библиотека была musl и так далее. А у приложения может быть несколько десятков библиотек. И надо как-то потом все эти библиотеки обновить. И ещё так, чтобы другие приложения не зацепить. И при этом иметь возможно всё откатить если что-то не так пойдёт.
И ещё желательно максимально исключить человеческий фактор, который часто является причиной поломки (что-то забыл, упустил, мы люди, мы ошибаемся, это нормально). Особенно, когда надо обновить ОС и ещё с десяток библиотек.
А потом ещё начинаются различные хотелки, например, сетевой трафик не постоянный, а может сезонно увеличиваться, а затем уменьшаться. И хотелось бы оперативно горизонтально масштабировать приложение, и когда не надо, то отключать лишние экземпляры. И надо как-то следить за всеми проектами (допустим, в компании их около 100 штук), собирать метрики, собирать логи куда-нибудь. Дальше больше, наша реальность суровая и в ней может происходить всё что угодно. И в ней происходит что угодно, приложение может упасть, сломаться, жёсткий диск посыпаться, плата сгореть. Хотелось бы как-то восстановить работоспособность. Желательно быстро и с минимальными потерями.
И уже появляется оркестрация.
Контейнеры и всякие куберы (контейнеры ещё появились в 2005 году в Solaris) - всего лишь инструмент для решения определённых проблем. Решают ли они все проблемы и являются ли панацеей от всего? Нет. Где-то они не нужны и лишние, а где-то решают свои задачи. Хорошо ли они решают проблемы? Где-то да, где-то нет.
Xexa
Так и в чем проблема обеспечить зависимость одного приложения от версии одной библиотеки, а другого приложения от версий другой? Может реально если система не позволяет поставить н-цать версий в себя и подсунуть требуемую(или поддерживаемую) версию приложению - проблема в системе и её надо допиливать, а не делать "костыль" в виде очередной системы имеющей свои проблемы.
Опять же эта любовь линуксоидов ломать поддержку снизу вверх - концептуальная причина этих костылей
ma1uta
Допустим можно написать свой велосипед, чтобы твоё приложение зависело от определённых версий библиотек. Но есть же транзитивные зависимости, когда библиотека зависит от дрйгих библиотек. И надо там аналогичное реализовать, чтобы библиотека как-то умела зависеть от определённых версий своих зависимостей. И так далее. Сможете организовать, чтобы все-все-все разработчики отныне реализовали ваш механизм для версионирования? А этот ваш механизм сможет обеспечить все требования? С удовольствием послушаю как вы реализуете механизм версионирования и как вы убедите всех разработчиков следовать этому механизму. А потом ещё надо заставить все дистрибутивы Linux тоже следовать этому принципу. И не только дистрибутивы, а ещё и другие ОС, например OS X, чтобы разработчик на OS X смог написать приложение, которое сможет работать на CentOS-сервере, и другой разработчик на Arch Linux или MS Windows не имел бы проблем с его запуском и поддержкой.
И опять же, изоляция зависимостей - это одна из проблем, которую пытается решить контейнеры.
Жду от вас предложение как допилить систему, чтобы решить данную проблему.
AlexChIt
Зачем при грузовых перевозках используют контейнеры? Неужели так сложно сделать грузы, которые не мешают друг другу?
Если проблема в изоляции, то почему проблема не решается на уровне корабля и поезда?
zartdinov
Ну это было бы справедливо для всего ПО, включая ОС. Если бы не было зоопарка железа, которое постоянно меняется.
Криворукие разработчики хотят чтобы на новой малинке тоже работало. И все равно ни ОС, ни докер, ни библиотеки не гарантируют до конца, что работать будет так же хорошо.
iskatel-tut
Вообще, виртуализация зашла и расползлась вовсе не для этого (не для заворачивания приложений). Деньги всегда что-то продвигают (все хотят тратить их рационально) или что-то уходит в Лету из-за их отсутствия (из-за бесполезности этого чего-то). Виртуализация сильно подняла эффективность использования железа (можно сказать, КПД железа). Самое дорогое железо - серверное. Именно серверная виртуализация прокатилась по миру и все обратились в эту веру. Средняя нагрузка серверов до того - где-то 15-20%, значит, 80+ процентов дорогого железа 24/7 молотили воздух. Но админы не могли поднять планку средней загрузки больше, ибо в моменты (минуты, часы) пиковых нагрузок серверА должны их держать. Серверная виртуализация позволила поднять среднюю (именно среднюю!) нагрузку (на гипервизорах) до примерно 80% (всё зависит от конкретных условий). То есть КПД в 4-5 раз! То есть получать ту же вычислительную мощность, скажем, не за 100 000 денег, а за 20-25 тысяч тех денег. Вот в чем главная причина перехода к виртуализации. А то, что можно поиграться в Linux на Windows-машине или наоборот - это побочные плюшки, которые зашли, потому что деньги уже были "уплочены" - почему бы не использовать технологию? А потом пришли контейнеры - еще бОльшая эффективность использования железа. И увидели люди, что в них удобно заворачивать приложения. И пришел Doker и т.п.
Uasya_Petrovich
Можно еще весь код писать одной функцией, которая будет сразу делать всё что нужно под любым окружением и на любом железе с любыми драйверами (даже на том, которое будет выпущено в будущем). Вопрос изоляции в этом случае легко решается областью видимости и ИФами.
А еще можно версии хранить в папочках или в архивах. Проблема хранения файлов и кода ведь решается на уровне ОС, с какого перепугу эту проблему должен решать другой код.
А доставлять этот код заказчику можно просто зип-архивом через Скайп, всем известный файлообменник популярный в 2000-х.