Docker Ninja – Telegram
Docker Ninja
1.05K subscribers
30 photos
91 links
По всем вопросам обращаться к @nesudimov_eu
Download Telegram
🪬 Чёрная метка 🪬

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

Тэг состоит из двух частей:
- image_namе - непосредственно имя контейнера
- tag - дополнительная строка в которую пихают все, кто во что горазд, чтобы выделить между собой образы с одинаковым image_namе

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

Не смотря на то, что содержимое тэга чисто технически говорит нам только о порядке нажатых клавиш клавиатуры создателем этого образа, все же есть интересный моментик и тут. Не указав тэг при сборке образа, мы автоматически получаем образ с тэгом latest. А если повторим процедуру, предварительно внеся какие-то изменения в Dockerfile, то образ перезапишется.

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

Так что, будьте внимательны при работе с тэгами!!!

🥷 Docker Ninja 🥷
👍4
🤦 Attention Deficit Disorder 🤦

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

Конечно же в Dockerfile сделать это можно, и, вдобавок, не одним способом. Но конкретно сегодня хотелось бы обсудить инструкцию ADD.

ADD это один из способов копирования файлов внутрь контейнера. И способ этот специфичный, потому что он может копировать файлы:

1. Из build context
ADD ./config.yml /

2. Из локального архива
ADD ./my_files.tar.gz /

В случае такого копирования docker разархивирует указанный локальный конфиг в место назначения внутри конфига.

3. По http/https адресу
ADD https://example.com/my_files.tar.gz

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

4. Из git репозитория
ADD git@user/repo.git /


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

🥷 Docker Ninja 🥷
👍1
🔑 Ключ от всех дверей 🗝

Для работы с приватными репозиториями на Docker Hub или других Docker Registry необходимо сначала авторизоваться. Это можно сделать с помощью команды docker login.
Эта команда запрашивает ваши учетные данные и сохраняет их, чтобы вы могли безопасно скачивать и загружать образы.
docker login [OPTIONS] [SERVER]


Пример использования:
docker login

Так мы вызовем интерактивный запрос логина и пароля.
А так, передаем эти данные через ключи:
docker login -u papa_justify -p hudu_magic



🥷 Docker Ninja 🥷
🔥3👍2
🤩 Amazing Customer Service 🤩

Давайте разберёмся с директивой services в Docker Compose — основой, на которой строится вся конфигурация вашего многоконтейнерного приложения.

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

Пример:
services:
web:
image: nginx
ports:
- "80:80"
environment:
- NGINX_PORT=80
depends_on:
- app

app:
image: my-app
volumes:
- .:/code
environment:
- APP_ENV=production


Но возникает вопрос, зачем, а главное - нафига?! На кой черт сдался нам этот ваш сервис? Почему бы нам не взять и просто описать контейнер с параметрами запуска?

Все дело в назначении инструмента docker compose. Его основная фишка, это управление многоконтейнерными приложениями. И речь тут даже не столько о возможности деплойнуть сам сервис с контейнером базы - такое практикуют скорее на тесте. А, скорее, о необходимости разом поднимать несколько инстансов одного и того контейнера для отказоустойчивости. И в довесок, об управлении жизненным циклом этих инстансов.

Для этих целей и придумали структуру services, в которой будет удобно пояснить за то "какой details, какой fabrique..." А знатоки, наверное уже поняли что для данной директивы есть аналогия в k8s.


🥷 Docker Ninja 🥷
4👍2
👽 А царь то ненастоящий! 👽

Когда дело доходит до создания собственных контейнеров, команда docker build — ваш лучший друг. Она позволяет собрать образ на основе инструкций, указанных в Dockerfile.
docker build -t <your_image_name>:<your_tag> .

А что, если я вам скажу, что docker build, это на самом деле команда docker buildx build?

Спокойно✋🏻
Чтобы ваше войско не бунтовало, могу сказать, что вас не обманули! Точнее обманули, но в вашу пользу!
docker buildx — это расширенная версия, которая поддерживает мультиплатформенные сборки и другие полезные функции. А появилась она в версии docker engine 19.0.0

Чтобы начать, создайте Dockerfile с нужными инструкциями и выполните команду:
docker buildx build -t <your_image_name>:<your_tag> .

Здесь -t задаёт имя и тег для вашего образа, а . указывает на текущую директорию, где находится Dockerfile. С buildx вы получаете больше гибкости и возможностей для создания контейнеров! Ну а подробнее о различиях старого build и buildx build мы поговорим в следующий постах👌🏻


🥷 Docker Ninja 🥷
👍4🤔3
😎 Устроился драйвером в Яндекс GO. Теперь я в ИТ? 😎

