Глубокое погружение в контейнерные технологии для начинающих

1656512659 glubokoe pogruzhenie v kontejnernye tehnologii dlya nachinayushhih

от Вилла Ванга

Введение

Независимо от того, вы студент школы, разработчик в какой-то компании или энтузиаст программного обеспечения, скорее всего, вы слышали о контейнеры. Возможно, вы также слышали, что контейнеры — это легкие виртуальные машины, но что это на самом деле означает, как именно работают контейнеры и почему они так важны?

Эта история служит взглядом на контейнеры, их ключевые отличные технические идеи и приложения. Я не буду предполагать каких-либо предварительных знаний в этой области, кроме базового понимания информатики.

Ядро и ОС

Ваш ноутбук, как и любой другой компьютер, построен на основе некоторых частей аппаратного обеспечения, таких как центральный процессор, постоянное хранилище (диск, SSD), память, сетевая карта и т.д.

Чтобы взаимодействовать с этим аппаратным обеспечением, часть программного обеспечения в операционной системе называется ядро служит мостиком между аппаратным обеспечением и остальной системой. Ядро отвечает за планирование процессов (приложения) для запуска, управления устройствами (чтение и запись адресов на диск и память) и т.д.

Другая часть операционной системы служит для загрузки и управления пользовательским пространством, где запускаются пользовательские процессы, и будет постоянно взаимодействовать с ядром.

Dzj8uEQcg0VLXopQWmspJ3esROkT7vVRTB-r
Ядро является частью операционной системы и взаимодействует с аппаратным обеспечением. Операционная система в целом живет в «пространстве ядра», а пользовательские программы живут в «пользовательском пространстве». Пространство ядра отвечает за управление пользовательским пространством.

Виртуальная машина

Итак, у вас есть компьютер, на котором работает MacOS, и приложение, созданное для работы на Ubuntu. Хммм… Одним из распространенных решений является загрузка виртуальной машины на компьютере MacOS, на котором работает Ubuntu, а затем запустить там свое приложение.

А виртуальная машина состоит из определенного уровня виртуализации аппаратного обеспечения и ядра, где работает гостевая операционная система. Часть программного обеспечения под названием a гипервизор создает виртуализированное оборудование, которое может включать виртуальный диск, виртуальный сетевой интерфейс, виртуальный ЦБ и т.д. Виртуальные машины содержат также гостевое ядро, которое может общаться с этим виртуальным оборудованием.

Гипервизор может быть размещен, что означает, что это некое программное обеспечение, работающее на хост-ОС (MacOS), как в примере. Он также может быть обнажен, работать непосредственно на аппаратном обеспечении машины (заменяя вашу ОС). В любом случае, подход гипервизора считается трудным, поскольку он требует виртуализации нескольких частей, если не всего оборудования и ядра.

Когда на одной машине должно быть несколько изолированных групп, запуск виртуальной машины для каждой из этих групп слишком тяжелым и расточительным, чтобы быть хорошим подходом.

y4w7Yvlj0aGyKUDYWnFJLf8jfyUkyKgVfGDN
Накладные расходы не в масштабе.

Виртуальные машины нуждаются в виртуализации оборудования для изоляции на уровне машины, тогда как контейнеры работают на изоляции в пределах одной операционной системы. Разница накладных расходов становится действительно очевидной, когда количество изолированных пространств увеличивается. Обычный ноутбук может запускать десятки контейнеров, но может запустить даже одну виртуальную машину.

cgroups

В 2006 году инженеры Google изобрели «группы управления» в Linux, сокращенно cgroups. Это функция ядра Linux, которая изолирует и контролирует использование ресурсов для пользовательских процессов.

Эти процессы можно включить пространства имен, в сущности, набор процессов, имеющих одинаковые ограничения ресурсов. Компьютер может иметь несколько пространств имен, каждое со свойствами ресурса, снабжаемыми ядром.

Разделением ресурсов для пространства имен можно управлять, чтобы ограничить общий объем ЦБ, ОЗУ и т.д., которые могут использовать набор процессов. К примеру, для фоновой программы агрегации журналов, вероятно, потребуется ограничение ресурсов, чтобы случайно не перегрузить фактический сервер, который он регистрирует.

Хотя cgroups в Linux не было оригинальной функцией, в конце концов было переработано, чтобы включить функцию под названием изоляция пространства имен. Идея изоляции пространства имен сама по себе не нова, и у Linux уже было много видов изоляции пространства имен. Одним из распространенных примеров является изоляция процессов, которая отделяет каждый отдельный процесс и предотвращает такие вещи, как общая память.

Изоляция Cgroup – это более высокий уровень изоляции, который гарантирует, что процессы в пространстве имен cgroup не зависят от процессов в других пространствах имен. Ниже приведено несколько важных функций изоляции пространства имен, которые закладывают основу для изоляции, которую мы ожидаем от контейнеров.

  • PID (идентификатор процесса) Пространства имен: это гарантирует, что процессы в одном пространстве имен не знают о процессе в других пространствах имен.
  • Сетевые пространства имен: изоляция контроллера сетевого интерфейса, iptables, таблиц маршрутизации и других сетевых инструментов нижнего уровня.
  • Установка пространства имен: файловые системы монтируются, так что объем файловой системы пространства имен ограничивается только смонтированными каталогами.
  • Пространства имен пользователей: ограничивает пользователей в пространстве имен только этим пространством имен и избегает конфликтов идентификаторов пользователей в пространстве имен.

Проще говоря, каждое пространство имен будет смотреться как собственная машина для действий в нем.

Контейнеры Linux

Linux cgroups проложили путь для технологии под названием контейнеры linux (LXC). LXC был действительно первой серьезной реализацией того, что мы сегодня знаем как контейнер, используя преимущества cgroups и изоляции пространства имен для создания виртуальной среды с отдельным процессом и сетевым пространством.

В определенном смысле это позволяет быть независимым и изолированным пользовательские пространства. Идея о контейнеры следует непосредственно из LXC. Фактически предыдущие версии Docker были созданы непосредственно на основе LXC.

Docker

Docker – это самая распространенная контейнерная технология, и на самом деле большинство людей подразумевают, когда говорят о контейнерах. Хотя существуют другие технологии контейнеров с открытым кодом (например, rkt от CoreOS) и крупные компании, создающие собственный контейнерный двигатель (например, lmctfy в Google), Docker стал отраслевым стандартом для контейнеризации. Он по-прежнему построен на cgroups и пространстве имен, предоставляемых ядром Linux, а недавно также Windows.

7UNkwjdO9OZbH2zJyzwhVS5cncW1TsKHea2t
Источник изображения: Docker

Контейнер Docker состоит из слоев изображение, двоичные файлы, упакованные вместе в один пакет. Базовый образ содержит операционную систему контейнера, которая может отличаться от ОС хоста.

ОС контейнера представлена ​​в виде изображения. Это не полная операционная система, как на хосте, и разница в том, что изображение является только файловой системой и двоичными файлами для операционной системы, тогда как полная операционная система включает файловую систему, двоичные файлы и ядро.

Поверх основного изображения содержится несколько изображений, каждое из которых создает часть контейнера. Например, поверх основного изображения может быть изображение, содержащее apt-get зависимости. Поверх этого может быть изображение, содержащее двоичный файл программы и т.д.

Самое интересное, если есть два контейнера со слоями изображения a, b, c и a, b, dто вам нужно хранить только одну копию каждого слоя изображения a, b, c, d как локально, так и в репозитории. Это Docker’s файловая система union.

r6qYZxeT3GRKYh1BeueAWaQ1YJiCGGQHGJ-5

Каждое изображение, определенное хэшем, является лишь одним из множества возможных слоев изображений, образующих контейнер. Однако контейнер идентифицируется только по изображению верхнего уровня, имеющему ссылку на родительские изображения. Два изображения верхнего уровня (Изображение 1 и Изображение 2), показанные здесь, разделяют первые три слоя. Изображение 2 имеет два дополнительных слоя, связанных с конфигурацией, но имеет те же исходные изображения, что и изображение 1.

Когда контейнер загружается, изображения и его родительские изображения загружаются из репозитории, создаются cgroup и пространства имен, а изображение используется для создания виртуальной среды. Внутри контейнера файлы и двоичные файлы, указанные на изображении, представляют собой единственные файлы на всей машине. Затем запускается основной процесс контейнера и контейнер считается живым.

