[Docker] Основы Docker: Dockerfile и docker-compose.yml

Zerox Обновлено: 26.11.2020 Devops, WordPress 10 комментариев 2,146 Просмотры

Что такое докер

Инфо

Docker — программное обеспечение для автоматизации развёртывания и управления приложениями в среде виртуализации на уровне операционной системы. Позволяет «упаковать» приложение со всем его окружением и зависимостями в контейнер, который может быть перенесён на любую Linux-систему с поддержкой cgroups в ядре, а также предоставляет среду по управлению контейнерами. Изначально использовал возможности LXC, с 2015 года применял собственную библиотеку, абстрагирующую виртуализационные возможности ядра Linux — libcontainer. С появлением Open Container Initiative начался переход от монолитной к модульной архитектуре.

Википедия

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

Образы Docker#

Для начала заглянув в документацию вспомним, что же такое контейнер Docker и поймем, что Docker-контейнер — это Docker image (образ) который оживили. Собственно говоря Docker image — это то, из чего запускается любой Docker-container.

Каждому Docker image соответствует свой набор инструкций и файл с такими инструкция называется Dockerfile – без расширений и каких-либо точек. Из Dockerfile в дальнейшем собираются Docker images (образы). Сброка нового образа выполняется запуском команды:

docker build -f ./Dockerfile

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

docker buid

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

Читайте также:  Бесплатный виртуальный сервер / Free VPS / Free VDS

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

Базовый образ является лишь исходным слоем (слоями) создаваемого образа (иногда называют родительским образом).

Технология виртуализацииСкопировать ссылку

В 7 главе знаменитой книги Эндрю Таненбаума, ставшей хрестоматией для современного поколения инженеров в области Computer Science, понятие виртуализации рассматривается достаточно подробно. Вся концепция сводится к существованию менеджера виртуальных машин (Virtual Machine Manager), или, по-другому, гипервизора (hypervisor), который позволяет запускать ОС так, как-будто она существует сама по себе и запущена на отдельном компьютере. Гипервизоры бывают двух типов: функционирующие на уровне «железа» и программные, работающие уже как слой в базовой ОС (host OS).

Применение виртуализации связано как с развитием самой вычислительной техники и программ, так и с построением сложных инфраструктурных решений для обеспечения работы компаний разного уровня. Выделенный сервер у хостинг-провайдера, к примеру, будет запускаться на «железном» гипервизоре, а у вас, скорее всего — на программном типа VMWare или VirtualBox.

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

На ОС, которые не относятся к семейству Linux, служба Docker запускается как отдельная, хоть и очень быстрая, виртуальная машина. Потери ресурсов ОС, хоть и небольших, не избежать. Об этом лучше знать заранее. Подробнее об архитектуре Docker можно почитать в Anatomy of Docker, мы же рассмотрим лишь основные моменты.

Ограничим память

Первое, что может прийти на ум — это ограничить размер самого Docker-контейнера. Создадим простое приложение на Spring Boot и запустим контейнер, поставив ограничение памяти 150 мегабайт. Вот пример команды на хосте с одним гигабайтом памяти:

$ docker run -it —rm —name mycontainer150 -p 8080:8080 -m 150M rafabene/java-container:openjdk

В приложении заранее был создан rest-метод, который загружает память до отказа объектами типа String. Вызовем его:

Читайте также:  Обновление iOS 13.4 выпущено сегодня для всех

$ curl http://`docker-machine ip docker1024`:8080/api/memory

Вызванный метод возвращает что-то вроде «Выделено более чем 80% памяти (219.8 MiB) из максимально доступных JVM (241.7 MiB) «.

Но отсюда два вопроса:

1. Почему максимальный размер для JVM 241 мегабайт?

2. Если мы выше указали, что контейнеру доступно только 150 мегабайт памяти, то почему приложение потребляет почти 220?

Первое, что нужно помнить о максимальном размере кучи (max heap size) у JVM, это то, что размер по умолчанию будет занимать 1/4 памяти. И второе — когда мы при запуске контейнера выше указывали флаг «-m 150M», то докер зарезервировал 150 мегабайт в оперативной памяти и 150 мегабайт в Swap. Поэтому-то приложение и не рухнуло и отработало как нужно. Но при этом вы должны понимать, что увеличение памяти в контейнере — это не решение проблемы. Всегда может случиться ситуация, когда Java-приложение может выйти за рамки лимита, и тогда процесс будет убит.

Запуск первого контейнера в Docker

Итак, у вас запушен Docker и вы можете запустить первый контейнер. Выполните в консоли команду:

sudo docker pull busybox

Данной командой, мы скачали готовый образ busybox с сервера Docker Hub. Docker hub – это публичнй репозиторий docker образов. Он предоставляет возможность хранить свои image , обмениваться ими с другими людьми. В данном репозитории собраны множество готовых образов с популярным ПО. Busybox — это собранное в одном исполняемом файле набор утилит unix.

sudo docker run -it —rm busybox sh

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

Внутри контейнера busybox доступны основные команды unix/linux.

Допустим можно посмотреть список директорий:

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

Читайте также:  Книги Гугл букс (Google Play книги), что это такое и как пользоваться

exit

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

sudo docker images

В конце списка недавно скачанный busybox.

Посмотреть список запущенных контейнеров можно командой:

sudo docker ps -a

Также можно передать фильтр:

sudo docker ps —filter status=’exited’

Данная команда, выведет все контейнеры со статусом exited. Это контейнеры, которые остановлены, но не удалены.

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

Бэкап wordpress в docker

Отдельно расскажу, как такой сайт бэкапить или куда-то переносить. Первым делом надо сделать дамп базы данных, которая живет в docker. У меня была отдельная заметка на этот счет — Backup mysql базы в docker контейнере. В нашем случае получается такая команда:

# docker exec mysql /usr/bin/mysqldump -u root —password=root wordpress | gzip -c > ~/`date +%Y-%m-%d`_

Исходники сайта будут лежать в директории html. Таким образом, для бэкапа всего сайта вам достаточно куда-то скопировать исходники и дамп с базой. Я рекомендую для этого использовать rsync. У меня есть отдельная статья по этой теме — настройка бэкапа с помощью rsync.

Хранилище реестра

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

$ docker run -d \ -p 5000:5000 \ —restart=always \ —name registry \ -v /mnt/registry:/var/lib/registry \ registry:2

если использовать различные драверы, то данные реестра можно сохранить в S3, Google Cloud, OSS, Azure…