Uploaded by amt2007

¥¬  8. GitLab, Docker, Kubernetes ¢¥à.1

advertisement
Жизнь - это движение! А тестирование - это жизнь :)
ООО «Имплика»
Учебное пособие для самостоятельного изучения
Курс «Тестирование Web-приложений»
GitLab, Docker, Kubernetes
2021
Оглавление
Введение................................................................................................................ 7
1. GitHub? ............................................................................................................... 8
1.1 Возможности GitHub ..................................................................................... 9
1.2 Продвинутое использование GitHub: интерактивная подготовка ............ 9
1.3 Продвинутое использование GitHub: правим историю ........................... 10
1.4 Изменяем сообщение коммита в GitHub и разбиваем коммиты ............. 10
1.5 Перезапись нескольких коммитов в GitHub.............................................. 10
1.6 Объединение нескольких коммитов в GitHub .......................................... 11
1.7 Переносим отдельный коммит в GitHub ................................................... 11
2. GitLab ............................................................................................................... 12
2.1 Возможности GitLab .................................................................................... 12
2.2 Основные этапы работы с GitLab ............................................................... 14
2.2.1 Создание аккаунта ................................................................................. 14
2.2.2 Создание репозитория ........................................................................... 16
2.2.3 Загрузка файлов проекта ....................................................................... 17
2.2.4 SSH-ключи .............................................................................................. 18
2.2.5 Ветки репозитория ................................................................................. 20
2.2.6 Слияние веток......................................................................................... 22
2.2.7 Добавление пользователей.................................................................... 23
2.2.8 Как создавать баг-репорты....................................................................... 24
2.2.8 Удаление проекта ................................................................................... 25
2.3 Возможные проблемы ................................................................................. 25
2.4 Итог................................................................................................................ 25
3. Docker ............................................................................................................... 27
3.1 Чем docker отличается от VM .................................................................. 27
3.2 Зачем докер тестировщикам .................................................................... 28
3.4 Docker: основы .......................................................................................... 29
3.4.1 Концепции Docker ................................................................................. 29
3.4.1.1 Виртуальные машины ........................................................................ 29
3.5
Docker: термины и концепции ............................................................. 30
3.5.1 Платформа Docker ................................................................................. 30
2
3.5.2 Движок Docker ....................................................................................... 30
3.5.3 Клиент Docker ........................................................................................ 31
3.5.4 Демон Docker.......................................................................................... 31
3.5.5 Тома Docker ............................................................................................ 31
3.5.6 Реестр Docker ......................................................................................... 32
3.5.7 Хаб Docker .............................................................................................. 32
3.5.8 Репозиторий Docker ............................................................................... 32
3.5.9 Сеть Docker ............................................................................................. 32
3.5.10 Docker Compose.................................................................................... 33
3.5.11 Docker Swarm ....................................................................................... 33
3.5.12 Сервисы Docker .................................................................................... 33
3.5.13 Kubernetes ............................................................................................. 34
3.6
Docker: файлы Dockerfile ...................................................................... 34
3.6.1 Образы Docker ........................................................................................ 34
3.6.2 Файлы Dockerfile .................................................................................... 35
3.6.3 Инструкции Dockerfile и примеры их использования ....................... 35
3.6.3.1 Простой Dockerfile .............................................................................. 36
3.6.3.2 Инструкция FROM.............................................................................. 36
3.6.3.3 Более сложный Dockerfile .................................................................. 37
3.6.3.4 Инструкция LABEL ............................................................................ 38
3.6.3.5 Инструкция ENV ................................................................................. 38
3.6.3.6 Инструкция RUN ................................................................................ 39
3.6.3.7 Инструкция COPY .............................................................................. 39
3.6.3.8 Инструкция ADD ................................................................................ 40
3.6.3.9 Инструкция CMD ................................................................................ 40
3.6.3.10 Ещё более сложный Dockerfile ........................................................ 40
3.6.3.11 Инструкция WORKDIR .................................................................... 42
3.6.3.12 Инструкция ARG .............................................................................. 42
3.6.3.13 Инструкция ENTRYPOINT .............................................................. 42
3.6.3.14 Инструкция EXPOSE ........................................................................ 43
3.6.3.15 Инструкция VOLUME ...................................................................... 44
3.7 Docker: Размер образа и ускорение их сборки ....................................... 44
3
3.7.1 Кэширование .......................................................................................... 44
3.7.2 Уменьшение размеров образов............................................................. 46
3.7.2.1 Тщательный подбор базового образа ............................................... 46
3.7.2.2 Многоступенчатая сборка образов ................................................... 47
3.7.2.3 Файл .dockerignore .............................................................................. 48
3.7.3 Исследование размеров образов........................................................... 49
3.7.4 Рекомендации по уменьшению размеров образов и ускорению
процесса их сборки ......................................................................................... 49
3.8 Docker: команды........................................................................................ 50
3.8.1 Общие сведения о командах Docker .................................................... 51
3.8.2 Примечание о командах, поддерживаемых Docker CLI 1.13 ............ 51
3.8.3 Команды для управления контейнерами ............................................. 51
3.8.4 Команды для управления образами ..................................................... 52
3.8.5 Разные команды ..................................................................................... 52
3.8.6 Контейнеры............................................................................................. 53
3.8.6.1 Начало существования контейнера................................................... 53
3.8.6.2 Проверка состояния контейнера ....................................................... 54
3.8.6.3 Завершение работы контейнера ........................................................ 55
3.8.7 Образы ..................................................................................................... 56
3.8.7.1 Создание образов ................................................................................ 56
3.8.7.2 Исследование образов ........................................................................ 57
3.8.7.3 Удаление образов ................................................................................ 57
3.8.8 Разные команды ..................................................................................... 58
3.9 Docker: работа с данными ........................................................................ 58
3.9.1 Временное хранение данные ................................................................ 58
3.9.2 Постоянное хранение данных............................................................... 59
3.9.3 Тома Docker ............................................................................................ 59
3.9.4 Создание томов ...................................................................................... 60
3.9.5 Работа с томами из командной строки ................................................ 60
3.9.5.1 Создание тома ..................................................................................... 60
3.9.5.2 Выяснение информации о томах ....................................................... 60
3.9.5.3 Удаление тома ..................................................................................... 61
4
3.9.5.4 Флаги --mount и --volume ................................................................... 61
3.10 Вывод ....................................................................................................... 62
4. Kubernetes: основы, установка и настройка ................................................. 64
4.1
История создания ......................................................................................... 64
4.2
Как работает технология ............................................................................. 65
4.1.1
Принципы устройства .............................................................................. 65
4.1.2
Основные задачи Kubernetes ................................................................... 65
4.1.3
Преимущества K8s ................................................................................... 65
4.3
Основные компоненты кластера ................................................................ 66
4.4
Основные объекты кластера Kubernetes .................................................... 68
Node (Нода)...................................................................................................... 68
Namespaces (пространства имен) .................................................................. 69
Pod (Под) .......................................................................................................... 70
Controllers (Контроллеры) .............................................................................. 72
Label/Selector (Метки/Селекторы)................................................................. 75
Service (Сервис) ............................................................................................... 75
Persistent Volumes (Постоянные тома) .......................................................... 76
Процесс установки....................................................................................... 78
4.5
Установка контейнеров на Ubuntu 16.04 ...................................................... 79
Установка контейнеров в CentOS 7 .............................................................. 80
Установка kubeadm, kubelet и kubectl в Ubuntu ........................................... 80
Установка kubeadm, kubelet и kubectl в CentOS .......................................... 81
4.6
Настройка Kubernetes .................................................................................. 82
4.6.1
Инициализация кластера.......................................................................... 82
4.6.2
Настройка CNI .......................................................................................... 83
4.6.3
Добавление узлов (нод) в кластер........................................................... 84
4.6.4
Получение токена авторизации кластера (<token>) .............................. 84
4.6.5
Дополнительные настройки .................................................................... 85
4.7
Проверка работоспособности кластера ..................................................... 85
4.8
Расширяемость кластера сторонними инструментами ............................ 86
4.9
Нужен ли вам Kubernetes? .......................................................................... 86
4.10 Итог ............................................................................................................... 87
5
Источники ........................................................................................................ 87
6
Введение
Каждому тестировщику важно знать и понимать, чем отличаются и
схожи Git, GitLab и GitHub.
Ранее была рассмотрена система контроля версий Git (Тема 3.
«Система контроля версий»), которая представляет собой распределенную
систему контроля версий. Она позволяет разработчикам контролировать
изменения в файлах и работать совместно с другими специалистами. Git также
локально сохраняет весь репозиторий в файл небольшого объема, не снижая
качества данных.
GitHub — крупнейший веб-сервис для хостинга IT-проектов и их
совместной разработки. Веб-сервис основан на системе контроля версий Git и
разработан на Ruby on Rails и Erlang компанией GitHub, Inc. Сервис бесплатен
для проектов с открытым исходным кодом и небольших частных проектов,
предоставляя им все возможности (включая SSL), а для крупных
корпоративных проектов предлагаются различные платные тарифные планы.
GitHub идеален для введения в Git и дополняет VCS новыми
возможностями.
Создатели сайта называют GitHub «социальной сетью для
разработчиков». Кроме размещения кода, участники могут общаться,
комментировать правки друг друга, а также следить за новостями знакомых.
С помощью широких возможностей Git программисты могут
объединять свои репозитории — GitHub предлагает удобный интерфейс для
этого и может отображать вклад каждого участника в виде дерева.
Для проектов есть личные страницы, небольшие Вики и система
отслеживания ошибок.
Прямо на сайте можно просмотреть файлы проектов с подсветкой
синтаксиса для большинства языков программирования.
Можно создавать приватные репозитории, которые будут видны только
вам и выбранным вами людям. Раньше такая возможность была платной.
Есть возможность прямого добавления новых файлов в свой
репозиторий через веб-интерфейс сервиса.
Код проектов можно не только скопировать через Git, но и скачать в
виде обычных архивов с сайта.
Кроме Git, сервис поддерживает получение и редактирование кода
через SVN и Mercurial.
На сайте есть pastebin-сервис gist.github.com для быстрой публикации
фрагментов кода.
GitHub ограничивает перечень возможностей для пользователей,
проживающих в странах и регионах, на которые распространяются
американские ограничения и санкции, таких как Крым, Куба, Иран, Северная
Корея и Сирия.
GitLab — веб-инструмент жизненного цикла DevOps с открытым
исходным кодом, представляющий систему управления репозиториями кода
7
для Git с собственной вики, системой отслеживания ошибок, CI/CD
пайплайном и другими функциями.
Код изначально был написан на Ruby, а некоторые его части были
позже переписаны на Go. Первоначально GitLab представлял собой решение
для управления исходным кодом и совместной разработки, созданное
Дмитрием Запорожцем для собственных нужд. Позже GitLab превратился в
интегрированное решение, охватывающее весь жизненный цикл разработки
программного обеспечения, а затем и весь жизненный цикл DevOps. Текущий
стек технологий включает в себя Go, Ruby on Rails и Vue.js.
Как известно, главный конкурент GitLab — это сервис GitHub.
Появился он на три года раньше (в 2008), поэтому более популярен. Да что там
говорить, GitHub сегодня — это сайт номер один по размещению open sourceпроектов. Они почти все на нём и размещаются.))) И у многих людей Git
напрямую ассоциируется с сервисом GitHub.
Да, плюсов у GitHub много, но мы не будем сейчас сравнивать оба
сервиса. Скажем только, что несмотря на повышенную популярность и
огромнейшее комьюнити GitHub (26 млн. человек), наблюдается тенденция
перехода крупных команд разработчиков на GitLab. Это происходит
благодаря расширенным возможностям второго.
Оба сервиса предназначены для использования группами
разработчиков, поэтому многие функции и возможности GitHub и GitLab
дублируются. Вместе с тем, есть и отличия:

В GitLab реализована встроенная бесплатная непрерывная
интеграция. В GitHub есть инструмент Actions. Он позволяет запускать
бесплатные непрерывные интеграции в публичных репозиториях, а что
касается частных репозиториев — стоимость указана здесь.

GitLab
задействует
Kubernetes
для
беспроблемного
развертывания. В GitHub встроенной платформы развертывания нет.

