Какой тип ресурсов содержит ссылку на образ нашего приложения из registry
Перейти к содержимому

Какой тип ресурсов содержит ссылку на образ нашего приложения из registry

  • автор:

Docker. Начало

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

Начнем с того, для чего же нам нужен Docker:

  1. изолированный запуск приложений в контейнерах
  2. упрощение разработки, тестирования и деплоя приложений
  3. отсутствие необходимости конфигурировать среду для запуска — она поставляется вместе с приложением — в контейнере
  4. упрощает масштабируемость приложений и управление их работой с помощью систем оркестрации контейнеров.

Предыстрория

Для изоляции процессов, запущенных на одном хосте, запуска приложений, предназначенных для разных платформ, можно использовать виртуальные машины. Виртуальные машины делят между собой физические ресурсы хоста:

  • процессор,
  • память,
  • дисковое пространство,
  • сетевые интерфейсы.

На каждой ВМ устанавливаем нужную ОС и запускаем приложения. Недостатком такого подхода является то, что значительная часть ресурсов хоста расходуется не на полезную нагрузку(работа приложений), а на работу нескольких ОС.

Контейнеры

Альтернативным подходом к изоляции приложений являются контейнеры. Само понятие контейнеров не ново и давно известно в Linux. Идея состоит в том, чтобы в рамках одной ОС выделить изолированную область и запускать в ней приложение. В этом случае говорим о виртуализации на уровне ОС. В отличие от ВМ контейнеры изолированно используют свой кусочек ОС:

  • файловая система
  • дерево процессов
  • сетевые интерфейсы
  • и др.

Т.о. приложение, запущенное в контейнере думает, что оно одно во всей ОС. Изоляция достигается за счет использования таких Linux-механизмов, как namespaces и control groups. Если говорить просто, то namespaces обеспечивают изоляцию в рамках ОС, а control groups устанавливают лимиты на потребление контейнером ресурсов хоста, чтобы сбалансировать распределение ресурсов между запущенными контейнерами.

Т.о. контейнеры сами по себе не являются чем-то новым, просто проект Docker, во-первых, скрыл сложные механизмы namespaces, control groups, а во-вторых, он окружен экосистемой, обеспечивающей удобное использование контейнеров на всех стадиях разработки ПО.

Образы

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

Но при таком рассмотрении возникает вопрос: если мы хотим использовать несколько образов на одном хосте, то будет нерационально как с точки зрения загрузки, так и с точки зрения хранения, чтобы каждый образ тащил все необходимое для своей работы, ведь большинство файлов будут повторяться, а различаться — только запускаемое приложение и, возможно, среда выполнения. Избежать дублирования файлов позволяет структура образа.

Образ состоит из слоев, каждый из которых представляет собой неизменяемую файловую систему, а по-простому набор файлов и директорий. Образ в целом представляет собой объединенную файловую систему (Union File System), которую можно рассматривать как результат слияния файловых систем слоев. Объединенная файловая система умеет обрабатывать конфликты, например, когда в разных слоях присутствуют файлы и директории с одинаковыми именами. Каждый следующий слой добавляет или удаляет какие то файлы из предыдущих слоев. В данном контексте «удаляет» можно рассматривать как «затеняет», т.е. файл в нижележащем слое остается, но его не будет видно в объединенной файловой системе.
Можно провести аналогию с Git: слои — это как отдельные коммиты, а образ в целом — результат выполнения операции squash. Как мы увидим дальше, на этом параллели с Git не заканчиваются. Существуют различные реализации объединенной файловой системы, одна из них — AUFS.

Для примера рассмотрим образ произвольного .NET приложения MyApplication: первым слоем является ядро Linux, далее следуют слои ОС, среды исполнения и уже самого приложения.

Слои являются read only и, если в слое MyApplication нужно изменить файл, находящийся в слое dotnet, то файл сначала копируется в нужный слой, а потом в нем изменяется, оставаясь в исходном слое в первозданном виде.

Неизменяемость слоев позволяет использовать их всеми образами на хосте. Допустим MyApplication — это веб-приложение, которое использует БД и взаимодействует также с NodeJS сервером.

Совместное использование проявляется также и при скачивании образа. Первым загружается манифест, который описывает какие слои входят в образ. Далее скачиваются только те слои из манифеста, которых еще нет локально. Т.о. если мы для MyApplication уже скачали ядро и ОС, то для PostgreSQL и Node.js эти слои уже загружаться не будут.

  • Образ — это набор файлов, необходимых для работы приложения на голой машине с установленным Docker.
  • Образ состоит из неизменяемых слоев, каждый из которых добавляет/удаляет/изменяет файлы из предыдущего слоя.
  • Неизменяемость слоев позволяет их использовать совместно в разных образах.

Docker-контейнеры

Docker-контейнер строится на основе образа. Суть преобразования образа в контейнер состоит в добавлении верхнего слоя, для которого разрешена запись. Результаты работы приложения (файлы) пишутся именно в этом слое.

Например, мы создали на основе образа с PostgreSQL сервером контейнер и запустили его. Когда мы создаем БД, то соответствующие файлы появляются в верхнем слое контейнера — слое для записи.

Можно провести и обратную операцию: из контейнера сделать образ. Верхний слой контейнера отличается от остальных только лишь разрешением на запись, в остальном это обычный слой — набор файлов и директорий. Делая верхний слой read only, мы преобразуем контейнер в образ.

Теперь я могу перенести образ на другую машину и запустить. При этом на сервере PostgreSQL можно будет увидеть БД, созданные на предыдущем этапе. Когда при работе контейнера будут внесены изменения, то файл БД будет скопирован из неизменяемого слоя с данными в слой для записи и там уже измененен.

Docker

Когда мы устанавливаем докер на локальную машину, то получаем клиент (CLI) и http-сервер, работающий как демон. Сервер предоставляет REST API, а консоль просто преобразует введенные команды в http-запросы.

Registry

Registry — это хранилище образов. Самым известным является DockerHub. Он напоминает GitHub, только содержит образы, а не исходный код. На DockerHub также есть репозитории, публичные и приватные, можно скачивать образы (pull), заливать изменения образов (push). Скачанные однажды образы и собранные на их основе контейнеры хранятся локально, пока не будут удалены вручную.

Существует возможность создания своего хранилища образов, тогда при необходимости Docker будет искать там образы, которых еще нет локально. Надо сказать, что при использовании Docker хранилище образов становится важнейшим звеном в CI/CD: разработчик делает коммит в репозиторий, запускаются тесты. Если тесты прошли успешно, то на основе коммита обновляется существующий или собирается новый образ с последующим деплоем. Причем в registry обновляются не целые образы, а только необходимые слои.

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

Dockerfile

Dockerfile представляет собой набор инструкций, на основе которых строится новый образ. Каждая инструкция добавляет новый слой к образу. Для примера рассмотрим Dockerfile, на основе которого мог бы быть создан образ рассмотренного ранее .NET-приложения MyApplication:

FROM microsoft/aspnetcore WORKDIR /app COPY bin/Debug/publish . ENTRYPOINT["dotnet", "MyApplication.dll"] 