Docker имеет некоторые другие действительно замечательные функции, такие как копирование во время записи, тома (общие файловые системы между контейнерами), демон docker (управляет контейнерами на машине), репозитории с контролируемыми версиями (например, Github для контейнеров) и т.д. Чтобы узнать больше о них и увидеть несколько практических примеров использования Docker, эта статья для СМИ очень полезна.

pKupNiDXvO5DNVaBiaxQ3In3DuPX3heDIrA5
Клиент командной строки (1) сообщает процессу на машине, который называется демоном докеров (2), что делать. Демон извлекает образы из реестра/хранилища (3). Эти образы кэшируются (4) на локальной машине и могут быть загружены демоном для запуска контейнеров (5). Источник изображения: Docker

Почему контейнеры

Кроме технологической изоляции, контейнеры обладают многими другими полезными свойствами.

Контейнер служит в качестве самоизолированного блока, который может работать в любом месте, где его поддерживает. И в каждом из этих случаев сам контейнер будет полностью схожим. Неважно, есть ли ОС хоста CentOS, Ubuntu, MacOS или даже что-то не UNIX, например Windows — внутри контейнера ОС будет любой ОС, которую указал контейнер. Таким образом, вы можете быть уверены, что контейнер, созданный на своем ноутбуке, также будет работать на серверах компании.

Контейнер также действует как стандартизированная единица работы или вычисления. Общая парадигма состоит в том, что каждый контейнер запускает один веб-сервер, один фрагмент базы данных или один рабочий файл Spark. Затем, чтобы масштабировать приложение, вам просто нужно масштабировать количество контейнеров.

В этой парадигме каждому контейнеру предоставляется фиксированная конфигурация ресурса (ЦБ, оперативная память, количество потоков и т.п.), а масштабирование программы требует масштабирования только количества контейнеров вместо отдельных ресурсных примитивов. Это обеспечивает гораздо более легкую абстракцию для инженеров, когда приложения нужно масштабировать вверх или уменьшить.

Контейнеры также служат отличным инструментом для реализации. микросервисная архитектура, где каждый микросервис – это только набор взаимодействующих контейнеров. Например, микросервис Redis можно реализовать с помощью одного основного контейнера и нескольких репликовых контейнеров.

Эта (микро)сервисно-ориентированная архитектура имеет несколько очень важных свойств, облегчающих инженерным командам создание и развертывание программ (подробнее смотрите в моей предыдущей статье).

Оркестровка

Еще со времен контейнеров Linux пользователи пытались развернуть крупномасштабные программы на многих виртуальных машинах, где каждый процесс выполняется в собственном контейнере. Для этого необходимо иметь возможность эффективно разворачивать от десятков до тысяч контейнеров на потенциально сотнях виртуальных машин и управлять их сетями, файловыми системами, ресурсами и т.д. Сегодня Docker делает это немного проще, поскольку предоставляет абстракции для определения сети контейнеров, тома для файлов системы, конфигурации ресурсов и т.д.

Однако инструмент все еще нужен, чтобы:

  • фактически взять спецификацию и назначить контейнеры машинам (планирование)
  • фактически загружать указанные контейнеры на машинах через Docker
  • иметь дело с обновлениями/откатами/постоянно изменяющейся природой системы
  • реагировать на сбои, такие как аварии контейнера
  • и создавать ресурсы кластера, такие как обнаружение служб, сеть между виртуальными машинами, вход/выход кластера и т.д.

Этот набор проблем относится к оркестровка распределенной системы, построенной на основе набора (возможно, временных или постоянно изменяющихся) контейнеров, и люди создали несколько действительно удивительных систем для решения этой проблемы.

В своем следующем рассказе я подробно расскажу о внедрении Kubernetes, основного оркестратора с открытым кодом, а также двух не менее важных, но менее известных, Mesos и Borg.

Эта история является частью серии. Я студент университета в Беркли. Мои исследования проводятся в распределенных системах, и меня консультирует Скотт Шенкер.

Предыдущий: Как микросервисы спасли Интернет

Далее: Оркестровка (TBD)

Добавить комментарий

Ваш адрес email не будет опубликован.