Docker

Docker

enter image description here

Docker — это открытая платформа для разработки, доставки и запуска приложений.

Установка

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

Добавить пользователя в группу докер

sudo usermod -aG docker $USER
newgrp docker

О концепции Docker

Docker состоит из нескольких компонентов:

  1. Docker Daemon — то самое Container Engine; запускает контейнеры.
  2. Docker CLI — утилита по управлению Docker.
  3. Dockerfile — инструкция по тому, как собирать образ.
  4. Image — образ, из которого раскатывается контейнер.
  5. Container.
  6. Docker registry — хранилище образов.
    enter image description here

На Docker_host работает Docker daemon, запускает контейнеры. Есть Client, который передаёт команды: собери образ, скачай образ, запусти контейнер. Docker daemon ходит в registry и выполняет их. Docker-клиент может обращаться и локально (к юникс-сокету), и по TCP с удалённого хоста.

Пройдёмся по каждому компоненту.

Docker daemon (демон) — это серверная часть, она работает на хост-машине: скачивает образы и запускает из них контейнеры, создаёт сеть между контейнерами, собирает логи. Когда мы говорим «создай образ», этим тоже занимается демон.

Docker CLI — клиентская часть Docker, консольная утилита для работы с демоном. Повторю, она может работать не только локально, но и по сети.

Базовые команды:

docker ps — показать контейнеры, которые сейчас запущены на Docker-хосте.
docker ps -a — показать все контейнеры

CONTAINER ID   IMAGE                     COMMAND                  CREATED          STATUS                      PORTS                                                                                  NAMES
cc7cbb81f382   diski_shop_local_django   "/entrypoint python …"   17 minutes ago   Exited (1) 17 minutes ago                                                                                          django
dd6371bd652c   diski_shop_local_django   "python /opt/.pychar…"   30 hours ago     Up 30 hours                 0.0.0.0:32773->32773/tcp                                                               backend_django_run_748a1832e8d3
1b2a4ef92227   elasticsearch:7.8.1       "/tini -- /usr/local…"   30 hours ago     Up 30 hours                 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp   elasticsearch
ac58581fed73   mailhog/mailhog:v1.0.0    "MailHog"                30 hours ago     Up 30 hours                 1025/tcp, 0.0.0.0:8025->8025/tcp, :::8025->8025/tcp                                    mailhog
c1af0b9f78a9   postgres:11.2-alpine      "docker-entrypoint.s…"   30 hours ago     Up 30 hours                 5432/tcp                                                                               postgres
4ea52b8e54b3   b8b2ac8cbe30              "/bin/sh"                30 hours ago     Created                                                                                                            pycharm_helpers_PY-211.6693.115

docker images — показать образы, скачанные локально.

REPOSITORY                TAG               IMAGE ID       CREATED        SIZE
diski_shop_local_django   latest            cf649f95a185   30 hours ago   762MB
pycharm_helpers           PY-211.6693.115   b8b2ac8cbe30   30 hours ago   39.5MB
python                    3.8-slim-buster   b281745b6df9   2 weeks ago    114MB
busybox                   latest            388056c9a683   2 weeks ago    1.23MB
elasticsearch             7.8.1             a529963ec236   9 months ago   811MB
postgres                  11.2-alpine       cd1fb3df8252   2 years ago    70.8MB
mailhog/mailhog           v1.0.0            09b680955aed   4 years ago    19.3MB

<> - name\id
docker run <> — запуск контейнер.
docker rm <> — удалить контейнер.
docker rm $(docker ps -aq) — удалить все контейнеры
docker rmi <> — удалить образ.

docker inspect <>— показать детальноую информацию о контейнер.

docker search <> — поиск образа в registry.
docker pull <> — скачать образ из registry на машину.
docker build <</path/to/dir>> — собрать образ.
docker logs <> — логи контейнера
docker start/stop/restart <> — работа с контейнером

Dockerfile — инструкция для создания образа. Почти каждая команда инструкции — новый слой. Посмотрим на примере.

Примерно так выглядит Dockerfile: слева команды, справа — аргументы. Каждая команда, что здесь есть (и вообще пишется в Dockerfile), создаёт новый слой в Image.

Даже глядя на левую часть, можно примерно понять, что происходит. Мы говорим: «создай нам папку» — это один слой. «Сделай папку рабочей» — это ещё один слой, и так далее. Слоёный пирог упрощает жизнь. Если я создам ещё один Dockerfile и в последней строчке что-то изменю — запущу не “python” “main.py”, а что-нибудь другое, или установлю зависимости из другого файла — то предыдущие слои будут переиспользованы, как кеш.

Image — это упаковка контейнера, из образа запускаются контейнеры. Если смотреть на Docker с точки зрения пакетного менеджера (как будто мы работаем с deb или rpm-пакетами), то image — это по сути rpm-пакет. Через yum install мы можем поставить приложение, удалить его, найти в репозитории, скачать. Здесь примерно то же самое: из образа запускаются контейнеры, они хранятся в Docker registry (по аналогии с yum, в репозитории), и каждый image имеет хеш SHA-256, имя и тег.

Image собирается по инструкции из Dockerfile. Каждая инструкция из Dockerfile создаёт новый слой. Слои могут использоваться повторно.

Docker registry — это репозиторий образов Docker. По аналогии с ОС, у Docker есть общедоступный стандартный реестр — dockerhub. Но можно собрать свой репозиторий, свой Docker registry.

Container — то, что запускается из образа. По инструкции из Dockerfile собрали образ, затем мы его из этого образа запускаем. Этот контейнер изолирован от остальных контейнеров, он должен содержать в себе всё необходимое для работы приложения. При этом один контейнер — один процесс. Случается, что приходится делать два процесса, но это несколько противоречит идеологии Docker.

Требование «один контейнер — один процесс» связано с PID Namespace. Когда в Namespace запускается процесс с PID 1, если он вдруг умрёт, то весь контейнер тоже умирает. Если же там запущено два процесса: один живёт, а второй умер, то контейнер всё равно продолжит жить. Но это к вопросу Best Practices, мы про них поговорим в других материалах.

Схематично это выглядит примерно вот так:
???

Полезные ссылки и Литература

  1. https://rotoro-cloud.github.io/ + видеолекции
  2. Изучаем Docker
  3. 50 вопросов по Docker, которые задают на собеседованиях, и ответы на них
  4. Как и для чего использовать Docker