В GitLab есть бесплатные репозитории частного формата для
проектов, имеющих открытый исходный код. В GitHub такого нет.
Подробнее о том, чем еще отличается GitLab, можно прочитать на
официальном сайте веб-приложения.
1. GitHub?
GitHub — это платформа, хранящая различные Git-репозитории на
своих многочисленных серверах. Также GitHub называют крупнейшим вебсервисом для хостинга и совместной разработки IT-проектов. Гитхаб основан
на системе контроля версий Git и разработан компанией GitHub на Ruby on
Rails. Он бесплатен для тех проектов, которые имеют открытый исходный код.
Для крупных корпоративных клиентов доступны платные тарифные планы.
Создатели говорят, что GitHub — это социальная сеть для
разработчиков, ведь участники могут не только кодить, но и общаться,
8
следить за новостями, комментировать правки других. Слоган GitHub —
«Пишем код вместе» (Social Coding), хотя часто можно встретить и другую
его интерпретацию, англоязычный вариант которой намекает на
неформальность общения: Fork you! («Ответвись!»).
1.1 Возможности GitHub
Если вы являетесь пользователем GitHub, вы можете без проблем
хранить удалённые репозитории на данных серверах и одновременно с этим
вносить свой вклад в репозитории open-source. По сути GitHub дополняет
использование Git, плюс открывает некоторые новые возможности.
К примеру, появляется возможность сделать форк удалённого
репозитория, создав свою копию репозитория на GitHub-сервере. Это может
быть полезным, если у вас отсутствуют права на создание ветви в
оригинальном репозитории. После того, как вы используете команду git clone,
ваш локальный репозиторий сможет отслеживать оригинальный репозиторий
как upstream, а удалённый форк как origin.
После этого может возникнуть необходимость слить тематическую
ветвь удалённого репозитория в основную ветвь оригинального. Для этого
создаётся новый запрос на внесение изменений (Pull Request), причём GitHub
проверит наличие конфликтов перед выполнением слияния. Также в запросе
можно обсуждать код, а все коммиты, отправляемые вами в удалённую ветвь,
автоматически добавятся в запрос.
1.2 Продвинутое использование GitHub: интерактивная
подготовка
В GitHub можно удобно управлять областью подготовленных файлов
(допустим, для фиксации вместо одного большого коммита нескольких
небольших). Для этого используется интерактивная консоль, запускаемая
следующим образом:
git add –i
В данной консоли пользователю доступны 8 команд:
• update — для подготовки отслеживаемых файлов;
• revert — убирает несколько либо один файл из подготовленной
области;
• status — показывает для каждого из файлов краткое описание (что
подготовлено/не подготовлено);
• add untracked — обеспечивает подготовку неотслеживаемого файла;
• patch — служит для подготовки лишь части файла (это полезно, если
вы изменили несколько функций, однако хотите разбить изменения на
некоторое число коммитов);
• quit — для выхода из интерактивной консоли;
9
• diff — показывает перечень подготовленных файлов, плюс даёт
возможность увидеть изменения по каждому из них;
• help — показывает краткое описание каждой команды.
Если вы видите рядом с файлом символ *, это значит, что команда
изменит его статус на «неподготовлен» либо «подготовлен» в зависимости от
того, происходит откат либо обновление. Если нажмёте Enter, не введя данные
ни в одно из подменю команды, имеющиеся файлы перейдут в
подготовленное/неподготовленное состояние.
Учтите, что создание патчей возможно как в интерактивной консоли,
так и посредством команды git add -p.
1.3 Продвинутое использование GitHub: правим историю
Для улучшения контроля над историей коммитов локальной ветви
используют команду:
git rebase -i HEAD~n
Она открывает интерактивную консоль в целях перемещения набора
последних n-коммитов, которые перечислены в порядке от старых к новым.
Так вы сможете «отредактировать историю», но учтите, что оригинальные
коммиты можно лишь переместить, но не изменить.
Также можно изменить порядок коммитов, поменяв порядок их
перечисления.
1.4 Изменяем сообщение коммита в GitHub и разбиваем коммиты
Чтобы указать коммит, который нужно изменить, используют команду
edit. Далее, когда Git будет выполнять перемещение, он на этом коммите
остановится. После этого для изменения сообщения либо подготовки забытых
файлов можно будет воспользоваться git commit –amend.
Когда желаете разделить коммит, введите после остановки git reset
HEAD^ (в итоге HEAD будет перемещён назад на один коммит, а все
изменённые в данном коммите файлы перейдут в статус «неподготовленные»).
После этого можно зафиксировать файлы в отдельных коммитах привычным
образом. После завершения редактирования, используйте команду:
git rebase --continue
1.5 Перезапись нескольких коммитов в GitHub
В некоторых случаях нужно перезаписать несколько коммитов — для
этого предусмотрена команда git filter-branch. Допустим, если хотите удалить
по ошибке зафиксированный файл, введите:
git filter-branch --tree-filter 'git rm -f <имя файла>' HEAD
10
При этом помните, что вся история перемещается.
1.6 Объединение нескольких коммитов в GitHub
Рисунок 1 – Объединение нескольких коммитов
При работе над новой функцией в проекте можно постепенно
фиксировать малейшие изменения в тематической ветви. Но это засоряет
историю небольшими коммитами, что иногда не соответствует правилам
проекта. Это можно исправить, если объединить ряд маленьких коммитов в
один большой. Тут используйте команду pick, с помощью которой вы сможете
выбрать первый коммит, а с помощью squash — все последующие. В
результате Git применит все изменения в одном коммите, плюс попросит
отредактировать сообщение для общего коммита.
1.7 Переносим отдельный коммит в GitHub
Кроме перемещения и слияния, вас может интересовать, например,
какой-нибудь определённый коммит. Представьте, что есть локальная ветвь
drafts, в которой вы трудитесь над несколькими потенциальными статьями,
однако хотите опубликовать лишь одну из них. Чтобы это сделать,
предусмотрена команда git cherry-pick. А чтобы получить определённые
коммиты, используйте:
git log <основная ветка>..<тематическая>
Учтите, что так создаётся новый коммит, который лишь повторяет
diff выбранного вами коммита. То есть он повторяет разницу между этим
коммитом и предыдущим, однако не его состояние.
11
Рисунок 2 – Перенос коммита
2. GitLab
При разработке программного обеспечения большое значение имеют
службы контроля версий, автоматизации, развертывания и тестирования.
Когда дело касается репозиториев Git, в этом может помочь GitLab —
современное решение для коллективной разработки.
GitLab представляет собой веб-приложение и систему управления
репозиториями программного кода для распределенной системы контроля
версий Git. GitLab, как правило, используется с Git, что позволяет
разработчикам сохранять написанный код в онлайн-формате и работать с
другими разработчиками над разными проектами.
GitLab позволяет взаимодействовать с репозиториями, управлять
правами доступа и пользователями, отслеживать ошибки, автоматизировать
процессы и выполнять многие другие операции. Установить и использовать
его можно на собственном сервере или же в облаке.
2.1 Возможности GitLab
GitLab — это отличный инструмент для разработчиков, который
предоставляет следующие возможности: — управление публичными и
приватными git-репозиториями; — управление пользователями и группами,
правами доступа к git-репозиториям; — отслеживание ошибок, деплой, анализ
кода; — интеграция с разными CI-системами CI (Jenkins и т. п.), организация
самостоятельного процесса CI посредством встроенных средств.
Есть и другие возможности (функционал api, wiki страниц, доски
задач и идей, отслеживание изменений, комментарии к проектам и прочие).
Подробнее можно узнать из официальной документации.
Основные возможности GitLab представлены ниже.
Планирование. GitLab способен эффективно поддерживать различные
модели коллективной работы вне зависимости от выбранной методологии
разработки. Гибкие инструменты управления проектами GitLab позволяют
делать процесс разработки наглядным, координировать его, отслеживать и
назначать приоритеты.
Создание. С Gitlab команда разработчиков может консолидировать
исходный код в общей распределенной среде контроля версий. Веб-сервис
12
позволяет управлять и поддерживать распределенную среду, не нарушая
процессы разработки.
GitLab имеет целый арсенал инструментов для управления ветками и
доступом к проектам, создавая общую достоверную среду для совместной
работы команды разработчиков.
Тестирование. В GitLab реализованы инструменты ревью кода, его
тестирования и оценки качества, что позволяет разработчикам быстрее
находить ошибки и сокращать цикл их исправления.
Можно персонально настраивать модель приемки качества,
тестировать код в автоматическим режиме и назначать изменения в среды
тестирования для каждой версии кода.
Сборка. Репозиторий контейнеров GitLab дает возможность создавать
безопасное хранилище кастомных образов контейнеров Docker. Причем для
этого не придется задействовать дополнительные инструменты —
возможности скачивания и загрузки образов внедрены в среду управления
репозиторием Git по умолчанию.
Релиз. Компоненты поддержки технологий непрерывной доставки и
развертывания позволяют эффективно автоматизировать операции, связанные
со сборкой, автоматическим тестированием и установкой релизов. Установка
релиза как на один сервер, так и на множество, будет занимать минимум
времени.
Конфигурирование. GitLab позволяет автоматизировать весь процесс
разработки приложения. Для этого предоставляются готовые шаблоны
моделей, с которыми начать работу можно без сложных предварительных
настроек — достаточно добавить специфику приложения на каждом этапе
сборки и развертывания.
В качестве сервиса с предварительно настроенными шаблонами
приложений для разработки можно использовать GitLab CE Virtual
Appliance.
Мониторинг. С GitLab можно отслеживать время, затраченное на
каждый этап, проверять работоспособность приложения, собирать и
просматривать метрики, а также анализировать, как изменения кода влияют на
производительность среды.
13
Рисунок 3 – Пример страницы Мониторинга
2.2 Основные этапы работы с GitLab
Рассмотрим основные этапы работы с GitLab:
2.2.1 Создание аккаунта
На GitLab простая процедура регистрации. На главной странице
официального сайта есть форма входа, в которой надо ввести только имя
пользователя или адрес электронной почты и придумать пароль. После
отправки запроса остается только подтвердить регистрацию в письме,
отправленном на указанную почту.
14
Рисунок 4 – Страница регистрации в GitLab
Для начала, зарегистрируемся на сайте GitLab. Для этого нужно
перейти на вкладку Register, которая находится в правой части экрана.
Появится форма, где нужно будет ввести имя, логин, электронную почту.
Далее вы получите на почту сообщение, где будет находиться ссылка
для подтверждения аккаунта. После перехода по ней появится форма
авторизации.
Рисунок 5 – Учетная запись готова
Учетная запись готова. Теперь можно переходить непосредственно к
знакомству с GitLab.
15
Для входа можно использовать аккаунты в других сервисах и
социальных сетях.
Путём ввода пароля и логина вы окажетесь на главной странице вашего
профиля на GitLab. Сначала это будет страница приветствия, но позже здесь
появится перечень ваших Git-репозиториев.
2.2.2 Создание репозитория
Проектом в GitLab считается глобальное рабочее пространство, в котором
будет размещен репозиторий с файлами ваших сайтов и приложений. А также в
нем можно взаимодействовать с коллегами и использовать другие возможности
сервиса.
Рисунок 6 –
Поэтому при первом входе под своей учетной записью GitLab попросит
вас указать род деятельности, наличие или отсутствие команды, имя рабочей
группы и название проекта.
После формирования проекта можно переходить непосредственно к
созданию репозиториев, загрузке программ в GitLab и т.п.
Для добавления проекта GitLab потребуется кликнуть по значку +,
который находится в центре верхней панели. Далее нужно выбрать New
Project:
16
Рисунок 7 – Страница создания проекта
Теперь вводим имя и описание репозитория, выбираем уровень
доступа. Их существует три: — Private. Доступен только для вас; — Internal.
К репозиторию смогут получить доступ все зарегистрированные
пользователи; — Public. Свободный доступ для всех.
Также можно инициализировать репозиторий файлом README,
поставив соответствующую галочку. Однако, если планируете залить файлы
из уже существующего Git-репозитория, то не стоит этого делать.
Чтобы попасть на страницу репозитория, нажмите кнопку «Create
repo». GitLab предложит первоначальный набор действий с целью
проинициализировать ваш репозиторий. В итоге вы сможете создать файлы
здесь либо загрузить их из своего ПК.
Также GitLab позволяет настроить работу удаленного репозитория. Это
значит, что продвинутые пользователи смогут решать большинство рутинных
задач через консольные команды или графических клиентов.
2.2.3 Загрузка файлов проекта
В интерфейсе предусмотрены удобные варианты загрузки проектов. На
главной странице репозитория можно загрузить файл, создать новый файл,
добавить лицензию и файл Readme. При этом загрузка файлов с компьютера
выполняется быстро, не требует переформатирования или других операций.
Теперь перейдём к созданию нового локального репозитория на ПК и
загрузим содержимое на GitLab. Сначала создадим папку репозитория, назвав
её, к примеру, test-repo. Теперь проинициализириуем в ней новый
репозиторий, используя команду git:
mkdir test-repo && cd test-repo
git init
17
Теперь создаём файл test.txt:
vi test.txt
This is test losst repo
И фиксируем изменения:
git add test.txt
git commit -m "Inital commit"
Сейчас давайте добавим наш удалённый репозиторий с GitLab к
нашему локальному, выполнив следующую команду:
git remote add origin https://gitlab.com/losst/test-repo.git
Потом отправим изменения в удалённый репозиторий:
git push origin master
Чтобы отправить данные, введём пароль и логин на GitLab. После
обновления страницы на GitLab, увидим наш файл:
Рисунок 8 –
Кстати, если удалённый репозиторий пустым не является, так сделать
не получится. Потребуется сначала его скачать, слить с ним локальные
изменения, а только потом отправить всё назад.
2.2.4 SSH-ключи
При загрузке данных на GitLab требовалось ввести пароль и логин на
сервере. Но есть и другой путь — SSH-ключи для авторизации. Для создания
ключа выполните:
ssh-keygen
18
Рисунок 9 –
Потом вводим путь к файлу сохранения ключ и оставляем пароль
пустым. В результате создаются 2 файла — закрытый ключ и открытый с
расширением .pub. Нас интересует открытый, поэтому мы открываем его в
текстовом редакторе и копируем содержимое в буфер обмена:
vi /home/sergiy/.ssh/id-gitlab
Потом возвращаемся GitLab-интерфейсу, кликаем по иконке профиля
и выбираем настройки Settings:
Рисунок 10 –
Потом ищем на левой панели пункт SSH Keys. Далее находим Key и
вставляем в соответствующее поле скопированный ключ. Всё, осталось лишь
сохранить изменения.
19
Рисунок 11 –
Теперь возвращаемся в репозиторий, находим кнопку Clone (правый
верхний угол) и кликаем по ней. Интересует адрес Clone with SSH:
Рисунок 12 –
Возвращаемся в локальный репозиторий, удаляем https, добавляем
ssh:
git remote remove origin
git remote add origin git@gitlab.com:losst/test-repo.git
На этом настройка ssh в GitLab закончена. С этого момента все
действия выполняются по SSH, поэтому вводить логин и пароль не
потребуется.
SSH-ключи можно использовать для авторизации в GitLab и для
управления репозиториями по протоколу Secure Shell. Чтобы это сделать:
1. Генерируем ключ с помощью команды ssh-keygen (вводим ее
в терминал).
2.2.5 Ветки репозитория
20
По умолчанию репозиторий имеет лишь master-ветку. Однако
разработку можно выносить и в отдельные ветки, что позволит реализовать
дополнительные функции.
Ветки в GitLab-интерфейсе отображаются слева:
Рисунок 13 –
Для создания новой, кликаем по значку + и выбираем New branch.
Также, если вы создадите ветку в git, а потом зальёте в репозиторий
изменения, ветка появится там автоматически.
Рисунок 14 –
Если ветку по умолчанию нужно изменить, открываем настройки
репозитория (Settings -> Repository), где выбираем нужную ветку в разделе
Default branch:
21
Рисунок 15 –
2.2.6 Слияние веток
Мерджинг (или объединение) веток – это механизм слияния двух наборов
функций одной программы, позволяющий переносить функции из
дополнительных веток в основную ветку разработки, где лежит приложение.
Результат увидят еще и пользователи, а не только разработчики.
В ветках разрабатывается функциональность, поэтому может
потребоваться их перенос — для этого предназначены запросы слияния
(«Merge request gitlab»). Продемонстрируем это на ветке new-feature, где
создадим файл new-feature с текстом:
git checkout -b new-feature
vi new-feature.txt
New feature with change
git add new-feature.txt
git commit -m "add feature"
git push --set-upstream origin new-feature
Если мы после этого перейдём в новую ветвь с помощью интерфейса
GitLab, мы увидим появившуюся кнопку Create merge request. Естественно,
нажимаем:
22
Рисунок 16 –
Тут пишем описание Merge Request, выбираем ветку-цель и веткуисточник. Кроме того, можно выбрать пользователя, который получит
уведомление о созданном запросе.
Теперь запрос на слияние следует одобрить. Посмотреть изменения
можно через терминал или, нажав кнопку Open IDE. Чтобы слить ветки,
осталось нажать кнопку Merge.
Запрос на объединение веток будет появляться на сайте GitLab каждый
раз, когда вы будете вносить изменения в код одной или нескольких веток.
Выглядит это следующим образом:
 На сайте появляется большая синяя кнопка Create merge request.
Кликаем по ней.
 Затем
рассказываем о своем запросе (поясняем, для чего он делается).
 Указываем автор запроса в поле Assignee.
 Указываем человека, который будет проверять запрос в поле Reviewer.
 Потом указываем Milestone (если используете их).
 Ставим теги.
 И нажимаем на Create merge request.
 Если с запросом все ок, то проверяющий нажмет на кнопку Merge, и
весь код перекочует в основную ветку проекта (ну или ту, которую указал автор
запроса).
2.2.7 Добавление пользователей
В GitLab можно добавлять неограниченное количество разработчиков
даже к приватным репозиториям. Чтобы сделать это, надо перейти в меню
«Настройки» (Settings) и выбрать пункт «Участники» (Members). В этом
пункте в поле «Выбрать участника для приглашения» (Select members to invite)
надо указать адрес электронной почты пользователя или его никнейм. Перед
отправкой приглашения также указывается уровень доступа. Для добавления
надо нажать «Добавить в проект» (Add to project):
 Для этого кликаем по кнопке Project information в боковой панели
GitLab.
 Выбираем пункт Members.
 В графу GitLab member or Email address вписываем ник GitLabпользователя или его email-адрес.
 Выбираем для него роль (гость, наблюдатель, разработчик).
23
 Также
указываем время действия приглашения (в указанный день
приглашенный будет исключен из проекта).
 А потом кликаем на Invite.
Рисунок 17 –
Если выбранный человек согласится присоединиться, то ваша команда
расширится.
2.2.8 Как создавать баг-репорты
В git-системах есть инструменты, помогающие оповещать разработчиков
об ошибках и обсуждать их как с пользователями, так и с коллегами.
Речь идет о разделе Issues. Если возникла проблема, то нужно сообщить
о ней тут. Для этого:

Открываем раздел Issues в боковой панели управления.

Затем нажимаем на кнопку New issue.
Рисунок 18 –
Даем имя обнаруженной проблеме, а затем подробно описываем ее
в разделе Description.

Затем назначаем ответственного в пункте Assignee и срок, в
течение которого нужно найти решение найденной проблемы.

А потом нажимаем на кнопку Create issue.

24
Рисунок 19 –
2.2.8 Удаление проекта
Для удаления проекта нужно перейти в «Настройки» (Settings) ->
«Главные» (General) -> «Продвинутые» (Advanced) и выбрать пункт «Удалить
проект» (Remove Project). Перед удалением проекта потребуется ввести его
имя.
2.3 Возможные проблемы
При работе с GitLab могут возникать проблемы, для каждой из которых
есть решение:
1. Ошибка при выполнении pull-запросов. Причиной может быть
длительная фаза SSH-аутентификации или низкая скорость обработки
запросов. Решается перенастройкой репозиториев.
2. Ошибка при входе. Может появляться после некорректного
введения логина и пароля учетной записи. Решается удалением данных через
панель управления.
3. Ошибка при запуске. Система может указывать на отсутствие
GitLab-серверов по заявленным IP-адресам. Причиной проблемы может быть
неверное введение команды запуска, использование динамического IP или
ошибки при назначении порта. Решается перенастройкой.
2.4 Итог
На этом все. Рассмотрены базовые возможности GitLab, аналитические
инструменты, интеграция с Kubernetes и дополнительные функции не
25
рассматривались. Это то, что необходимо для старта, независимо от того,
пользовались вы ранее другими системами управлениями репозиториями или
нет.
26
3. Docker
Docker — это платформа, которая предназначена для разработки,
развёртывания и запуска приложений в контейнерах. Слово «Docker» в
последнее время стало чем-то вроде синонима слова «контейнеризация». И
если вы ещё не пользуетесь Docker, но при этом работаете или собираетесь
работать в сферах разработки приложений или анализа данных, то Docker —
это то, с чем вы непременно встретитесь в будущем.
Docker — это контейнер для приложения. В котором уже всё настроено
— и операционная система, и сервер приложения, и вся инфраструктура. Бери
да используй!
Docker активно используют разработчики и тестировщики для
проверки приложений. Его используют и для поставок клиентам готового
продукта. В нем поднимают приложения, гоняют автотесты...
3.1 Чем docker отличается от VM
Принципы работы у них очень похожи. Но докер — это не виртуальная
машина. И работает он на другом уровне. Давайте разберемся в отличиях.
Исходно у нас есть наш основной компьютер, на котором мы всё
запускаем. Его принято называть хост-машиной, или хостом. Хост система —
та система, в которой стартует контейнер докера или виртуальная машина. Это
может быть отдельный сервер или домашний компьютер. Или даже
виртуальная машина!
Любая программа, запущенная на Хосте, обращается к OS этой
системы. И через нее к железу.
Обычная ВМ (виртуальная машина) — по сути своей компьютер в
компьютере. У него есть собственное железо, хоть и виртуальное: своя
операционная система, своё ядро... Да, железо работает на ресурсах хостсистемы, но программа, установленная на виртуалке, будет обращаться
именно к железу виртуальной машины.
В отличие от виртуальных машин докер не создает отдельное ядро. Не
требует установки операционной системы, выделения памяти и процессорных
мощностей.
Вместо этого он использует существующую в линукс-системах
технологию, которая позволяет запускать код в отдельных namespace. Код,
запущенный таким образом, полностью отделен от работы основной системы,
но при этом использует память и процессор просто как очередная программа
в системе. То есть программа, запущенная в докере, обращается напрямую к
железу хост-системы.
По крайней мере так работает в linux системах. Именно там
«настоящий» докер: он работает на технологиях, доступных в этой OS.
В мак или винде такой технологии нет. А значит, сами по себе они не
могут выступать хост-машинами. Поэтому для того, чтобы все работало на
других ОС, были созданы специальные инструменты — например, Docker
27
Desktop и Docker Toolbox. Если не вдаваться в подробности, при запуске они
создают виртуальную машину с линукс, и уже она выступает хост-машиной
для всех ваших контейнеров докера.
Преимущества docker перед VM:
1. Контейнеры докера стартуют быстрее виртуальных машин, ведь им
не надо загружать операционную систему.
2. Потребление ресурсов (диска, процессора, памяти) не
увеличивается само по себе, ведь в контейнере мощности используются
только для запущенных программ, а не для ОС.
3. Сам образ контейнера весит меньше, ведь в нем только нужные вам
программы и больше ничего лишнего.
Docker имеет клиент-серверную архитектуру. Есть клиент, с которого
вы посылаете запросы через restful api, и docker -демон, который их
обрабатывает, а также создает, запускает и распределяет ваши контейнеры.
Клиент и сервер могут находиться как на одной машине, так и на
разных. Технически ничего не мешает вам подключиться к удаленному
серверу докер при помощи вашего клиента.
Клиент докера обычно представляет собой командный интерфейс.
Поэтому увы, красивых кнопочек в интерфейсе не ждите, работайте через
консоль.
3.2 Зачем докер тестировщикам
Когда докер только появился, его считали очередной утилитой для
devops или сисадминов. А тестировщики, мол, дальше как-нибудь на
виртуалках поработают. Но потом стало понятно, что докер удобнее. Что он
дает?
Изоляция процессов
Докер позволяет изолировать любые процессы, в том числе и процессы
запуска тестов. Значит, мы можем сколько угодно раз запустить наши тесты
на нужной системе, так еще и сделать это быстрее, чем с ВМ (виртуальной
машиной). И для этого нам потребуется компьютер меньшей мощности.
Быстрое разворачивание окружений
Докер умеет быстро разворачивать систему. Если нужно запустить
тест, теперь не надо каждый раз разворачивать на свою машину testNG или
selenium, достаточно скачать и запустить нужный вам докер-контейнер. И
при этом потребление памяти будет куда ниже, чем у виртуалки. А, значит,
контейнеров, запущенных одновременно, может быть сколько угодно.
Проверка разных версий
Докер позволяет проверить разные версии одной программы. Или
работу программы на разных окружениях:

centos 6

centos 7
Или на разных серверах приложения:
28

jboss 6

jboss 7.1

wildfly 8.0
Или с разными версиями Java:

JDK 7

JDK 10

JDK 11
В докере это сделать намного проще и быстрее, чем в «обычных»
условиях. Загрузил контейнер из образа, проверил, контейнер прибил.
Профит!
Чистота на рабочей машине
Вы можете поддерживать чистоту на своей рабочей машине. Если
нужно попробовать другую версию какой-то программы, не нужно будет
ставить ее в параллели или удалять старую. Можно просто запустить ее в
другом контейнере.
Отделение от инфраструктуры
Вы можете отделить приложение от инфраструктуры. Вариант «на
моей машине все работает» с докер-контейнером случается куда реже, чем с
машиной разработчика.
3.4 Docker: основы
3.4.1 Концепции Docker
3.4.1.1 Виртуальные машины
Предшественниками контейнеров Docker были виртуальные машины.
Виртуальная машина, как и контейнер, изолирует от внешней среды
приложение и его зависимости. Однако контейнеры Docker обладают
преимуществами перед виртуальными машинами. Так, они потребляют
меньше ресурсов, их очень легко переносить, они быстрее запускаются и
приходят в работоспособное состояние. В этом материале можно найти
подробное сравнение контейнеров и виртуальных машин.
3.4.1.2 Образ контейнера Docker
Выше мы уже говорили об «образах».То, что в терминологии Docker
называется «образом», или, по-английски, «image», это совсем не то же самое,
что, например, фотография (это — одно из значений слова «image»).
Образы контейнеров Docker можно сравнить с чертежами, с
формочками для печенья, или с пресс-формами для изготовления пластиковых
изделий. Образы — это неизменные шаблоны, которые используются для
создания одинаковых контейнеров.
В образе контейнера Docker содержится образ базовой операционной
системы, код приложения, библиотеки, от которого оно зависит. Всё это
29
скомпоновано в виде единой сущности, на основе которой можно создать
контейнер.
3.4.1.3 Файл Dockerfile
Файл Dockerfile содержит набор инструкций, следуя которым Docker
будет собирать образ контейнера. Этот файл содержит описание базового
образа, который будет представлять собой исходный слой образа. Среди
популярных официальных базовых образов можно отметить python, ubuntu,
alpine.
В образ контейнера, поверх базового образа, можно добавлять
дополнительные слои. Делается это в соответствии с инструкциями
из Dockerfile. Например, если Dockerfile описывает образ, который
планируется использовать для решения задач машинного обучения, то в нём
могут быть инструкции для включения в промежуточный слой такого образа
библиотек NumPy, Pandas и Scikit-learn.
И, наконец, в образе может содержаться, поверх всех остальных, ещё
один тонкий слой, данные, хранящиеся в котором, поддаются изменению. Это
— небольшой по объёму слой, содержащий программу, которую планируется
запускать в контейнере.
3.4.1.4 Контейнер Docker
Для того чтобы запустить контейнер, нам нужен, во-первых, образ
контейнера, во-вторых — среда, в которой установлен Docker, способная
понять команду вида docker run image_name. Эта команда создаёт контейнер
из образа и запускает его.
3.4.1.5 Репозиторий контейнеров
Если вы хотите дать возможность другим людям создавать контейнеры
на основе вашего образа, вы можете отправить этот образ в облачное
хранилище. Самым крупным подобным хранилищем является репозиторий
Docker Hub. Он используется при работе с Docker по умолчанию.
3.5 Docker: термины и концепции
3.5.1 Платформа Docker
Платформа Docker (Docker Platform) — это программа, которая даёт
нам возможность упаковывать приложения в контейнеры и запускать их на
серверах. Платформа Docker позволяет помещать в контейнеры код и его
зависимости. Как результат, системы, основанные на контейнерах, легко
масштабировать, так как контейнеры можно переносить и воспроизводить.
3.5.2 Движок Docker
30
Движок Docker (Docker Engine) — это клиент-серверное приложение.
Компания Docker разделила движок Docker на два продукта. Docker
Community Edition (CE) — это бесплатное ПО, во многом основанное
на опенсорсных инструментах.
Вероятно, вы будете пользоваться именно этой версией Docker. Docker
Enterprise — это платная версия системы, дающая пользователям
дополнительные возможности в области поддержки систем, управления ими и
безопасности. Платная версия Docker даёт компании средства, необходимые
для её существования.
3.5.3 Клиент Docker
Рисунок 20 – Клиент Docker и другие механизмы экосистемы
Клиент Docker (Docker Client) — это основное средство, которое
используют для взаимодействия с Docker. Так, при работе с интерфейсом
командной строки Docker (Docker Command Line Interface, CLI), в терминал
вводят команды, начинающиеся с ключевого слова docker, обращаясь к
клиенту. Затем клиент использует API Docker для отправки команд демону
Docker.
3.5.4 Демон Docker
Демон Docker (Docker Daemon) — это сервер Docker, который ожидает
запросов к API Docker. Демон Docker управляет образами, контейнерами,
сетями
и
томами.
3.5.5 Тома Docker
Тома Docker (Docker Volumes) представляют собой наиболее
предпочтительный механизм постоянного хранения данных, потребляемых
или производимых приложениями.
31
3.5.6 Реестр Docker
Реестр Docker (Docker Registry) представляет собой удалённую
платформу, используемую для хранения образов Docker. В ходе работы с
Docker образы отправляют в реестр и загружают из него. Подобный реестр
может быть организован тем, кто пользуется Docker. Кроме того, поставщики
облачных услуг могут поддерживать и собственные реестры. Например, это
касается AWS и Google Cloud.
3.5.7 Хаб Docker
Хаб Docker (Docker Hub) — это самый крупный реестр образов Docker.
Кроме того, именно этот реестр используется при работе с Docker по
умолчанию. Пользоваться хабом Docker можно бесплатно.
3.5.8 Репозиторий Docker
Репозиторием Docker (Docker Repository) называют набор образов
Docker, обладающих одинаковыми именами и разными тегами. Теги — это
идентификаторы образов. Обычно в репозиториях хранятся разные версии
одних и тех же образов. Например, Python — это имя популярнейшего
официального репозитория Docker на хабе Docker. А вот Python:3.7-slim — это
версия образа с тегом 3.7-slim в репозитории Python. В реестр можно
отправить как целый репозиторий, так и отдельный образ.
3.5.9 Сеть Docker
Рисунок 21 – Сеть Docker
32
Сетевые механизмы Docker (Docker Networking) позволяют
организовывать связь между контейнерами Docker. Соединённые с помощью
сети контейнеры могут выполняться на одном и том же хосте или на разных
хостах. Подробности о сетевой подсистеме Docker можно почитать здесь.
3.5.10 Docker Compose
Docker Compose — это инструмент, который упрощает развёртывание
приложений, для работы которых требуется несколько контейнеров Docker.
Docker Compose позволяет выполнять команды, описываемые в файле dockercompose.yml. Эти команды можно выполнять столько раз, сколько
потребуется. Интерфейс командной строки Docker Compose упрощает
взаимодействие с многоконтейнерными приложениями. Этот инструмент
устанавливается при установке Docker.
3.5.11 Docker Swarm
Docker Swarm — это решение, предназначенное для управления
контейнерными развёртываниями (то есть, как говорят, для оркестрации
контейнеров). В этом материале из официального учебного курса по Docker
можно найти сведения о Docker Swarm. Мне хотелось бы порекомендовать вам
не тратить время на изучение Docker Swarm в том случае, если у вас нет на то
веской причины.
3.5.12 Сервисы Docker
Сервисы Docker (Docker Services) — это различные части
распределённого приложения. Вот что о них говорится в документации:
Сервисы — это всего лишь «контейнеры в продакшне». В пределах
сервиса выполняется лишь один образ, но сервис определяет то, как именно
выполняется образ. В частности, речь идёт о том, какие порты должны
использоваться, сколько реплик контейнера должно выполняться для того,
чтобы сервис обеспечивал бы необходимую вычислительную мощность, и так
далее. Масштабирование сервисов предусматривает изменение количества
экземпляров контейнера, в которых работает некая программа, благодаря
чему сервису выделяется столько системных ресурсов, сколько ему
требуется для решения некоей задачи.
Сервисы Docker позволяют масштабировать контейнеры в пределах
нескольких демонов Docker, благодаря им существует и технология Docker
Swarm.
33
3.5.13 Kubernetes
Этот термин относится не к самой платформе Docker, а к технологии,
которая очень часто используется совместно с Docker.
Kubernetes — это технология, которая позволяет автоматизировать
развёртывание и масштабирование контейнеризированных приложений, а
также управление ими. Это — бесспорный лидер рынка средств для
оркестрации контейнеров. Если вам нужен инструмент для работы с группами
контейнеров, для масштабирования решений, основанных на них, используйте
не Docker Swarm, а Kubernetes. Kubernetes не является частью Docker. Они с
Docker, скорее, похожи на лучших друзей.
3.6 Docker: файлы Dockerfile
3.6.1 Образы Docker
Контейнер Docker — это образ Docker, вызванный к жизни. Это —
самодостаточная операционная система, в которой имеется только самое
необходимое и код приложения. Образы Docker являются результатом
процесса их сборки, а контейнеры Docker — это выполняющиеся образы. В
самом сердце Docker находятся файлы Dockerfile. Подобные файлы сообщают
Docker о том, как собирать образы, на основе которых создаются контейнеры.
Каждому образу Docker соответствует файл, который называется Dockerfile.
Его имя записывается именно так — без расширения. При запуске
команды docker build для создания нового образа подразумевается, что
Dockerfile находится в текущей рабочей директории. Если этот файл
находится в каком-то другом месте, его расположение можно указать с
использованием флага -f.
Контейнеры состоят из слоёв. Каждый слой, кроме последнего,
находящегося поверх всех остальных, предназначен только для чтения.
Dockerfile сообщает системе Docker о том, какие слои и в каком порядке надо
добавить в образ.
Каждый слой, на самом деле, это всего лишь файл, который описывает
изменение состояния образа в сравнении с тем состоянием, в котором он
пребывал после добавления предыдущего слоя. В Unix, кстати, практически
всё что угодно — это файл.
Базовый образ — это то, что является исходным слоем (или слоями)
создаваемого образа. Базовый образ ещё называют родительским образом.
Когда образ загружается из удалённого репозитория на локальный
компьютер, то физически скачиваются лишь слои, которых на этом
компьютере нет. Docker стремится экономить пространство и время путём
повторного использования существующих слоёв.
34
3.6.2 Файлы Dockerfile
В файлах Dockerfile содержатся инструкции по созданию образа. С
них, набранных заглавными буквами, начинаются строки этого файла. После
инструкций идут их аргументы. Инструкции, при сборке образа,
обрабатываются сверху вниз. Вот как это выглядит:
FROM ubuntu:18.04
COPY . /app
Слои
в
итоговом
образе
создают
только
инструкции FROM, RUN, COPY, и ADD. Другие инструкции что-то
настраивают, описывают метаданные, или сообщают Docker о том, что во
время выполнения контейнера нужно что-то сделать, например — открыть
какой-то порт или выполнить какую-то команду.
Здесь мы исходим из предположения, в соответствии с которым
используется образ Docker, основанный на Unix-подобной ОС. Конечно, тут
можно воспользоваться и образом, основанным на Windows, но использование
Windows — это менее распространённая практика, работать с такими образами
сложнее. В результате, если у вас есть такая возможность, пользуйтесь Unix.
Для начала приведём список инструкций Dockerfile с краткими
комментариями.
3.6.3 Инструкции Dockerfile и примеры их использования
1. FROM — задаёт базовый (родительский) образ.
2. LABEL — описывает метаданные. Например — сведения о том,
кто создал и поддерживает образ.
3. ENV — устанавливает постоянные переменные среды.
4. RUN — выполняет команду и создаёт слой образа. Используется
для установки в контейнер пакетов.
5. COPY — копирует в контейнер файлы и папки.
6. ADD — копирует файлы и папки в контейнер, может
распаковывать локальные .tar-файлы.
7. CMD — описывает команду с аргументами, которую нужно
выполнить когда контейнер будет запущен. Аргументы могут быть
переопределены при запуске контейнера. В файле может присутствовать
лишь одна инструкция CMD.
8. WORKDIR — задаёт рабочую директорию для следующей
инструкции.
9. ARG — задаёт переменные для передачи Docker во время сборки
образа.
35
10. ENTRYPOINT — предоставляет команду с аргументами для
вызова во время выполнения контейнера. Аргументы не переопределяются.
11. EXPOSE — указывает на необходимость открыть порт.
12. VOLUME — создаёт точку монтирования для работы с
постоянным хранилищем.
3.6.3.1 Простой Dockerfile
Dockerfile может быть чрезвычайно простым и коротким. Например
— таким:
FROM ubuntu:18.04
3.6.3.2 Инструкция FROM
Файл Dockerfile должен начинаться с инструкции FROM, или с
инструкции ARG, за которой идёт инструкция FROM. Ключевое
слово FROM сообщает Docker о том, чтобы при сборке образа использовался
бы базовый образ, который соответствует предоставленному имени и тегу.
Базовый образ, кроме того, ещё называют родительским образом.
В этом примере базовый образ хранится в репозитории ubuntu. Ubuntu
— это название официального репозитория Docker, предоставляющего
базовую версию популярной ОС семейства Linux, которая называется Ubuntu.
Обратите внимание на то, что рассматриваемый Dockerfile включает в
себя тег 18.04, уточняющий то, какой именно базовый образ нам нужен.
Именно этот образ и будет загружен при сборке нашего образа. Если тег в
инструкцию не включён, тогда Docker исходит из предположения о том, что
требуется самый свежий образ из репозитория. Для того чтобы яснее выразить
свои намерения, автору Dockerfile рекомендуется указывать то, какой именно
образ ему нужен.
Когда вышеописанный Dockerfile используется на локальной машине
для сборки образа в первый раз, Docker загрузит слои, определяемые
образом ubuntu. Их можно представить наложенными друг на друга. Каждый
следующий слой представляет собой файл, описывающий отличия образа в
сравнении с тем его состоянием, в котором он был после добавления в него
предыдущего слоя.
При создании контейнера слой, в который можно вносить изменения,
добавляется поверх всех остальных слоёв. Данные, находящиеся в остальных
слоях, можно только читать.
36
Рисунок 21 – Структура контейнера
Docker, ради эффективности, использует стратегию копирования при
записи. Если слой в образе существует на предыдущем уровне и какому-то
слою нужно произвести чтение данных из него, Docker использует
существующий файл. При этом ничего загружать не нужно. Когда образ
выполняется, если слой нужно модифицировать средствами контейнера, то
соответствующий файл копируется в самый верхний, изменяемый слой. Для
того чтобы узнать подробности о стратегии копирования при записи,
взгляните на этот материал из документации Docker.
3.6.3.3 Более сложный Dockerfile
Хотя файл Dockerfile, который мы только что рассмотрели, получился
аккуратным и понятным, он устроен слишком просто, в нём используется
всего одна инструкция. Кроме того, там нет инструкций, вызываемых во время
выполнения контейнера. Взглянем на ещё один файл, который собирает
маленький образ. В нём имеются механизмы, определяющие команды,
вызываемые во время выполнения контейнера.
FROM python:3.7.2-alpine3.8
LABEL maintainer="jeffmshale@gmail.com"
ENV ADMIN="jeff"
RUN apk update && apk upgrade && apk add bash
COPY . ./app
37
ADD https://raw.githubusercontent.com/discdiver/pachyvid/master/sample_vids/vid1.mp4 \
/my_app_directory
RUN ["mkdir", "/a_directory"]
CMD ["python", "./my_script.py"]
Возможно, на первый взгляд этот файл может показаться довольно
сложным. Поэтому давайте с ним разберёмся.
Базой этого образа является официальный образ Python с тегом 3.7.2alpine3.8. Проанализировав этот код можно увидеть, что данный базовый
образ включает в себя Linux, Python, и, по большому счёту, этим его состав и
ограничивается. Образы ОС Alpine весьма популярны в мире Docker. Дело в
том, что они отличаются маленькими размерами, высокой скоростью работы
и безопасностью. Однако образы Alpine не отличаются широкими
возможностями, характерными для обычных операционных систем. Поэтому
для того, чтобы собрать на основе такого образа что-то полезное, создателю
образа нужно установить в него необходимые ему пакеты.
3.6.3.4 Инструкция LABEL
Инструкция LABEL (метка) позволяет добавлять в образ метаданные.
В случае с рассматриваемым сейчас файлом, она включает в себя контактные
сведения создателя образа. Объявление меток не замедляет процесс сборки
образа и не увеличивает его размер. Они лишь содержат в себе полезную
информацию об образе Docker, поэтому их рекомендуется включать в файл.
Подробности о работе с метаданными в Dockerfile можно прочитать здесь.
3.6.3.5 Инструкция ENV
Инструкция ENV позволяет задавать постоянные переменные среды,
которые будут доступны в контейнере во время его выполнения. В
предыдущем примере после создания контейнера можно пользоваться
переменной ADMIN.
Инструкция ENV хорошо подходит для задания констант. Если вы
используете некое значение в Dockerfile несколько раз, скажем, при описании
команд, выполняющихся в контейнере, и подозреваете, что, возможно, вам
когда-нибудь придётся сменить его на другое, его имеет смысл записать в
подобную константу.
Надо отметить, что в файлах Dockerfile часто существуют разные
способы решения одних и тех же задач. Что именно использовать — это
вопрос, на решение которого влияет стремление к соблюдению принятых в
среде Docker методов работы, к обеспечению прозрачности решения и его
38
высокой
производительности.
Например,
инструкции RUN, CMD и ENTRYPOINT служат разным целям, но все они
используются для выполнения команд.
3.6.3.6 Инструкция RUN
Инструкция RUN позволяет создать слой во время сборки образа.
После её выполнения в образ добавляется новый слой, его состояние
фиксируется. Инструкция RUN часто используется для установки в образы
дополнительных пакетов. В предыдущем примере инструкция RUN apk update
&& apk upgrade сообщает Docker о том, что системе нужно обновить пакеты
из базового образа. Вслед за этими двумя командами идёт команда && apk add
bash, указывающая на то, что в образ нужно установить bash.
То, что в командах выглядит как apk — это сокращение от Alpine Linux
package manager (менеджер пакетов Alpine Linux). Если вы используете
базовый образ какой-то другой ОС семейства Linux, тогда вам, например, при
использовании Ubuntu, для установки пакетов может понадобиться команда
вида RUN apt-get. Позже мы поговорим о других способах установки пакетов.
Инструкция RUN и схожие с ней инструкции — такие,
как CMD и ENTRYPOINT, могут быть использованы либо в exec-форме, либо
в shell-форме. Exec-форма использует синтаксис, напоминающий описание
JSON-массива. Например, это может выглядеть так:
RUN ["my_executable", "my_first_param1", "my_second_param2"].
В предыдущем примере мы использовали shell-форму инструкции RUN
в таком виде:
RUN apk update && apk upgrade && apk add bash.
Позже в нашем Dockerfile использована exec-форма инструкции RUN,
в виде RUN ["mkdir", "/a_directory"] для создания директории. При этом,
используя инструкцию в такой форме, нужно помнить о необходимости
оформления строк с помощью двойных кавычек, как это принято в формате
JSON.
3.6.3.7 Инструкция COPY
Инструкция COPY представлена в нашем файле так: COPY . ./app. Она
сообщает Docker о том, что нужно взять файлы и папки из локального
контекста сборки и добавить их в текущую рабочую директорию образа. Если
39
целевая
директория
не
существует,
эта
инструкция
её
создаст.
3.6.3.8 Инструкция ADD
Инструкция ADD позволяет решать те же задачи, что и COPY, но с ней
связана ещё пара вариантов использования. Так, с помощью этой инструкции
можно добавлять в контейнер файлы, загруженные из удалённых источников,
а также распаковывать локальные .tar-файлы.
В этом примере инструкция ADD была использована для копирования
файла, доступного по URL, в директорию контейнера my_app_directory. Надо
отметить, однако, что документация Docker не рекомендует использование
подобных файлов, полученных по URL, так как удалить их нельзя, и так как
они увеличивают размер образа.
Кроме того, документация предлагает везде, где это возможно, вместо
инструкции ADD использовать инструкцию COPY для того, чтобы сделать
файлы Dockerfile понятнее. Полагаю, команде разработчиков Docker стоило
бы объединить ADD и COPY в одну инструкцию для того, чтобы тем, кто
создаёт образы, не приходилось бы помнить слишком много инструкций.
Обратите внимание на то, что инструкция ADD содержит символ
разрыва строки — \. Такие символы используются для улучшения
читабельности длинных команд путём разбиения их на несколько строк.
3.6.3.9 Инструкция CMD
Инструкция CMD предоставляет Docker команду, которую нужно
выполнить при запуске контейнера. Результаты выполнения этой команды не
добавляются в образ во время его сборки. В нашем примере с помощью этой
команды запускается скрипт my_script.py во время выполнения контейнера.
Вот ещё кое-что, что нужно знать об инструкции CMD:

В одном файле Dockerfile может присутствовать лишь одна
инструкция CMD. Если в файле есть несколько таких инструкций, система
проигнорирует все кроме последней.

Инструкция CMD может иметь exec-форму. Если в эту
инструкцию не входит упоминание исполняемого файла, тогда в файле должна
присутствовать инструкция ENTRYPOINT. В таком случае обе эти
инструкции должны быть представлены в формате JSON.

Аргументы командной строки, передаваемые docker run,
переопределяют аргументы, предоставленные инструкции CMD в Dockerfile.
3.6.3.10 Ещё более сложный Dockerfile
Рассмотрим ещё один файл Dockerfile, в котором будут использованы
некоторые новые команды.
40
FROM python:3.7.2-alpine3.8
LABEL maintainer="jeffmshale@gmail.com"
# Устанавливаем зависимости
RUN apk add --update git
# Задаём текущую рабочую директорию
WORKDIR /usr/src/my_app_directory
# Копируем код из локального контекста в рабочую директорию
образа
COPY . .
# Задаём значение по умолчанию для переменной
ARG my_var=my_default_value
# Настраиваем команду, которая должна быть запущена в контейнере
во время его выполнения
ENTRYPOINT ["python", "./app/my_script.py", "my_var"]
# Открываем порты
EXPOSE 8000
# Создаём том для хранения данных
VOLUME /my_volume
В этом примере, кроме прочего, вы можете видеть комментарии,
которые начинаются с символа #.
Одно из основных действий, выполняемых средствами Dockerfile —
это установка пакетов. Как уже было сказано, существуют различные способы
установки пакетов с помощью инструкции RUN.
Пакеты в образ Alpine Docker можно устанавливать с помощью apk.
Для этого, как мы уже говорили, применяется команда вида
RUN apk update && apk upgrade && apk add bash.
Кроме того, пакеты Python в образ можно устанавливать с
помощью pip, wheel и conda. Если речь идёт не о Python, а о других языках
программирования, то при подготовке соответствующих образов могут
использоваться и другие менеджеры пакетов.
При этом для того, чтобы установка была бы возможной, нижележащий
слой должен предоставить слою, в который выполняется установка пакетов,
подходящий менеджер пакетов. Поэтому если вы столкнулись с проблемами
при установке пакетов, убедитесь в том, что менеджер пакетов установлен до
того, как вы попытаетесь им воспользоваться.
41
Например, инструкцию RUN в Dockerfile можно использовать для
установки списка пакетов с помощью pip. Если вы так поступаете —
объедините все команды в одну инструкцию и разделите её символами
разрыва строки с помощью символа \. Благодаря такому подходу файлы будут
выглядеть аккуратно и это приведёт к добавлению в образ меньшего
количества слоёв, чем было бы добавлено при использовании нескольких
инструкций RUN.
Кроме того, для установки нескольких пакетов можно поступить и подругому. Их можно перечислить в файле и передать менеджеру пакетов этот
файл с помощью RUN. Обычно таким файлам дают имя requirements.txt.
3.6.3.11 Инструкция WORKDIR
Инструкция WORKDIR позволяет изменить рабочую директорию
контейнера. С этой директорией работают инструкции COPY, ADD, RUN,
CMD и ENTRYPOINT, идущие за WORKDIR. Вот некоторые особенности,
касающиеся этой инструкции:

Лучше устанавливать с помощью WORKDIR абсолютные пути к
папкам, а не перемещаться по файловой системе с помощью команд cd в
Dockerfile.

Инструкция WORKDIR автоматически создаёт директорию в том
случае, если она не существует.

Можно использовать несколько инструкций WORKDIR. Если
таким инструкциям предоставляются относительные пути, то каждая из них
меняет текущую рабочую директорию.
3.6.3.12 Инструкция ARG
Инструкция ARG позволяет задать переменную, значение которой
можно передать из командной строки в образ во время его сборки. Значение
для переменной по умолчанию можно представить в Dockerfile. Например:
ARG my_var=my_default_value.
В отличие от ENV-переменных, ARG-переменные недоступны во
время выполнения контейнера. Однако ARG-переменные можно использовать
для задания значений по умолчанию для ENV-переменных из командной
строки в процессе сборки образа. А ENV-переменные уже будут доступны в
контейнере во время его выполнения. Подробности о такой методике работы
с переменными можно почитать здесь.
3.6.3.13 Инструкция ENTRYPOINT
42
Инструкция ENTRYPOINT позволяет задавать команду с аргументами,
которая должна выполняться при запуске контейнера. Она похожа на
команду CMD,
но
параметры,
задаваемые
в ENTRYPOINT,
не
перезаписываются в том случае, если контейнер запускают с параметрами
командной строки.
Вместо этого аргументы командной строки, передаваемые в
конструкции вида docker run my_image_name, добавляются к аргументам,
задаваемым инструкцией ENTRYPOINT. Например, после выполнения
команды вида docker run my_image bash аргумент bash добавится в конец
списка аргументов, заданных с помощью ENTRYPOINT. Готовя Dockerfile, не
забудьте об инструкции CMD или ENTRYPOINT.
В документации к Docker есть несколько рекомендаций, касающихся
того, какую инструкцию, CMD или ENTRYPOINT, стоит выбрать в качестве
инструмента для выполнения команд при запуске контейнера:

Если при каждом запуске контейнера нужно выполнять одну и ту
же команду — используйте ENTRYPOINT.

Если контейнер будет использоваться в роли приложения —
используйте ENTRYPOINT.

Если вы знаете, что при запуске контейнера вам понадобится
передавать ему аргументы, которые могут перезаписывать аргументы,
указанные в Dockerfile, используйте CMD.
В нашем примере использование инструкции
ENTRYPOINT ["python", "my_script.py", "my_var"]
приводит к тому, что контейнер, при запуске, запускает Pythonскрипт my_script.py с аргументом my_var. Значение, представленное my_var,
потом можно использовать в скрипте с помощью argparse. Обратите внимание
на то, что в Dockerfile переменной my_var, до её использования, назначено
значение по умолчанию с помощью ARG. В результате, если при запуске
контейнера ему не передали соответствующее значение, будет применено
значение по умолчанию.
Документация Docker рекомендует использовать execформу ENTRYPOINT:
ENTRYPOINT ["executable", "param1", "param2"].
3.6.3.14 Инструкция EXPOSE
Инструкция EXPOSE указывает на то, какие порты планируется
открыть для того, чтобы через них можно было бы связаться с работающим
контейнером. Эта инструкция не открывает порты. Она, скорее, играет роль
43
документации к образу, средством общения того, кто собирает образ, и того,
кто запускает контейнер.
Для того чтобы открыть порт (или порты) и настроить перенаправление
портов, нужно выполнить команду docker run с ключом -p. Если использовать
ключ в виде -P (с заглавной буквой P), то открыты будут все порты, указанные
в инструкции EXPOSE.
3.6.3.15 Инструкция VOLUME
Инструкция VOLUME позволяет указать место, которое контейнер
будет использовать для постоянного хранения файлов и для работы с такими
файлами. Об этом мы ещё поговорим.
3.7 Docker: Размер образа и ускорение их сборки
3.7.1 Кэширование
Одной из сильных сторон Docker является кэширование. Благодаря
этому механизму ускоряется сборка образов.
При сборке образа Docker проходится по инструкциям файла
Dockerfile, выполняя их по порядку. В процессе анализа инструкций Docker
проверяет собственный кэш на наличие в нём образов, представляющих собой
то, что получается на промежуточных этапах сборки других образов. Если
подобные образы удаётся найти, то система может ими воспользоваться, не
тратя время на их повторное создание. Если кэш признан недействительным,
то инструкция, в ходе выполнения которой это произошло, выполняется,
создавая новый слой без использования кэша. То же самое происходит и при
выполнении инструкций, которые следуют за ней.
В результате, если в ходе выполнения инструкций из Dockerfile
оказывается, что базовый образ имеется в кэше, то используется именно этот
образ из кэша. Это называется «попаданием кэша». Если же базового образа в
кэше нет, то весь процесс сборки образа будет происходить без использования
кэша.
Затем следующая инструкция сопоставляется со всеми образами из
кэша, в основе которых лежит тот же самый базовый образ, который уже
обнаружен в кэше. Каждый кэшированный промежуточный образ проверяется
на предмет того, имеется ли в нём то, что было создано такой же инструкцией.
Если совпадения найти не удаётся, это называется «промахом кэша» и кэш
считается недействительным. То же самое происходит до тех пор, пока не
будет обработан весь файл Dockerfile.
44
Большинство новых инструкций просто сравниваются с тем, что уже
есть в промежуточных образах. Если системе удаётся найти совпадение, то
при сборке используется то, что уже есть в кэше.
Использование кэша способно ускорить сборку образов, но тут есть
одна проблема. Например, если в Dockerfile обнаруживается инструкция RUN
pip install -r requirements.txt, то Docker выполняет поиск такой же инструкции
в своём локальном кэше промежуточных образов. При этом содержимое
старой и новой версий файла requirements.txt не сравнивается.
Подобное может приводить к проблемам в том случае, если
в requirements.txt были добавлены сведения о новых пакетах, после чего, при
сборке обновлённого образа для того, чтобы установить новый набор пакетов,
нужно снова выполнить инструкцию
RUN pip install.
Совсем скоро мы поговорим о том, как бороться с этой проблемой.
В отличие от других инструкций Docker, при выполнении
инструкций ADD и COPY от Docker требуется проверка содержимого файла
или файлов для определения того, можно ли, при формировании образа,
воспользоваться кэшем. А именно, контрольная сумма файлов, упомянутых в
этих инструкциях, сравнивается с контрольной суммой файлов, которые
имеются в промежуточных образах, которые уже есть в кэше. Если изменилось
содержимое файлов или их метаданные, тогда кэш признаётся
недействительным.
Вот несколько советов, касающихся эффективного использования кэша
Docker:

Кэширование можно отключить, передав ключ
--no-cache=True команде docker build.
Если вы собираетесь вносить изменения в инструкции Dockerfile,
тогда каждый слой, созданный инструкциями, идущими после изменённых,
будет достаточно часто собираться повторно, без использования кэша. Для
того чтобы воспользоваться преимуществами кэширования, помещайте
инструкции, вероятность изменения которых высока, как можно ближе к
концу Dockerfile.

Объединяйте команды RUN apt-get update и apt-get install в
цепочки для того, чтобы исключить проблемы, связанные с неправильным
использованием кэша.

Если вы используете менеджеры пакетов, наподобие pip, с
файлом requirements.txt, тогда придерживайтесь нижеприведённой схемы
работы для того, чтобы исключить использование устаревших

45
промежуточных образов из кэша, содержащих набор пакетов, перечисленных
в старой версии файла requirements.txt. Вот как это выглядит:
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
COPY . /tmp/
Если вам известны другие способы борьбы с
requirements.txt» — можете рассказать о них в комментариях.
«проблемой
3.7.2 Уменьшение размеров образов
3.7.2.1 Тщательный подбор базового образа
Образы Docker могут быть довольно большими. Это противоречит
вполне обоснованному стремлению того, кто их создаёт, к тому, чтобы сделать
их как можно более компактными, что облегчит их загрузку из удалённого
репозитория и благотворно скажется на объёме свободного места на
компьютере, на который они загружаются. Поговорим о том, как уменьшать
их размеры.
Одним из способов уменьшения размеров образов является
тщательный подбор базовых образов и их последующая настройка.
Так, например, базовый образ Alpine представляет собой полноценный
дистрибутив Linux-подобной ОС, содержащий минимум дополнительных
пакетов. Его размер — примерно 5 мегабайт. Однако сборка собственного
образа на основе Alpine потребует потратить достаточно много времени на то,
чтобы оснастить его всем необходимым для обеспечения работы некоего
приложения.
Существуют и специализированные варианты базового образа Alpine.
Например, соответствующий образ из репозитория python, в который упакован
скрипт print("hello world") весит около 78.5 Мб. Вот Dockerfile для сборки
такого образа:
FROM python:3.7.2-alpine3.8
COPY . /app
ENTRYPOINT ["python", "./app/my_script.py", "my_var"]
При этом на Docker Hub сказано, что этот базовый образ имеет размер
29 Мб. Размер образа, основанного на этом базовом образе, увеличивается за
счёт загрузки и установки Python.
46
Помимо использования базовых образов, основанных на Alpine,
уменьшить размеры образов можно благодаря использованию технологии
многоступенчатой сборки.
3.7.2.2 Многоступенчатая сборка образов
В Dockerfile, описывающем многоступенчатую сборку образа,
используется несколько инструкций FROM. Создатель такого образа может
настроить выборочное копирование файлов, называемых артефактами сборки,
из одной ступени сборки в другую ступень. При этом появляется возможность
избавиться от всего того, что в готовом образе не понадобится. Благодаря
этому методу можно уменьшить размер готового образа.
Вот как работает каждая инструкция FROM:


Она начинает новый шаг сборки.
Она не зависит от того, что было создано на предыдущем шаге
сборки.
Она может использовать базовый образ, отличающийся от того,
который применялся на предыдущем шаге.

Вот
модифицированный
пример
файла
Dockerfile
из документации Docker, описывающего многоступенчатую сборку.
FROM golang:1.7.3 AS build
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o
app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=build /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
Обратите внимание на то, что мы дали имя первой ступени сборки,
указав его после инструкции FROM. К именованному этапу сборки мы
обращаемся в инструкции
47
COPY --from= ниже в Dockerfile.
Применение процесса многоступенчатой сборки образов имеет смысл
в некоторых случаях, когда приходится создавать множество контейнеров для
продакшн-окружения. Многоступенчатая сборка позволяет максимально
сократить размеры готовых образов. Но иногда такой подход приводит к
усложнению поддержки образов. Поэтому вы, вероятно, не будете
пользоваться многоступенчатой сборкой образов в тех случаях, в которых без
неё можно обойтись. Об особенностях этой технологии можно
почитать здесь и здесь.
Как видите, многоступенчатая сборка — технология интересная, но
подходит она далеко не для всех случаев. Тот же способ уменьшения размера
образов, который мы обсудим ниже, можно порекомендовать абсолютно всем.
3.7.2.3 Файл .dockerignore
О файлах .dockerignore нужно знать абсолютно всем, кто хочет освоить
Docker. Эти файлы похожи на файлы .gitignore. Они содержат список файлов
и папок, в виде имён или шаблонов, которые Docker должен игнорировать в
ходе сборки образа.
Этот файл размещают там же, где находится файл Dockerfile, и всё
остальное, входящее в контекст сборки образа.
При запуске команды docker build, инициирующей сборку образа,
Docker проверяет папку на наличие в ней файла .dockerignore. Если такой файл
найти удаётся, тогда этот файл разбирается, при этом при определении списка
файлов,
которые
нужно
игнорировать,
используются правила функции Match() из пакета filepath Go и некоторые
собственные правила Docker.
Так, например, если в файле .dockerignore встретится шаблон
вида *.jpg, то при создании образа проигнорированы будут файлы с любым
именем и с расширением .jpg. Если в файле встретится строка videos, то
система проигнорирует папку videos и всё её содержимое.
При
составлении
файла .dockerignore его
комментариями, используя символ #.
можно
снабжать
Вот что даёт тому, кто занимается созданием образов Docker,
применение файлов .dockerignore:
Это позволяет исключать из состава образа файлы, содержащие
секретные сведения наподобие логинов и паролей.

48
Это позволяет уменьшить размер образа. Чем меньше в образе
файлов — тем меньше будет его размер и тем быстрее с ним можно будет
работать.

Это даёт возможность уменьшить число поводов для признания
недействительным кэша при сборке похожих образов. Например, если при
повторной сборке образа меняются некие служебные файлы проекта,
наподобие файлов с журналами, из-за чего данные, хранящиеся в кэше, по
сути, необоснованно признаются недействительными, это замедляет сборку
образов.
Подробности о файле .dockerignore можно почитать в документации к
Docker.

3.7.3 Исследование размеров образов
Поговорим о том, как, пользуясь средствами командной строки,
узнавать размеры образов и контейнеров Docker.
Для того чтобы выяснить примерный размер выполняющегося
контейнера, можно использовать команду вида

docker container ls -s.
Команда docker image ls выводит размеры образов.

Узнать размеры промежуточных образов, из которых собран
некий образ, можно с помощью команды

docker image history my_image:my_tag.
Команда docker image inspect my_image:tag позволяет узнать
подробные сведения об образе, в том числе — размер каждого его слоя. Слои
немного отличаются от промежуточных образов, из которых состоит готовый
образ, но, в большинстве случаев их можно рассматривать как одинаковые
сущности. Вот хороший материал, который посвящён подробностям
внутреннего устройства образов Docker.

Для того чтобы исследовать содержимое контейнеров можно
установить пакет dive.

