DevOps -- стратегия разработки ПО, призванная устранить разрыв между разработчиками, и другими командами. Методология автомтизации технологических процессов сборки, настройки и развёртывания программного обеспечения. Методология предполагает активное взаимодействие специалистов по разработке со специалистами по информационно-технологическому обсулуживанию и взаимную интеграцию их технологических процессов друг в друга, для обеспечения высокого качества программного продукта.
Методологии разработки - waterfall (последовательный переход от одного этапа к другому), agile (scrum, lean) -- гибкая методология, система идей. Ключевой принцип - разработка через короткие итерации.
Водопадная модель разработки (Waterfall-разработка):
\item Системные и программные требования: закрепляются в PRD (product requirements documents, документ требований к продукту).
\item Анализ: воплощается в моделях, схемах и бизнес-правилах.
\item Дизайн: разрабатывается внутренняя архитектура ПО, способы реализации требований; Не только интерфейс, и внешний вид ПО, но и его внутренняя структурная логика.
\item Кодинг: непосредственно пишется код программы, идёт интеграция ПО.
\item Тестирование: баг-тестеры (тестировщики) проверяют финальный продукт, занося в трекеры сведения о дефектах кода программы или функционала. В случае ошибок и наличия времени/финансов происходит исправление багов.
\item Операции: продукт адаптируется под разные операционные системы, регулярно обновляется для исправления обнаруженных пользователями багов и добавления функционала. В рамках стадии также осуществляется техническая поддержка клиентов.
Обычно ИТ-команда это разработчики(Dev), тестировщики(QA), группа эксплуатации(Ops). Толчком к появлению девопс стало появление микросервисов. Цели девопс -- Сокращение времени выхода на рынок, надёжность (снижение частоты отказов новых релизов), сокращение времени выполнения исправлений, уменьшение количества времени на восстановления (в случае сбоя).
девопс предлагает представителям ранее разрозненных подразделений координировать свои действия. Культура: совместная работа и согласованность, изменения в сфере участия и ответственности, сокращение циклов выпуска (не количество, а сами циклы), непрерывное обучение.
\item\textbf{Планирование} помогает обеспечить командам гибкость и прозрачность
\begin{itemize}
\item представляют, определяют и описывают функции и возможности создаваемых приложений
\item отслеживают ход работы на низком и высоком уровнях детализации
\item создают журналы невыполненной работы, отслеживая ошибки, и так далее.
\end{itemize}
\item\textbf{Разработка} включает написание, тестирование, проверку и интеграцию кода участниками команды. Быстро внедряют инновации, автоматизируя рутинные действия, а также запускают итерации с маленьким шагом при помощи автоматического тестирования и непрерывной интеграции.
\item\textbf{Доставка} -- это процесс последовательного и надёжного развёртывания приложений в рабочих средах. Этап доставки также включает развёртывание и настройку полностью управляемой базовой инфраструктуры, лежащей в основе этих сред.
\begin{itemize}
\item определяют процесс управления выпусками
\item устанавливают автоматические шлюзы, с помощью которых приложения перемещаются между этапами, пока не станут доступными клиентам
\end{itemize}
\item\textbf{Эксплуатация}.
\begin{itemize}
\item обслуживание
\item мониторинг
\item устранение неполадок приложений в рабочих средах
\end{itemize}
внедряя методики девопс, различные подразделения стремятся обеспечить надёжность системы и высокую доступность, свести простои к нулю, а также повысить уровень безопасности и усовершенствовать управление.
Девопс предполагает представителям ранее разрозненных подразделений компании координировать свои действия и совместно создавать более качественные и надёжные продукты (постоянная обратная связь и оптимизация). Совместная работа и согласованность, изменения в сфере участия и ответственности, сокращение циклов выпуска, непрерывное обучение.
Внедрение облачных технологий в корне изменило способы создания развёртывания и эксплуатации приложений. Преимущества: затраты, скорость, глобальный масштаб, производительность, эффективность, надёжность, безопасность.
DevOps-инженер -- высококвалифицированный специалист, который отвечает за автоматизацию всех этапов создания приложений и обеспечивает взаимодействие программистов и системных администраторов. Прорабатывает сборку, доставку и тестирование. Build-инженер, Release-инженер, Automation-инженер, Security-инженер.
\begin{itemize}
\item [+] высокий заработок
\item [+] востребованность
\item [+] интересные задачи
\item [+] перспектива карьерного роста
\item [-] непрерывное обучение (\textit{а минус ли это? прим. Овчинников})
\item [-] необходимость знать много из разных областей
\item [-] возможны стрессовые ситуации и высокая нагрузка
\item Основы программирования (базовый уровень, несколько языков)
\item освоиться в принципах работы ОС
\item понимать облачные и гибридные решения
\item разбираться в системах оркестрации
\item освоить принципы работы микросервисов
\item понимать принципы работы с системами конфигурации
\end{itemize}
Используемые инструменты -- Jenkins, Docker, Kubernetes, Git, Приложения для управления инфраструктурой (Terraform), платформенные и облачные сервисы, утилиты мониторинга и оповещений.
Микросервисная архитектура -- это такой подход, при котором единое приложение строится как набор небольших сервисов, каждый из которых работает в собственном процессе и коммуницирует с остальными, используя легковесные механизмы. Такой подход получил распространение в середине 2010х годов в связи с развитием гибких практик разработки.
До появления микросервисов и контейнеров повсеместно использовались монолитные приложения на основе систем виртуализации.
Виртуализацция -- это технология с помощью которой на одном физическом устройстве можно создать несколько виртуальных компьютеров. На компьютере с одной ОС можно запустить несколько других ОС или приложений. ОС запускаются в виртуальной среде, но используется инфраструктура хоста и позволяет им работать на одном устройстве изолированно друг от друга. ОС компьютера, на котором работает виртуальная среда, называется хост-системой, аОС, которая запускается в этой виртуальной среде -- гостевой системой. Хостовая и гостевая ОС могут иметь взаимоисключающие компоненты, но виртуальная среда позволяет урегулировать эти конфликты.
Виртуальная среда создаётся при помощи программной или аппаратной схемы -- гипервизора -- инструмента, обеспечивающего параллельное управление несколькими ОС на одном хосте.
Назрела необходимость в ином подходе к построению архитектуры приложений, при котором ядро ОС поддерживают несколько изолированных экземпляров пользовательского пространства вместо одного (namespaces)\footnote{namespace -- это функция ядра Linux, позволяющая изолировать и виртуализировать глобальные системные ресурсы множества процессов.}. Возникновение контейнеризации -- контейнерной виртуализации. Контейнеризация использует ядро хост системы, оставаясь при этом не менее функциональной и обеспечивающей необходимую изоляцию.
Контейнерная виртуализация -- это способ, при котором виртуальная среда запускается прямо из ядра хотовой ОС (то есть без установки другой ОС). В данном случае изоляцию ОС и приложений поддерживает контейнер. Контейнер содержит всё, что нужно для запускаемого в нём приложения: код, библиотеки, инструменты и настройки. Всё это упаковано в отдельный образ, работу которого запускает контейнерный движок.
В случае с контейнерами у нас есть базовая аппаратная инфраструктура (железа компьютера), ОС и движок, установленный на этой ОС. Движок управляет контейнерами, которые работают с библиотеками и зависимостями сами, в одиночку. В случае виртуальной машины у нас есть ОС на базовом оборудовании (наше железо), затем гипервизор, а затем виртуальные машины. У каждой ВМ внутри своя ОС. Контейнеры загружаются быстрее и работают эффективнее.
Докер -- платформа автоматизации и доставки приложений с открытым исходным кодом. Платформа позволяет быстрее тестировать и выкладывать приложения, запускать на одной машине требуемое количество контейнеров.
\item хост -- хост ПК, компьютер, на котором работает докер.
\item демон -- фоновый процесс, работающий на хосте постоянно и ожидающий команды управления. Имеет информацию обо всех контейнерах на хосте. Демон знает всё о контейнерах, запущенных на одном хосте -- сколько всего контейнеров, какие из них работают, где хранятся образы и так далее.
\item клиент -- клиент при помощи с котрого пользователь взаимодействует с демоном. Это может быть консоль, API или графический интерфейс.
Образ -- шаблон с набором инструкций, предназначенных для создания контейнера. Приложения упаковываются в образ, из которого затем создаются контейнеры.
Образ -- это единица, используемая для распространения приложений. Контейнер -- имеет стандартизированный формат, который используется как группой эксплуатации
Программное обеспечение, упакованное в контейнер, не ограничивается приложениями, создаваемыми разработчиками. ОС узла -- это OC, в которой выполняется модуль Docker. Контейнеры Docker, работающие в Linux, совместно используют ядро ОС узла и не нуждаются в ОС контейнера, если двоичный код может напрямую обращаться к ядру ОС.
Однако контейнеры Windows нуждаются в ОС контейнера. Контейнер полагается на ядро ОС для управления службами, такими как файловая система, сеть, планирование процессов и управление памятью.
Например, разрабатываем портал отслеживания заказов, который будут использоваться торговыми точками некоторой компании. Нам нужно рассмотреть полный стек ПО длоял выполнения этого веб-приложения. MVC .Net Core, и мы планируем развернуть егос помощью Nginx в качестве обратного прокси-сервера в Ubuntu Linux. Все эти программные компоненты входят в образ контейнера
Образ контейнера -- это переносимый пакет, содержащий ПО. При запуске он становится контейнером. Образ неизменен, после сборки образа, невозможно внести в него изменения.
ОС узла -- это ОС в которой выполняется модуль Docker. ОС контейнера -- это ОС, которая входит в упакованный образ. В контейнере можно включать различные версии ОС Linux/Windows. ОС контейнера изолирована от ОС узла и представляет собой среду, в которой развёртывается и выполняется приложение. В сочетании с неизменностью образа такая изоляция означает, что среда для приложения на этапе разработки аналогична рабочей среде. В нашем примере мы используем Ubuntu Linux в качестве ОС контейнера, и эта ОС не меняется в течение всего процесса: от разработки до рабочего развертывания. Образ всегда один и тот же
ОС контейнера - это ОС, которая входит в упакованный образ. В контейнер можно включать различные версии ОС Linux или Windows Такая гибкость позволяет получать доступ K определенным возможностям ОС или устанавливать дополнительное ПО, требуемое приложениям.
Мы создаём образ для описанного веб-приложения. Расположим дистрибутив Ubuntu как базовый образ поверх файловой системы загрузки. Далее устанавливаем Nginx, который таким образом будет поверх Ubuntu. Последний доступный для записи слой создается после запуска контейнера из образа. Этот слой не сохраняется при уничтожении контейнера.
Для создания образов Docker используется Unionfs. Unionfs -- это файловая система, позволяющая объединять в стек несколько каталогов, При этом содержимое представляется как объединенное. Однако на физическом уровне оно хранится раздельно.
Образ контейнера это переносимый пакет, содержащий программное обеспечение. При запуске он становится контейнером. Образ контейнера неизменен. После сборки образа внести в него изменения нельзя. Единственный способ изменить образ создать новый. Эта особенность дает гарантию того, что образ, используемый в рабочей среде, полностью совпадает с образом, который применялся при разработке и контроле качества.
Образы Docker - это файлы большого размера, которые изначально сохраняются на компьютере. Для управления ими нужны специальные средства. Интерфейс командной строки (CLI) Docker позволяет управлять образами:
Базовый образ использует Docker scratch -- пустой образ, который не создает слой файловой системы. Он предполагает, что запускаемое приложение может напрямую использовать ядро ОС узла.
Родительский образ это образ контейнера, из которого создается наш - образ. Например, в нашем случае, вместо того чтобы создавать образ из cratch, a затем устанавливать Ubuntu, лучше использовать образ, уже основанный на Ubuntu. Можно даже использовать образ, в котором уже установлен Nginx.
Родительский образ чаще всего -- предустановленная ОС или другая основа.
Оба типа образов позволяют создавать многократно используемые образы. Однако базовые образы дают больше возможностей для содержимого итогового образа. Помним, что образ является неизменяемым. В него можно добавлять компоненты, но удалять из него ничего нельзя.
Пример Dockerfile для создания образа для веб-сайта.
\item [] \textbf{RUN} выполняет команду и создаёт слой образа. Используется для установки контейнер пакетов. B
\item [] \textbf{COPY} - копирует в контейнер файлы и папки.
\item [] \textbf{EXPOSE} - задает определенный порт в контейнере
\item [] \textbf{CMD} описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен. Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция СMD.
\item [] \textbf{WORKDIR} задаёт рабочую директорию для следующей инструкции.
\item [] \textbf{ENTRYPOINT} - указывает, какой процесс будет - выполняться при запуске контейнера из образа.
\end{itemize}
\begin{verbatim}
# Step 1: Specify the parent Image for the new image
FROM ubuntu:18.04
# Step 2: Update OS packages and Install additional software
#STEP 8: Define the entrypoint of the process in the container
ENTRYPOINT ["dotnet", "website.dll"]
\end{verbatim}
\subsection{Сборка образа Docker}
Для сборки образов Docker служит команда \code{docker build}. Предположим, что для сборки образа мы используем приведенное выше Определение Dockerfile. Ниже представлен пример команды сборки.
\begin{verbatim}
docker build-t temp-ubuntu
\end{verbatim}
В предыдущем примере сборки последнее сообщение было:
\begin{verbatim}
"Successfully tagged temp-ubuntu: latest"
\end{verbatim}
Тег образа -- это текстовая строка, используемая для указания версии образа.
Зачем присваивать контейнерам имена? Это позволяет запускать несколько экземпляров контейнеров, созданных из одного образа. Имена контейнеров уникальны.Т.е. указанное имя не может использоваться повторно для создания другого контейнера. Единственный способ повторно использовать определенное имя -- удалить предыдущий контейнер.
Чтобы вывести список выполняющихся контейнеров используется команда
\begin{verbatim}
docker ps
\end{verbatim}
Чтобы просмотреть все контейнеры во всех состояниях, передайте аргумент \code{-a}. Docker автоматически настраивает локальный реестр образов на компьютере. Просмотреть образы в реестре с помощью команды:
\begin{verbatim}
docker images
\end{verbatim}
Удалить образ из локального реестра Docker с помощью команды \code{docker rmi}. Указывается имя или ID образа, который требуется удалить. Допустим, удалим образ с именем temp-Ubuntu:version-1.0:
\begin{verbatim}
docker rmi temp-Ubuntu:version-1.0
\end{verbatim}
Если образ используется контейнером, удалить ero нельзя. Команда \code{docker rmi} возвращает сообщение об ошибке, в котором указывается контейнер, использующий образ.
Для удаления контейнера служит команда \code{docker rm}
\begin{verbatim}
docker rm happy_wilbur
\end{verbatim}
После удаления контейнера все данные B нем уничтожаются. При планировании хранения данных важно учитывать, что контейнеры являются временными.
Для перезапуска контейнера используется команда docker restart
\begin{verbatim}
docker restart happy_wilbur
\end{verbatim}
Так контейнер получает команду stop, а затем команду start.
Приостанавливает контейнер команда docker pause.
\begin{verbatim}
docker pause happy_wilbur
\end{verbatim}
Приостановка контейнера приводит к приостановке всех процессов. Эта команда позволяет контейнеру продолжить процессы в дальнейшем. Команда docker unpause отменяет приостановку всех процессов в указанных контейнерах.
\subsection{Флаги команды \code{docker run}}
Если перед флагом стоит два тире -- то это его полная форма, флаг с одним тире -- это сокращённый вариант некоего флага. Действуют они одинаково. Например, \code{-р} -- это сокращённая форма флага \code{--port}; \code{-i} (\code{--interactive}) -- поток STDIN поддерживается в открытом состоянии даже если контейнер к STDIN не подключён; \code{-t} (\code{--tty}) -- соединяет используемый терминал с потоками STDIN и STDOUT контейнера.
Для того чтобы получить возможность взаимодействия с контейнером через терминал нужно совместно использовать флаги \code{-i} и \code{-t}.
\begin{verbatim}
docker run -it tmp-ubuntu
\end{verbatim}
Запускает контейнер команда \code{docker run}. Для запуска контейнера из образа нужно просто указать его имя или идентификатор.
\begin{verbatim}
docker run -d tmp-ubuntu
\end{verbatim}
Здесь для запуска контейнера в фоновом режиме следует добавить флаг \code{-d}.
\code{-p} (\code{--port}) порт -- это интерфейс, благодаря которому контейнер взаимодействует с внешним миром. Например: конструкция \code{1000:8000} перенаправляет порт Docker 8000 на порт 1000 компьютера, на котором выполняется контейнер. Если в контейнере работает некое приложение, способное выводить что-то в браузер, то, для того, чтобы к нему обратиться, в нашем случае можно перейти в браузере по адресу \code{localhost:1000}.
\code{-d} (\code{--detach}) запуск контейнер в фоновом режиме. Это позволяет использовать терминал, из которого запущен контейнер, для выполнения других команд во время работы контейнера.
При планировании хранения данных контейнерным необходимо помнить - контейнеры являются временными. При уничтожении контейнера все накопленные данные в нем будут потеряны. Поэтому приложения нужно разрабатывать так, чтобы они не полагались на хранилище данных в контейнере (принцип Stateless, все данные из остановленных контейнеров уничтожаются).
Их различие в том, что мount более явно заставляет указывать источник монтирования папки. В случае параметра -V указывается два пути "откуда куда". В случае --mount это именованные параметры разделенные запятыми. Пример работы обоих:
Конфигурация сети Docker по умолчанию обеспечивает изоляцию контейнеров в узле Docker. Это позволяет создавать и настраивать приложения, которые могут безопасно взаимодействовать друг с другом.
Docker предоставляет следующие конфигурации сети:
\begin{itemize}
\item Мост (Bridge)
\item Узел (Host)
\item Macvlan
\item Overlay
\item none
\end{itemize}
Сеть типа мост -- конфигурация по умолчанию к контейнерам при запуске, если иное не указано при запуске. Эта сеть является внутренней частной сетью, используемой контейнером. Она изолирует сеть узла от сети контейнера.
По умолчанию Docker не публикует порты контейнеров. Для включения сопоставления портов контейнеров и портов узла Docker используется флаг - publish порта Docker. Флаг publish фактически настраивает правило брандмауэра, которое сопоставляет порты.
ПРИМЕР: Порт 80 контейнера необходимо сопоставить с доступным портом узла. В узле открыт порт 8080:
Узел (Host) позволяет запускать контейнер непосредственно в сети узла. Эта конфигурация фактически устраняет изоляцию между узлом и контейнером на сетевом уровне. В предыдущем примере предположим, что используем конфигурацию типа Host. Доступ будет по IP-адресу узла. То есть теперь используем порт 80 вместо сопоставленного порта. Помните, что контейнер может использовать только те порты, которые еще не используются узлом.
Macvlan. Контейнер подключается при помощи виртуального интерфейса, подключенного к физическому. При этом у каждого из них есть свой МАС- адрес. В этом случае у контейнеров есть прямой доступ к интерфейсу и субинтерфейсу (vlan) хоста.
Overlay. Использование этого драйвера позволяет строить сети на нескольких хостах с Docker (обычно на Docker Swarm кластере). У контейнеров также есть свои адреса сети и подсети, и они могут напрямую обмениваться данными, даже если они располагаются физически на разных хостах.
\section{Когда следует использовать контейнеры Docker?}
Переносимость приложений. Контейнеры могут выполняться практически везде: на Настольных компьютерах, физических серверах, в виртуальных машинах и в облаке. Такая совместимость со средами выполнения позволяет легко перемещать контейнерные приложения между разными средами. Так как контейнеры требуют меньше ресурсов, увеличение времени запуска или завершения работы сказывается на виртуальных машинах. Благодаря этому упрощается и ускоряется повторное развертывание.
Доставка приложений при использовании докер единицей распространения становится контейнер, благодаря этому происходит стандартизация.
Управление средами размещения. Среда для приложения настраивается внутри контейнера. Благодаря этому команда эксплуатации может более гибко управлять средой приложения. Можно также управлять тем, какие приложения следует установить, обновить или удалить, не затрагивая другие контейнеры. Каждый контейнер изолирован. Облачные развертывания.
Контейнеры Docker поддерживаются на многих облачных платформах.
\section{Когда НЕ следует использовать контейнеры Docker?}
использование ядро ОС хоста, которое может стать объектом атаки. для обеспечения безопасности нужно принимать во внимание конфигурацию хранения и сети, в некоторых случаях целесообразнее использовать виртуальные машины.
Управление контейнерами сложнее, чем ВМ, можем узнать состояние, но получить журнал за определённое время - не очень просто (\code{docker stats} это поток данных, поэтому их обработка и хранение не производится).
\section{docker-compose}
Надстройка над docker, применяется для многоконтейнерных приложений. позволяет запускать множество сервисов при помощи одной команды. docker применяется для управления отдельными контейнерами или сервисами. compose -- для одновременного управления несколькими контейнерами.
compose написан на python, конфигурация в yaml-файлах.
в составе docker desktop (Windows, mac) уже есть, на linux надо доставить руками.
докер-композ
нгинкс
докерфайл
пхп
докерфайл
ввв
индекс.хтмл
подменяем нгинкс.конф
докер-композ ямл - описывает процесс загрузки и настройки контейнеров.
Оркестраторы управляют ЖЦ контейнеров микросервисных приложений. Задачи оркестратора:
\begin{itemize}
\item подготовка инфраструктуры и развёртывание -- установка приложения и его зависимостей на сервер, включая подготовку этого сервера -- установку библиотек, служб, и так далее.
\item Разделение ресурсов -- Для развёртывания в кластере требуется...
\item Масштабирование контейнеров на основе рабочих нагрузок -- простой излишних ресурсов приводит к издержкам, а недостаток -- к нестабильно йработе приложения. Регулировать объёмы используемых ресурсов позволяет масштабирование, основанное на анализе нагрузок. Может быть ручным или автоматизированным.
\item Балансировка нагрузок -- автоматический анализ и распределение рабочих нагрузок на сервер целиком и контейнеры в частности. Балансировка оптимизирует использование ресурсов, увеличивает пропускную способность каналов связи,...
\item Маршрутизация трафика
\item Мониторинг состояния контейнеров -- позволяет видеть какие контейнеры и образы запущены
\item Обеспечение безопасного взаимодействия между контейнерами -- на основе непрерывной оценки кластеров, узлов и реестра контейнеров...