Рассмотрим отдельно каждую инструкцию:

  1. определяем базовый образ, на основе которого будем строить свой. В данном случае берем microsoft/aspnetcore — официальный образ от Microsoft, который можно найти на DockerHub
  2. задаем рабочую директорию внутри образа
  3. копируем предварительно спаблишенное приложение MyApplication в рабочую директорию внутри образа. Сначала пишется исходная директория — путь относительно контекста, указанного в команде docker build , а вторым аргументом — целевая директория внутри образа, в данном случае точка обозначает рабочую директорию
  4. конфигурируем контейнер как исполняемый: в нашем случае для запуска контейнера будет выполнена команда dotnet MyApplication.dll

Рассмотрим еще один Dockerfile, который демонстрирует прекрасную возможность Docker, обеспечивающую легковесность образов. Подобный файл генерирует VisualStudio 2017 для проекта с поддержкой контейнеров и он позволяет собирать образ из исходного кода приложения.

FROM microsoft/aspnetcore-build:2.0 AS publish WORKDIR /src COPY . . RUN dotnet restore RUN dotnet publish -o /publish FROM microsoft/aspnetcore:2.0 WORKDIR /app COPY --from=publish /publish . ENTRYPOINT ["dotnet", "MyApplication.dll"] 

Инструкции в файле разбиты на две секции:

  1. Определение образа для сборки приложения: microsoft/aspnetcore-build. Данный образ предназначен для сборки, паблиша и запуска .NET приложений и согласно DockerHub с тегом 2.0 имеет размер 699 MB. Далее происходит копирование исходных файлов приложения внутрь образа и внутри него выполняются команды dotnet restore и dotnet publish с размещением результатов в директории /publish внутри образа.
  2. Определяется базовый образ, в данном случае это microsoft/aspnetcore, который содержит в себе только среду исполнения и согласно DockerHub с тегом 2.0 имеет размер всего 141 MB. Далее определяется рабочая директория и в нее копируется результат предыдущей стадии (ее имя указывается в аргументе —from ), определяется команда запуска контейнера и все — образ готов.

Напоследок хочу отметить, что намеренно для простоты оперировал понятием образ, рассматривая работу с Dockerfile. На самом деле изменения, вносимые каждой инструкцией происходят конечно же не в образе (ведь в нем только неизменяемые слои), а в контейнере. Механизм такой: из базового образа создается контейнер (добавляется ему слой для записи), выполняется инструкция в данном слое (она может добавлять файлы в слой для записи: COPY или нет: ENTRYPOINT ), вызывается команда docker commit и получается образ. Процесс создания контейнера и коммита в образ повторяется для каждой инструкции в файле. В итоге в процессе формирования конечного образа создается столько промежуточных образов и контейнеров, сколько инструкций в файле. Все они автоматически удаляются после окончания сборки конечного образа.

Заключение

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

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

Ссылки

  1. Документация Docker
  2. Механизм namespaces
  3. Механизм control groups
  4. Статья о Docker
  • Docker
  • Linux контейнеры

Образы

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

Как правило, образ контейнера с приложением предварительно собирается и размещается в реестре, после чего его можно использовать в Pod’е.

На этой странице представлено общее описание концепции контейнерных образов.

Названия образов

Образам контейнеров обычно присваивается имя, намекающее на их функционал и цели, например, pause , example/mycontainer или kube-apiserver . Образы также могут включать имя хоста реестра, например, fictional.registry.example/imagename , и (в некоторых случаях) номер порта, например, fictional.registry.example:10443/imagename .

Если имя хоста реестра не указано, Kubernetes по умолчанию будет использовать публичный реестр Docker.

После имени образа можно добавить тег (как, например, в командах docker и podman ). Теги помогают идентифицировать различные версии одной и той же линейки образов.

Теги образов могут состоять из строчных и прописных букв, цифр, знаков подчеркивания ( _ ), точек ( . ) и дефисов ( — ). Кроме того, существуют дополнительные правила размещения символов-разделителей ( _ , — и . ) внутри тега. Если тег не указан, Kubernetes по умолчанию использует тег latest .

Обновление образов

При первоначальном создании объекта типа Deployment, StatefulSet, Pod или другого объекта, включающего шаблон Pod’а, политика извлечения всех контейнеров в этом Pod’е будет по умолчанию установлена на IfNotPresent , если иное не указано явно. В рамках этой политики kubelet не извлекает образ, если тот уже присутствует в кэше.

Политика извлечения образов

Политика imagePullPolicy контейнера и тег образа определяют поведение kubelet’а при извлечении (загрузке) данного образа.

Вот список возможных значений imagePullPolicy и их влияние:

IfNotPresent образ извлекается только в том случае, если он еще не доступен локально. Always каждый раз при запуске контейнера kubelet запрашивает дайджест образа в реестре образов контейнеров. Если полученный дайджест полностью совпадает с дайджестом кэшированного образа, kubelet использует кэшированный образ; иначе извлекается и используется образ с полученным дайждестом. Never kubelet не пытается скачать образ. Если образ уже присутствует локально, kubelet пытается запустить контейнер; в противном случае запуск завершается неудачей. Для получения более подробной информации обратитесь к разделу о предварительно извлеченных (pre-pulled) образах.

Благодаря семантике кэширования, лежащей в основе механизма поставки образов, даже imagePullPolicy: Always может быть вполне эффективной (при условии, что реестр надежно доступен). Исполняемая среда для контейнера может обнаружить, что слои образов уже имеются на узле и их не нужно скачивать еще раз.

Примечание:

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

Всегда указывайте содержательный тег, например v1.42.0 .

Чтобы убедиться, что Pod всегда использует одну и ту же версию образа контейнера, можно указать дайджест образа вместо тега; для этого замените : на @ (например, image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2 ).

Изменение кода, к которому привязан некий тег, может привести к тому, что в Pod’ах окажется две версии кода — старая и новая. Дайджест образа однозначно идентифицирует конкретную версию образа, что гарантирует идентичность кода при запуске контейнера с заданным именем образа и дайджестом. Таким образом, изменение кода в реестре уже не может привести к смешению версий.

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

Политика извлечения образов по умолчанию

Когда информация о новом Pod’е поступает на сервер API, кластер устанавливает поле imagePullPolicy в соответствии со следующими условиями:

  • imagePullPolicy автоматически присваивается значение Always , если поле imagePullPolicy не задано, а тег для образа контейнера имеет значение :latest ;
  • imagePullPolicy автоматически присваивается значение Always , если поле imagePullPolicy не задано, а тег для образа контейнера не указан;
  • imagePullPolicy автоматически присваивается значение IfNotPresent , если поле imagePullPolicy не задано, а тег для образа контейнера имеет значение, отличное от :latest .

Примечание:

Значение imagePullPolicy контейнера всегда устанавливается при первом создании объекта и не обновляется при последующем изменении тега образа.