3.7.4 Рекомендации по уменьшению размеров образов и
ускорению процесса их сборки
1. Используйте всегда, когда это возможно, официальные образы в
качестве базовых образов. Официальные образы регулярно обновляются, они
безопаснее неофициальных образов.
2. Для того чтобы собирать как можно более компактные образы,
пользуйтесь базовыми образами, основанными на Alpine Linux.
49
3. Если
вы
пользуетесь apt,
комбинируйте
в
одной
инструкции RUN команды apt-get update и apt-get install. Кроме того,
объединяйте в одну инструкцию команды установки пакетов. Перечисляйте
пакеты в алфавитном порядке на нескольких строках, разделяя список
символами \.
Например,
это
может
выглядеть
так:
RUN apt-get update && apt-get install -y \
package-one \
package-two \
package-three
&& rm -rf /var/lib/apt/lists/*
Этот метод позволяет сократить число слоёв, которые должны быть
добавлены в образ, и помогает поддерживать код файла в приличном виде.
4.
Включайте конструкцию вида
&& rm -rf /var/lib/apt/lists/*
в конец инструкции RUN, используемой для установки пакетов. Это
позволит очистить кэш apt и приведёт к тому, что он не будет
сохраняться в слое, сформированном командой RUN. Подробности об
этом можно почитать в документации.
5. Разумно пользуйтесь возможностями кэширования, размещая в
Dockerfile команды, вероятность изменения которых высока, ближе к концу
файла.
6. Пользуйтесь файлом .dockerignore.
7. Взгляните на dive — отличный инструмент для исследования
образов Docker, который помогает в деле уменьшения их размеров.
8. Не устанавливайте в образы пакеты, без которых можно обойтись.
3.8 Docker: команды
Давайте вспомним о том, что образы Docker создают на основе файлов
Dockerfile, описывающих всё то, что нужно для сборки образов. Кроме того,
не будем забывать и о том, что контейнер — это образ Docker, вызванный к
жизни. Для того чтобы эффективно пользоваться командами Docker, в первую
очередь нужно выяснить — с чем вы имеете дело — с образом или с
контейнером. Если подумать об образах и контейнерах, то можно понять, что
образ Docker может либо существовать, либо не существовать. То же самое
50
можно сказать и о контейнерах Docker. Существующий контейнер Docker,
кроме того, может пребывать либо в работающем, либо в неработающем
состоянии.
3.8.1 Общие сведения о командах Docker
Вот кое-что, о чём полезно знать тем, кто хочет работать с Docker:

Команды интерфейса командной строки Docker, используемые для
управления чем-либо, начинаются с ключевого слова docker, за которым идёт
пробел, затем идёт указание на то, на что именно будет направлена некая
команда, потом ещё один пробел, а потом следует сама команда. Например,
именно так построена такая команда: docker container stop.

Если команда направлена на конкретный образ или контейнер, то
в ней используется имя или идентификатор такого образа или контейнера.
Например, команда docker container run my_app — это команда для
создания и запуска контейнера с именем my_app. В примерах, которые будут
приведены ниже, контейнеры мы будем называть my_container, образы
— my_image, теги — my_tag, и так далее.
Сначала мы будем рассматривать саму команду, потом — флаги,
которые можно с ней использовать, если такие флаги существуют. Если перед
флагом стоит два тире — то это его полная форма, флаг с одним тире — это
сокращённый вариант некоего флага. Действуют они одинаково. Например, p — это сокращённая форма флага --port.
Цель этого материала заключается в том, чтобы дать вам общие
сведения о командах Docker. Так вы, имея общее представление о них и зная
о возможностях платформы, доступных благодаря этим командам, сможете,
при необходимости, найти подробные сведения о них. Команды, о которых
пойдёт речь, испытаны на ОС семейства Linux с использованием движка
Docker версии 18.09.1 и API версии 1.39.
3.8.2 Примечание о командах, поддерживаемых Docker CLI 1.13
В интерфейсе командной строки Docker версии 1.13 представлены
обновлённые, логически сгруппированные команды. При этом старые
команды всё ещё работают, но новыми пользоваться легче, особенно —
начинающим. Речь идёт, например, о том, что в версии 1.12 использовалась
команда вида docker create, а в версии 1.13 стала доступна команда docker
container create. Сведения о соответствии старых и новых команд можно
найти здесь.
Сначала мы посмотрим на команды, предназначенные для управления
контейнерами,
затем
обсудим
управление
образами.
3.8.3 Команды для управления контейнерами
51
Общая схема команд для управления контейнерами выглядит так:
docker container my_command
Вот команды, которые могут быть подставлены туда, где мы
использовали my_command:

create — создание контейнера из образа.

start — запуск существующего контейнера.

run — создание контейнера и его запуск.

ls — вывод списка работающих контейнеров.

inspect — вывод подробной информации о контейнере.

logs — вывод логов.

stop — остановка работающего контейнера с отправкой главному
процессу контейнера сигнала SIGTERM, и, через некоторое время, SIGKILL.

kill — остановка работающего контейнера с отправкой главному
процессу контейнера сигнала SIGKILL.

rm — удаление остановленного контейнера.
3.8.4 Команды для управления образами
Для управления образами используются команды, которые выглядят
так:
docker image my_command
Вот
некоторые
из
команд
этой
группы:
build — сборка образа.

push — отправка образа в удалённый реестр.

ls — вывод списка образов.

history — вывод сведений о слоях образа.

inspect — вывод подробной информации об образе, в том числе —
сведений о слоях.

rm — удаление образа.

3.8.5 Разные команды

docker version — вывод сведений о версиях клиента и сервера
Docker.
docker login — вход в реестр Docker.

docker system prune — удаление неиспользуемых контейнеров,
сетей и образов, которым не назначено имя и тег.
Теперь
рассмотрим
эти
команды
подробнее.

52
3.8.6 Контейнеры
3.8.6.1 Начало существования контейнера
На начальном этапе работы с контейнерами используются
команды create, start и run. Они применяются, соответственно, для создания
контейнера, для его запуска, и для его создания и запуска.
Вот команда для создания контейнера из образа:
docker container create my_repo/my_image:my_tag
В следующих примерах конструкция my_repo/my_image:my_tag будет
сокращена до my_image.
Команда create принимает множество флагов. Например, её можно
записать в таком виде:
docker container create -a STDIN my_image
Флаг -a представляет собой краткую форму флага --attach. Этот флаг
позволяет подключить контейнер к STDIN, STDOUT или STDERR.
После того, как контейнер создан, его можно запустить следующей
командой:
docker container start my_container
Обратите внимание на то, что сослаться на контейнер в команде можно
либо используя его ID, либо имя.
Теперь взглянем на команду, которая позволяет создать и запустить
контейнер:
docker container run my_image
Эта
команда
тоже
способна
принимать
множество аргументов командной строки. Рассмотрим некоторые из них на
примере такой конструкции:
docker container run -i -t -p 1000:8000 --rm my_image
Флаг -i — это сокращение для --interactive. Благодаря этому флагу
поток STDIN поддерживается в открытом состоянии даже если контейнер
к STDIN не подключён.
53
Флаг -t — это сокращение для --tty. Благодаря этому флагу выделяется
псевдотерминал,
который
соединяет
используемый
терминал
с
потоками STDIN и STDOUT контейнера.
Для того чтобы получить возможность взаимодействия с контейнером
через терминал нужно совместно использовать флаги -i и -t.
Флаг -p представляет собой сокращение для --port. Порт — это
интерфейс, благодаря которому контейнер взаимодействует с внешним
миром.
Конструкция 1000:8000 перенаправляет
порт
Docker 8000 на
порт 1000 компьютера, на котором выполняется контейнер. Если в контейнере
работает некое приложение, способное выводить что-то в браузер, то для того,
чтобы к нему обратиться, в нашем случае можно перейти в браузере по
адресу localhost:1000.
Флаг --rm автоматически удаляет контейнер после того, как его
выполнение завершится.
Рассмотрим ещё некоторые примеры команды run:
docker container run -it my_image my_command
В подобной конструкции может применяться команда sh, которая
создаст сессию терминала в контейнере, с которой можно взаимодействовать
через ваш терминал. При работе с образами, основанными на Alpine, лучше
ориентироваться на использование sh а не bash, так как в этих образах, по
умолчанию, оболочка bash не установлена. Для выхода из интерактивной
сессии воспользуйтесь командой exit.
Обратите внимание на то, что здесь мы скомбинировали флаги -i и -t в it.
Вот
ещё
один
пример
работы
с
командой run:
docker container run -d my_image
Флаг -d — это сокращение для --detach. Эта команда запускает
контейнер в фоновом режиме. Это позволяет использовать терминал, из
которого запущен контейнер, для выполнения других команд во время работы
контейнера.
3.8.6.2 Проверка состояния контейнера
Если у вас имеются запущенные контейнеры Docker и вы хотите узнать
о том, что это за контейнеры, вам понадобится вывести их список. Сделать это
можно такой командой:
54
docker container ls
Эта команда выводит список выполняющихся контейнеров и снабжает
этот список некоторыми полезными сведениями о них. Вот ещё один пример
этой команды:
docker container ls -a -s
Ключ -a этой команды — это сокращение для --all. Благодаря
использованию этого ключа можно вывести сведения обо всех контейнерах, а
не только о выполняющихся.
Ключ -s — это сокращение для --size. Он позволяет вывести размеры
контейнеров.
Вот команда, которая выводит подробные сведения о контейнере:
docker container inspect my_container
Вот команда, выводящая логи контейнера:
docker container logs my_container
3.8.6.3 Завершение работы контейнера
Иногда работающий контейнер надо
используется такая команда:
остановить.
Для
этого
docker container stop my_container
Она позволяет останавливать работающие контейнеры, позволяя им
корректно завершить работу. У контейнера есть, по умолчанию, 10 секунд, на
то, чтобы завершить работу.
Если же контейнер нужно остановить быстро, не заботясь о корректном
завершении его работы, можно воспользоваться такой командой:
docker container kill my_container
Команда kill, если сравнить работающий контейнер с включенным
телевизором, напоминает выключение телевизора путём отключения его от
электричества. Поэтому, в большинстве ситуаций, для остановки контейнеров
рекомендуется использовать команду stop.
Вот команда, которая позволяет быстро остановить все работающие
контейнеры:
55
docker container kill $(docker ps -q)
Для удаления остановленного контейнера можно воспользоваться
такой командой:
docker container rm my_container
Вот команда, которая позволяет удалить все контейнеры, которые на
момент вызова этой команды не выполняются:
docker container rm $(docker ps -a -q)
Подведём итоги этого раздела. Сначала контейнер создают, потом его
запускают, или комбинируют эти два шага, используя команду вида docker run
my_container. После этого запускается контейнеризированное приложение.
Потом контейнер останавливают командой docker stop my_container.
Для удаления контейнера используется команда docker rm my_container.
Поговорим теперь о командах, используемых для работы с образами, с
теми самыми шаблонами, из которых создают контейнеры.
3.8.7 Образы
3.8.7.1 Создание образов
Вот команда, которая позволяет собирать образы Docker:
docker image build -t my_repo/my_image:my_tag .
В данном случае создаётся образ с именем my_image, при его сборке
используется файл Dockerfile, находящийся по указанному пути или URL.
Флаг -t — это сокращение для --tag. Он указывает Docker на то, что
создаваемому образу надо назначить предоставленный в команде тег. В
данном случае это my_tag.
Точка в конце команды указывает на то, что образ надо собрать с
использованием файла Dockerfile, находящегося в текущей рабочей
директории.
После того, как образ собран, его можно отправить в удалённый реестр.
Благодаря этому им смогут воспользоваться другие люди, его можно будет
загрузить и запустить на другом компьютере. Предположим, вы хотите
использовать Docker Hub. Если так — вам понадобится завести там учётную
запись. Пользоваться этим ресурсом можно бесплатно.
После того, как вы зарегистрируетесь на Docker Hub, вам нужно войти
в систему. И хотя команда, которая для этого используется, напрямую к
командам, предназначенным для работы с образами, не относится, её полезно
будет рассмотреть именно здесь. Речь идёт о следующей команде:
56
docker login
Она позволяет войти в учётную запись на Docker Hub. Для входа в
систему вам понадобится ввести имя пользователя и пароль.
После входа в систему можно будет отправлять образы в реестр.
Делается это так:
docker image push my_repo/my_image:my_tag
Теперь, когда у вас наберётся несколько образов, вы можете их
исследовать
с
помощью
специальных
команд.
3.8.7.2 Исследование образов
Вот команда, которая выводит список образов, выводя, в том числе, и
сведения об их размере:
docker image ls
Следующая команда позволяет вывести сведения о промежуточных
образах, входящих в состав образа, в частности — данные об их размерах и о
том, как они были созданы:
docker image history my_image
Вот команда, которая выводит подробные сведения об образе, в том
числе — данные о слоях, из которых состоит образ:
docker image inspect my_image
Если вы создадите очень много образов, может случиться так, что
некоторые из них понадобится удалить.
3.8.7.3 Удаление образов
Вот команда, которая позволяет удалить указанный образ:
docker image rm my_image
Если образ хранится в удалённом репозитории, он оттуда удалён не
будет.
Вот команда, которая позволяет удалить все локальные образы:
docker image rm $(docker images -a -q)
Пользоваться этой командой стоит с осторожностью, но надо заметить,
что при её использовании образы, хранящиеся в удалённом репозитории,
57
удалены не будут. В этом заключается одно из преимуществ хранения образов
в репозиториях.
Мы рассмотрели основные команды, используемые для управления
контейнерами и образами. Поговорим теперь ещё о некоторых командах.
3.8.8 Разные команды
Вот команда, которая выводит сведения о версиях клиента и сервера
Docker:
docker version
Эта, уже известная вам команда, применяется для входа в реестр
Docker:
docker login
Такая команда позволяет удалить неиспользуемые контейнеры, сети и
образы, которым не назначено имя и тег:
docker system prune
Вот пример её использования:
docker system prune -a --volumes
Ключ -a — сокращение для --all, позволяет удалить неиспользуемые
образы, а не только те, которым не назначено имя и тег. Ключ -volumes позволяет удалить неиспользуемые тома.
3.9 Docker: работа с данными
Обратите внимание на то, что этот материал подготовлен с
использованием движка Docker версии 18.09.1 и API версии 1.39.
Данные в Docker могут храниться либо временно, либо постоянно.
Начнём с временных данных.
3.9.1 Временное хранение данные
В контейнерах Docker организовать работу с временными данными
можно двумя способами. По умолчанию файлы, создаваемые приложением,
работающим в контейнере, сохраняются в слое контейнера, поддерживающем
запись. Для того чтобы этот механизм работал, ничего специально настраивать
не нужно. Получается дёшево и сердито. Приложению достаточно просто
сохранить данные и продолжить заниматься своими делами. Однако после
того как контейнер перестанет существовать, исчезнут и данные, сохранённые
таким вот нехитрым способом.
Для хранения временных файлов в Docker можно воспользоваться ещё
одним решением, подходящим для тех случаев, когда требуется более высокий
58
уровень производительности, в сравнении с тем, который достижим при
использовании стандартного механизма временного хранения данных. Если
вам не нужно, чтобы ваши данные хранились бы дольше, чем существует
контейнер, вы можете подключить к контейнеру tmpfs — временное
хранилище информации, которое использует оперативную память хоста. Это
позволит ускорить выполнение операций по записи и чтению данных.
Часто бывает так, что данные нужно хранить и после того, как
контейнер прекратит существовать. Для этого нам пригодятся механизмы
постоянного хранения данных.
3.9.2 Постоянное хранение данных
Существуют два способа, позволяющих сделать срок жизни данных
большим срока жизни контейнера. Один из способов заключается в
использовании технологии bind mount. При таком подходе к контейнеру
можно примонтировать, например, реально существующую папку. Работать с
данными, хранящимися в такой папке, смогут и процессы, находящиеся за
пределами Docker. Вот как выглядят монтирование tmpfs и технология bind
mount.
Рисунок 22 - Монтирование tmpfs и bind mount
Минусы использования технологии bind mount заключаются в том, что её
использование усложняет резервное копирование данных, миграцию данных,
совместное использование данных несколькими контейнерами. Гораздо
лучше для постоянного хранения данных использовать тома Docker.
3.9.3 Тома Docker
Том — это файловая система, которая расположена на хост-машине за
пределами контейнеров. Созданием и управлением томами занимается Docker.
Вот основные свойства томов Docker:
 Они представляют собой средства для постоянного хранения
информации.
 Они самостоятельны и отделены от контейнеров.
59
Ими могут совместно пользоваться разные контейнеры.
 Они позволяют организовать эффективное чтение и запись данных.
 Тома можно размещать на ресурсах удалённого облачного провайдера.
 Их можно шифровать.
 Им можно давать имена.
 Контейнер может организовать заблаговременное наполнение тома
данными.
 Они удобны для тестирования.
Как видите, тома Docker обладают замечательными свойствами.
Давайте поговорим о том, как их создавать.

3.9.4 Создание томов
Тома можно создавать средствами Docker или с помощью запросов к
API.
Вот инструкция в Dockerfile, которая позволяет создать том при
запуске контейнера.
VOLUME /my_volume
При использовании подобной инструкции Docker, после создания
контейнера, создаст том, содержащий данные, которые уже имеются в
указанном месте. Обратите внимание на то, что если вы создаёте том с
использованием Dockerfile, это не освобождает вас от необходимости указать
точку монтирования тома.
Создавать тома в Dockerfile можно и используя формат JSON.
Кроме того, тома можно создавать средствами командной строки во
время работы контейнера.
3.9.5 Работа с томами из командной строки
3.9.5.1 Создание тома
Создать самостоятельный том можно следующей командой:
docker volume create —-name my_volume
3.9.5.2 Выяснение информации о томах
Для того чтобы просмотреть список томов Docker, воспользуйтесь
следующей командой:
docker volume ls
Исследовать конкретный том можно так:
docker volume inspect my_volume
60
3.9.5.3 Удаление тома
Удалить том можно так:
docker volume rm my_volume
Для того чтобы удалить все тома, которые не используются
контейнерами, можно прибегнуть к такой команде:
docker volume prune
Перед удалением томов Docker запросит у вас подтверждение
выполнения этой операции.
Если том связан с каким-либо контейнером, такой том нельзя удалить
до тех пор, пока не удалён соответствующий контейнер. При этом, даже если
контейнер удалён, Docker не всегда это понимает. Если это случилось —
можете воспользоваться следующей командой:
docker system prune
Она предназначена для очистки ресурсов Docker. После выполнения
этой команды у вас должна появиться возможность удалить тома, статус
которых до этого определялся неправильно.
3.9.5.4 Флаги --mount и --volume
Для работы с томами вам, при вызове команды docker, часто придётся
пользоваться флагами. Например, для того чтобы создать том во время
создания контейнера можно воспользоваться такой конструкцией:
docker container run --mount source=my_volume,
target=/container/path/for/volume my_image
В давние времена (до 2017 года) популярен был флаг --volume.
Изначально этот флаг (ещё им можно пользоваться в сокращённом виде, тогда
он выглядит как -v) использовался для самостоятельных контейнеров, а флаг -mount — в среде Docker Swarm. Однако, начиная с Docker 17.06, флаг -mount можно использовать в любых сценариях.
Надо отметить, что при использовании флага --mount увеличивается
объём дополнительных данных, которые приходится указывать в команде, но,
по нескольким причинам, лучше использовать именно этот флаг, а не -volume. Флаг --mount — это единственный механизм, который позволяет
работать с сервисами или указывать параметры драйвера тома. Кроме того,
работать с этим флагом проще.
В существующих примерах команд, направленных на работу с
данными в Docker, вы можете встретить множество примеров употребления
61
флага -v. Пытаясь адаптировать эти команды для себя, учитывайте то, что
флаги --mount и --volume используют различные форматы параметров. То
есть, нельзя просто заменить -v на --mount и получить рабочую команду.
Главное различие между --mount и --volume заключается в том, что при
использовании флага --volume все параметры собирают вместе, в одном поле,
а при использовании --mount параметры разделяются.
При работе с --mount параметры представлены как пары вида ключзначение, а именно, это выглядит как key=value. Эти пары разделяют
запятыми. Вот часто используемые параметры --mount:
— тип монтирования. Значением для соответствующего ключа
могут выступать bind, volume или tmpfs. Мы тут говорим о томах, то есть —
нас интересует значение volume.
 source — источник монтирования. Для именованных томов это — имя
тома. Для неименованных томов этот ключ не указывают. Он может быть
сокращён до src.
 destination — путь, к которому файл или папка монтируется в
контейнере. Этот ключ может быть сокращён до dst или target.
 readonly — монтирует том, который предназначен только для чтения.
Использовать этот ключ необязательно, значение ему не назначают.
Вот пример использования --mount с множеством параметров:
 type
docker run --mount
type=volume,source=volume_name,destination=/path/in/container,readonly
my_image
3.10 Вывод
Doker — программа, которая позволяет положить любой софт в
замкнутую среду (контейнер). А потом передавать этот контейнер дальше, на
любой компьютер.
Фишка в том, что разработчик ПО настраивает всё сам:

операционную систему

сервер приложения

само приложение
А пользователю передает уже готовый и настроенный продукт. Тем
самым сокращая запросы в техподдержку «я попытался просто тык-тык, не
читая инструкцию, теперь расскажите мне, что же я пропустил».
Также докер используется в тестировании и разработке вместо
виртуальных машин, потому что имеет ряд преимуществ. Он изолирует
процессы, быстро поднимает окружения и позволяет легко и быстро прогонять
автотесты на разных версиях системы.
62
63
4. Kubernetes: основы, установка и настройка
Контейнеризация приложений — один из главных трендов
современных IT-разработок. Однако, у контейнеров есть один существенный
недостаток для массового потребителя — сложная настройка
масштабирования.
Решением
стали
автоматические
системы
управления
контейнеризацией, наиболее популярной из которых является Kubernetes. Это
программное обеспечение с открытым исходным кодом от компании Google
завоевало признание благодаря сочетанию гибкости, безопасности и
мощности.
Kubernetes — система оркестрации, позволяющая упростить
управление
множеством
контейнеров,
ускорить
разработку
контейнеризованных приложений и выкатку обновлений. В этой статье мы
поговорим об основах этой популярной технологии и разберемся, как она
работает.
4.1 История создания
Проект Kubernetes (сокращенно K8s) вырос из системы управления
кластерами Borg. Внутренний продукт поискового гиганта Google получил
название в честь кибер-рассы боргов из легендарного сериала «Звездный
путь».
Команде разработчиков Google Borg была поставлена масштабная
задача — создать открытое программное обеспечение для оркестрирования*
контейнеров, которое станет вкладом Google в развитие мировых ITтехнологий. Приложение было написано на основе языка Go.
* Под «оркестрированием» подразумевается автоматизированное
управление связанными сущностями — контейнерами или виртуальными
машинами.
На этапе разработки K8s назвался Project Seven («Проект «Седьмая»).
Это было прямой отсылкой к персонажу «Звездного пути» Seven of Nine
(«Седьмая-из-девяти») — андроиду-боргу, сумевшему вернуть себе
человечность. Позже проект получил имя «Кубернетес», от греческого слова
κυβερνήτης, которое означает «управляющий», «рулевой» или «кормчий».
В 2014 году общественности представили исходные коды, а годом
позже появилась первая версия программы Kubernetes 1.0. В дальнейшем все
права на продукт были переданы некоммерческому фонду Cloud Native
Computing Foundation (CNCF), куда входят Google, The Linux Foundation и ряд
крупнейших технологических корпораций.
64
4.2 Как работает технология
4.1.1Принципы устройства
Основы работы K8s – применение декларативного подхода. От
разработчика требуется указать, чего необходимо достичь, а не способы
достижения.
Помимо этого, в Kubernetes могут быть задействованы императивные
команды (create, edit, delete), которые позволяют непосредственно создавать,
модифицировать и удалять ресурсы. Однако, их не рекомендуется
использовать для критически важных задач.
Для развертывания программного обеспечения в Kubernetes
применяется база Linux-контейнеров (например, Containerd или CRI-O) и
описание — сколько потребуется контейнеров и в каком количестве им
потребуются ресурсы. Само развертывание контейнеров происходит на основе
рабочих нод — виртуальных или физических машин.
4.1.2Основные задачи Kubernetes
1. Развертывание контейнеров и все операции для запуска
необходимой конфигурации. В их число входят перезапуск остановившихся
контейнеров, их перемещение для выделения ресурсов на новые контейнеры
и другие операции.
2. Масштабирование и запуск нескольких контейнеров
одновременно на большом количестве хостов.
3. Балансировка множества контейнеров в процессе запуска. Для
этого Kubernetes использует API, задача которого заключается в логическом
группировании контейнеров. Это дает возможность определить их пулы,
задать им размещение, а также равномерно распределить нагрузку.
4.1.3Преимущества K8s
Обнаружение сервисов и балансировка нагрузок. Контейнеры
могут работать через собственные IP-адреса или использовать общее имя DNS
для целой группы. K8s может регулировать нагрузку сетевого трафика и
распределять его, чтобы поддержать стабильность развертывания.
 Автоматическое управление хранилищами. Пользователь может
задавать, какое хранилище использовать для развертывания по умолчанию —
внутреннее, внешнего облачного провайдера (GKE, Amazon EKS, AKS),
другие варианты.
 Автоматическое внедрение и откат изменений. Пользователь
может на лету делать любые дополнения к текущей конфигурации
контейнеров. Если это нарушит стабильность развертывания, K8s
самостоятельно откатит изменения до стабильно работающей версии.
 Автоматическое
распределение ресурсов. Kubernetes сам
распределяет пространство и оперативную память из выделенного кластера
нод, чтобы обеспечить каждый контейнер всем необходимым для работы.

65
Управление паролями и настройками. K8s может служить
приложением для безопасной обработки конфиденциальной информации,
связанной с работой приложений — паролей, OAuth-токенов, SSH-ключей. В
зависимости от способа применения, данные и настройки можно обновлять
без создания контейнера заново.
 Самовосстановление при возникновении сбоя. С помощью особых
метрик и тестов система может быстро опознать поврежденные или
переставшие отвечать на запросы контейнеры. Вышедшие из строя
контейнеры создаются заново и перезапускаются на том же поде.
Kubernetes – удобный инструмент оркестрации контейнеров. Однако,
это решение, не работает само по себе, без подготовки и дополнительных
настроек. Например, пользователям придется решать вопросы по миграции
схем баз данных или разбираться с обратной совместимостью API.

4.3 Основные компоненты кластера
Компоненты — это модули, службы и программы, которые
обеспечивают работу всего кластера. Они работают внутри нод, то есть
физических или виртуальных серверов, на которых работает Kubernetes —
некоторые внутри управляющих Master-нод, некоторые внутри рабочих
Worker-нод.
66
Рисунок 23 - Упрощенная архитектура компонентов кластера
Итак, в кластер Kubernetes входят следующие компоненты:
1. kube-apiserver. Сервер API обеспечивает работу API кластера,
обрабатывает REST-операции и предоставляет интерфейс, через который все
остальные компоненты взаимодействуют между собой. Также через него
проходят все запросы на чтение или изменение состояния кластера. Работает
на Master-нодах.
2. etcd. Распределенное хранилище формата «ключ-значение», в
котором хранится состояние всего кластера. Его основная задача —
обеспечить консистентность данных и отказоустойчивость кластера. Etcd —
это самостоятельный проект, который развивается отдельно от Kubernetes и
используется в разных продуктах. Хранилище использует алгоритм
консенсуса Raft, то есть в нем уже заложены механизмы для достижения
отказоустойчивости. Чтобы их использовать, нужно создать несколько реплик
etcd на отдельных машинах либо на основных нодах кластера. Работает на
Master-нодах.
3. kube-scheduler. Компонент, который планирует, на каких узлах
будут разворачиваться поды. При этом он учитывает множество факторов,
включая требования к ресурсам, ограничения, местонахождение данных и так
далее. Работает на Master-нодах.
67
4. kube-controller-manager. Компонент, который запускает процессы
контроллеров. Что такое контроллеры, мы рассказываем ниже . Работает на
Master-нодах.
5. kubelet. Cлужба, которая отвечает за управление состоянием ноды:
запуск, остановку и поддержание работы подов и контейнеров. Работает на
Worker-нодах.
6. kube-proxy. Служба, которая управляет правилами балансировки
нагрузки. Она конфигурирует правила iptables или IPVS, через которые
осуществляется роутинг и проксирование. Работает на Worker-нодах.
4.4 Основные объекты кластера Kubernetes
Объекты — сущности, которые Kubernetes использует для
представления состояния кластера. Здесь мы расскажем о самых основных
объектах Kubernetes.
Рисунок 24 - Схема взаимодействия основных компонентов K8s
Node (Нода)
Ноды или узлы — виртуальные или физические машины, на которых
разворачивают и запускают контейнеры. Совокупность нод образует кластер
Kubernetes.
Серверы, на которых работает Kubernetes бывают двух типов:
68
1. Master (мастер-нода) — узел, который управляет всем кластером.
Он следит за остальными нодами и распределяет между ними нагрузку. Как
правило, мастер-нода занимается только управлением и не берет на себя
никакие рабочие нагрузки. Для повышения отказоустойчивости мастер-нод
должно быть несколько. Первая запущенная нода или мастер-нода
непосредственно управляет кластером, используя для этого менеджер
контроллеров (controller manager) и планировщик (scheduler). Она
ответственна за интерфейс взаимодействия с пользователями через сервер API
и содержит в себе хранилище «etcd» с конфигурацией кластера, метаданными
и статусами объектов.
2. Worker (рабочие ноды) — узлы, на которых и работают
контейнеры. На одном узле может работать много контейнеров в зависимости
от параметров ноды (объем памяти и CPU) и требований контейнера.
Рабочих узлов обычно больше, чем мастер-нод. Потенциально чем их
больше, тем большее количество приложений можно запустить и тем
отказоустойчивее будет кластер, потому что в случае выхода из строя одной
ноды нагрузка переносится на другие.
Рисунок 25— Вот так выглядит кластер Kubernetes в упрощенном виде
Namespaces (пространства имен)
Объект, предназначенный для разграничения ресурсов кластера между
командами и проектами. Пространства имен — несколько виртуальных
кластеров, запущенные на одном физическом.
Это возможность разделить один физический кластер Kubernetes на
несколько виртуальных, каждый из которых изолирован от других. Подобно
тому, как один физический компьютер разбивается на несколько виртуальных
69
машин. Как правило, пространства имен создают для того, чтобы разделить
разные проекты, команды или среды развертывания (dev, test, prod).
Ресурсы в пространствах имен скрыты друг от друга, но по умолчанию
не изолированы полностью. Сервис из одного Namespace может общаться с
сервисом из другого Namespace. При необходимости Namespace можно
изолировать полностью, это бывает полезно при разграничении доступа.
В каждом пространстве имен есть свой набор ресурсов: поды, сервисы,
развертывания. В одном пространстве имен у ресурсов должны быть
уникальные названия, но эти же названия можно использовать в других
Namespace. Однако не все ресурсы входят в пространство имен, например,
ноды и Persistent Volumes доступны всему кластеру.
Рисунок 26 — Так выглядят отдельные Namespace внутри Kubernetes
Pod (Под)
Первичный объект развертывания и основной логический юнит в K8s.
Поды — набор из одного и более контейнеров для совместного развертывания
на ноде.
Группировка контейнеров разных типов требуется в том случае, когда
они взаимозависимы и должны запускаться в одной ноде. Это позволяет
увеличить скорость отклика во время взаимодействия. Например, это могут
быть контейнеры, хранящие веб-приложение и сервис для его кэширования.
70
Это абстрактный объект Kubernetes, который представляет собой
группу из одного или нескольких контейнеров. Контейнеры внутри пода
вместе запускаются и работают, имеют общее хранилище и сетевые ресурсы.
Под — минимальная единица, которой оперирует Kubernetes, то есть он не
управляет контейнерами напрямую, он «оборачивает» их в поды и управляет
ими.
Под и все его контейнеры работают на одном узле и остаются там до
окончания работы. Под может прекратить работу по разным причинам: в
соответствии со своим жизненным циклом, в случае выхода из строя узла или
при обновлении контейнера в составе пода. Когда под пересоздается, он может
создаться на другой ноде, отличной от первоначальной.
Чаще всего под — это обертка лишь над одним контейнером
(приложением), потому что у каждого приложения могут быть разные
требования к производительности, масштабированию, SLA и так далее.
Реже встречаются поды, в которых объединены несколько
контейнеров. Обычно так делают, когда нужно объединить несколько
взаимосвязанных приложений, которые зависят друг от друга и нет смысла
запускать их отдельно.
Например
Веб-сервер использует базу данных Redis для кэширования. Если Redis
больше нигде не используется и нужна только для этого веб-сервера, тогда
есть смысл объединить их в один под. При этом инстансы одного
приложения не используют кэш совместно, базы данных Redis в разных подах
никак не связаны между собой. Если эта же БД используется не только для
одного веб-сервера, но и для других приложений, тогда лучше обернуть ее в
отдельный под, который не будет зависеть от жизненного цикла остальных
контейнеров.
Рисунок 27 - На одном узле кластера находится несколько подов,
внутри которых может быть один или несколько контейнеров
71
Обычно поды не создаются вручную — Kubernetes делает это сам. Но
для этого ему нужно знать, как создавать поды: какие именно образы, какие
требования к узлам и так далее. Для этого используются контроллеры,
например Deployments.
Controllers (Контроллеры)
Контроллеры — это общее название класса средств управления,
которые следят за кластером и стараются поддерживать желаемое состояние.
Есть несколько типов контроллеров, которые следят за ресурсами и делают
это немного по-разному, например:
1. Deployment (Развертывание)—
это
описание
желаемого
состояния для подов; указание Kubernetes, как он должен управлять
жизненным циклом подов. Поддерживает набор подов с нужной
конфигурацией,
управляет
обновлениями
и
откатами.
Самый
распространенный способ разместить приложение в Kubernetes.
2. ReplicaSet (Набор реплик) — создает стабильный набор подов,
выполняющих одну и ту же задачу. Гарантирует, что всегда работает
указанное число реплик подов. То есть если с каким-то подом что-то случится,
Kubernetes запустит новый, чтобы число реплик оставалось заданным. Обычно
это служебный объект, который Kubernetes создает сам.
Объект, отвечающий за описание и контроль за несколькими
экземплярами (репликами) подов, созданных на кластере. Наличие более
одной реплики позволяет повысить устойчивость от отказов и
масштабирование приложение. На практике ReplicaSet создается с
использованием Deployment.
ReplicaSet является более продвинутой версией предыдущего способа
организации создания реплик (репликации) в K8s – Replication Controller.
3. StatefulSet (Набор состояния) — используется для управления
приложениями с отслеживанием состояния (Stateful-приложениями) с
помощью постоянного хранилища. Как и другие объекты, например —
ReplicaSet или Deployment, Statefulset позволяет развертывать и управлять
одним или несколькими подами. Но в отличие от них, идентификаторы подов
имеют предсказуемые и сохраняемые при перезапуске значения.
4. DaemonSet (Набор даемона) — гарантирует, что все или
некоторые узлы запускают копию пода. То есть по мере добавления узлов в
кластер добавляются поды. Объект, который отвечает за то, чтобы на каждой
отдельной ноде (или ряде выбранных) запускался один экземпляр выбранного
пода.
5. Job (Задания) — недолговечные рабочие нагрузки, используемые
для выполнения одной задачи. Job создает один или несколько подов и
дождется, пока они выполнят свою работу. CronJob (Задания по расписанию)
— создает задачи по расписанию. Объекты для регулировки однократного или
регулярного запуска выбранных подов и контроля завершения их работы.
72
Контроллер Job отвечает за однократный запуск, CronJob — за запуск
нескольких заданий по расписанию.
Мы для примера рассмотрим, как работают Deployments
(развертывания).
Например, в развертывании мы указываем, что нужно запустить
образ HTTP-сервера, у которого должно быть три реплики, при этом для
работы ему нужно 256 Мб памяти. После создания развертывания Kubernetes
сам проанализирует, на каких узлах нужно разместить поды, и будет
следить за их состоянием. Если по какой-то причине одна из реплик пода или
весь узел выйдут из строя, Kubernetes сам развернет новые реплики на других
узлах.
Когда мы что-то меняем в параметрах развертывания, Kubernetes
подхватит эти изменения и опять будет стремиться достигнуть
желаемого состояния. Например, у нас есть развертывание с тремя
репликами пода, в которых работает наше приложение. Через какое-то
время мы выпускаем новую версию приложения, которую нужно развернуть
в кластере.
Вот что происходит, когда мы выпускаем обновление приложения:
73
Рисунок 28 - Kubernetes стремится достичь заданного состояния
74
В процессе такого обновления не было простоев, то есть в каждый
момент времени приложение работало и отвечало на запросы. При этом
Kubernetes сам решал, как и в каком порядке ему лучше обновлять поды. Это
упрощенный пример, в нем все действия происходят только в рамках одного
узла. Но для общего понимания этого достаточно.
Похожим образом работают и остальные контроллеры: они стараются
поддерживать желаемое состояние управляемых ими ресурсов.
Label/Selector (Метки/Селекторы)
Метки предназначены для маркировки ресурсов. Позволяют упростить
групповые манипуляции с ними. Селекторы позволяют выбирать/фильтровать
объекты на основе значения меток.
По факту, метки и селекторы не являются самостоятельными
объектами Kubernetes, но без них система не сможет полноценно
функционировать.
Service (Сервис)
Это абстракция, которая объединяет поды в логическую группу и
определяет политику доступа к ним. То есть что-то вроде маршрутизатора и
балансировщика нагрузки между подами.
Поды — непостоянные ресурсы. Они могут уничтожаться,
пересоздаваться, переезжать на другие ноды и менять IP-адреса. Если внешняя
система или сервис захотят обратиться к поду, то они должны постоянно
следить за его жизненным циклом и знать, куда обратиться в конкретный
момент времени. Это неудобно и неправильно.
Поэтому в Kubernetes существуют сервисы, которые знают:

сколько всего подов, то есть сколько реплик у деплоймента;

на каких хостах они работают;

какие из них сейчас доступны, а какие нет.
Сервис принимает запрос от внешних систем или других сервисов,
решает, какому именно поду адресовать запрос, и адресует его. При этом
внешней системе не нужно знать о жизненном цикле подов: они обращаются
к сервису по DNS-именам, которые всегда постоянны.
75
Рисунок 29 - Схема работы сервисов в Kubernetes
Persistent Volumes (Постоянные тома)
Это способ хранить данные между перезапусками контейнеров.
Контейнеры по своей природе непостоянные сущности. Они могут
быть в любой момент уничтожены или перезапущены. Идея контейнеров в
том, что они легко «умирают» и появляются заново при необходимости.
Поэтому любые постоянные данные нужно хранить где-то вне контейнера. Но
контейнеры изолированы от основной системы — это сделано для
безопасности. Приложения не могут напрямую получить доступ к файловой
системе. Также часто для отказоустойчивости создается несколько
экземпляров контейнеров, и это порождает новую проблему: нужно как-то
синхронизировать данные между репликами.
Kubernetes решает эти проблемы с помощью Persistent Volume. Это
абстракция над хранилищами данных, которая позволяет хранить данные в
76
зависимости от жизни контейнеров. Это постоянные тома, жизненный цикл
которых никак не связан с подами и контейнерами. PV — это самостоятельные
ресурсы, которые создаются и управляются отдельно.
Для работы с PV используются два ресурса: PersistentVolume и
PersistentVolumeClaim.
1. PersistentVolume — это место, где хранятся постоянные данные:
раздел на жестком диске, облачное хранилище или распределенная файловая
система (CephFS, NFS и др.). Жизненный цикл PV не зависит какого-то
отдельного контейнера или пода. Если контейнер или под уничтожается, PV
остается.
2. PersistentVolumeClaim — это запрос на использование хранилища.
Под отправляет этот запрос в PV с просьбой выделить ему место в постоянном
хранилище. Storage Provisioner (специальная программа, которую запускает
Kubernetes) оценивает запрос и принимает решение, где лучше выделить
место, ведь PV может быть несколько и они могут быть разных типов. Когда
решение найдено, PVC выделяет место и возвращает результат поду.
Такой подход позволяет приложениям абстрагироваться от конкретной
реализации хранилища. Вместо того чтобы запрашивать конкретное
хранилище по конкретному адресу, приложения просто запрашивают PVC,
как бы говоря: «Мне нужно 1GB для моих данных». А PersistentVolume уже
сам определяет, где находится это хранилище, и резервирует место для пода.
77
Рисунок 30 - Как работают постоянные тома Kubernetes
При этом сами хранилища не создаются автоматически. Для начала
нужно определить, какое это хранилище и где оно будет находиться, создать
его. Потом создать соответствующий ресурс в Kubernetes и подключить его к
хранилищу. Если запускать Kubernetes On-premise, то внедрение и
обслуживание постоянного хранилища — дополнительная головная боль. А
управляемый Kubernetes, например KaaS на платформе Mail.ru Cloud
Solutions , умеет создавать PV динамически по требованию.
4.5 Процесс установки
78
Установка Kubernetes, рассмотренная ниже, предполагает наличие
одного (или более) серверов с операционной системой Centos 7 или Ubuntu
16.04.
Важно! Нужно заранее отключить раздел «swap». Если на сервере
пока не установлена операционная система, достаточно не создавать этот
раздел. Для отключения нужно выполнить в терминале команду: swapoff -a.
Затем открыть «/etc/fstab» с правами root и удалить
соответствующую команде строчку «#/swapfile».
Проект Kubernetes действует на основе контейнеров Docker,
существенно расширяя их функциональность. Логично, что начинать работу
Kubernetes следует именно с установки Docker.
Проще всего остановить выбор на версии, добавленной на текущий
момент в репозитории. Ее протестировали разработчики Kubernetes и она
работает наиболее стабильно.
Установка контейнеров на Ubuntu 16.04
Чтобы установить Docker на Ubuntu 16.04, необходимо выполнить
следующие команды с правами суперпользователя:
apt-get update
apt-get install -y docker.io
Если требуется работать с более новыми версиями контейнеров,
запустите команды:
apt-get update
apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
curl -fsSL https://downloa
d.docker.com/linux/ubuntu/gpg | apt-key add –
79
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release;
echo "$ID") \
$(lsb_release -cs) \
stable"
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
Установка контейнеров в CentOS 7
Для установки Docker на Centos, в консоли нужно выполнить
команды:
yum install -y docker
systemctl enable docker && systemctl start docker
Установка kubeadm, kubelet и kubectl в Ubuntu
Для работы с Kubernetes понадобится установить компоненты
kubeadm, kubelet и kubectl. Эти утилиты понадобятся для создания управления
кластером Kubernetes.

Kubectl — позволяет создавать и настраивать объекты в
кластере.
80

Kubelet — занимается запуском контейнеров на хостах.
Kubeadm —
составляющие кластер.

позволит
настраивать
компоненты,
В Ubuntu эти компоненты можно установить следующим способом:
apt-get update && apt-get install -y apt-transport-https software-propertiescommon
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add add-apt-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
apt-get update
apt-get install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet
Установка kubeadm, kubelet и kubectl в CentOS
В CentOS 7 компоненты устанавливаются следующим образом:
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
81
EOF
setenforce 0
yum install -y kubelet kubeadm kubectl
systemctl enable kubelet && systemctl start kubelet
Обращаем
внимание! Команда setenforce 0 позволит
получить
корректный доступ контейнеров к файловой системе хоста. Последняя
необходима для функционирования сети у подов.
Нужно убедиться, что «kubelet» и «docker» пользуются одним и тем же
драйвером «cgroup». В этом может помочь команда:
cat << EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
4.6 Настройка Kubernetes
4.6.1Инициализация кластера
Нужно указать сервер, на котором установлен K8s (он будет
первичным — там будут запускаться остальные операции) и выполнить
инициализацию кластера:
kubeadm init --pod-network-cidr=10.244.0.0/16
Обращаем внимание! Опция «—pod-network-cidr» задает адрес
виртуальной сети подов и может отличаться, в зависимости от
используемого сетевого плагина.
В данном примере будем использован наиболее распространенный
сетевой плагин — Flannel. По умолчанию он использует сеть «10.244.0.0/16»,
которая была указана в параметре, приведенном выше.
При выполнении команды в консоли, есть вероятность появления
ошибок или предупреждений. Ошибки нужно исправлять в обязательном
порядке, а на предупреждения можно не обращать внимание, если это не
окружение «production».
Если все сделано правильно, на экране отобразится команда,
позволяющая присоединить остальные ноды кластера к первичному хосту.
82
Команда может отличаться, в зависимости от структуры кластера. Ее нужно
сохранить на будущее.
После выполнения этой команды система выведет примерный
результат:
Остается выполнить следующие команды от имени пользователя,
который будет управлять кластером:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
4.6.2Настройка CNI
Перед тем, как начать запускать в кластере приложения, нужно
выполнить настройку Container Network Interface («сетевой интерфейс
контейнера» или CNI). CNI нужен для настройки взаимодействия и
управления контейнерами внутри кластера.
Существует много плагинов для создания CNI. В данном примере
применяется Flannel, так как это наиболее простое и проверенное решение.
Однако, не меньшей популярностью пользуются плагины Weave Net от
компании Weaveworks и Calico (Project Calico), обладающие более широким
функционалом и возможностями сетевых настроек.
Чтобы установить Flannel, выполните в терминале команду:
83
kubectl apply -f
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kubeflannel.yml
В выводе будут отображены имена всех созданных ресурсов.
4.6.3Добавление узлов (нод) в кластер
Чтобы добавить новые ноды в существующий кластер, требуется выполнить
следующий алгоритм:
 Подключиться к серверу через SSH.
 Установить на сервер Docker, Kubelet, Kubeadm (как показано выше).
 Выполнить команду:
kubeadm join --token <token> <control-plane-host>:<control-plane-port> -discovery-token-ca-cert-hash sha256:<hash>
Данная команда была выведена при выполнении команды «kubeadm init» на
мастер-ноде.
Если команда не была сохранена, то можно ее составить повторно.
4.6.4Получение токена авторизации кластера (<token>)
1. Подключиться к серверу через SSH.
2. Запустить команду, которая присутствовала на выводе команды
«kubeadm init». Например:
kubeadm join --token <token> <control-plane-host>:<control-plane-port> -discovery-token-ca-cert-hash sha256:<hash>
Если токена нет, его можно получить, выполнив следующую команду на
мастер-ноде:
kubeadm token list
Вывод должен быть примерно таков:
По умолчанию, срок действия токена — 24 часа. Если требуется добавить
новый узел в кластер по окончанию этого периода, можно создать новый
токен следующей командой:
84
kubeadm token create
Вывод будет примерно таков:
5didvk.d09sbcov8ph2amjw
Если значение параметра «—discovery-token-ca-cert-hash» неизвестно, его
можно получить следующей командой:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
Будет получен примерно такой вывод:
8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec7
8
Для ввода IPv6-адреса в параметр «<control-plane-host>:<control-planeport>», адрес должен быть заключен в квадратные скобки. Например:
[fd00::101]:2073
3. Должен быть получен вывод следующего вида:
4. Спустя несколько секунд нода должна появиться в выводе команды:
kubectl get nodes
4.6.5Дополнительные настройки
В дефолтной конфигурации мастер-нода не запускает контейнеры, так
как занимается отслеживанием состояния кластера и перераспределением
ресурсов. Ввод данной команды даст возможность запускать контейнеры на
мастере, собенно, если кластер содержит лишь одну ноду:
kubectl taint nodes --all node-role.kubernetes.io/master-
4.7 Проверка работоспособности кластера
Проверить, что кластер запустился и правильно работает, можно так:
kubectl -n kube-system get pods
Вывод будет аналогичен. В нем будут отображены системные POD’ы
k8s.
85
Теперь установку можно считать завершенной. Далее можно
продолжить настройку K8s для работы с веб-приложениями. Например,
подключить диспетчер пакетов «helm» для автоматического развертывания
приложений или контроллер «nginx ingress», отвечающий за маршрутизацию
внешнего трафика.
4.8 Расширяемость кластера сторонними инструментами
Невозможно создать решение, которое удовлетворит все потребности
и будет содержать все возможные функции. Поэтому сторонние разработчики
создают или интегрируют свои инструменты с Kubernetes, чтобы расширить
его возможности, архитектура технологии позволяет это сделать. Для примера
опишем несколько инструментов, но не будем подробно в них погружаться.
Мы просто хотим показать, как можно расширить стандартные возможности
Kubernetes. Вы также можете прочитать статью , в которой мы рассказываем о
90 полезных инструментах для Kubernetes.
Мониторинг . Часто для мониторинга используется связка Prometheus
+ Grafana. Первый инструмент собирает метрики, второй визуализирует их.
Можно мониторить как инфраструктуру самого Kubernetes, так и свои
приложения.
Инструменты для разработки . Например, Jenkins позволяет настроить
процесс непрерывной интеграции, а пакетный менеджер Helm помогает
создавать единые шаблоны для описания приложений и запускать их.
Инструменты безопасности . Например, Kubesec. Он может
обнаруживать избыточные привилегии и разрешения, предоставленные поду,
запуск контейнера с Root-полномочиями или опасные монтирования вроде
/proc хоста или сокета Docker.
Service Mesh . Например, Istio — это инструмент конфигурации Service
Mesh; полноценный фреймворк для подключения, управления и мониторинга
микросервисной архитектуры.
4.9 Нужен ли вам Kubernetes?
Чтобы самостоятельно развернуть кластер Kubernetes, нужно
подготовить оборудование (физические или виртуальные серверы),
установить Kubernetes и затем настроить его. Настройка — самое сложное,
потому что по умолчанию в Kubernetes нет всех нужных инструментов и
надстроек. Для нормальной работы кластера потребуется настроить сеть и
86
аутентификацию, сконфигурировать поды, организовать балансировку
нагрузки, мониторинг, логирование и многое другое.
В общем, самостоятельное развертывание кластера — непростая
задача, поэтому сначала стоит разобраться, нужна ли вам эта технология в
принципе.
Нужно учесть, что Kubernetes — сложная и многоуровневая система
и мало кто сможет разобраться, правильно его настроить и поддерживать
без предварительного обучения. Поэтому нужно либо искать
соответствующего специалиста, либо использовать Managed-решение от
облачного провайдера , например Mail.ru Cloud Solutions.
Это позволит не вдаваться в подробности установки кластера и
переложить его поддержку на плечи провайдера. А также получить
дополнительные преимущества над «обычным» Kubernetes вроде
автомасштабирования кластера по клику, автоматического балансировщика
нагрузки и простой интеграции с другими облачными сервисами.
4.10 Итог
Несмотря на кажущуюся сложность настройки, K8s стоит времени,
потраченного на его изучение. Kubernetes — наиболее совершенный на
сегодня инструмент оркестрирования контейнеров. Он позволяет не только
автоматизировать процесс развертывания, но и максимально упрощает
дальнейший процесс работы с массивами контейнеров. В дальнейшей работе
с платформой поможет подробная официальная документация, доступная, в
том числе, на русском языке.
Источники
https://otus.ru/nest/post/774/
https://sbercloud.ru/ru/warp/gitlab-about
https://otus.ru/nest/post/864
https://www.freecodecamp.org/news/a-beginner-friendly-introduction-tocontainers-vms-and-docker-79a9e3e119b/
https://www.amazon.com/Docker-Deep-Dive-Nigel-Poultonebook/dp/B01LXWQUFF
https://dockerbook.com/
https://habr.com/ru/post/310460/
https://proglib.io/p/docker
https://mcs.mail.ru/blog/osnovy-kubernetes-vvedenie-v-tehnologiju
https://www.labirint.ru/books/673939/
https://www.digitalocean.com/community/tutorials/an-introduction-tokubernetes
https://ipsoftware.ru/posts-cloud/k8s-quickstart/
https://kubernetes.io/
https://gitlab.softmart.ru/
87
https://selectel.ru/blog/gitlab/
https://otus.ru/nest/post/864/
https://losst.ru/kak-polzovatsya-gitlab
https://serveradmin.ru/ustanovka-i-nastroyka-gitlab/?pdf=7240
https://itlogia.ru/article/gitlab_i_github_v_chem_razlichiya
https://about.gitlab.com/devops-tools/github-vs-gitlab/
88
Download