Docker Ninja – Telegram
Docker Ninja
1.05K subscribers
30 photos
91 links
По всем вопросам обращаться к @nesudimov_eu
Download Telegram
⁉️ А как же два стула ⁉️

Хочу напомнить вам про загадку двух стульев, а если точнее, то что конкретно будет удалять команда озвученная выше?
👍4👏1
🦫 Залетаем в топ с левой пятки 🦫

Сидим с бобром за компом, к релизу готовим контейнер с nginx-ом.


Как помним, контейнеры изолируют приложения, и каждый контейнер функционирует как отдельный процесс. Но внутри контейнера может запускаться множество разных процессов. И как тогда это работает??

В случае с Nginx, например, это означает, что внутри контейнера будет основной (master) процесс и один или несколько дочерних (worker) процессов. И тут очень важно убедиться, что все worker-ы веб-сервера работают корректно, а иначе плакаль ваш хайлоуд крипто-стартап крокодьими слезками😭

docker top позволяет вам следить за всей этой процессной кухней: убедиться, что они запущены и функционируют без сбоев.

Начнем с базового использования.
# Пускаем контейнер
docker run -d --name my_container nginx

# Смотрим, какие процессы запущены внутри контейнера
docker top my_container


Пример вывода команды:
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root 12345 12344 0 00:00 ? 00:00:00 nginx: master process nginx -g daemon off;
101 12346 12345 0 00:00 ? 00:00:00 nginx: worker process


Видим тут PID и PPID, шо значит process id и parent process id. Проверяем: root, в виде nginx-master, у нас родитель для nginx-worker.

Прочитал? Тогда поставь 🔥 за тех, кто не знал про команду и остался курвой после факапа в пятничный релиз!

🥷 Docker Ninja 🥷
🔥20👍3
⚠️ Коллеги, ATTENTION PLEASE ⚠️

Вчера ловил жуткие отходняки от магнитных дурей🤯

Так что ловите сердечную сорямбу за пропущенный пост🫶🏻

И викторину для трениров-очки🕶

👇🏻👇👇🏿
15
Твое приложение должно работать на нескольких хостах и требует высокую производительность работы в сети, но так же важно сохранить сетевую изоляцию между контейнерами на одном сервере. Какой тип сетевого драйвера Docker выберешь?
Anonymous Quiz
39%
Bridge 🛠
10%
Host 🌍
35%
Overlay 🕸
16%
Macvlan 🔌
👍6🔥2🤔2
😈 Понедельник - день суровый 😈

Как говорил, классик, "Опять работа...". Увы и ах, а, может быть, для кого-то и ура, но впереди у нас еще 5 рабочих дней! И поэтому, чтобы жизнь совсем перестала казаться медом, сегодня погутарим опять за сети. А точнее, подумаем над вопросом, почему же, если контейнер это процесс, то его порты не конфликтуют с портами хоста?

Повторюсь в очередной раз, контейнеры в Docker, хотя и являются процессами на хостовой системе, изолированы с помощью пространства имён (namespaces) и cgroups. Это изоляция позволяет контейнерам иметь свои собственные сетевые стеки, включая независимый пул портов.

В результате имеем:

1. Сетевые namespaces:
Каждый контейнер работает в своём собственном сетевом пространстве имён. Это означает, что он имеет свой собственный сетевой интерфейс и стек, который изолирован от хостовой сети и других контейнеров. Благодаря этому порты, используемые в контейнере, не конфликтуют с портами хоста.

2. Проброс портов (Port Binding):
Чтобы контейнер был доступен извне, нужно явно настроить проброс портов с хоста в контейнер. В docker это делается с помощью флага -p, но мы то с вами знаем, что изнутри там ковыряются в политиках iptables. Именно через iptables, в том числе, настраиваются и пробросы портов сквозь разные сетевые неймспейсы.

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

Как-то так. А мы дружно ставим 🍾 за тех, кто сегодня не на удаленке!

🥷 Docker Ninja 🥷
🍾14👍6
🫠 Работаю над ошибками. Следующая будет фатальная! 🫠

Docker compose простой и очень понятный инструмент, но не смотря на его простоту, даже тут в процессе разработки часто возникают различные проблемы. Ошибки в файле docker-compose.yml, скорее всего ничего не сломают, но могут привести к неожиданным возгораниям в области соприкосновения вас со стулом🍑. Поэтому, имеем все нарастающую необходимость проверить корректность compose файла. Это особенно важно, когда работаешь над сложными проектами с множеством сервисов и зависимостей.

Для этого используйте команду:
# Находясь в контексте compose проекта
docker compose config

# Или принудительно указывая путь до файла
docker compose config -f /home/user/docker-compose.yml


Эта команда проверит наш docker-compose.yml на наличие ошибок и выведет итоговую конфигурацию с учётом всех переменных и параметров. И последняя фича, кстати, очень удобна, когда надо прокинуть какие-то данные через .env и затем проверить, что все хорошо подставляется. Если в конфигурации имеются ошибки, мы получим сообщение об ошибке, что позволит вам их оперативно исправить.


🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
2👍142
Ты обнаружил, что на продовом хосте не хватает CPU, из-за чего система работает медленно. Один из контейнеров вызывает подозрения. Как ты поступишь, чтобы оптимально разобраться с проблемой, не потеряв данные и состояние приложения?
Anonymous Quiz
80%
docker compose pause <service_name>, чтобы заморозить контейнер, и изучу логи.
4%
Обновлю все контейнеры до последних версий, чтобы обновления исправили проблему с CPU.
11%
Удалю. подозрительный контейнер и пересоздам его с нуля, чтобы избавиться от возможных ошибок.
5%
Перезапущу весь сервер, чтобы освободить ресурсы и быстро устранить проблему.
👍61
🎮 Первому игроку приготовиться 🎮

Четверг, иной раз, выдаётся даже похуже понедельника. Поэтому любая автоматизация рутины для нас в такие деньки, как глоток воздуха!

Один из таких способов не делать лишних движений - команда docker init.


docker init инициализирует docker проект со всеми необходимыми для запуска контейнера файлами, да ещё может делать это из специальных шаблонов под конкретный язык 😝

Находясь в папке с нашим проектом запускаем:
docker init

Welcome to the Docker Init CLI!

This utility will walk you through creating the following files with sensible defaults for your project:
- .dockerignore
- Dockerfile
- compose.yaml
- README.Docker.md

Let's get started!

? What application platform does your project use? [Use arrows to move, type to filter]
PHP with Apache - (detected) suitable for a PHP web application
Go - suitable for a Go server application
Java - suitable for a Java application that uses Maven and packages as an uber jar
Python - suitable for a Python server application
Node - suitable for a Node server application
Rust - suitable for a Rust server application
ASP.NET Core - suitable for an ASP.NET Core application
Other - general purpose starting point for containerizing your application
Don't see something you need? Let us know!
Quit

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

После её запуска в папке с проектом обнаружим следующие файлы:
- .dockerignore
- Dockerfile
- compose.yaml
- README.Docker.md

Если какой-то из указанных файлов уже имеется в папке (или в случае с compose, там будет docker-compose.yml) то команда спросит надо ли перезаписать существующий файл.

Лёгким движением руки экономим себе драгоценные минуты на более полезные задачи 🪄


🥷 Docker Ninja 🥷
1👍10🔥1
💰 No cash, no trash 🗑

Сегодня поговорим о флаге --no-cache в команде docker build. Этот флаг незаменим, когда необходимо гарантировать, что все шаги сборки выполняются с нуля, игнорируя кэш.

А начерта нам игнорить кэш, когда у него сплошные плюсы? - спросите вы и будете правы. Но, лишь от части.

Самый базированный кейс для этого флага, это сборка образа через CI систему. Например, если мы в своем dockerfile указали тэг для базового образа latest, то всегда держим в уме, что тэг это всего-то строка, которая не всегда отражает реальную версию образа. И, чтобы гарантировать, что при сборке у нас будет использован наисвежайший свежак, мы ставим флаг —no-cache

