🐳 Гнездо кита 🐳
Как все мы с вами помним, Docker Engine архитектурно состоит из трех компонентов:
Взаимодействие может происходит через различные механизмы. Всего их три: UNIX сокеты, TCP и FD.
🔹 UNIX Сокеты:
Это наиболее распространенный способ взаимодействия Docker клиента с демоном Docker на одной и той же машине. UNIX сокеты обеспечивают быструю и безопасную связь, так как они не требуют сети и защищены атрибутами файловой системы. По умолчанию Docker использует UNIX сокет
🔹 TCP Сокеты:
Когда ты работаешь с удалёнными Docker демонами, на помощь приходят TCP сокеты. Они позволяют взаимодействовать с Docker API через сеть. Это удобно для управления Docker на удалённых серверах, но стоит помнить о безопасности и использовать TLS для шифрования данных.
🔹 File Denoscriptor (FD):
Этот способ менее распространён, но иногда используется в специфичных сценариях, когда необходимо передать сокет напрямую в уже открытый дескриптор файла. Это может быть полезно для интеграций с другими системами, где передача через файловый дескриптор предпочтительнее.
Более подробно каждый из них мы рассмотри в последующих постах, а сейчас пока можно просто запомнить их, чтобы в случайной беседе с коллегами блеснуть своими глубочайшими познаниями😎
🥷 Docker Ninja 🥷
Как все мы с вами помним, Docker Engine архитектурно состоит из трех компонентов:
dockerd, docker API и клиент в виде cli командлета. И сегодня мы поговорим о том, через какие механизмы осуществляется связь клиента с API. Тут есть в чем разобраться, поехали!Взаимодействие может происходит через различные механизмы. Всего их три: UNIX сокеты, TCP и FD.
🔹 UNIX Сокеты:
Это наиболее распространенный способ взаимодействия Docker клиента с демоном Docker на одной и той же машине. UNIX сокеты обеспечивают быструю и безопасную связь, так как они не требуют сети и защищены атрибутами файловой системы. По умолчанию Docker использует UNIX сокет
/var/run/docker.sock. И, частенько, этот файлик надо прокидывать в контейнеры, которым необходима информация о других контейнерах. Например, когда ставим Traefik🔹 TCP Сокеты:
Когда ты работаешь с удалёнными Docker демонами, на помощь приходят TCP сокеты. Они позволяют взаимодействовать с Docker API через сеть. Это удобно для управления Docker на удалённых серверах, но стоит помнить о безопасности и использовать TLS для шифрования данных.
🔹 File Denoscriptor (FD):
Этот способ менее распространён, но иногда используется в специфичных сценариях, когда необходимо передать сокет напрямую в уже открытый дескриптор файла. Это может быть полезно для интеграций с другими системами, где передача через файловый дескриптор предпочтительнее.
Более подробно каждый из них мы рассмотри в последующих постах, а сейчас пока можно просто запомнить их, чтобы в случайной беседе с коллегами блеснуть своими глубочайшими познаниями
🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍9🔥1
⚖️ Вокруг одна политика 📜
Все мы знаем как запускать контейнеры и перезапускать их вручную, но не менее важно иметь возможность перезапускать их автоматически. То есть полезно было бы иметь возможность настраивать какие-то политики перезапуска контейнеров в случае их падения. И тут нам поможет флаг
Начнем с базового использования:
В этом примере контейнер будет автоматически перезапущен в случае остановки или перезагрузки системы.
Всего же у нас имеется 4 вида restart-policy:
-
-
-
-
Теперь мы знаем еще один дополнительный способавтоматизации рабочей рутины, который даст нам больше времени на изучение нового поменьше работать. Все-таки чувствуется приближение пятницы😉
🥷 Docker Ninja 🥷
Все мы знаем как запускать контейнеры и перезапускать их вручную, но не менее важно иметь возможность перезапускать их автоматически. То есть полезно было бы иметь возможность настраивать какие-то политики перезапуска контейнеров в случае их падения. И тут нам поможет флаг
—-restart у команды docker run.Начнем с базового использования:
# Запускаем контейнер с политикой перезапуска
docker run --restart=always mywebserver
В этом примере контейнер будет автоматически перезапущен в случае остановки или перезагрузки системы.
Всего же у нас имеется 4 вида restart-policy:
-
no: контейнер не будет перезапускаться (это значение по умолчанию).-
always: контейнер будет перезапускаться всегда. В случае ручной остановки контейнера, он будет запущен только после ручного запуска или после рестарта dockerd.-
unless-stopped: похож на always, но после ручной остановки контейнера с такой политикой, стартануть его можно только через ручной запуск.-
on-failure[:max-retries]: контейнер будет перезапущен только в случае ошибки, и можно указать максимальное количество перезапусков.Теперь мы знаем еще один дополнительный способ
🥷 Docker Ninja 🥷
👍12
Я просто уверен, что многие из вас знают и активно юзают команду, о которой сегодня пойдет речь. Но не сказать о ней будет просто преступлением.
Сегодня я расскажу вам о том. как же мы можем посмотреть существующие на хосте контейнеры.
Выглядит это так:
# Запускаем команду
docker ps
# Получаем вывод
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1f2e3c4b5f6 nginx:latest "nginx -g 'daemon of…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp web_server
a7b8c9d0e1f2 mysql:5.7 "docker-entrypoint.s…" 2 days ago Up 2 days 3306/tcp, 33060/tcp db_server
Как видим, команда показывает нам табличку со следующими данными:
- CONTAINER ID - уникальный ID контейнера, присваеваемый при его создании. По этому id так же можно найти папку с данными конкретного контейнера в файловой системе хоста, на котором он запущен.
- IMAGE - используемый образ для создания контейнера
- COMMAND - cli команда, которая по-умолчанию запускается при старте контейнера (та самая CMD)
- CREATED - время создания контейнера
- STATUS - статус, по которому можно отследить состояние контейнера. Если юзать команду без флагов, то мы увидим только работающие контейнеры, а как увидеть все, расскажу в следующих постах
- PORTS - пара host/container port, которая назначена при старте контейнера
- NAMES - имя контейнера, назначенное с помощью флага или сгенерированное автоматически
Это пример самого базового использования и на деле данная команда дает нам множество возможностей для управления нашими контейнерами. Но о них мы поговорим в последующих постах.
🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍9
В Dockerfile твоего приложения указан базовый образ с тегом latest. Какой подход позволит гарантировать, что при каждой сборке через CI систему будет использована самая актуальная версия базового образа?
Anonymous Quiz
16%
Использовать команду docker build -t my_app_image:tag .
40%
Использовать команду docker build --no-cache -t my_app_image:tag .
9%
Добавить в Dockerfile строку RUN apt-get update
35%
Перед сборкой каждый раз пуллить latest версию базового образа docker pull base_image:latest
👍4
🤘 Гоп-стоп, мы подошли из-за угла 🤘
Понедельник...
Контейнер упал после очередного наплыва пользователей в выходные дни. Прод горит, в кофемашине образовался чайный гриб, а PM орет что-то про дедлайны...
А все потому, что кто-то забыл ограничить память для своего "легкого" сервиса, который внезапно сожрал всю RAM на хосте!
И тут на помощь приходит флаг
Этот флажок позволяет установить лимит потребления оперативной памяти для контейнера:
Как можно понять из листинга команд, мы тут предлагаем каждому контейнеру не брать на грудь более 512 Мб и 2 Гб соответственно. А помогает нам в этом Linux cgroups.
А что будет, если контейнер попытается съесть больше дозволенного? В таком случае, на сцену выходит OOM Killer с предложением посмотреть на звезды, небо с этим морем, потому что контейнер увидит это в последний раз.💀
Зачем это нужно?
Где еще можем встретить:
- У вас микросервис с утечкой памяти (особенно часто такое можно встретить в Java коде - привет финтеху👋🏻) — ограничили 1GB и спите спокойно
- Тестовое окружение на одном сервере — каждому контейнеру свой кусочек пирога и никто никому не мешает.
Помните: железо не резиновое, а память — самый дорогой ресурс в дата-центре!
Ставь 🔥, если пост спас твой прод от внезапного OOM!
🥷 Docker Ninja 🥷
Понедельник...
Контейнер упал после очередного наплыва пользователей в выходные дни. Прод горит, в кофемашине образовался чайный гриб, а PM орет что-то про дедлайны...
А все потому, что кто-то забыл ограничить память для своего "легкого" сервиса, который внезапно сожрал всю RAM на хосте!
И тут на помощь приходит флаг
--memory (или -m для ленивых).Этот флажок позволяет установить лимит потребления оперативной памяти для контейнера:
docker run -m 512m nginx
docker run --memory=2g my_heavy_app
Как можно понять из листинга команд, мы тут предлагаем каждому контейнеру не брать на грудь более 512 Мб и 2 Гб соответственно. А помогает нам в этом Linux cgroups.
А что будет, если контейнер попытается съесть больше дозволенного? В таком случае, на сцену выходит OOM Killer с предложением посмотреть на звезды, небо с этим морем, потому что контейнер увидит это в последний раз.💀
Зачем это нужно?
Где еще можем встретить:
- У вас микросервис с утечкой памяти (особенно часто такое можно встретить в Java коде - привет финтеху👋🏻) — ограничили 1GB и спите спокойно
- Тестовое окружение на одном сервере — каждому контейнеру свой кусочек пирога и никто никому не мешает.
Помните: железо не резиновое, а память — самый дорогой ресурс в дата-центре!
Ставь 🔥, если пост спас твой прод от внезапного OOM!
🥷 Docker Ninja 🥷
🔥9👍3👌2
🤞 Last hope 🤞
Бывало так. Приходишь в офис, наливаешь себе спокойно кофе и думаешь:
- Ну, вчерашний релиз мы успешно пережили. Сегодня будет хороший день!
Но тут залетает PO и говорит, что какой-то умник ломает наше приложение. Id сессии можно увидеть лишь только в логах.
- Отлично, - думаешь ты, - сейчас глянем вывод docker logs. Если только...
Да, именно так - любимый коллега забыл прокинуть логирование в stdout.
- Не проблема. Таким меня не сломаешь! - тут же сам себя успокоил, - найдем их через псевдотерминал.
А вот и нет! В базовом образе контейнера не завезли оболочку. Да, и такое бывает - оптимизация, мать ее за ногу!
И вот, ты уже совсем поник и не знаешь что делать, как вдруг О великий и могучийчатгпт stackoverflow рассказывает нам про команду
Синтаксис простой как три копейки:
И да, копировать можно даже целые папки:
Ну и самое интересно, что команда работает независимо от того, запущен контейнер или висит мертвым грузом. Главное — узнать его ID или имя, например с помощью docker ps! Ай, хорошо...!!!
Зачем это нужно?
Реальные кейсы из окопов DevOps-а:
- Приложение легло, а тебе нужно вытащить дамп памяти или логи для анализа
- Срочно подкинуть исправленный конфиг без пересборки образа
- Забэкапить данные перед обновлением
- Вытащить артефакты сборки из билд-контейнера
Ставь 👍, если спас твой стул от следов возгорания!
🥷 Docker Ninja 🥷
Бывало так. Приходишь в офис, наливаешь себе спокойно кофе и думаешь:
- Ну, вчерашний релиз мы успешно пережили. Сегодня будет хороший день!
Но тут залетает PO и говорит, что какой-то умник ломает наше приложение. Id сессии можно увидеть лишь только в логах.
- Отлично, - думаешь ты, - сейчас глянем вывод docker logs. Если только...
Да, именно так - любимый коллега забыл прокинуть логирование в stdout.
- Не проблема. Таким меня не сломаешь! - тут же сам себя успокоил, - найдем их через псевдотерминал.
А вот и нет! В базовом образе контейнера не завезли оболочку. Да, и такое бывает - оптимизация, мать ее за ногу!
И вот, ты уже совсем поник и не знаешь что делать, как вдруг О великий и могучий
docker cp, которая позволяет дешево и сердито копировать файлы туда-сюда между контейнером и хостом!Синтаксис простой как три копейки:
# Из контейнера на хост
docker cp my_container:/path/to/file ./local_path
# С хоста в контейнер
docker cp ./local_file my_container:/path/inside
И да, копировать можно даже целые папки:
docker cp my_container:/app/logs ./debug_logs
Ну и самое интересно, что команда работает независимо от того, запущен контейнер или висит мертвым грузом. Главное — узнать его ID или имя, например с помощью docker ps! Ай, хорошо...!!!
Зачем это нужно?
Реальные кейсы из окопов DevOps-а:
- Приложение легло, а тебе нужно вытащить дамп памяти или логи для анализа
- Срочно подкинуть исправленный конфиг без пересборки образа
- Забэкапить данные перед обновлением
- Вытащить артефакты сборки из билд-контейнера
Ставь 👍, если спас твой стул от следов возгорания!
🥷 Docker Ninja 🥷
👍17❤2
Новый разработчки вручную настроил рабочую среду внутри контейнера и хочет сохранить все изменения в новый образ. Какая команда поможет создать образ из текущего состояния запущенного контейнера?
Anonymous Quiz
22%
docker save my_container my_new_image:v1
27%
docker commit my_container my_new_image:v1
21%
docker export my_container > my_new_image:v1
30%
docker build -t my_new_image:v1 my_container
🔬 Проникаем в СИЗО🔬
Мы уже не раз задавались вопросом, как Docker умудряется так ловко изолировать контейнеры друг от друга? И уже дошли до того, что все эти контейнеры — обычные процессы в хостовой системе, так почему же они не видят друг друга?
Внимание! За кулисами работают механизмы Системной ИЗОляции - Linux Namespaces 🕵️
В команду великих комбинаторов входят:
🔹 PID namespace — каждый контейнер видит только свои процессы. Твой nginx думает, что он единственный на свете!
🔹 Mount namespace — файловая система контейнера изолирована от хоста. Можешь крушить что угодно внутри — хост останется цел!
🔹 Network namespace — вот почему порты контейнеров не конфликтуют с хостом! У каждого свой сетевой стек!
🔹 IPC namespace — изоляция межпроцессного взаимодействия. Никто не подслушает твои сообщения!
🔹 UTS namespace — каждый контейнер может иметь свой hostname, не мешая соседям.
🔹 User namespace — мапинг пользователей между контейнером и хостом.
Зная это становится понятно, что Docker это вовсе не чорное колдунство, а просто виртуозное использование совсем не новых возможностей Linux ядра для создания изолированных процессов! 🧙♂️
Ставь 👌, если тайны изоляции стали чуточку понятнее!
🥷 Docker Ninja 🥷
Мы уже не раз задавались вопросом, как Docker умудряется так ловко изолировать контейнеры друг от друга? И уже дошли до того, что все эти контейнеры — обычные процессы в хостовой системе, так почему же они не видят друг друга?
Внимание! За кулисами работают механизмы Системной ИЗОляции - Linux Namespaces 🕵️
В команду великих комбинаторов входят:
🔹 PID namespace — каждый контейнер видит только свои процессы. Твой nginx думает, что он единственный на свете!
🔹 Mount namespace — файловая система контейнера изолирована от хоста. Можешь крушить что угодно внутри — хост останется цел!
🔹 Network namespace — вот почему порты контейнеров не конфликтуют с хостом! У каждого свой сетевой стек!
🔹 IPC namespace — изоляция межпроцессного взаимодействия. Никто не подслушает твои сообщения!
🔹 UTS namespace — каждый контейнер может иметь свой hostname, не мешая соседям.
🔹 User namespace — мапинг пользователей между контейнером и хостом.
Зная это становится понятно, что Docker это вовсе не чорное колдунство, а просто виртуозное использование совсем не новых возможностей Linux ядра для создания изолированных процессов! 🧙♂️
Ставь 👌, если тайны изоляции стали чуточку понятнее!
🥷 Docker Ninja 🥷
👌10👎1🔥1
💊Игра на нервах💊
Сегодня поговорим о высоком - о тонком искусстве заставить ваших коллег тихо плакать в туалетной кабинке после каждого PR важих докерфайлов! Я говорю об искусстве наговнокодить в Dockerfile.
И первый наш кейс - контекст выполнения команд внутри контейнера во время сборки.
Для примера, посмотрим на код.
Почему же это плохо?
1. На каждый
2. В случае использвания других директив, наподобие COPY, необходимо будет прописать полный путь до нужной папки. То есть поведение остальных инструкций совсем не явная история.
3. Из предыдущих двух пунктов вытекает 3 - сопровождать такой Dockerfile неудобно от слова "горите в Оду, авторы этого чуда".
А вот, правильный вариант:
И чем это лучше?
1) Получаем постоянство контекста. Установив раз рабочую директорию в /app мы будем производить все действий только в ней, то тех пор пока не переназначим. А это минус cd /app в каждом блоке команд, да и самих таких блоков станет гораздо меньше.
2) Не нужны лишние RUN-ы чтобы создавать папку. Если папки нет, то
3) Такой код более читаемый и предсказуемый
4) Так мы можем использовать относительные пути для других дирректив файла
Так что, берите на заметку и ваши коллеги вам скажут спасибо👌🏻
А впереди у нас выходнульки, значит дружно ставим 🔥
🥷 Docker Ninja 🥷
Сегодня поговорим о высоком - о тонком искусстве заставить ваших коллег тихо плакать в туалетной кабинке после каждого PR важих докерфайлов! Я говорю об искусстве наговнокодить в Dockerfile.
И первый наш кейс - контекст выполнения команд внутри контейнера во время сборки.
Для примера, посмотрим на код.
FROM ubuntu:20.04
RUN cd /app && mkdir logs
COPY . /app/
RUN cd /app && npm install
CMD cd /app && npm start
Почему же это плохо?
1. На каждый
RUN необходимо указывать контекст исполнения - cd /app &&.... Привет принципы DRY.2. В случае использвания других директив, наподобие COPY, необходимо будет прописать полный путь до нужной папки. То есть поведение остальных инструкций совсем не явная история.
3. Из предыдущих двух пунктов вытекает 3 - сопровождать такой Dockerfile неудобно от слова "горите в Оду, авторы этого чуда".
А вот, правильный вариант:
FROM ubuntu:20.04
WORKDIR /app
RUN mkdir logs
COPY . .
RUN npm install
CMD npm start
И чем это лучше?
1) Получаем постоянство контекста. Установив раз рабочую директорию в /app мы будем производить все действий только в ней, то тех пор пока не переназначим. А это минус cd /app в каждом блоке команд, да и самих таких блоков станет гораздо меньше.
2) Не нужны лишние RUN-ы чтобы создавать папку. Если папки нет, то
WORKDIR создает ее автоматически3) Такой код более читаемый и предсказуемый
4) Так мы можем использовать относительные пути для других дирректив файла
...
WORKDIR /app
COPY . ./subdir/
...
Так что, берите на заметку и ваши коллеги вам скажут спасибо👌🏻
А впереди у нас выходнульки, значит дружно ставим 🔥
🥷 Docker Ninja 🥷
🔥15
🆘 Спасите наши push-и 🆘
Представь:
Ты геройски настроил все, что хотел твой тимлид, на уже запущенном контейнере. Но тут, посреди бела дня у тебя вырубает электричество (ты конечно же сидишь на удаленке - понедельник же!!!).
И вот, интернета нет, комп отсчитывает последние 10 минут оставшиеся на бесперебойнике. Весь фронт работ отразить в Dockerfile или compose не успеешь, а хорошо бы было сохранить все каким-то образом и донести до офисного компа. И ты начинаешь тихо материться под нос...
Но погоди паниковать! У нас есть старый добрый
🎯 Как это работает:
Базовый синтаксис не замысловатый:
Или через перенаправление, как истинный пигвин из Мадагаскара🐧:
Хочешь сохранить сразу несколько образов? Не вопрос:
🤔 Шо та такое ты уже рассказывал!...
🔹О да! Давным давно, в посте про команду docker export, которая создает архив файловой системы контейнера. В отличие от него,
🔹Кстати, у
🔹А еще мы можем вспомнить docker commit, который вместо пушей, спасает наши нервы, путем сохранения всех изменений из работающего контейнера в образ.🤡
Теперь то ты точно сохранишь свои труды в целости! Поставь реакцию, если сразу захотел записать образ на дискету!
🥷 Docker Ninja 🥷
Представь:
Ты геройски настроил все, что хотел твой тимлид, на уже запущенном контейнере. Но тут, посреди бела дня у тебя вырубает электричество (ты конечно же сидишь на удаленке - понедельник же!!!).
И вот, интернета нет, комп отсчитывает последние 10 минут оставшиеся на бесперебойнике. Весь фронт работ отразить в Dockerfile или compose не успеешь, а хорошо бы было сохранить все каким-то образом и донести до офисного компа. И ты начинаешь тихо материться под нос...
Но погоди паниковать! У нас есть старый добрый
docker save - команда, которая упакует твой образ в tar-архив быстрее, чем ты скажешь "надо было читать канал Docker Ninja, там точно был ответ!".🎯 Как это работает:
Базовый синтаксис не замысловатый:
docker save -o nginx.tar nginx:latest
Или через перенаправление, как истинный пигвин из Мадагаскара🐧:
docker save nginx:latest > nginx.tar
Хочешь сохранить сразу несколько образов? Не вопрос:
docker save -o my_stack.tar nginx:latest postgres:13 redis:alpine
🤔 Шо та такое ты уже рассказывал!...
🔹О да! Давным давно, в посте про команду docker export, которая создает архив файловой системы контейнера. В отличие от него,
docker save сохраняет полный образ со всеми его слоями, метаданными и историей. Это как разница между копированием папки и созданием полноценной резервной копии диска.🔹Кстати, у
docker save есть команда антоним, как docker import для экспорта. Но это уже история для другого поста!🔹А еще мы можем вспомнить docker commit, который вместо пушей, спасает наши нервы, путем сохранения всех изменений из работающего контейнера в образ.🤡
Теперь то ты точно сохранишь свои труды в целости! Поставь реакцию, если сразу захотел записать образ на дискету!
🥷 Docker Ninja 🥷
1👍6🔥3
❓ Зачем оно вообще нужно!?❓
Понимаю возможно возникший у вас вопрос. Кому нафиг это может понадобиться. 21 век на дворе, а ты про архивы.
Но есть несколько щепетильных ситуаций...⬇️
Понимаю возможно возникший у вас вопрос. Кому нафиг это может понадобиться. 21 век на дворе, а ты про архивы.
Но есть несколько щепетильных ситуаций...⬇️
👍8
Ты работаешь с legacy приложением в контейнере. Необходимо создать backup всей файловой системы контейнера в tar-архив для миграции на другой сервер. Какую команду использовать?
Anonymous Quiz
29%
docker save container_name > backup.tar
44%
docker export container_name > backup.tar
12%
docker commit container_name backup_image
15%
docker cp container_name:/ backup.tar
🐶 На вайбах Хатико 🐶
На днях коллега спрашивает: "Слушай, как мне подключиться к контейнеру, который уже запущен?
Речь пойдет о
Базовый синтаксис прост как валенок:
Например, запустили контейнер в фоне:
И хоба! Ты видишь логи процесса в реальном времени, можешь взаимодействовать с основным процессом. Но фишка тут в том, что
🎯 Зачем это нужно?
1. Дебаг интерактивных приложений - основной процесс ждем, что ты ему введешь какие-то данные.
2. Работа с legacy-контейнерами - где нету встроенной терминальной оболочки
3. Мониторинг в реальном времени - например контейнер постоянно падает и через docker logs ты не успеваешь увидеть его логи
⚠️ Главная ловушка: нажал
Помни:
🥷 Docker Ninja 🥷
На днях коллега спрашивает: "Слушай, как мне подключиться к контейнеру, который уже запущен?
docker exec же только новые процессы создает!" И тут я понял - настало это время!!! Пора рассказать про команду, которая может как спасти твой день, так и безжалостно убить весь контейнер одним неосторожным Ctrl+C!Речь пойдет о
docker attach. Команде для подключения к основному процессу уже запущенного контейнера. Базовый синтаксис прост как валенок:
docker attach richard_gere:2009
Например, запустили контейнер в фоне:
docker run -d --name professor parker:wilson
docker attach professor
И хоба! Ты видишь логи процесса в реальном времени, можешь взаимодействовать с основным процессом. Но фишка тут в том, что
attach подключает тебя именно к процессу с PID 1 (тому самому, что указан в CMD/ENTRYPOINT), а не создает новую сессию как docker exec!🎯 Зачем это нужно?
1. Дебаг интерактивных приложений - основной процесс ждем, что ты ему введешь какие-то данные.
2. Работа с legacy-контейнерами - где нету встроенной терминальной оболочки
3. Мониторинг в реальном времени - например контейнер постоянно падает и через docker logs ты не успеваешь увидеть его логи
⚠️ Главная ловушка: нажал
Ctrl+C в attach-сессии = отправил SIGINT основному процессу! Это может его убить и завалить весь контейнер. Чтобы безопасно отключиться, используй Ctrl+P, Ctrl+Q.Помни:
attach = привязка к существующему процессу, exec = новый процесс. Выбирай с умом!🥷 Docker Ninja 🥷
👍6🔥4❤2
Ты создаешь Dockerfile для веб-приложения. Нужно скопировать конфигурационный файл config.json из локальной папки /configs в контейнер по пути /app/config.json. Какую директиву использовать правильнее всего?
Anonymous Quiz
9%
VOLUME /configs/config.json /app/config.json
11%
ADD /configs/config.json /app/config.json
8%
RUN cp /configs/config.json /app/config.json
72%
COPY /configs/config.json /app/config.json
👌4👍2
⏰ Жди меня, и я вернусь ⏰
Пятница, конец недели, мозги уже настроены на выходные, а тут еще и контейнеры какие-то надо один за другим запускать - один отработал, врубить другой и тд. А настроенице то такое, чтобы весь мир подождал до понедельника, а дальше это уже проблемы завтрашнего Гомера...
Кажется, товарищам из команды разработки докера ничто человеческое не чуждо. Именно поэтому (я просто уверен) была придумана команда, которая может терпеливо ждать завершения контейнера и даже скажет, с каким кодом он завершился?
Прошу любить и жаловать -
Основы использования:
Команда вернет exit code контейнера. 0 — все ОК, любое другое число — что-то пошло не так.
Зачем это нужно?
🔹В скриптах автоматизации часто нужно дождаться завершения одного контейнера перед запуском следующего. Представь: у тебя есть контейнер с миграциями БД, и только после их успешного завершения можно поднимать основное приложение.
🔹Тестовые пайплайны в CI/CD: запускается контейнер с тестами, а скрипт с помощью docker wait ожидает его завершения, чтобы по коду возврата определить, упали тесты или прошли успешно, и принять решение о продвижении сборки.
🔹Оркестрация зависимых сервисов: когда нужно гарантировать, что контейнер-инициатор какой-либо задачи (например, обработки данных) завершил работу, прежде чем запускать контейнер-потребитель результатов.
Помнишь наш пост про docker kill? Так вот,
Команда работает только с запущенными контейнерами. Если контейнер уже завершился,
Простая команда, а сколько пользы для автоматизации! 🚀
🥷 Docker Ninja 🥷
Пятница, конец недели, мозги уже настроены на выходные, а тут еще и контейнеры какие-то надо один за другим запускать - один отработал, врубить другой и тд. А настроенице то такое, чтобы весь мир подождал до понедельника, а дальше это уже проблемы завтрашнего Гомера...
Кажется, товарищам из команды разработки докера ничто человеческое не чуждо. Именно поэтому (я просто уверен) была придумана команда, которая может терпеливо ждать завершения контейнера и даже скажет, с каким кодом он завершился?
Прошу любить и жаловать -
docker wait. Простая, но очень полезная команда для тех, кто любит порядок в своих скриптах! 🎯Основы использования:
# Ждем завершения одного контейнера
docker wait my_container
# Ждем несколько контейнеров сразу
docker wait container1 container2 container3
Команда вернет exit code контейнера. 0 — все ОК, любое другое число — что-то пошло не так.
Зачем это нужно?
🔹В скриптах автоматизации часто нужно дождаться завершения одного контейнера перед запуском следующего. Представь: у тебя есть контейнер с миграциями БД, и только после их успешного завершения можно поднимать основное приложение.
🔹Тестовые пайплайны в CI/CD: запускается контейнер с тестами, а скрипт с помощью docker wait ожидает его завершения, чтобы по коду возврата определить, упали тесты или прошли успешно, и принять решение о продвижении сборки.
🔹Оркестрация зависимых сервисов: когда нужно гарантировать, что контейнер-инициатор какой-либо задачи (например, обработки данных) завершил работу, прежде чем запускать контейнер-потребитель результатов.
Помнишь наш пост про docker kill? Так вот,
wait — его полная противоположность. Вместо принудительной остановки мы терпеливо ждем естественного завершения 🧘Команда работает только с запущенными контейнерами. Если контейнер уже завершился,
wait моментально вернет его последний exit code. Простая команда, а сколько пользы для автоматизации! 🚀
🥷 Docker Ninja 🥷
🔥6👍2
🚦 Зависимые отношения 🚦
Ты пушишь в прод свежий
На такой случай имеем директиву
Базовый пример:
Польза данной диррективы в том, она гарантирует порядок запуска: сначала поднимутся db и redis, потом уже web.
Теперь веб дождется, когда контейнер базы стартанет и начнет стартовать! 🎯
Но есть нюанс — это НЕ означает, что PostgreSQL будет готов принимать коннекты! Как решать такие проблемы, разберем в следующих постах.
Зачем юзать?
🔹 Избегаешь race conditions между сервисами на уровне инфраструктуры
🔹 Контролируешь сложные зависимости (API → DB → Cache)
🔹 Спасаешься от факапов с "недоступной базой"
Ставь 🔥 если тоже страдал от преждевременных стартов!
🥷 Docker Ninja 🥷
Ты пушишь в прод свежий
docker-compose up -d, а через секунду получаешь unhealthy статус и сообщение в логах: "Connection to database failed". Вот это поворот... Твое веб-приложение стартануло быстрее PostgreSQL и упало так и не дождавшись готовности базы. Как бы сказал великий классик: "Ha, ha, classic"! Уж простите за тафтологию.На такой случай имеем директиву
depends_on!Базовый пример:
services:
web:
image: nginx
depends_on:
- db
- redis
db:
image: postgres:15
redis:
image: redis:alpine
Польза данной диррективы в том, она гарантирует порядок запуска: сначала поднимутся db и redis, потом уже web.
Теперь веб дождется, когда контейнер базы стартанет и начнет стартовать! 🎯
Но есть нюанс — это НЕ означает, что PostgreSQL будет готов принимать коннекты! Как решать такие проблемы, разберем в следующих постах.
Зачем юзать?
🔹 Избегаешь race conditions между сервисами на уровне инфраструктуры
🔹 Контролируешь сложные зависимости (API → DB → Cache)
🔹 Спасаешься от факапов с "недоступной базой"
Ставь 🔥 если тоже страдал от преждевременных стартов!
🥷 Docker Ninja 🥷
👍9🔥4
👴🏼Тряхнем стариной👴🏼
Если говорить честно, то механизм depends_on существовал не всегда, но и у него были альтернативы.
Узнать, что за механизм и зачем тебе о нем знать, ты можешь нажав на кнопку ниже⬇️
Если говорить честно, то механизм depends_on существовал не всегда, но и у него были альтернативы.
Узнать, что за механизм и зачем тебе о нем знать, ты можешь нажав на кнопку ниже⬇️
🔥9
В чем основное отличие виртуализации от контейнеризации с точки зрения архитектуры?
Anonymous Quiz
20%
Виртуальные машины имеют лучшую изоляцию процессов
2%
Контейнеры потребляют больше ресурсов, чем виртуальные машины
1%
Виртуальные машины быстрее запускаются, чем контейнеры
76%
Контейнеры используют общее ядро ОС, виртуальные машины - отдельные ядра
👍3🤔2👎1🤡1
📚 Все дороги ведут в Registry 📚
Помнишь старые времена, когда образы передавали флешками и ссылками на Dropbox? Не помнишь?! И правильно, потому что никогда такого не было! Все потому, что разработчики docker придумали Docker Registry, который стал центральной нервной системой контейнерной вселенной. Но что он из себя представляет под капотом?
🔹Registry - это библиотека образов с блек джеком и прочими прелестями!
Если коротко, то Docker Registry - это специализированное веб-приложение (REST API), которое управляет хранением и распределением Docker-образов по определенному стандарту (OCI Distribution Spec). Это не просто файловое хранилище вроде S3 или FTP, а интеллектуальная система, которая понимает все нюансы Docker-образов.
🔹Архитектура: слоеный пирог
Фишка Registry в том, что образы хранятся не целиком, а слоями! Каждый слой - это дифф изменений файловой системы. Когда несколько образов используют одинаковую базу (например, Ubuntu), Registry умно дедуплицирует слои. Один слой - много ссылок. Экономия дискового пространства на лицо!
🔹Push/Pull
При пуше Docker разбивает образ на слои, хеширует их и отправляет только новые в виде tar.gz архива. При пулле скачиваются только недостающие слои в том же виде и собираются обратно в образ. Магия дедупликации работает и тут - если у тебя уже есть слой с nginx:alpine, он не будет скачиваться повторно для другого образа!
🔹Теги и версионирование
Система тегов - это не Git, это проще! Один и тот же по составу образ может иметь множество тегов, которые просто указывают на один манифест. Тег
🔹Манифест:
Каждый образ содержит "инструкция по сборке" - манифест. Изнутри это JSON-файл, который содержит метаданные — список всех слоев, их хеши, размер, а также конфигурацию контейнера (например, переменные окружения, точку входа)
Когда ты делаешь docker pull, Docker сначала загружает манифест, а затем по списку в нем скачивает необходимые слои.
🔹Приватные vs публичные
Docker Hub удобен для открытых проектов, но для продакшена лучше приватный registry. Harbor, AWS ECR, Azure Container Registry - все они работают по одному API, но дают контроль над безопасностью и retention policies.
Понимание Registry - это понимание того, как живет весь Docker-экосистем!
Жми реакт, если Registry больше не кажется черной магией!
🥷 Docker Ninja 🥷
Помнишь старые времена, когда образы передавали флешками и ссылками на Dropbox? Не помнишь?! И правильно, потому что никогда такого не было! Все потому, что разработчики docker придумали Docker Registry, который стал центральной нервной системой контейнерной вселенной. Но что он из себя представляет под капотом?
🔹Registry - это библиотека образов с блек джеком и прочими прелестями!
Если коротко, то Docker Registry - это специализированное веб-приложение (REST API), которое управляет хранением и распределением Docker-образов по определенному стандарту (OCI Distribution Spec). Это не просто файловое хранилище вроде S3 или FTP, а интеллектуальная система, которая понимает все нюансы Docker-образов.
🔹Архитектура: слоеный пирог
Фишка Registry в том, что образы хранятся не целиком, а слоями! Каждый слой - это дифф изменений файловой системы. Когда несколько образов используют одинаковую базу (например, Ubuntu), Registry умно дедуплицирует слои. Один слой - много ссылок. Экономия дискового пространства на лицо!
🔹Push/Pull
При пуше Docker разбивает образ на слои, хеширует их и отправляет только новые в виде tar.gz архива. При пулле скачиваются только недостающие слои в том же виде и собираются обратно в образ. Магия дедупликации работает и тут - если у тебя уже есть слой с nginx:alpine, он не будет скачиваться повторно для другого образа!
🔹Теги и версионирование
Система тегов - это не Git, это проще! Один и тот же по составу образ может иметь множество тегов, которые просто указывают на один манифест. Тег
latest не последняя версия, а просто алиас, который может указывать на что угодно.🔹Манифест:
Каждый образ содержит "инструкция по сборке" - манифест. Изнутри это JSON-файл, который содержит метаданные — список всех слоев, их хеши, размер, а также конфигурацию контейнера (например, переменные окружения, точку входа)
Когда ты делаешь docker pull, Docker сначала загружает манифест, а затем по списку в нем скачивает необходимые слои.
🔹Приватные vs публичные
Docker Hub удобен для открытых проектов, но для продакшена лучше приватный registry. Harbor, AWS ECR, Azure Container Registry - все они работают по одному API, но дают контроль над безопасностью и retention policies.
Понимание Registry - это понимание того, как живет весь Docker-экосистем!
Жми реакт, если Registry больше не кажется черной магией!
🥷 Docker Ninja 🥷
👍8❤3
Ты создал контейнер с веб-приложением и хочешь скопировать лог-файл из контейнера на хост для анализа. Какая команда позволит это сделать?
Anonymous Quiz
31%
docker copy container_name:/app/logs/app.log ./app.log
3%
docker transfer container_name:/app/logs/app.log ./app.log
64%
docker cp container_name:/app/logs/app.log ./app.log
1%
docker move container_name:/app/logs/app.log ./app.log
👍5🔥3😱1