March 26, 2022

Docker

Заметки по докеру.

* Механизмы Docker:

Контейнер/приложение — развернутый работающий проект

Образ(image) — неизменяемый готовый проект с определенным функционалом(шаблон)

Платформа(Docker Platform) — программа упаковывает и запускает контейнеры

Движок(Docker Engine) — клиент-серверное приложение(Community или Enterprise)

Клиент(Docker Client) — обращаясь к клиенту использует API Docker для отправки команд демону Docker посредством CLI.

Демон(Docker Daemon) — сервер для запросов к API Docker, управляет образами, контейнерами, сетями и томами.

Тома(Docker Volumes) — хранилище информации, используемое в контейнерах.

Реестр (Docker Registry) — удалённое хранилище образов.

Хаб(Docker Hub) — самый крупный реестр образов(по умолчанию)

Репозиторий (Docker Repository) — коллекция образов Docker с одним и тем же именем(тегом). Теги — идентификаторы образов.

Обычно в репозиториях хранятся разные версии одних и тех же образов. Например, Python — это имя популярнейшего официального репозитория Docker на хабе Docker. А вот Python:3.7-slim — это версия образа с тегом 3.7-slim в репозитории Python. В реестр можно отправить как целый репозиторий, так и отдельный образ.

* Масштабирование:

Сеть Docker (взято из документации)

Сеть. Сетевые механизмы(Docker Networking) — среда, которая позволяет организовывать взаимодействие контейнеров(на одном и том же хосте или на разных хостах)

Docker Compose — развёртывает приложения из нескольких контейнеров.

Выполняет команды изdocker-compose.yml

Docker Swarm — управление контейнерными развёртываниями(оркестрация контейнеров)

Сервисы (Docker Services)— контейнеры в продакшне.

В настройках docker "general" -> [ ] "☑️ Expose daemon on tcp://localhost:2375 without TLS"

в cmd ввести команду -> "docker" для отображения всех доступных команд

Команды:

"docker -v" — Версия Docker Engine
"docker run {id/name}" — запускает(если нет, то скачивает)

"--help" - отобразит всю справочную информацию для команды ("run")
"docker run -d -p 80:80 docker/geting-started"
-d — параметр "--detach"(запуск в фоне) -p — параметр "--publish list" (Публикация контейнера на определенные порты) -m — параметр "--memory bytes" (Ограничение используемой памяти) -i — это сокращение для --interactive. Благодаря этому флагу поток STDIN поддерживается в открытом состоянии даже если контейнер к STDIN не подключён.
-t — это сокращение для --tty выделяется псевдотерминал с потоками STDIN и STDOUT контейнера.
--rm — автоматически удаляет контейнер после завершения

"docker pull" — скачать без запуска с DockerHub

"docker build"  — собирает образ из Dockerfile и контекста(из файлов пути или URL)

-t — чтобы задать имя образа "docker build -t {container_name} ."

"docker info" - отображает статус приложений

"docker images" — отображает подробную информация об образах

"docker ps" - отображает подробную информация о запущенных контейнерах

("-a" — отобразит все, "-q" — только id)

"docker stop {id}"  —  останавливает один и более контейнеров.

"docker stop {container_name}" остановит один контейнер,

а docker stop $(docker ps -a -q) — все запущенные. Более грубый способ — использовать

"docker kill {container_name}", который не пытается сначала аккуратно завершить процесс.

"docker kill $(docker ps -q)." — Останавливаем все запущенные контейнеры

"docker start {id}" — запустить контейнер

"docker pause {id}" — поставить на паузу контейнер

"docker unpause {id}" — выключить паузу контейнера

"docker login " — авторизоваться на портале docker.hub

"docker logout " — выйти из docker.hub

"docker logs"  —  просмотр логов контейнера

--follow : "docker logs --follow {container_name}".

"docker volume ls"  —  показывает список томов, которые являются предпочитаемым механизмом для сохранения данных, генерируемых и используемых контейнерами Docker.

"docker volume create {volume_name}" — создаём том {volume_name}

"docker container ls -s" — примерный размер выполняющегося контейнера

"docker image ls" — размеры образов

"docker rm {id}"  —  удаляет один и более контейнеров,

"docker rm $(docker ps -a -q)." — Удаляем все остановленные контейнеры

"docker rmi"  —  удаляет один и более образов

"docker rmi $(docker images -q)." — Удаляем все образы
"docker rmi $(docker images -f "dangling=true" -q)" — удаляет только безымянные образы

"docker exec -it {container_id} bash" — подключится к bash интерактивно внутри определенного контейнера

"exit" — выход

"docker attach {container_id}" — подключиться к процессу

"docker commit -m "{comment}" -a "{author}" {container_id} {repository}/{new}" — Создать Image из контейнера

"docker search {image_name}" — поиск образа в hub.docker.com

"docker tag {image_name:tag1} {image_name:tag2}" — Создать копию Image с другим именем и tag

"docker container ...

  • create — создание контейнера из образа(url).
docker container create my_repo/my_image:my_tag
  • start — запуск существующего контейнера.
docker container run my_image
  • run — создание контейнера и его запуск.
docker container run -i -t -p 1000:8000 --rm my_image
  • ls — вывод списка работающих контейнеров.
"-a"(--all) — сведения обо всех контейнерах, не только о выполняющихся.
"-s"(--size) — вывести размеры контейнеров.
  • inspect — вывод подробной информации о контейнере.
  • logs — вывод логов.
  • stop — остановка работающего контейнера с отправкой главному процессу контейнера сигнала SIGTERM, и, через некоторое время, SIGKILL.
  • kill — остановка работающего контейнера с отправкой главному процессу контейнера сигнала SIGKILL.
docker container kill $(docker ps -q)
  • rm — удаление остановленного контейнера.
docker container rm $(docker ps -a -q)

..."

"docker image ...

  • build — сборка образа.
"docker image build -t my_repo/my_image:my_tag ." -t(--tag) — назначить предоставленный в команде тег
Точка в конце команды указывает на то, что образ надо собрать с использованием файла Dockerfile, находящегося в текущей рабочей директории.
  • push — отправка образа в удалённый реестр.
docker image push my_repo/my_image:my_tag
  • ls — вывод списка образов(в т.ч. размер)
  • history — вывод сведений о слоях образа(размерах т.д.).
docker image history my_image
  • inspect — вывод подробной информации об образе, в том числе — сведений о слоях.
  • rm — удаление образа.
docker image rm $(docker images -a -q)

..."

"docker version" — вывод сведений о версиях клиента и сервера Docker.

"docker login" — вход в реестр Docker.

"docker system prune" — удаление неиспользуемых контейнеров, сетей и образов, которым не назначено имя и тег.

docker system prune -a --volumes
-a(--all) — удалить неиспользуемые образы, а не только те, которым не назначено имя и тег.
--volumes позволяет удалить неиспользуемые тома.


docker inspec — ?

"docker run -it -p 7777:8080 tomcat"	— Запустить интерактивно контейнер  tomcat на порте 7777
"docker run -d -p 8888:8080 tomcat"	— Запустить НЕ интерактивно контейнер  tomcat на порте 8888
"docker run -d -p 80:80 nginx" — Запустить НЕ интерактивно контейнер  nginx на порте 80
	

"docker build -t myimage:latest ." — Создать Image с именем myimage:latest из локального Dockerfile
"docker run -d myimage:latest" — Запустить НЕ интерактивно контейнер myimage:latest
	

"echo "New Version v2" >> /var/www/html/index.html	Изменить файл в контейнере
exit	Выйти из контейнера

Узнать размеры промежуточных образов, из которых собран некий образ, можно с помощью команды docker image history my_image:my_tag.
Команда docker image inspect my_image:tag позволяет узнать подробные сведения об образе, в том числе — размер каждого его слоя. Слои немного отличаются от промежуточных образов, из которых состоит готовый образ, но, в большинстве случаев их можно рассматривать как одинаковые сущности. Вот хороший материал, который посвящён подробностям внутреннего устройства образов Docker.
Для того чтобы исследовать содержимое контейнеров можно установить пакет dive.


dockerfile — файл с описанием подключения всех необходимых компонентов?

так же можно установить определенную версию: "docker pull {image_name}:{version}"

"docker run -it --name {MyName} {image_name}" — запуск в интерактивном режиме

"Ctrl + d" — выход из интерактивного режима

При создании контейнера слой, в который можно вносить изменения, добавляется поверх всех остальных слоёв. Данные, находящиеся в остальных слоях, можно только читать.(url)


.dockerignore file

Как и .gitignore содержат список файлов и папок, в виде имён или шаблонов, которые Docker должен игнорировать в ходе сборки образа.(url)
  • Позволяет исключать из состава образа файлы, содержащие секретные сведения наподобие логинов и паролей.
  • Позволяет уменьшить размер образа. Чем меньше в образе файлов — тем меньше будет его размер и тем быстрее с ним можно будет работать.
  • Даёт возможность уменьшить число поводов для признания недействительным кэша при сборке похожих образов. Например, если при повторной сборке образа меняются некие служебные файлы проекта, наподобие файлов с журналами, из-за чего данные, хранящиеся в кэше, по сути, необоснованно признаются недействительными, это замедляет сборку образов.


Dockerfile

*При запуске docker build (создания нового образа) Dockerfile должен быть в текущей директории иначе нужно использовать "-f"

*Слои в итоговом образе создают только инструкции RUN, COPY, ADD. Другие инструкции создают временные промежуточные образы, и не увеличивают размер сборки(настраивают, описывают метаданные, открывают порты и т.д.)

"FROM {image}:{version}"(url) — задаёт базовый (родительский) образ. (первая инструкция)

"RUN {commands}"(url) — Выполняется1 раз при создании. Выполняет команду и создаёт слой образа. Используется для установки в контейнер пакетов.

*писать несколько команд через && крайне полезен. Он означает что вместо трех отдельных слоев будет создан лишь один, что заметно уменьшает и размер образа и скорость его разворачивания. Перечисляйте пакеты в алфавитном порядке на нескольких строках, разделяя список символами \. Например, это может выглядеть так:
RUN apt-get update && apt-get install -y \ package-one \ package-two \ package-three && rm -rf /var/lib/apt/lists/* * Включайте конструкцию вида && rm -rf /var/lib/apt/lists/* в конец инструкции RUN, используемой для установки пакетов. Это позволит очистить кэш apt и приведёт к тому, что он не будет сохраняться в слое, сформированном командой RUN. Подробности об этом можно почитать в документации.

"CMD [{command}, {command}]"(url) — Выполняется каждый раз при запуске. Описывает команду с аргументами, которую нужно выполнить когда контейнер будет запущен.

*Аргументы могут быть переопределены при запуске контейнера. В файле может присутствовать лишь одна инструкция CMD.

"LABEL "(url) — описывает метаданные. Например — сведения о том, кто создал и поддерживает образ. Не влияет на скорость(url)

"EXPOSE {port}"(url) — указывает на необходимость открыть порт. Для того чтобы docker run с ключом -p — открыть порт.(-P открыты будут все порты, указанные в инструкции EXPOSE)

"ENV "(url) — устанавливает постоянные переменные среды.(+ ADMIN)

"ADD "(url) — копирует файлы и папки в контейнер, может распаковывать локальные .tar-файлы.

"COPY /{folder_source} /{folder_receive}"(url) — копирует в контейнер файлы и папки. "COPY . ." - текущая папка

"ENTRYPOINT "(url) — предоставляет команду с аргументами для вызова во время выполнения контейнера. Аргументы не переопределяются. "ENTRYPOINT ["executable", "param1", "param2"]."

*похожа на команду CMD, но параметры, задаваемые в ENTRYPOINT, не перезаписываются в том случае, если контейнер запускают с параметрами командной строки (если нужно перезаписывать используйте CMD)

"VOLUME "(url) — создаёт точку монтирования для работы с постоянным хранилищем.

"WORKDIR /{folder}"(url) — задаёт рабочую директорию для следующей инструкции.

* Лучше устанавливать с помощью WORKDIR абсолютные пути к папкам, а не перемещаться по файловой системе с помощью команд cd в Dockerfile.

"ARG "(url) — задаёт переменные для передачи Docker во время сборки образа.

*В отличие от ENV-переменных, ARG-переменные недоступны во время выполнения контейнера(url)

"USER " —

"HEALTHCHECK " —

"SHELL " —

"ONBUILD " —

MAINTAINER (deprecated) —

* Разумно пользуйтесь возможностями кэширования, размещая в Dockerfile команды, вероятность изменения которых высока, ближе к концу файла.

Пример Dockerfile

FROM python:3.7.2-alpine3.8
LABEL maintainer="jeffmshale@gmail.com"
ENV ADMIN="jeff"
RUN apk update && apk upgrade && apk add bash
COPY . ./app
ADD https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4 \
/my_app_directory
RUN ["mkdir", "/a_directory"]
CMD ["python", "./my_script.py"]
*apk — это сокращение от Alpine Linux package manager (менеджер пакетов Alpine Linux), так же можно устанавливать через pip, wheel и conda
*можно как JSON-массив: "RUN ["my_executable", "my_first_param1", "my_second_param2"]"
*для создания директории. "RUN ["mkdir", "/a_directory"]"
*"COPY . ./app"—Docker возьмет файлы и папки из локального контекста сборки и добавить их в текущую рабочую директорию образа.
*ADD — контейнеры из удаленных источников(не рекомендуется, так как раздувает размер образа), локальные .tar-файлы (рекомендуется ADD -> COPY)
*CMD — команда при запуске. Результаты не добавляются в образ сборки. + может быть только одна + может иметь exec-форму(должна быть инструкция ENTRYPOINT)

пример2:

FROM python:3.7.2-alpine3.8
LABEL maintainer="email@gmail.com"
#Устанавливаем зависимости
RUN apk add --update git
#Задаём текущую рабочую директорию
WORKDIR /usr/src/my_app_directory
# Копируем код из локального контекста в рабочую директорию образа
COPY . .
# Задаём значение по умолчанию для переменной
ARG my_var=my_default_value
# Настраиваем команду, которая должна быть запущена в контейнере во время его выполнения
ENTRYPOINT ["python", "./app/my_script.py", "my_var"]
# Открываем порты
EXPOSE 8000
# Создаём том для хранения данных
VOLUME /my_volume


Docker volume

Том(url) — это файловая система, которая расположена на хост-машине за пределами контейнеров. Созданием и управлением томами занимается Docker. Вот основные свойства томов Docker:

  • Они представляют собой средства для постоянного хранения информации.
  • Они самостоятельны и отделены от контейнеров.
  • Ими могут совместно пользоваться разные контейнеры.
  • Они позволяют организовать эффективное чтение и запись данных.
  • Тома можно размещать на ресурсах удалённого облачного провайдера.
  • Их можно шифровать.
  • Им можно давать имена.
  • Контейнер может организовать заблаговременное наполнение тома данными.
  • Они удобны для тестирования.

VOLUME /my_volume
*Обратите внимание на то, что если вы создаёте том с использованием Dockerfile, это не освобождает вас от необходимости указать точку монтирования тома.

"docker volume ...

  • create — создать том
"docker volume create --name {volume_name}"
  • ls — список томов
  • inspect — исследовать конкретный том
  • rm — удалить том
  • prune — удалить все тома, которые не используются контейнерами
docker volume prune

"docker system prune" — очистка ресурсов Docker. После выполнения этой команды у вас должна появиться возможность удалить тома, статус которых до этого определялся неправильно.

Флаги:

-v(--volume) —

--mount —

  • type={volume} — тип монтирования. Значением для соответствующего ключа могут выступать bind, volume или tmpfs.
  • source={volume_name} — источник монтирования. Для именованных томов это — имя тома. Для неименованных томов этот ключ не указывают. Он может быть сокращён до src.
  • destination={path} (/path/in/container) — путь, к которому файл или папка монтируется в контейнере. Этот ключ может быть сокращён до dst или target.
  • readonly(url) — монтирует том, который предназначен только для чтения. Использовать этот ключ необязательно, значение ему не назначают.
"docker container run --mount source=my_volume, target=/container/path/for/volume my_image"

"docker run --mount type=volume,source=volume_name,destination=/path/in/container,readonly my_image"
*Главное различие между --mount и --volume заключается в том, что при использовании флага --volume все параметры собирают вместе, в одном поле, а при использовании --mount параметры разделяются


Кэш

*Если в Dockerfile обнаруживается инструкция RUN pip install -r requirements.txt, то Docker выполняет поиск такой же инструкции в своём локальном кэше промежуточных образов. При этом содержимое старой и новой версий файла requirements.txt не сравнивается!

  • Кэширование можно отключить, передав ключ --no-cache=True команде docker build.
  • Если вы собираетесь вносить изменения в инструкции Dockerfile, тогда каждый слой, созданный инструкциями, идущими после изменённых, будет достаточно часто собираться повторно, без использования кэша. Для того чтобы воспользоваться преимуществами кэширования, помещайте инструкции, вероятность изменения которых высока, как можно ближе к концу Dockerfile.
  • Объединяйте команды RUN apt-get update и apt-get install в цепочки для того, чтобы исключить проблемы, связанные с неправильным использованием кэша.
  • Если вы используете менеджеры пакетов, наподобие pip, с файлом requirements.txt, тогда придерживайтесь нижеприведённой схемы работы для того, чтобы исключить использование устаревших промежуточных образов из кэша, содержащих набор пакетов, перечисленных в старой версии файла requirements.txt. Вот как это выглядит:
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
COPY . /tmp/



Docker-compose

для работы с несколькими контейнерами на одной машине

docker-comose.yml

version: '1.1'

services:

...
...

"docker-compose build" — собираем образы из Yaml файла

"docker-compose up" — запускаем образы

"docker-compose run" — запускаем образы с дополнительными командами

"docker-compose down" — останавливаем образы

"Ctrl + c" — выход из интерактивного режима и останавливаем контейнеры

"Ctrl + p, Ctrl + q" — выход из интерактивного режима БЕЗ остановки контейнера


Docker Swarm — для работы с кластером одного и того же контейнера из нескольких машинах

Дополнительные материалы


Безопасность в Docker

Шпаргалки по безопасности: Docker

Безопасная работа с секретами при сборке в Docker Compose

10 практических рекомендаций по безопасности образов Docker
(Часть 1 и Часть 2)

Безопасность для Docker-контейнеров

Лучшие практики при написании безопасного Dockerfile

Способы и примеры внедрения утилит для проверки безопасности Docker

Часто забываемые правила безопасности Docker: заметки энтузиаста ИБ

Как повысить безопасность Docker-контейнеров


Хороший курс по docker

Скачать docker можно отсюда

удобная площадка для тренировки labs.play-with-docker.com


Часть 1: основы
Часть 2: термины и концепции
Часть 3: файлы Dockerfile
Часть 4: уменьшение размеров образов и ускорение их сборки
Часть 5: команды
Часть 6: работа с данными

Установка Docker на Ubuntu

dive — для глубокого изучения контейнера

Полезные ресурсы


Список использованных источников
1. https://wiki.merionet.ru
2. https://habr.com
3. https://techrocks.ru
4. https://docs.microsoft.com/ru-ru/
5. https://www.digitalocean.com/community/tutorials
6. https://www.docker.com
7. https://selectel.ru
8. https://tproger.ru/
9. https://www.reg.ru
10. https://eternalhost.net/blog
11. https://mcs.mail.ru/blog/
12. https://proglib.io