Пример использования команды:
docker build --no-cache -t my_app_image:latest .



🥷 Docker Ninja 🥷
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
📌 Раздаём ярлыки 📌


Мы как devops-ы работаем свою работу во славу станадартизации, автоматизации и улучшения рабочей культуры. Про первое и второе постов хоть отбавляй, а вот с последним мы еще ничего не рассматривали. Так что сегодня у нас будет пост про директиву LABEL в Dockerfile.

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

Пример использования директивы LABEL:
# Базовый образ
FROM ubuntu:20.04

# Добавляем метаданные
LABEL maintainer="Senpai <senpai@devops.com>"
LABEL version="1.0"
LABEL denoscription="Это образ для веб-приложения на базе Ubuntu 20.04"

# Установка необходимых пакетов
RUN apt-get update && apt-get install -y nginx

# Копируем файл конфигурации
COPY nginx.conf /etc/nginx/nginx.conf

# Запускаем Nginx
CMD ["nginx", "-g", "daemon off;"]


Теперь ваш образ содержит метаданные, которые помогут быстро понять его назначение и версию/ А так же, вы теперь знаете кому дать в лоб за косяки в образе😈


🥷 Docker Ninja 🥷
1👍15🔥1
🔮Видишь терминал? А его нет 🔮

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

Сегодня же у нас на повестке флаг --tty (-t) . И польза его в том, что он прокидывает так называемый pseudo-tty в контейнер (о том, что это такое мы поговорим попозже), что дает нам возможность лицезреть терминал в контейнере.

docker run -it nginx /bin/bash


Этот самый режим есть как для команды run, так и для exec:
docker exec -it my_container /bin/bash


Как видим, флаг -t используется у нас в связке с -i. И, если последний и возможно хоть как-то применить в одиночку, то вот -t без интерактивного режима ничем нам не поможет. А все потому, что для работы с терминалом нам, как ни крути, нужен доступный stdin. Без него мы просто не сможем ничего написать в терминале.

Так что запоминаем как "Отче наш": нужен терминал, смело ставь -it!

🥷 Docker Ninja 🥷
👌6👍3
Ты готовишь контейнер с Nginx к релизу и хочешь убедиться, что все процессы внутри контейнера работают корректно. Какая команда поможет тебе быстро увидеть список процессов и их идентификаторы внутри запущенного контейнера?
Anonymous Quiz
23%
docker inspect my_container
21%
docker top my_container
43%
docker exec my_container ps aux
12%
docker ps -a
👍6👎3🔥1👏1
🐳 Гнездо кита 🐳

Как все мы с вами помним, 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
⚖️ Вокруг одна политика 📜

Все мы знаем как запускать контейнеры и перезапускать их вручную, но не менее важно иметь возможность перезапускать их автоматически. То есть полезно было бы иметь возможность настраивать какие-то политики перезапуска контейнеров в случае их падения. И тут нам поможет флаг —-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 на хосте!

И тут на помощь приходит флаг --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
Please open Telegram to view this post
VIEW IN TELEGRAM
🤞 Last hope 🤞

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

Но тут залетает PO и говорит, что какой-то умник ломает наше приложение. Id сессии можно увидеть лишь только в логах.

- Отлично, - думаешь ты, - сейчас глянем вывод docker logs. Если только...
Да, именно так - любимый коллега забыл прокинуть логирование в stdout.

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

А вот и нет! В базовом образе контейнера не завезли оболочку. Да, и такое бывает - оптимизация, мать ее за ногу!
И вот, ты уже совсем поник и не знаешь что делать, как вдруг О великий и могучий чатгпт stackoverflow рассказывает нам про команду 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 🥷
👍172
Новый разработчки вручную настроил рабочую среду внутри контейнера и хочет сохранить все изменения в новый образ. Какая команда поможет создать образ из текущего состояния запущенного контейнера?
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