Однажды, в студеную зимнюю пору
Болтали мы с вами про докер тома.
Но как-то давно прочитал я на хабре,
Что в докере драйвер есть - overlay номер 2...


Сегодня расскажу вам про такую интересную штуку как docker storage drivers. Но, прежде чем понять а на*уй он нам нужон, этот ваш docker storage drivers, стоит углубиться в механизм работы со слоями в докере.

Как помним, есть модная-сковородная технология LFS, которая помогает нам быстренько и бюджетненько крутить различными контейнерами и не бояться пересечения данных. А работает это потому, что в контейнерах есть image layer и writable layer. У образа есть только первый. У контейнера есть и первый и второй. Соответственно, первый неизменный, второй постоянно меняется и удаляется при удалении контейнера.

За обслуживание всех этих танцев со слоями и берется docker storage drivers.

Буква s, говорящая нам о множественном числе в английском языке не врет - драйверов есть несколько видов и каждый имеет свои преимущества и недостатки. Но об этом поговорим попозже.


🥷 Docker Ninja 🥷
😁3
🧑🏼‍💻 У композитора проекты за проектами 🧑🏼‍💻


Если вы хоть раз наблюдали как в Docker Desktop отображаются контейнеры, запущенные с помощью docker compose, то наверняка задавались вопросом: "А че это за прикол такой?"

А дело тут в том, что компоуз при запуске приложений из compose.yml оперирует абстракцией компоуз проекта. В него он включает все сервисы, их настроки, сети и тд. Зачем это нужно поговорим чуть позже, а вот удобства ради приведу вам одну интересную команду.

docker compose ls


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


🥷 Docker Ninja 🥷
👍5
🤔 Аргументный Аргумент 🤔

Когда работаем с Dockerfile, иногда требуется передавать переменные, которые могут изменяться в зависимости от окружения. С этой задачей нам поможет директива ARG.

ARG позволяет задавать значения, которые могут быть использованы на этапе сборки образа. Это особенно полезно, когда необходимо передать различные параметры, такие как версии ПО или пути.

Пример использования:
FROM alpine

ARG VERSION=latest
RUN apk add --no-cache mypackage=$VERSION


Теперь, при сборке образа, можно указать нужную версию:
docker build --build-arg VERSION='1.2.3' .


Это делает ваш Dockerfile более универсальным и адаптивным к изменениям.


🥷 Docker Ninja 🥷
👍7
Ты задеплоил на прод приложение в контейнере. Через пару минут твой коллега тестировщик сообщил тебе о том, что не проходят платежи. Ты судорожно заходишь на хост, где запущено приложение и видишь что контейнер работает. Твой дальнейший шаг?
Anonymous Quiz
6%
docker restart <container_name>
4%
Скажу что без бутылки не справиться и надо откатывать обновление
6%
Полезу в контейнер смотреть файлы логов
84%
docker logs <container_name>. А не поможет, полезу внутрь смотреть лог файлы
😈 Республика должна умереть! 😈

Когда ваш контейнер уже запущен и держит на борту все, что нужно для вашей задачи, может возникнуть необходимость проникнуть внутрь и выполнить какие-то операции. Именно здесь на помощь приходит команда docker exec.

docker exec позволяет выполнять команды внутри уже запущенного контейнера без необходимости его перезапуска. Это как зайти в работающий механизм и подкрутить что-то прямо на ходу.

docker exec far_far_galaxy_container /order_66

Киллер фича данной команды в том, что Вы можете выполнять ее столько раз, сколько нужно, без влияния на основную задачу контейнера. То есть команда никак не затрагивает корневой процесс контейнера (PID 1), как это происходит при docker attach, а порождает дочерний. То есть, даже ошибочное исполнение процесса в docker exec не сломает контейнер.

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

🥷 Docker Ninja 🥷
👍4😁2
📡 Networking здорового человека 📡

Сегодня давайте разберёмся, как Docker разруливает свои сетевые делишки, начиная с их создания и заканчивая запуском контейнеров. Могу сказать, что разбираться там действительно есть в чем!

Создание сети
1. Выбор драйвера сети:
- Docker поддерживает несколько типов сетевых драйверов, но по умолчанию используется bridge, обеспечивающий изоляцию и взаимодействие на уровне одного хоста.
2. Создание сети:
- Когда вы создаёте сеть, Docker инициирует создание сетевого пространства.
- Для bridge-сети создаётся программный сетевой мост, к которому будут подключаться контейнеры.
3. Настройка сетевых параметров:
- Docker автоматически назначает подсеть и шлюз сети. Вы также можете задать эти параметры вручную для большей гибкости.
- Создаются правила iptables для управления доступом и маршрутизацией трафика.

