itmo_conspects

Технологии сборки и развертывания программного обеспечения (DevOps). Трек от Nexign

В курс будет входить изучение DevOps-технологий, необходимых для непрерывных сборки и развертывания ПО, таких как Docker, Ansible, Kubernetes и виртуальные машины

Лекция 1. Введение

DevOps (от англ. Development & Operations) - методология автоматизации технологических процессов сборки, настройки и развертывания программного обеспечения

До выделения DevOps, как отдельной области, разработка и развертывание ПО в каскадной модели разработки проходили в 3 этапа:

  1. Разработчики разрабатывают ПО, стремясь как можно быстрее внедрять новые функции и изменения
  2. Тестировщики тестируют ПО
  3. Системные администраторы запускают ПО в эксплуатацию и отвечают за стабильность работающей системы и поэтому неохотно принимают любые обновления, способные её сломать

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

С появлением гибкой модели Agile и необходимость обновлять проект очень часто появилась потребность согласовать процессы разработки (development), тестирования и эксплуатации (operations) ПО

DevOps появился в конце 2000-ых годов как решение проблемы плохого взаимодействия между разработчиками ПО и специалистами по системному администрированию (эксплуатации)

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


Ключевая концепция DevOps заключается в непрерывной интеграции и непрерывной доставке (CI/CD, Continuous Integration и Continuous Delivery/Deployment)

Цикл разработки получается таким:

Цикл разработки

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


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

Подробнее об этом описано в курсе “Операционные системы”

Чтобы абстрагировать среды исполнения от аппаратного обеспечения, используют виртуализацию. Всего можно выделить 3 применяющихся метода:

Все эти методы позволяют запускать приложения в разных средах исполнения, но на одном и том же физическом сервере

Виртуализация

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

Лекция 2. Контейнеризация

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

Механизмы контейнеризации

Этими механизмами являются пространства имен и контрольные группы:

С помощью пространств имен можно изолировать процессы друг от друга. Для этого существует 8 пространств имен:

  1. Cgroup - изолирует корневую директорию контрольных групп, чтобы процесс в контейнере видел свою иерархию контрольных групп.
  2. IPC (от Inter-Process Communication) - изолирует ресурсы для межпроцессного взаимодействия (такие как очереди сообщений или разделяемая память)
  3. Network - изолирует сетевые устройства, стеки, порты и таблицы маршрутизации
  4. Mount - изолирует точки монтирования файловых систем
  5. PID (от Process ID) изолирует пространство идентификаторов процессов. Процесс внутри контейнера видит только свои процессы и считает, что его идентификатор равен 1, а не реальному идентификатору на хосте
  6. Time - изолирует системное время, позволяя контейнеру иметь своё представление о времени (появилось в Linux 5.6)
  7. User - изолирует идентификаторы пользователей и групп, что позволяет процессу в контейнере быть пользователем root внутри контейнера
  8. UTS (от UNIX Time-Sharing System) - изолирует имена хоста и домена NIS (Network Information Service, системы для распространения конфигурации между несколькими узлами)

Пространства имен можно создавать с помощью утилиты unshare:

sudo unshare --uts /bin/bash

Оболочка Bash запуститься в окружении в изолированном пространстве UTS. Для создания пространств имен используются флаги --ipc, --mount, --net, --pid, --uts, --user, --cgroup, --time

Для создания контейнеров интересны три пространства: PID, Network и Mount

Чтобы ограничивать ресурсы процессора, ОЗУ, ПЗУ и прочего, используется механизм контрольных групп. Для создания контрольных групп есть три способа:

Работа с Docker

В Docker управлением контейнерами занимается демон containerd. Этот демон управляется утилитой командной строки docker-cli

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

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

docker run hello-world

Здесь hello-world - минимальный образ, который был загружен из репозитория Docker Hub (https://hub.docker.com/_/hello-world). При запуске запускается контейнер, который выводит обучающую информацию о Docker

Чтобы создать образ, используется Dockerfile - специальный файл, который описывает создание образа. Например, для hello-world файл Dockerfile выглядит так:

FROM scratch
COPY hello /
CMD ["/hello"]

Здесь инструкциями указано, что:

  1. Образ основан на другом образе scratch (который представляет из себя пустой образ)
  2. Далее копируется исполняемый файл hello в корень контейнера
  3. А затем запускается команда /hello

В Dockerfile также могут использоваться другие команды (*тык*)

Далее используется команда:

docker build -t hello-world:v1 .

Здесь hello-world:v1 - это имя и версия образа, а . - корневой путь контейнера, относительно которого выполняются команды в Dockerfile. По умолчанию docker build будет искать файл ./Dockerfile, но можно указать флагом -f ./otherfolder/Dockerfile другое местоположение

Чтобы узнать список загруженных и созданных образов, используется команда docker images:

IMAGE                ID           DISK USAGE   CONTENT SIZE   EXTRA
hello-world:latest   5e2309035332     25.9kB         9.49kB    U

Здесь указаны идентификатор образа и объем на диске

Команда docker image inspect <image-name>:<version> позволяет изучить образ:

docker image inspect

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

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

Далее образ можно запустить:

docker run -d -p 8000:80 --name <container-name> <image-name>

Здесь применены флаги: