Docker (Докер) для чайников

Вступление от автора руководства — Dmytro Yakovenko 2022/04/23: Дорогие мои читатели, я сам чайник в докерах, но куда деваться нужно изучить предметную область. Начнем помолясь:) Как всегда я стараюсь осветить терминологию, второй шаг установку, а дальше какой-нибудь интересную задачу решим с использованием доккера и какую-нибудь распространённую.

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

  • Docker Image (образы) - собственно, шаблон готового к запуску приложения со всем нужным для работы окружением. Является основой для контейнеров. Команда docker pull используется, чтобы скачать образ.
  • Контейнер (Containers) - это уже выполняющийся, запущенный образ (командой docker run), готовый к дальнейшему использованию. Список запущенных контейнеров можно увидеть с помощью команды docker ps.
  • Docker Hub (докер хаб) - сервис с реестром образов, где можно брать и загружать свои образы. Грубо говоря, архив всех доступных образов.
  • Docker Daemon (демон Докера) - Фоновый сервис, запущенный на хост-машине, который отвечает за создание, запуск и уничтожение Докер-контейнеров. Демон — это процесс, который запущен на операционной системе, с которой взаимодействует клиент.
  • Docker Client (клиент Докера) - Утилита командной строки, которая позволяет пользователю взаимодействовать с демоном. Существуют другие формы клиента, например, Kitematic, с графическим интерфейсом.

Основные компоненты Docker.

Есть два способа упаковки и переноса приложений со всеми его библиотеками между различными системами: использовать виртуальную машину или Docker-контейнер. Если выбрать виртуальную машину:

  • это ещё одна полноценная операционная система, в которой живут десятки процессов;
  • долгий старт приложения;
  • минимальный образ ОС весит более 100 МБ;
  • виртуальная машина потребляет много ресурсов, таких как процессор и оперативная память.

Из плюсов — у виртуальной машины удобные способы управления.

Если выбрать Docker-контейнер:

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

Из минусов — у Docker сложная система управления контейнерами, которой можно управлять как локально на сервере, так и по протоколу HTTP.

Главное отличие технологий в том, что виртуальная машина виртуализирует аппаратные ресурсы, такие как процессор, память, системы input и output, а docker контейнеры виртуализируют только ОС.

Почитал мануалов и сказано в них, что не по-пацански (не по админски) устанавливать Docker из репозиториев, ибо грех это! И так какие VPS у меня есть на текущий момент в работе? Это Debian и CentOS 7. Значит устанавливаем Docker и там и там и сравниваем отличия в установке.

Пакет Docker можно найти в официальном репозитории Debian и Ubuntu. Но чтобы получить наиболее актуальную версию программы, нужно обратиться к официальному репозиторию Docker. В этом разделе показано, как загрузить и установить пакет из официального репозитория Docker.

  • Обновление репозитория и установка зависимостей:
apt update
apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common
  • Теперь можно загрузить и установить пакет Docker. Добавьте в систему GPG-ключ репозитория Docker.

Для Debian:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

Для Ubuntu (версии 18.04 LTS и выше):

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
  • Добавьте этот репозиторий Docker в APT и обновить индекс пакетов.

Для Debian:

add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt update

Для Ubuntu:

 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
  • Чтобы установить Docker, введите,

Для Debian:

apt install docker-ce

Для Ubuntu:

apt-get install docker-ce docker-ce-cli containerd.io
  • После установки должен запустится демон и настроится автозапуск процесса, проверим командой:
systemctl status docker

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

docker run hello-world

Теперь попробуем установить Docker в всё еще не умирающем CentOS версии 7. Кстати Доккер официально поддерживается только в 7 и 8 версии CentOS, а 6 забыли, хотя она до сих пор распространена.

В CentOS сначала придется удалить все намеки на старую версию Docker.

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

Рекомендуемый подход: настроить репозитории Docker и устанавливать из них него простоты установки и обновления. Для этого установим пакет yum-utils, который содержит утилиту yum-config-manager и настроим стабильный (stable) репозиторий. Есть еще nightly репозиторий, но думаю стабильного нам хватит:)

yum install -y yum-utils
 
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

Теперь установка самого Docker:

yum install docker-ce docker-ce-cli containerd.io

Запускаем Докер и тестовую программу, чтобы убедиться что он работает:

systemctl start docker
docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:10d7d58d5ebd2a652f4d93fdd86da8f265f5318c6a73cc5b6a9798ff6d2b2e67
Status: Downloaded newer image for hello-world:latest
 
Hello from Docker!

Последний штрих, проверяем загружается ли при перезагрузке Linux наш Докер автоматически, используем для этого systemctl:

# systemctl is-enabled docker
disabled

Конечно же нет, добавим в автозагрузку Docker:

# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service
to /usr/lib/systemd/system/docker.service.

Все что нужно знать об установки Docker в Windows 10 Pro это то, что у вас перестанут работать программы, такие как VirtualBox, эмуляторы Android.

А там уже смотрите сами, нужно ли вам такое счастье или нет.

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

docker [option] [command] [arguments]
  • Можно получить информацию о ключах, просто запустить команду docker. Для получения справки по использованию выбранной команды введите:
docker subcommand --help
  • Для получения полной информации по Docker потребуется ввести следующее или для краткой используйте ключ v, как показано ниже:
docker info
docker -v
Docker version 20.10.14, build a224086

Для просмотра запущенных контейнеров применяется команда docker ps, ключ а также показывает все контейнеры в системе. Разберем поля вывода команды

docker ps -a
или
docker container ls -a
  • CONTAINER ID - идентификатор контейнера, он уникален.
  • IMAGE - название образа, на основе которого запущен контейнер;
  • COMMAND - выполняемая при запуске контейнера команда;
  • CREATED - Когда был создан контейнер.
  • STATUS - статус контейнера, активен он или выключен.
  • PORTS - порты, через которые сервисы извне взаимодействует с контейнером и тем, что внутри него;
  • NAMES - имя контейнера.
  • Для просмотра последних созданных контейнеров используется опция -l:
docker ps -l
  • docker stats информация о потреблении ресурсов
  • docker logs ID вывод логов из указанного контейнера -f вывод логов в стиле tail –f
docker logs -f eef97a115270
  • docker kill ID принудительная остановка указанного контейнера, кроме того: stop, pause, unpause, restart.
  • -it опции, говорящие о том, что мы хотим интерактивно взаимодействовать с контейнером (оказаться «внутри» него). Добавление опций -i (видеть, что происходит в контейнере) и -t (взаимодействовать, то есть пересылать в контейнер наши команды) предоставляет доступ в интерактивном режиме к командному процессору.
  • -d, –detach указывает запуск в фоновом режиме
  • -p 8080:80 Проброс порта. Порт 80 «изнутри» контейнера становится портом 0.0.0.0:8080
  • Чтобы узнать IP адрес контейнера, используйте вывод ключа inspect:
docker container inspect ee7c5bd0f90e | grep IPAddress

Источник: Удаление образов, контейнеров и томов Docker

  • Очистить все не связанные с контейнерами ресурсы, в том числе образы, контейнеры, тома и сети.
docker system prune
docker system prune -a
docker system prune --all

Чтобы удалить все остановленные контейнеры и неиспользуемые образы (а не только образы, не связанные с контейнерами), добавьте в эту команду флаг -a.

  • Удаление одного или нескольких конкретных контейнеров.

Используйте команду docker ps с флагом -a для поиска имен или идентификаторов контейнеров, которые вы хотите удалить:

docker ps -a
docker rm ID_or_Name ID_or_Name
  • Удаление контейнера при выходе.

Если вы создаете контейнер, который вам не будет нужен после завершения его использования, вы можете использовать команду docker run –rm для его автоматического удаления при выходе.

docker run --rm image_name
  • Удаление всех контейнеров, из которых выполнен выход.

Вы можете найти контейнеры с помощью команды docker ps -a и отфильтровать их по статусу: created (создан), restarting (перезапускается), running (работает), paused (пауза) или exited (выполнен выход). Чтобы просмотреть список контейнеров, из которых выполнен выход, используйте флаг -f для фильтрации по статусу. Убедитесь, что вы хотите удалить эти контейнеры, и используйте флаг -q для передачи идентификаторов в команду docker rm.

docker ps -a -f status=exited
docker rm $(docker ps -a -f status=exited -q)

Более простой вариант

docker container prune
  • Удаление одного или нескольких конкретных образов.

Используйте команду docker images с флагом -a, чтобы найти идентификатор удаляемых образов. Эта команда покажет вам все образы, включая промежуточные слои образов. Когда вы определитесь с составом удаляемых образов, вы можете передать их идентификаторы или теги в docker rmi:

docker images -a
docker rmi Image Image
  • Удаление образов, не привязанных к контейнеру.

Образы Docker состоят из нескольких слоев. Несвязанные образы — это слои, не имеющие связей с каким-либо образами с тегами. У них нет никакого назначения, и они просто занимают место на диске. Их можно найти, добавив флаг фильтра -f со значением dangling=true в команду docker images. Если вы уверены, что хотите удалить их, вы можете использовать команду docker images purge:

docker images -f dangling=true
docker images purge
  • Удаление образов по шаблону.

Вы можете найти все образы, соответствующие определенному шаблону, используя комбинацию команд docker images и grep. Когда вы будете довольны, вы можете удалить их, используя awk для передачи идентификаторов в docker rmi. Эти утилиты не предоставляются Docker и могут быть доступны не во всех системах:

docker images -a |  grep "pattern"
docker images -a | grep "pattern" | awk '{print $3}' | xargs docker rmi

Изначально Docker берет образы в хабах Docker Hub (докер хаб). Docker Hub является реестром образов, поддерживаемых разработчиком. Любой имеет возможность создавать и загружать собственные образы. Для большей части дистрибутивов и программ уже имеются необходимые образы в Docker Hub.

Докер хранит файлы (контейнеры) в виде папок и файлов в директории /var/lib/docker/containers.

  • Представленные в хабе образы можно найти при помощи команд docker и search. К примеру, найти образ MariaDB можно следующим образом:
docker search mariadb

Строчка OK в столбце OFFICIAL говорит о том, что образ создан и его поддержка осуществляется компанией, ответственной за этот проект.

  • Выбрав требуемый образ, например PhpMyAdmin, его можно скачать на компьютер (свое локальное хранилище), используя подкоманду pull.
docker pull phpmyadmin
  • Чтобы посмотреть, какие образы были загружены на компьютер, используется команда:
docker images
  • Запуск контейнера docker run
docker run hello-world

Добавление опций -i (видеть, что происходит в контейнере) и -t (взаимодействовать, то есть пересылать в контейнер наши команды) предоставляет доступ в интерактивном режиме к командному процессору.

docker run -it ubuntu
  • Чтобы запустить остановленный контейнер, необходимо ввести docker start и далее указать идентификатор или имя контейнера. Так выглядит запуск контейнера 98ed79500b2d:
docker start 98ed79500b2d
  • Чтобы выключить активный контейнер, используется команда docker stop с указанием его идентификатора или имени.
  • Для перезапуска контейнер, не отключая его используйте ключ restart.
  • Docker compose. Отдельного внимания заслуживает запуск контейнера docker compose. Так, после смены настроек в файле docker-compose.yml (например, проброс порта) изменения не выполнятся автоматически. Вдобавок, команда restart также не поможет и потребуется выполнить пересборку контейнера, применив для этого команду build. Другими словами, он будет заново создан. Выполнить операцию можно следующей командой:
docker-compose up -d --no-deps --build
  • Удалить можно только остановленный контейнер. Для удаления используйте rm, указав имя или идентификатор контейнера:
docker container rm имя_контейнера
или
docker rm [OPTIONS] CONTAINER [CONTAINER...]

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

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

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

docker commit -m "Что вы сделали с образом" -a "Имя автора" container_id repository/new_image_name

Добавление опции -m дает возможность указать сообщение подтверждения. Это позволит будущим пользователям образа понять, что именно было изменено. Что касается параметра -a — с его помощью можно указать, кто его создатель. container_id является тем же идентификатором, который был использован ранее, во время запуска интерактивной сессии в Docker.

Если вы не занимались до этого созданием новых репозиториев в Docker Hub, имя создаваемого репозитория по умолчанию будет названо именем вашего пользователя в Docker Hub.

Ваш сервера перезагрузился и все запущенные контейнеры остановились. Чтобы избавиться от необходимости вручную запускать их, можно настроить автозапуск контейнеров. Для этого следует создать текстовые файлы со специальным форматом для сервиса systemd. Рассмотрим пример автозапуска контейнера my-db, для этого создадим файл

nano /etc/systemd/system/my-db.service
[Unit]
Description=MY DB (PG) docker container
Requires=docker.service
After=docker.service
 
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a my-db
ExecStop=/usr/bin/docker stop -t 2 my-db
TimeoutSec=30
 
[Install]
WantedBy=multi-user.target

После этого остается перезапустить демон systemcmd и включить автозагрузку контейнера mydb, набрав в терминале поочередно команды:

systemctl daemon-reload
systemctl start my-db.service
systemctl enable my-db.service

По сути дела это «пакетный менеджер» для Docker, как, к примеру, composer для PHP. Пользоваться им несложно:

  • Описываем конфигурацию контейнеров для нашего проекта в файле docker-compose.yaml
  • Собираем проект, используя команду
docker-compose up --build -d

Убеждаемся, что нужные нам контейнеры созданы и запущены!

Рассмотрим как правильно установить и настроить СУБД MySQL MariaDB в виде приложения Docker, при этом все постоянные данные будут храниться в файловой системе хоста.

Зачем использовать Docker для установки MariaDB? Использование Docker-контейнера позволяет не только обеспечивает чистое развертывание, не зависящее от программного обеспечения сервера, но и позволяет поддерживать несколько СУБД MySQL разных версий и различного назначения в рамках одной операционной системы.

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

mkdir -p /opt/mariadb/{data,etc,logs}

Создадим конфигурационный файл /opt/mariadb/etc/config.cnf, который будет уточнять настройки, применяемые контейнером по умолчанию. В этом файле вы можете переопределять переменные MySQL для задания нужного поведения. Мы определим 3 переменных для демонстрации возможностей:

[mysqld]
log_error=/var/lib/mysql/logs/errorlog
slow_query_log=on
slow_query_log_file=/var/lib/mysql/logs/slowlog

Теперь можно запустить сам сервер MySQL:

sudo docker run -d --restart=always --name mariadb_1 \
         -v /opt/mariadb/data:/var/lib/mysql \
         -v /opt/mariadb/etc:/etc/mysql/conf.d \
         -v /opt/mariadb/logs:/var/lib/mysql/logs \
         -e MYSQL_ROOT_PASSWORD=secret \
         -p 127.0.0.1:3306:3306 mariadb:10.3

Где ключи

  • name задает собственное (удобное нам) имя для контейнера
  • -d, –detach указывает запуск в фоновом режиме
  • -v, –volume list несколько ключей v указывают монтирование директории из хостовой машины
  • -e, –env list Обратите внимание на пароль пользователя root, который задается с помощью переменной окружения MYSQL_ROOT_PASSWORD. Этот пароль будет записан в системную БД mysql, если вы после остановите контейнер и поменяете его, это не окажет влияние на пароль в БД.
  • -p, –publish list публикация портов контейнера на хосте

Для проверки работоспособности сервера используйте консольный клиент MySQL:

sudo docker run -it --rm --link mariadb_1:mysql mariadb:10.3 \
       mysql -hmysql -uroot -psecret

Выгрузка данных БД для резервных копий в самом простом случае может выполняться стандартным

sudo docker run -it --rm --link mariadb_1:mysql mariadb:10.3 \
   mysqldump --all-databases -hmysql -uroot -psecret > all-databases.sql

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

Запуск

docker run --rm -d --name nginxfront1 -p 8080:80 nginx

Проверка, вы должны получить исходный код HTML

curl localhost:8080

Запустим Nginx с меппингом томов (папок):

docker run --rm -d --name nginxfront1 -p 8080:80 -v ${PWD}:/usr/share/nginx/html nginx
или
docker run --rm -d \
 --name nginxfront1 \
 -p 8080:80 \
 -v /var/www/html:/usr/share/nginx/html \
 nginx

Проверим

curl localhost:8080

Подключиться к запущенному Nginx с запуском командной оболочки

docker exec -it dea628c3adf4 bash
eTalk курсы английского языка.