Запуск контейнера
1. Подключение контейнера к сети:
- При запуске контейнера с указанием сети, Docker создаёт виртуальный сетевой интерфейс (veth), который связывает сетевое пространство контейнера с bridge-сетью.
2. Настройка сетевых интерфейсов:
- В контейнере создаётся сетевой интерфейс, получающий IP-адрес из диапазона сети.
- Docker настраивает DNS для контейнера, чтобы он мог разрешать имена хостов других контейнеров в той же сети.
3. Маршрутизация и правила доступа:
- Docker обновляет iptables для разрешения или блокировки трафика в зависимости от политик сети.
- Контейнер получает доступ к другим контейнерам в той же сети через DNS-имена, что упрощает их взаимодействие.

🥷 Docker Ninja 🥷
🔥6👍2
🌿 Дискомфортная окружающая сре пятница 🌿

Недавно рассматривали с вами механизм аргументов в Dockerfile. С ним рядом нога в ногу марширует другая полезная фича. Переменные среды обладают похожим на аргументы функционалом, но в отличие от последних, остаются внутри контейнера на веки вечные!

Давайте посмотрим как с ним работать.
Для начала необходимо указать директиву ENV в Dockerfile.Значение переменной по умолчанию задается напрямую:
FROM week_before_new_year:latest
ENV PLAN_100_RELEASES_BEFORE_HOLIDAYS=false


Теперь остается только собрать образ из полученного Dockerfile
docker build -t goodbye_production:2024 .


Попав в образ эта переменная уже никуда не денется и ее можно использовать внутри контейнера как мы бы использовали переменные среды в Linux.

Сильное заявление! Проверять я его конечно же буду:
# Заходим в контейнер
docker run -e PLAN_100_RELEASES_BEFORE_HOLIDAYS=true goodbye_production:2024 /bin/bash

# Чекаем переменные
env


А вы, конечно же, подпишитесь и оставьте реакт, если пост понравился😉

🥷 Docker Ninja 🥷
👍3👌3
⚓️ Курс на Тортугу! ⚓️

Порты контейнера - это самый главный способ достучаться до приложения в нем снаружи. Поэтому, в 90 процентах случаев, мы будем открывать какие порты при его запуске. Самый простой способ сделать это, запустить команду docker run с флагом -p.

Запускаем контейнер
docker run -p <host_port>:<container_port> <image_name>


Как видим, значение флага состоит из двух частей, разделенных символом :.
1. <host_port> - порт на машии с docker engine, где запущен контейнер с нашим приложением. После запуска контейнера приложение будет доступно по адресу <host_address>:<host_port>.
2. <container_port> - порт, на котором работает наше приложение внутри контейнера. Его можно подсмотреть в EXPOSE образа. Трафик, приходящий по <host_address>:<host_port> будет перенаправлен на этот порт внутри контейнера.

Но и это еще не все. За раз мы можем указать сразу не сколько портов, повторно указывая флаг -p.
docker run -p 80:80 -p 123:321 my_container:latest


Ну и теперь, вишенка на торте! В обоих портах, мы можем указать протокол (udp, tcp, sctp) или даже принудительно хост:
docker run -p 127.0.0.1:80:80/udp my_container:latest

Вот такие вот пироги с огурцами может вылепить, казалось бы, простейшая команда!

🥷 Docker Ninja 🥷
👍4🔥3👌1
🛻 Синий трактор едет к нам🛻

Коллеги, вот и настало время новогодних праздников. Большинство из нас в эти дни полноценно отдыхает, расслабляется и набирается сил перед новым рывком длинной в один год. Админ канала Docker Ninja (то есть я) не исключение, поэтому до 5 числа включительно будет небольшое затишье. Но не стоит расстраиваться, потому что следующий год будет ещё интереснее и насыщеннее!🥳🥳🥳

Ну и конечно же, куда без поздравления?!
В новом году хочу пожелать вам простых ит-шных радостей: интересных задач, много бабок и ещё столько же вдобавок, крепкого здоровья и полноценную и интересную личную жизнь!

Много слов и мало по делу, поэтому, обобщу словами классика:
Пожелаю я братве
Фартовой воли на Земле!
Здоровья, счастья, пацаны
И чтоб не трогали менты!


Дж. Стетхем (Стэйтем)


🥷 Docker Ninja 🥷
🎅5🎄21
В ходе сборки docker image из файла тебе необходимо скачать файл с гитхаба. Но репозиторий на гитхабе закрытый и надо как-то передать токен в процесс сборки контейнера. Как сделать это максимально безопасно, чтобы образ можно было сделать публичным?
Anonymous Quiz
12%
Указать ENV token=<token> прямо в dockerfile
52%
Прописать в dockerfile ARG token и указывать его при каждой сборке через флаг
32%
Скачаю файл заранее и с помощью COPY передам его в образ.
🐴 Андрюха, у нас сигнал. Возможен graceful shutdown. По коням! 🐴

В разработке есть такое понятие - graceful shutdown. Нужен он для корректного завершения работы приложения, чтобы все соединения, файлики и прочия и подобныя были закрыты перед завершением самого приложения. Подобная фича предусмотрена и в работе Docker Engine.
Поскольку контейнер это процесс, docker daemon может управлять этим процессом, посредством механизма сигналов (Unix signals).

Вот что он использует:
🔹 SIGQUIT (Signal Quit): Этот сигнал часто используется для завершения процесса и создания дампа памяти. В Docker его можно отправить, чтобы приложение завершалось с созданием отладочной информации, если оно поддерживает обработку SIGQUIT.

🔹 SIGTERM (Signal Terminate): Это стандартный сигнал для завершения процесса контейнера docker container stop. Docker сначала отправляет SIGTERM, чтобы дать процессу возможность завершиться корректно. Если процесс не завершится в течение тайм-аута (по умолчанию 10 секунд), отправляется SIGKILL.

🔹 SIGKILL (Signal Kill): Принудительное завершение процесса, если он не реагирует на другие сигналы.

🔹 SIGINT (Signal Interrupt): Используется для прерывания процесса, как при нажатии Ctrl+C. Срабатывает, когда мы, например, мы запускаем терминальную сессию как родительский процесс контейнера в интерактивном режиме, а после завершаем его через Ctrl+C.

🔹 SIGHUP (Signal Hang Up): Этот сигнал обычно используется для уведомления процесса о том, что терминал был отключен. В контексте Docker он может использоваться для перезагрузки конфигурации приложения без полного перезапуска контейнера, если приложение поддерживает обработку SIGHUP.

🔹 SIGUSR1 и SIGUSR2: Эти сигналы могут использоваться для пользовательских задач. Docker Daemon, например, использует SIGUSR1 для сброса стека и SIGUSR2 для перезагрузки конфигурации.

А ты ставь 🔥 если сделал graceful shutdown, завершив 2024 год без факапов на работе!

🥷 Docker Ninja 🥷
🔥9👍2👌1
🤤 И пусть весь мир подождет 🤤

Представь себе: выходишь ты такой с новогодних с 3-мя лишними киллограммами, а тут еще и продовый хост с множеством важных контейнеров кричит о нехватке CPU. И все начинает тормозить, как в пятничный вечер в пробке.

Ну, конечно же, подозрения падают на один из контейнеров и возникает непреодолимое желание решить все старым дедовским ресетом... Но у меня есть идея получше!

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

Для этого просто скажи терминалу:
docker compose pause <service_name>


Пока твой железный друг медитирует, у тебя есть время спокойно изучить логи, найти корень проблемы и, может быть, даже выпить чашку кофе с рюмочкой конь молока. А когда все будет готово, и ты раскроешь все тайны контейнера, просто верни его к жизни:
docker compose unpause <service_name>


🥷 Docker Ninja 🥷
👍5🔥4👌1
💩 Чуешь?! Сигналами пахнет? 💩

Функционал паузы стоит в одном ряду с фичей "вырубить к чертям этот контейнер" и есть большой соблазн подумать, что данным поведением заведуют наши любимые сигнальчики. Но я - не я, если бы впихнул два поста по схожей тематике по соседству!

Так что, коллеги, знайте, docker compose pause абсолютный singnal free! За его работу отвечает другой механизм.
👍3👌1
🏋️ Сколько вешать в граммах? 🏋️

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

Очень вряд ли в вашей жизни сложится ситуация, когда вы поднимите какой либо контейнер единожды и не будете к нему притрагиваться. Скорее всего, образ контейнера будет активно обновляться, ну и вы, чтобы идти в ногу со временем, будете обновлять образы локально. Ну и конечно же откатываться в случае проблем. Поэтому всегда полезно знать, какие версии образов у вас стоят локально. И на этот вопрос, конечно же, нашлась команда - docker image ls.

Заюзать ее проще простого:
docker image ls


Или еще проще, через алиас:
docker images


А если нужна информация про образы из конкретного репозитория, то делаем так:
docker images [REPOSITORY]


Ну и конечно же, можно добавить TAG через : после REPOSITORY. Что репо, что тэг должны быть максимально точными, иначе рискуете не получить ничего, либо инфу о совсем другом образе.

🥷 Docker Ninja 🥷
👍5🆒2👏1