Например, если в Deployment’е используется образ с тегом, отличным от :latest , а потом он меняется на :latest , поле imagePullPolicy останется прежним (т.е. не будет изменено на Always ). После первоначального создания любого объекта его политику извлечения можно изменить вручную.

Обязательное извлечение образов

Для принудительного извлечения образов можно сделать следующее:

  • Установить imagePullPolicy контейнера в Always ;
  • Не устанавливать imagePullPolicy и использовать тег :latest для образа; Kubernetes автоматически поменяет политику на Always , получив информацию о Pod’е;
  • Не устанавливать imagePullPolicy и тег образа; Kubernetes автоматически применит политику Always , получив информацию о Pod’е;
  • Включить admission-контроллер AlwaysPullImages.

ImagePullBackOff

При создании kubelet’ом контейнеров для Pod’а может возникнуть ситуация, когда контейнер пребывает в состоянии Waiting из-за ImagePullBackOff .

Статус ImagePullBackOff означает, что контейнер не может запуститься, поскольку у Kubernetes не получается извлечь его образ (например, из-за ошибки в имени или попытки извлечь образ из приватного репозитория без imagePullSecret ). BackOff в названии статуса указывает на то, что Kubernetes будет продолжать попытки извлечь образ, постепенно увеличивая интервал между ними.

Так, интервал между попытками будет расти до тех пор, пока не достигнет установленного предела в 300 секунд (5 минут).

Мультиархитектурные образы с индексами

Помимо обычных исполняемых образов реестр контейнеров также может хранить так называемые индексы образов. Индекс образа содержит ссылки на различные манифесты образов, каждый из которых предназначен для определенной архитектуры. Идея здесь в том, чтобы любой пользователь мог получить образ, оптимизированный под конкретную архитектуру, используя его унифицированное, общее для всех архитектур имя (например, pause , example/mycontainer , kube-apiserver ).

Сам Kubernetes обычно добавляет суффикс -$(ARCH) к имени образа. Для обратной совместимости также рекомендуется генерировать образы с суффиксами в названиях. Например, универсальный образ pause , содержащий манифест для всех архитектур, рекомендуется дополнить образом pause-amd64 для обратной совместимости со старыми конфигурациями или YAML-файлами, в которых могут быть жестко прописаны образы с суффиксами.

Работа с приватным реестром

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

  • Аутентификация на уровне узлов:
    • все Pod’ы имеют доступ ко всем настроенным приватным реестрам;
    • требуется конфигурация узлов администратором кластера;
    • все Pod’ы могут использовать любые образы, кэшированные на узле;
    • для настройки требуется root-доступ ко всем узлам;
    • доступ к реестру получают только Pod’ы с ключами;
    • в кастомных конфигурациях могут существовать специализированные механизмы аутентификации узлов в реестре контейнеров, реализованные самим пользователем или поставщиком облачных услуг.

    Ниже мы подробнее остановимся на каждом из вариантов.

    Аутентификация на уровне узлов

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

    Пример настройки частного реестра образов контейнеров приводится в упражнении Извлекаем образ из частного реестра. В нем используется частный реестр в Docker Hub.

    Интерпретация config.json

    Интерпретация config.json отличается в оригинальной Docker-реализации и в Kubernetes. В Docker ключи auths могут указывать только корневые URL, в то время как Kubernetes позволяет использовать URL с подстановками (globbing) и пути с префиксами. То есть config.json , подобный этому, вполне допустим:

      "auths":   "*my-registry.io/images":   "auth": "…"  >  > > 

    Корневой URL ( *my-registry.io ) сопоставляется с помощью следующего синтаксиса:

    pattern: < term >term: '*' соответствует любой последовательности символов, не являющихся разделителями '?' соответствует любому одиночному символу, не являющемуся разделителем '[' [ '^' ] < диапазон символов >']' класс символов (не может быть пустым) c соответствует символу c (c != '*', '?', '\\', '[') '\\' c соответствует символу c диапазон символов: c соответствует символу c (c != '\\', '-', ']') '\\' c соответствует символу c lo '-' hi соответствует символу c при lo  

    Учетные данные теперь будут передаваться в CRI-совместимую исполняемую среду для контейнеров для каждого действительного шаблона. Ниже приведены примеры имен образов, удовлетворяющие требованиям к паттерну:

    • my-registry.io/images
    • my-registry.io/images/my-image
    • my-registry.io/images/another-image
    • sub.my-registry.io/images/my-image
    • a.sub.my-registry.io/images/my-image

    kubelet последовательно извлекает образы для каждой обнаруженной учетной записи. Это означает, что config.json может содержать сразу несколько записей:

      "auths":   "my-registry.io/images":   "auth": "…"  >,  "my-registry.io/images/subpath":   "auth": "…"  >  > > 

    К примеру, если необходимо извлечь образ my-registry.io/images/subpath/my-image , kubelet будет пытаться загрузить его из второго источника, если первый не работает.

    Предварительно извлеченные образы

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

    По умолчанию kubelet пытается извлечь каждый образ из указанного реестра. Однако если параметр imagePullPolicy контейнера установлен на IfNotPresent или Never , используется локальный образ (преимущественно или исключительно, соответственно).

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

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

    При этом у всех Pod'ов будет доступ на чтение всех предварительно извлеченных образов.

    Задаем imagePullSecrets на уровне Pod'а

    Примечание: Это рекомендуемый подход для запуска контейнеров на основе образов в приватных реестрах.

    Kubernetes поддерживает указание ключей реестра образов на уровне Pod'а.

    Создаем Secret с помощью конфигурационного файла Docker

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

    Выполните следующую команду, подставив соответствующие значения вместо параметров, выделенных заглавными буквами:

    kubectl create secret docker-registry --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL 

    При наличии файла учетных данных Docker можно импортировать их как Secret'ы Kubernetes вместо команды, приведенной выше.

    Это особенно удобно в случае нескольких приватных реестров контейнеров, так как kubectl create secret docker-registry создает Secret, который работает только с одним приватным реестром.

    Примечание: Pod'ы могут работать только с Secret'ами в собственном пространстве имен, поэтому данный процесс необходимо повторить для каждого пространства имен.

    Ссылаемся на imagePullSecrets в Pod'е

    Теперь можно создавать Pod'ы, ссылающиеся на данный Secret, добавив раздел imagePullSecrets в манифест Pod'а.

    cat  pod.yaml apiVersion: v1 kind: Pod metadata:  name: foo  namespace: awesomeapps spec:  containers:  - name: foo  image: janedoe/awesomeapp:v1  imagePullSecrets:  - name: myregistrykey EOF  cat > ./kustomization.yaml resources: - pod.yaml EOF 

    Это необходимо проделать для каждого Pod'а, работающего с приватным репозиторием.

    Процесс можно автоматизировать, задав imagePullSecrets в ресурсе ServiceAccount.

    Этот подход можно использовать совместно с файлами .docker/config.json , определяемыми для каждого узла. Учетные данные будут объединены.

    Примеры использования

    Существует ряд решений для настройки приватных реестров. Вот некоторые распространенные случаи использования и рекомендуемые решения:

    1. Кластер, работающий только со свободными (например, Open Source) образами. Необходимость скрывать образы отсутствует.
      • Используйте общедоступные образы из Docker Hub;
        • Настройка не требуется;
        • Некоторые облачные провайдеры автоматически кэшируют или зеркалируют публичные образы, что повышает доступность и сокращает время их извлечения.
    2. В кластере используются закрытые образы. Они должны быть скрыты для всех за пределами компании, но доступны для всех пользователей кластера.
      • Используйте приватный репозиторий;
        • Может потребоваться ручная настройка на узлах, которым необходим доступ к частному репозиторию;
      • В качестве альтернативы можно завести внутренний приватный реестр с доступом на чтение, скрыв его за сетевым экраном;
        • Настройка Kubernetes не требуется;
      • Используйте сервис для работы с образами, контролирующий доступ к ним;
        • Этот подход лучше работает с автомасштабированием кластера, нежели ручная настройка узлов;
      • Если изменение конфигурации узлов в кластере затруднено, можно использовать imagePullSecrets.
    3. Кластер с несвободными образами, некоторые из которых требуют более строгого контроля доступа.
      • Убедитесь, что AlwaysPullImages admission-контроллер включен. В противном случае у всех Pod'ов потенциально будет доступ ко всем образам;
      • Переместите конфиденциальные данные в Secret вместо того, чтобы упаковывать их в образ.
    4. Кластер категории multi-tenant (многопользовательский), где каждому пользователю требуется собственный приватный репозиторий.
      • Убедитесь, что admission-контроллер AlwaysPullImages включен. В противном случае у всех Pod'ов всех пользователей потенциально будет доступ ко всем образам;
      • Создайте приватный реестр с обязательной авторизацией;
      • Сгенерируйте учетные данные для доступа к реестру для каждого пользователя, поместите их в Secret и добавьте его в пространство имен каждого пользователя;
      • Каждый пользователь должен добавить свой Secret в imagePullSecrets каждого пространства имен.

    Если нужен доступ к нескольким реестрам, можно создать по Secret'у для каждого реестра.

    Что дальше

    • Спецификация манифестов образов OCI.
    • Сборка "мусора" в Kubernetes — неиспользуемые контейнеры и образы.
    • Извлечение образов из приватных репозиториев.

    Обратная связь

    Эта страница была полезна?

    Спасибо за обратную связь! Если у вас есть конкретный вопрос об использовании Kubernetes, спросите на Stack Overflow. Создайте issue в репозитории GitHub, если вы хотите сообщить о проблеме или предложить улучшение.

    Какой тип ресурсов содержит ссылку на образ нашего приложения из registry

    Docker, первый выпуск которого был еще в 2013 году, — весьма удобный инструмент для сборки пакетов, поставки и запуска приложений в «контейнерах». Большинство крупных компаний, например, Google, Amazon и VMware рассматривают Docker как зрелую технологию для контейнеров, поэтому сейчас самое время изучить этот инструмент и в результате продвинуться по карьерной лестнице. Хотите? В статье будут приведены вопросы по Docker, ответы на которые нужно знать, если вы идете на собеседование.

    Что такое контейнер Docker?

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

    Опишите составные части архитектуры Docker

    Основные составные части архитектуры Docker — это:

    • сервер, содержит сервис Docker, образы и контейнеры. Сервис связывается с Registry, образы — метаданные приложений, запускаемых в контейнерах Docker.
    • клиент, применяется для запуска различных действий на сервере Docker.
    • registry, используется для хранения образов. Есть публичные, доступные каждому, например, Docker Hub и Docker Cloud.

    Опишите Registry подробнее

    Docker Registry служит для хранения образов Docker. Есть два публичных сервиса хранения: Docker Hub и Docker Cloud. Docker Hub — наиболее значимая публичная система хранения образов контейнеров, полностью поддерживаемая множеством разработчиков и другими участниками сообщества.

    Расскажите кратко о жизненном цикле контейнера Docker

    Жизненный цикл контейнера:

    • Создание контейнера
    • Работа контейнера
    • Приостановка контейнера
    • Возобновление работы контейнера
    • Запуск контейнера
    • Остановка контейнера
    • Перезапуск контейнера
    • Принудительная остановка контейнера
    • Удаление контейнера

    Назовите наиболее важные команды Docker

    Наиболее важные команды Docker:

    • build, сборка образа для Docker
    • create, создание нового контейнера
    • kill. принудительная остановка контейнера
    • dockerd, запуск сервиса Docker
    • commit, создание нового образа из изменений в контейнере

    Что такое пространства имен в Docker?

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

    Что такое Docker Swarm?

    Docker Swarm (теперь это уже swarm mode, прим. переводчика) — встроенный инструмент Docker, используемый для организации кластеризации и планирования контейнеров. Разработчики и системные администраторы с его помощью могут легко собрать несколько узлов в единую виртуальную систему Docker и управлять ею.

    Как определить состояние контейнера Docker?

    Чтобы определить состояние, надо запустить команду:

    docker ps -a

    Эта команда выведет список всех доступных контейнеров с их состоянием на сервере. Из этого списка нужно выбрать требуемый контейнер и узнать его состояние.

    Что такое образ Docker, что делает команда Docker run?

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

    Опишите функции и случаи применения Docker

    С помощью Docker можно:

    • Сделать процесс настройки проще и упростить настройку на уровне инфраструктуры;
    • Помочь разработчикам сосредоточиться исключительно на коде, сокращая время разработки и увеличивая продуктивность;
    • Усилить возможности отладки с использованием встроенных функций;
    • Изолировать приложения;
    • Улучшить плотность использования серверов в форме контейнеризации;
    • Делать быстрое развертывание на уровне операционной системы.

    Что такое объекты Docker?

    Под объектами понимают образы, сервисы и контейнеры.
    Образы — шаблоны с инструкциями только для чтения для создания контейнеров.
    Контейнеры — запущенные экземпляры образов.
    Сервисы — можно запустить несколько контейнеров поверх нескольких сервисов Docker, работающих совместно как swarm.

    Еще объектами можно назвать сети и тома.

    Какой тип приложений больше подходит для контейнеров Docker: с хранением состояния (stateful) или без хранения (stateless)?

    Приложения без хранения состояния (stateless) больше подходят для работы в Docker, чем приложения с хранением (stateful). Мы можем создать контейнер для нашего приложения и принять некоторые его настройки. Таким образом мы можем запускать один и тот же контейнер с разными настройками для различных окружений. Если мы не будем хранить состояние, сможем использовать один и тот же образ в разных сценариях. Также такие приложения проще масштабировать при их работе в контейнерах Docker.

    Что такое Dockerfile?

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

    Какие сети доступны по умолчанию в Docker?

    По умолчанию есть:

    • bridge, сеть, к которой подключаются контейнеры, если не указано иначе.
    • none, сетевой стек без наличия сетевого интерфейса в контейнере.
    • host, подключение к сетевому стеку сервера.

    Приведите необходимые шаги для развертывания докеризированного приложения, сохраненного в репозитории Git

    Шаги, необходимые для развертывания приложения зависят от окружения, основной процесс развертывания будет таким:

    • Сборка приложения с использованием Docker build в каталоге с кодом приложения
    • Тестирование образа
    • Выгрузка образа в Registry
    • Уведомление удаленного сервера приложений, что он может скачать образ из Registry и запустить его
    • Перестановка порта в прокси HTTP(S)
    • Остановка старого контейнера

    Чем Docker отличается от остальных технологий контейнеризации?

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

    Посредством Docker все больше приложений могут работать на старых серверах, также с его помощью можно упаковывать и поставлять программы. Существует также DockerHub, Registry для контейнеров, откуда можно легко и просто скачать образы контейнеров для использования. Еще более интересная функция — общие контейнеры для таких приложений. Также Docker хорошо задокументирован, что делает его лучше остальных технологий контейнеризации.

    Если вы остановите контейнер — потеряете данные?

    Если контейнер Docker останавливается, потери данных не происходит, поскольку все данные, пишутся на диск приложением с единственной целью — хранение. Этот процесс повторяется до тех пор, пока контейнер не будет однозначно удален. Более того: файловая система контейнера хранит изменения даже после полной остановки контейнера.

    Как выполняется мониторинг Docker в производственных окружениях?

    Для мониторинга есть инструменты Docker stats и Docker events. С их помощью можно получить отчеты по важной статистике. Если запустить stats с некоторым идентификатором контейнера, он вернет использование оперативной памяти и процессорного времени в контейнере. Это схоже с использованием команды top. С другой стороны есть events, показывающая список активностей в процессе работы сервиса Docker. Вот некоторые из них: подключение к консоли контейнера, commit, переименование, удаление и т.п., а также есть возможность фильтрации нужных событий.

    Расскажите о рабочем процессе использования Docker

    Краткое пояснение рабочего процесса с использованием Docker:

    • Все начинается c Dockerfile, поскольку это исходный код образа.
    • Как только он создан, его можно использовать для сборки образа контейнера. Образ — собранная версия Dockerfile.
    • Образ можно распространять, используя Registry, работающий как репозиторий образов.
    • Далее образ используется для запуска контейнеров. Контейнер при работе весьма похож на виртуальную машину, но без гипервизора.

    Поясните разницу между docker run и docker create

    Главная разница между этими командами заключается в том, что вторая создаст контейнер в остановленном состоянии. Также docker create может быть использована для хранения и вывода идентификатора контейнера для будущего использования. Лучше всего это делать с помощью docker run , добавляя --cidfile FILENAME , поскольку повторный запуска не перезаписывает файл.

    Что такое виртуализация?

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

    Что же в сухом остатке? С помощью виртуализации можно запустить две различных операционных системы на одном и том же оборудовании. Первая операционная система используется для административных целей, все остальные гостевые — загружаются как обычно, включая инициализацию, загрузку ядра и т.д. Это также идеально для безопасности, поскольку гостевая ОС не может получить полного доступа к управляющей (host) ОС, что могло бы привести к дырам в безопасности.

    Есть три типа виртуализации:

    • Паравиртуализация
    • Эмуляция
    • Контейнерная виртуализация

    В чем разница между Registry и Repository?

    Registry — это сервис хранения и распространения образов, также DockerHub — это Registry по умолчанию. Repository — это набор связанных образов. У них одно и то же имя, но разные метки.

    Можно ли использовать JSON вместо YAML в файле для docker-compose, если да — как?

    Да, так можно сделать. Для этого нужно явно указать имя файла, например так:

    docker-compose -f docker-compose.json up

    Расскажите о CMD и ENTRYPOINT в Dockerfile

    Эти инструкции Dockerfile задают команду, исполняемую при запуске контейнера. При их использовании есть несколько правил, например:

    • Должна быть минимум одна из них, CMD или ENTRYPOINT, в Dockerfile.
    • Если контейнер используется как исполняемый файл — ENTRYPOINT должна быть определена.
    • Если контейнер запускается с другими аргументами — CMD будет переопределена.

    Опишите процесс запуска приложения внутри контейнера Linux, используя Docker

    • Установите и запустите Docker;
    • Скачайте базовый образ с Docker Hub;
    • Загрузите ваше приложение в базовый образ;
    • Запустите контейнер в интерактивном режиме, используя полученный образ;
    • Проверьте контейнеры в системе;
    • Запустите или остановите контейнер;
    • Зайдите внутрь контейнера;
    • Удалите контейнер и образ.

    Что такое гипервизор?

    Гипервизор, он же монитор виртуальных машин, — это программное обеспечение для создания и запуска виртуальных машин. С его помощью можно запустить на одном компьютере несколько гостевых операционных систем. Это достигается с помощью разделения ресурсов, например, оперативной памяти, процессорного времени и т.п., сокращая требования к памяти, дисковому пространству и обслуживанию. Есть два типа гипервизоров:

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

    Расскажите о ключевом различии между виртуализацией и контейнеризацией

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

    Расскажите об образах Docker, DockerHub, Dockerfile

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

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

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

    Как проверить версии Docker client и Docker server?

    Версию Docker можно проверить с помощью docker version [параметры] . Если не указывать параметры, команда выдаст всю информацию, связанную с версией клиента и сервера. Чтобы получить только версию сервера, можно запустить такую команду:

    docker version --format '>'

    Расскажите о процедуре входа в Docker Repository

    Чтобы войти в Docker Repository, используется следующая команда:

    docker login [OPTIONS] [SERVER]

    Например, для входа в registry, размещенную на своих мощностях (локально), команда будет такой:

    $ docker login localhost:8080

    Расскажите о наиболее общих командах Docker

    • docker push: Закачать репозиторий или образ в Registry;
    • docker run: Запустить команду в новом контейнере;
    • docker pull: Скачать репозиторий или образ из Registry;
    • docker start: Запустить один или несколько контейнеров;
    • docker stop: Остановить один или несколько контейнеров;
    • docker search: Поиск образа на DockerHub;
    • docker commit: Сохранить изменения в новый образ.

    Чем отличается контейнеризация в виде Docker от других технологий?

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

    На каких платформах запускается Docker?

    Docker работает на Windows (x86_64), Linux (x86_64, ARM, s390x, ppc64le).

    Возможен ли самостоятельный перезапуск контейнера?

    Да, возможен. Docker задает различные политики перезапуска контейнера:

    • Off: контейнер не перезапускается, если он остановился или аварийно завершил работу;
    • On-failure: перезапуск только в случае аварийной остановки, но не по команде пользователя;
    • Unless-stopped: перезапуск будет работать до тех пор, пока пользователь его не остановит;
    • Always: перезапуск в любом случае, независимо от ошибок или других проблем.

    Политику можно задать так:

    $ docker run -dit — restart [unless-stopped|off|on-failure|always] [CONTAINER]

    Можно ли сравнить облака по возможностям контейнеризации с Docker?

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

    Опишите все возможные состояния контейнера Docker

    Created — контейнер создан, но не активен.
    Restarting — контейнер в процессе перезапуска.
    Running — контейнер работает.
    Paused — контейнер приостановлен.
    Exited — контейнер закончил свою работу.
    Dead — контейнер, который сервис попытался остановить, но не смог.

    Расскажите о средствах оркестрации и случаях их использования

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

    • Создание и развертывание контейнеров;
    • Балансировка нагрузки;
    • Разделение ресурсов между контейнерами;
    • Мониторинг контейнеров и серверов;
    • Масштабирование контейнеров;
    • Перенос контейнеров с одного сервера на другой, если на первом возникает недостаток ресурсов.

    Опишите параметр memory-swap

    С помощью параметра memory-swap можно разрешить контейнеру записывать на диск данные, превышающие размер оперативной памяти, выделенной контейнеру. Он работает, только если используется одновременно с параметром memory. Например, если memory = "400m" и memory-swap = "1g", то контейнер может использовать 400мб оперативной памяти и 600мб подкачки (1гб-400мб).

    Где хранятся тома Docker?

    Тома, создаваемые и управляемые Docker (у не-Docker процессов к ним нет доступа), хранятся в файловой системе сервера Docker по пути /var/lib/docker/volumes/ . Тома — наиболее эффективный способ сохранения данных в Docker.

    Назовите продвинутые команды Docker

    Наиболее важные из них:

    docker -version: узнать установленную версию Docker;
    docker ps: перечислить все запущенные контейнеры вместе с дополнительной информацией о них;
    docker ps -a: перечислить все контейнеры, включая остановленные, вместе с дополнительной информацией о них;
    docker exec: войти в контейнер и выполнить в нем команду;
    docker build: собрать образ из Dockerfile;
    docker rm: удалить контейнер с указанным идентификатором;
    docker rmi: удалить образ с указанным идентификатором;
    docker info: получить расширенную информацию об установленном Docker, например, сколько запущено контейнеров, образов, версию ядра, доступную оперативную память и т.п.;
    docker cp: сохранить файл из контейнера в локальную систему;
    docker history: показать историю образа с указанным именем.

    Расскажите о командах systemd для управления Docker

    Для запуска Docker многие дистрибутивы Linux используют systemd. Для запуска сервисов используется команда systemctl . Если ее нет, следует использовать команду service .

    $ sudo systemctl start docker $ sudo service docker start

    Чтобы добавить сервис в автозагрузку, либо убрать его:

    $ sudo systemctl enable docker $ sudo systemctl disable docker

    Для проверки параметров запуска сервиса и их изменения:

    $ sudo systemctl edit docker

    Просмотра связанных с сервисом журналов:

    $ journalctl -u docker

    Опишите процесс масштабирования контейнеров Docker

    Контейнеры могут быть масштабированы с использованием команды docker-compose scale . Процесс масштабирования такой:

    • Масштабируем контейнер и запускаем n экземпляров:
    $ docker-compose --file docker-compose-run-srvr.yml scale =

    В вышеприведенном примере имя сервиса задается в файле docker-compose-run-srvr.yml , а также запускается n копий контейнеров, где n — любое целое положительное число.

    • После масштабирования контейнера для проверки можно использовать такую команду:
    $ docker ps -a

    Что такое CNM?

    CNM или Container Network Model — описание, формально определяющее шаги, требуемые для предоставления сети контейнерам, где обслуживающая абстракция применяется для поддержки нескольких сетевых драйверов. CNM основан на трех компонентах: sandbox (песочница), оконечная точка и сеть.

    Какие типы монтирования доступны в Docker?

    • Bind mount: подключаются к любой точке файловой системы сервера;
    • Volume mount: управляются Docker и хранятся как часть файловой системы сервера;
    • tmpfs mount: хранятся в оперативной памяти сервера, поэтому никогда не пишутся на реальную файловую систему сервера.

    Расскажите о Docker Trusted Registry

    Это хранилище образов для безопасного хранения и управления образами Docker. Его можно установить на своих мощностях, либо в частном облаке. DTR применятся в процессах CI/CD для сборки, поставки и запуска приложений. Его также можно развернуть в отказоустойчивом варианте, есть встроенная система управления доступом.

    Каково назначение docker_host?

    Он задает URL или путь к сокету unix, используемые для соединения с API Docker. Значение по умолчанию — unix://var/run/docker.sock

    Для подключения к удаленному серверу обычно используется TCP, например:
    tcp://192.0.1.20:3230

    Возможен ли запуск нескольких копий одного и того же compose файла на одном и том же сервере? Как именно?

    Это можно сделать с помощью docker-compose, использующего файл YAML для настройки сервисов приложения. После его создания вы можете в одну команду создать и запустить все сервисы. Для того, чтобы начать им пользоваться:

    • Задайте окружение приложения в Dockerfile, так что оно сможет быть реплицировано везде
    • Определите все сервисы вашего приложения в файле docker-compose.yml
    • Запустите docker-compose up для создания и запуска приложения целиком

    Объясните метки объектов в Docker

    Метки объектов Docker — это пары ключ-значение, сохраняемые в виде строк. Мы можем применить метаданные с их помощью. Метки могут быть применены к любому объекту, например, образу, контейнеру, тому, сети, локальным сервисам, узлам swarm и непосредственно сервисам. Каждая пара должна быть уникальной для объекта, сами метки не меняются динамически на протяжении существования объекта.

    Результаты

    Это был список вопросов для собеседования по Docker. Как много ответов вы знали? Просим принять участие в опросе ниже. Также рекомендуем вам ознакомиться с руководствами от сообщества

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Зачем и как использовать контейнеры: разбираемся с Docker, Kubernetes и другими инструментами

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

    Цитируя разработчиков Docker, «контейнер — это стандартная единица программного обеспечения, в которую упаковано приложение со всеми необходимыми для его работы зависимостями — кодом приложения, средой запуска, системными инструментами, библиотеками и настройками».

    Контейнеры используются уже более десяти лет и на сегодняшний день примерно четверть компаний-лидеров в сфере IT задействуют контейнерные решения в продакшене, а ещё столько же, согласно опросам, планировали приступить к этому в 2019-м году.

    На рынке существует немало решений, представляющих среды запуска контейнеров и оркестрации, таких как CoreOS rkt, LXC, OpenVZ, containerd, Apache Mesos и Docker Swarm. Однако более 4/5 контейнеров запускается в среде Docker, а для оркестрации более половины пользователей выбрали Kubernetes. Об этих системах мы и поговорим.

    Чем полезны контейнеры

    Легковесность, быстродействие и возможность работать на высоком уровне абстракции, делегируя проблемы с железом и ОС провайдеру, — это преимущества контейнеров, позволяющие снизить операционные расходы, связанные с разработкой и эксплуатацией приложений, делающих решения на их базе столь привлекательными для бизнеса.

    Техническим же специалистам контейнеры прежде всего полюбились за возможность упаковать приложение вместе с его средой запуска, решая тем самым проблему зависимостей в разных окружениях. Например, различие версий языковых библиотек на ноутбуке разработчика и в последующих окружениях рано или поздно приведёт к сбоям, и нужно будет как минимум потратить время на их анализ, а как максимум — решать проблему проникших в продакшен багов. Использование контейнеров устраняет проблему «А на моей машине все работало! ¯\_(ツ)_/¯».

    Также контейнеры позволяют сократить время разработки приложения и упрощают управление им в продакшене благодаря лёгкости в настройке и изменении конфигурации, возможности версионировать её вместе с кодом приложения и удобным инструментам оркестрирования, позволяющим быстро масштабировать инфраструктуру. Кроме того, фактическое отсутствие привязки контейнеров к хостинговой платформе даёт огромную гибкость при выборе или смене провайдера — вы можете запускать их без принципиальных отличий в конечном результате на личном компьютере, bare metal серверах и в облачных сервисах.

    Чем контейнеры отличаются от виртуальных машин

    Наиболее частым вопросом при выборе среды запуска приложения является вопрос о различии между контейнерами и виртуальными машинами — двумя самыми популярными опциями на текущий момент. Между ними есть принципиальная разница. Контейнер, в сущности, является ограниченным внутри ОС пространством, использующим для доступа к аппаратным ресурсам ядро host-системы. ВМ представляет собой машину целиком со всеми необходимыми для её работы устройствами. Из этого образуются отличия, имеющие практическое значение:

    • Контейнеры требуют значительно меньше ресурсов для своей работы, что положительно сказывается на производительности и бюджете.
    • Контейнеры можно запускать только в той же операционной системе, что стоит на host-системе — то есть запустить Windows-контейнер на host-системе с Linux не получится (на персональных устройствах это ограничение обходится с помощью технологии виртуализации). Однако это не относится к разным дистрибутивам одной и той же ОС, например Ubuntu и Alpine Linux.
    • Контейнеры предоставляют меньшую степень изоляции, поскольку используют ядро host-системы, что потенциально создаёт бóльшие риски в эксплуатации при небрежном отношении к безопасности.

    Основные принципы контейнеризации приложений

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

    1 контейнер — 1 сервис

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

    Неизменность образа

    Все изменения внутри контейнера должны вноситься на стадии сборки образа — соблюдение этого принципа страхует вас от утраты данных при уничтожении контейнера. Неизменность контейнера также даёт возможность выполнять параллельные задачи в CI/CD системах — например, можно одновременно запустить разного рода тестирования, ускоряя тем самым процесс разработки продукта.

    Утилизируемость контейнеров

    Этот принцип являет собой яркий пример современной концепции «Обращайся с инфраструктурой как со скотом, не как с питомцами». Это значит, что любой контейнер может быть в любой момент уничтожен и заменён на другой без остановки обслуживания. Конфигурация контейнера в виде его образа сущностно отделена от непосредственно выполняющего работу экземпляра контейнера, что позволяет «пускать под нож» экземпляры, когда потребуется — при сбое проверки состояния контейнера, масштабировании на понижение и т. д. Соответствие этому принципу означает, что выход контейнеров из строя не должен быть новостью для вашего приложения: ротация контейнеров должна стать одним из требований к разработке.

    Отчётность

    Контейнер должен иметь точки проверки состояния его готовности (readiness probe) и жизнеспособности (liveness probe), предоставлять логи для отслеживания состояния запущенного в нём приложения.

    Управляемость

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

    Самодостаточность

    Образ с приложением должен обладать всеми необходимыми зависимостями для работы — библиотеками, конфигами и прочим. Сервисы же к этим зависимостям не относятся, иначе это противоречило бы принципу «1 контейнер — 1 сервис». Связность контейнеров, зависящих друг от друга, можно определить с помощью инструментов оркестрирования, о чём будет рассказано ниже.

    Лимитирование ресурсов

    К лучшим практикам эксплуатации контейнеров относится настройка ресурсных лимитов (CPU и RAM): следование этой практике позволяет сохранять внимательное отношение к экономии ресурсов и вовремя реагировать на их избыточное потребление.

    Docker

    Когда мы говорим о контейнерах в современных IT-системах, прежде всего мы подразумеваем Docker — open-source-технологию, благодаря своей популярности ставшую в IT синонимом слова «контейнер».

    Основные сущности Docker

    Dockerfile

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

    Image

    Готовая файловая система, сформированная по инструкциям из Dockerfile и служащая прообразом для запускаемых контейнеров.

    Instance

    Запущенный экземпляр образа, минимальная единица деплоя в Docker.

    Volume

    Подключаемая к контейнерам файловая система, не являющаяся их неотъемлемой частью и существующая независимо от образа. С помощью объектов Volume решается проблема сохранности данных, записанных в процессе работы контейнеров в локальной файловой системе после их уничтожения.

    Registry

    Репозиторий, используемый для хранения Docker-образов. Registry может быть как публичным, так и приватным, защищённым механизмом аутентификации.

    Процесс разработки в среде Docker

    Типичный процесс разработки в среде Docker выглядит следующим образом: разработчики устанавливают на свои машины Docker, загружают собранный заранее образ с установленной средой сборки и выполнения приложения, а затем запускают контейнер командой, которая также пробросит в него директорию с исходниками. Для установки Docker не требуется особого железа — он может быть установлен на вполне заурядной машине. Однако у него имеются ограничения по версиям ОС — Windows 7 64bit или выше для ПК с поддержкой Hyper-V, macOS Sierra 10.12 для устройств от Apple и версией ядра 3.10 для систем с Linux. Контейнеры Docker являются родной технологией для ОС Linux и запускаются на других с помощью виртуальных машин под её управлением.

    Инструкции по установке Docker на разных платформах: Windows, Mac, Linux Ubuntu.

    Чтобы запустить ваш первый контейнер на Docker, после его установки введите в командной строке docker run hello-world — эта команда загрузит образ hello-world с Docker hub’а (публично доступный Docker registry), создаст контейнер, используя этот образ, и выдаст приветственную фразу:

    Hello from Docker!This message shows that your installation appears to be working correctly.

    Оркестрирование контейнеров: Kubernetes

    Оркестрирование — это в высокой степени автоматизированный процесс управления связанными сущностями, такими как группы виртуальных машин или контейнеров.
    Kubernetes (также встречается в виде акронима K8s) — это совокупность сервисов, реализующих контейнерный кластер и его оркестрирование. Kubernetes не заменяет Docker — он серьёзно расширяет его возможности, упрощая управление развертыванием, сетевой маршрутизацией, расходом ресурсов, балансировкой нагрузки и отказоустойчивостью запускаемых приложений.

    Основные сущности, которыми оперирует Kubernetes

    Node (master и slave)

    Узлы, из которых состоит кластер Kubernetes. Master-нода осуществляет контроль над кластером через планировщик и менеджер контроллеров, обеспечивает интерфейс взаимодействия с пользователями посредством API-сервера и содержит хранилище etcd, где находится конфигурация кластера, статусы его объектов и метаданные. Slave-нода предназначена исключительно для запуска контейнеров, для этого на ней установлены два сервиса Kubernetes — сетевой маршрутизатор и агент планировщика.

    Namespace

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

    Pod

    Минимальная единица развёртывания в Kubernetes, группа из одного или более контейнеров, собранных для совместного деплоя на ноде. Группировать контейнеры разного вида в Pod имеет смысл, когда они зависят друг от друга и потому должны быть запущены на одной ноде, чтобы сократить время отклика при их взаимодействии. Пример — контейнеры с веб-приложением и кэширующим его сервисом.

    ReplicaSet

    Объект, описывающий и контролирующий соответствие запущенного на кластере количества реплик Pod’ов. Установка количества реплик больше одной требуется для повышения отказоустойчивости и масштабирования приложения. Общепринято создавать ReplicaSet с помощью Deployment.

    Deployment

    Объект, декларативно описывающий Pod’ы, количество реплик и стратегию их замены при обновлении параметров.

    StatefulSet

    Действует по тому же принципу, что и ReplicaSet, однако дополнительно позволяет описывать и сохранять при перезапуске уникальный сетевой адрес Pod’ов или их дисковое хранилище.

    DaemonSet

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

    Job и CronJob

    Объекты, запускающие соответственно однократно и регулярно по расписанию указанный Pod и отслеживающие результат завершения его работы.

    Label и Selector

    Метки, позволяющие маркировать ресурсы и тем самым упрощать групповые манипуляции, связанные с ними.

    Service

    Инструмент для публикации приложения в качестве сетевого сервиса, в том числе реализующий балансировку нагрузки между Pod’ами приложения.

    Если сравнить объекты Docker и Kubernetes, то станет понятна разница в задачах, решаемых этими инструментами: можно сказать, что Docker управляет контейнерами, в то время как Kubernetes управляет самим Docker.

    Управление конфигурацией (Configuration/Complexity Management)

    Развитие IT-систем ведёт ко всё большему их усложнению, и это порождает проблемы управления — даже на небольшом количестве серверов или контейнеров ручное управление приложением превращает практически любое изменение конфигурации в трудовой подвиг, а на десятках или сотнях делает его абсолютно невозможным. К счастью, новые проблемы ведут и к новым решениям — в этом разделе мы расскажем о некоторых инструментах управления конфигурацией (configuration management) или, как ещё принято говорить, управления сложностью (complexity management). Они используются для установки, управления и обновления приложений Kubernetes: например, с их помощью можно описать приложение, состоящее из фронтенда, бэкенда и всех необходимых для их работы сервисов, таких как объекты Kubernetes, контейнеры с веб-серверами, базами данных, серверами очередей и т. д.

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

    Kustomize

    Благодаря популярности у пользователей и своей простоте, начиная с версии Kubernetes 1.14, Kustomize является встроенным инструментом управления конфигурацией. Для описания приложений использует чистый язык разметки YAML без возможности шаблонизации и использования параметров, что является одновременно его сильной и слабой сторонами, упрощая процесс настройки и вместе с тем сильно его ограничивая.

    Ansible

    Многофункциональный инструмент, для которого конфигурация Kubernetes-приложений — лишь одно из великого множества применений, реализованная с помощью специального модуля интеграции. Например, Ansible может быть использован для настройки виртуальных машин, развертывания облачной инфраструктуры, выполнения бэкапов и т.д. Его универсальность позволяет решать разнообразные задачи, связанные с IT-проектами, одним инструментом – но ценой меньшей функциональности в отношении управления конфигурацией приложений Kubernetes. Для описания использует YAML и язык шаблонов Jinja2.

    Jsonnet

    Также как и Ansible, Jsonnet не является чем-то специфичным для Kubernetes, однако многие знакомы с ним именно благодаря K8s. Jsonnet описывает объекты с помощью расширенного JSON, включающего комментарии, текстовые блоки, параметры, переменные, условные включения и функции. Очень мощный и гибкий инструмент.

    Helm

    Пакетный менеджер приложений Kubernetes. Этот инструмент описывает приложения в виде декларативных диаграмм (charts), создающихся с помощью языка разметки YAML и шаблонов Golang. Helm обладает широкой базой готовых диаграмм, даёт возможность версионировать конфигурации и переключаться между версиями релизов, т. е. откатывать конфигурацию. Из всех приведенных здесь инструментов является наиболее функциональным в отношении управления приложениями Kubernetes и одновременно обладает наиболее сложным способом описания конфигурации из-за шаблонов Golang, весьма требователен к пользовательским навыкам.

    В этой статье перечислены лишь те инструменты, что наиболее заслуживают внимания по нашему мнению. Помимо них существует ещё с добрый десяток решений для задач управления конфигурацией в Kubernetes: такие как Kapitan, Ksonnet, Replicated Ship и т. д. При выборе менеджера управления конфигурацией мы рекомендуем определиться с требованиями, предъявляемыми к нему, и руководствоваться принципом разумной достаточности, не используя без нужды излишне сложный инструмент – хорошим путем будет начать с чего-то простого, дополнительно задействуя более мощный инструмент, когда возникнет необходимость.

    Платформы для хостинга контейнеров

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

    Своё железо (bare metal)

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

    Облачные решения (SaaS)

    Крупные облачные провайдеры предоставляют своим клиентам сервисы для запуска контейнеров — готовые среды, обёрнутые удобным интерфейсом управления. Построенные по такому принципу решения называются Software as a Service (SaaS). Они не требуют никаких капитальных затрат, поскольку вся инфраструктура арендуется, а конфигурация создаётся в минимальном объёме, относящемуся исключительно к запускаемому приложению. Сами же кластеры настраиваются провайдером по указанному пользователем небольшому объему параметров. SaaS-решения — оптимальный вариант для стартап-компаний, небольших и развивающихся проектов. Самым большим минусом этого решения можно назвать повышенную в сравнении с bare metal стоимость при условии многолетнего использования.

    Тремя наиболее популярными облачными платформами на сегодня являются Amazon Web Services, Microsoft Azure и Google Cloud. Все три провайдера имеют доступный в виде сервиса Kubernetes, и все три из них предлагают пробный период пользования сервисами, выдавая депозит на сумму 200–300 $. Чтобы оценить удобство и качество облачных решений и сравнить друг с другом их поставщиков, вам даже не придется тратить свои деньги.

    Заключение

    Ещё недавно не смолкали дебаты на тему оправданности использования контейнеров в продакшене, то и дело были слышны обвинения в их ненадежности. Однако время не стоит на месте, индустрия оценила их перспективность, сделала свой выбор, и инвестиции в контейнерные решения потекли широкой рекой, с каждым днем делая решения на их базе всё удобнее и привлекательнее. На сегодняшний день примитивную настройку кластера и деплой приложений в него можно выполнить используя один лишь веб-интерфейс, предварительно прочитав несколько страниц документации — настолько это стало просто. А их низкая по сравнению с виртуальными машинами стоимость откусывает у ВМ всё большую долю рынка, забирая то, что не требует для своей работы специфики устройства ВМ. Безусловно, контейнеры зарекомендовали себя как жизне- и конкурентоспособное решение, сокращающее время вывода продукта на рынок, стоимость его разработки и эксплуатации.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *