Существует популярный маркетплейс готовых приложений на базе Docker или образов виртуальных машин Bitnami. Это довольно известный сервис для тех, кто пользуется западными облачными провайдерами. Bitnami их партнёр и продаёт по подписке возможность работы со своими образами напрямую через сервисы провайдеров.
А все остальные могут совершенно бесплатно и свободно использовать их в своей работе, разворачивая в ручном режиме. Сразу возникает вопрос, а зачем это нужно? Всё просто. Bitnami берёт популярные наборы софта, пакует их в образы и поддерживает. То есть максимально быстро выпускает обновлённые версии образов.
Docker контейнеры Bitnami собраны на базе Debian. То есть это не кастратики по типу distroless, а более ли менее типовые контейнеры. Также они партнёры Docker, контейнеры подписаны доверенными цифровыми подписями. Докерфайлы всех контейнеров есть на github. То есть это контейнеры, которым можно доверять и использовать в продакшене.
Помимо контейнеров, есть готовые образы виртуальных машин в формате .ova для VirtualBox. Без проблем конвертируется в qcow2 или lvm с помощью qemu-img для запуска в Proxmox.
В каталоге много популярного софта. Так что если надо что-то посмотреть или потестировать, то можно смело брать и смотреть. В прод уже на своё усмотрение.
⇨ Сайт / Контейнеры / Виртуальные машины
#docker #devops
А все остальные могут совершенно бесплатно и свободно использовать их в своей работе, разворачивая в ручном режиме. Сразу возникает вопрос, а зачем это нужно? Всё просто. Bitnami берёт популярные наборы софта, пакует их в образы и поддерживает. То есть максимально быстро выпускает обновлённые версии образов.
Docker контейнеры Bitnami собраны на базе Debian. То есть это не кастратики по типу distroless, а более ли менее типовые контейнеры. Также они партнёры Docker, контейнеры подписаны доверенными цифровыми подписями. Докерфайлы всех контейнеров есть на github. То есть это контейнеры, которым можно доверять и использовать в продакшене.
Помимо контейнеров, есть готовые образы виртуальных машин в формате .ova для VirtualBox. Без проблем конвертируется в qcow2 или lvm с помощью qemu-img для запуска в Proxmox.
В каталоге много популярного софта. Так что если надо что-то посмотреть или потестировать, то можно смело брать и смотреть. В прод уже на своё усмотрение.
⇨ Сайт / Контейнеры / Виртуальные машины
#docker #devops
На днях в рассылке увидел любопытный инструмент, на который сразу обратил внимание. Название простое и неприметное — Task. Это утилита, написанная на Gо, которая умеет запускать задачи на основе конфигурации в формате yaml. Сейчас сразу на примерах покажу, как это работает, чтобы было понятно, для чего может быть нужно.
Сама программа это просто одиночный бинарник, который можно установить кучей способов, описанных в документации. Его даже в винде можно установить через winget.
Создаём файл с задачами Taskfile.yml:
Сохраняем и запускаем. Для начала посмотрим список задач:
Запустим первую задачу:
Или сразу обе, запустив task без параметров. Запустится задача default, которую мы описали в самом начале:
Идею, думаю, вы поняли. Это более простая и лёгкая в освоении замена утилиты make, которая используется в основном для сбора софта из исходников.
Первое, что приходит в голову, где утилита task может быть полезна, помимо непосредственно сборки из исходников, как замена make — сборка docker образов. Если у вас длинный RUN, который неудобно читать, поддерживать и отлаживать из-за его размера, то его можно заменить одной задачей с task. Это позволит упростить написание и поддержку, а также избавить от необходимости разбивать этот RUN на несколько частей, что порождает создание дополнительных слоёв.
Вместо того, чтобы описывать все свои действия в длиннющем RUN, оформите все свои шаги через task и запустите в RUN только его. Примерно так:
Скопировали бинарник + yaml с задачами и запустили их. А там они могут быть красиво оформлены по шагам. Писать и отлаживать эти задачи будет проще, чем сразу в Dockerfile. Для task написано расширение в Visual Studio Code.
Task поддерживает:
◽переходы по директориям
◽зависимости задач
◽импорт в Taskfile из другого Taskfile
◽динамические переменные
◽особенности OS, можно явно указать Taskfile_linux.yml или Taskfile_windows.yml
и многое другое. Всё это описано в документации.
Я немного поразбирался с Task. Он мне показался более простой заменой одиночных сценариев для ansible. Это когда вам не нужен полноценный playbook, а достаточно простого набора команд в едином файле, чтобы быстро его запустить и выполнить небольшой набор действий. Только в Task нет никаких модулей, только cmds.
#devops #script #docker
Сама программа это просто одиночный бинарник, который можно установить кучей способов, описанных в документации. Его даже в винде можно установить через winget.
Создаём файл с задачами Taskfile.yml:
version: "3"
tasks:
default:
desc: Run all tasks
cmds:
- task: task01
- task: task02
task01:
desc: Task 01
cmds:
- echo "Task 01"
task02:
desc: Task 02
cmds:
- echo "Task 02"
Сохраняем и запускаем. Для начала посмотрим список задач:
# task --list
task: Available tasks for this project:
* default: Run all tasks
* task01: Task 01
* task02: Task 02
Запустим первую задачу:
# task task01
task: [task01] echo "Task 01"
Или сразу обе, запустив task без параметров. Запустится задача default, которую мы описали в самом начале:
# task
task: [task01] echo "Task 01"
Task 01
task: [task02] echo "Task 02"
Task 02
Идею, думаю, вы поняли. Это более простая и лёгкая в освоении замена утилиты make, которая используется в основном для сбора софта из исходников.
Первое, что приходит в голову, где утилита task может быть полезна, помимо непосредственно сборки из исходников, как замена make — сборка docker образов. Если у вас длинный RUN, который неудобно читать, поддерживать и отлаживать из-за его размера, то его можно заменить одной задачей с task. Это позволит упростить написание и поддержку, а также избавить от необходимости разбивать этот RUN на несколько частей, что порождает создание дополнительных слоёв.
Вместо того, чтобы описывать все свои действия в длиннющем RUN, оформите все свои шаги через task и запустите в RUN только его. Примерно так:
COPY --from=bins /usr/bin/task /usr/local/bin/task
COPY tasks/Taskfile.yaml ./Taskfile.yaml
RUN task
Скопировали бинарник + yaml с задачами и запустили их. А там они могут быть красиво оформлены по шагам. Писать и отлаживать эти задачи будет проще, чем сразу в Dockerfile. Для task написано расширение в Visual Studio Code.
Task поддерживает:
◽переходы по директориям
◽зависимости задач
◽импорт в Taskfile из другого Taskfile
◽динамические переменные
◽особенности OS, можно явно указать Taskfile_linux.yml или Taskfile_windows.yml
и многое другое. Всё это описано в документации.
Я немного поразбирался с Task. Он мне показался более простой заменой одиночных сценариев для ansible. Это когда вам не нужен полноценный playbook, а достаточно простого набора команд в едином файле, чтобы быстро его запустить и выполнить небольшой набор действий. Только в Task нет никаких модулей, только cmds.
#devops #script #docker
Если вам приходится самому писать Dockerfiles для сборки образов, то рекомендую удобный и функциональный линтер для проверки синтаксиса и общих рекомендаций по оптимизации — Hadolint (Haskell Dockerfile Linter). Он проверяет Dockerfile на предмет использования общепринятых best practice, а shell код в
Hadolint можно использовать как локально, так и с помощью веб сервиса. Работает он чётко, все рекомендации по делу. Покажу несколько примеров. Простенький Dockerfile:
Казалось бы, что тут может быть не так. Проверяем рекомендации hadolint:
-:6 DL3007 warning: Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
-:7 DL3018 warning: Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
Вполне резонные замечания. Он не рекомендует использовать тэг latest и советует явно указывать версию софта в пакетном менеджере. В данном случае это скорее всего не критично. Но в общем случае за этим стоит следить, особенно за latest. Это разом может всё сломать в самый неподходящий момент.
Ещё небольшой пример:
Проверяем:
-:2 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
-:2 DL3009 info: Delete the apt-get lists after installing something
-:2 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`
Здесь та же рекомендация — указывать конкретную версию в установке пакетов. Дальше рекомендация подчистить за работой apt-get. Речь тут скорее всего про что-то типа в самом конце:
Ну и последняя рекомендация добавить ключ
То есть hadolint рекомендует привести
Как видите, все рекомендации адекватные, хотя каких-то явных ошибок тут нет.
#devops #docker
RUN
с помощью рекомендаций ShellCheck.Hadolint можно использовать как локально, так и с помощью веб сервиса. Работает он чётко, все рекомендации по делу. Покажу несколько примеров. Простенький Dockerfile:
FROM golang:1.7.3 AS build
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=build /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
Казалось бы, что тут может быть не так. Проверяем рекомендации hadolint:
# docker run --rm -i hadolint/hadolint < Dockerfile
-:6 DL3007 warning: Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
-:7 DL3018 warning: Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
Вполне резонные замечания. Он не рекомендует использовать тэг latest и советует явно указывать версию софта в пакетном менеджере. В данном случае это скорее всего не критично. Но в общем случае за этим стоит следить, особенно за latest. Это разом может всё сломать в самый неподходящий момент.
Ещё небольшой пример:
FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
Проверяем:
# docker run --rm -i hadolint/hadolint < Dockerfile
-:2 DL3008 warning: Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
-:2 DL3009 info: Delete the apt-get lists after installing something
-:2 DL3015 info: Avoid additional packages by specifying `--no-install-recommends`
Здесь та же рекомендация — указывать конкретную версию в установке пакетов. Дальше рекомендация подчистить за работой apt-get. Речь тут скорее всего про что-то типа в самом конце:
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
Ну и последняя рекомендация добавить ключ
--no-install-recommends
в apt-get, что тоже не лишено смысла. То есть hadolint рекомендует привести
RUN
к следующему виду:RUN apt-get update && \
apt-get install -y --force-yes --no-install-recommends apache2=2.4 \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
Как видите, все рекомендации адекватные, хотя каких-то явных ошибок тут нет.
#devops #docker
Разбираю ещё один документ от CIS с рекомендациями по настройке Docker. Напомню, что ранее я уже делал выжимки по настройке Nginx, MySQL, Apache, Debian 11. Используя эти руководства нелишним будет освежить свои инструкции и принять некоторую информацию к сведению.
📌 Директорию для информации
📌 У Docker высокие полномочия для доступа к хостовой системе. Следите за тем, чтобы в системной группе docker не было лишних пользователей.
📌 Для повышения безопасности рекомендуется настроить аудит службы docker, например с помощью auditd. Ставим службу:
Добавляем правило в
Перезапускаем службу:
Для повышенной безопасности можно настроить аудит и за файлами и директориями Docker, за конфигурационными файлами, за юнитом systemd, за сокетом. Это общая рекомендация для служб, которые работают с правами root.
📌 Разделяйте контейнеры по отдельным сетям для межконтейнерного взаимодействия. Если этого не делать, они будут взаимодействовать через общий системный бридж, который docker создаёт по умолчанию.
📌 Включите уровень логирования службы "info", добавив в файл конфигурации
Для повышения безопасности логи имеет смысл хранить где-то во вне. Их можно направить по syslog. Пример:
📌 Если используете подключение к службе Docker по TCP, не забудьте настроить аутентификацию по TLS и ограничьте сетевой доступ.
📌 Используйте параметр no-new-privileges при создании контейнеров, либо добавьте этот параметр в настройку службы по умолчанию.
Это предотвратит повышение привилегий в контейнере от пользователя до root. Подробнее тут.
📌 Включите параметр live-restore:
Это позволит не останавливать контейнеры в случае остановки самой службы docker, что позволит обновлять её без остановки сервисов. По умолчанию он отключен.
📌 Отключите использование userland-proxy.
В подавляющем большинстве случаев для проброса портов в контейнеры используется NAT. Отключение прокси уменьшает вектор атак.
📌 Чаще всего файл с настройками
📌 Не используйте без крайней необходимости в контейнерах пользователя root. Хорошая практика запускать всё от обычного пользователя.
📌 Ограничивайте использование памяти контейнерами так, чтобы они не могли использовать всю доступную память хоста. Для этого запускайте их с параметром
📌 Ограничивайте количество попыток перезапуска контейнера в случае ошибок. То есть не запускайте их с параметром
Было много советов по написанию DockerFile. Не стал их разбирать, так как мне кажется, это отдельная тема, которая к самой службе не имеет отношения. Также было много советов по запуску контейнеров. Например, не запускать там службу sshd, не монтировать системные директории и т.д. Это тоже отдельная тема, пропускал такие рекомендации.
К данной заметке будет актуальна ссылка на автоматическую проверку контейнеров с помощью Trivy и исправление с помощью Copacetic. Я написал небольшую статью:
⇨ Проверка безопасности Docker образов с помощью Trivy
Данный список составил на основе переработки вот этого документа: CIS Docker Benchmark v1.5.0 - 12-28-2022. Там подробное описание с обоснованием всех рекомендаций.
#cis #docker
📌 Директорию для информации
/var/lib/docker
рекомендуется вынести на отдельный раздел. Docker постоянно потребляет свободное место, так что переполнение раздела нередкое явление. 📌 У Docker высокие полномочия для доступа к хостовой системе. Следите за тем, чтобы в системной группе docker не было лишних пользователей.
📌 Для повышения безопасности рекомендуется настроить аудит службы docker, например с помощью auditd. Ставим службу:
# apt install auditd
Добавляем правило в
/etc/audit/rules.d/audit.rules
:-w /usr/bin/dockerd -k docker
Перезапускаем службу:
# systemctl restart auditd
Для повышенной безопасности можно настроить аудит и за файлами и директориями Docker, за конфигурационными файлами, за юнитом systemd, за сокетом. Это общая рекомендация для служб, которые работают с правами root.
📌 Разделяйте контейнеры по отдельным сетям для межконтейнерного взаимодействия. Если этого не делать, они будут взаимодействовать через общий системный бридж, который docker создаёт по умолчанию.
📌 Включите уровень логирования службы "info", добавив в файл конфигурации
/etc/docker/daemon.json
параметр:"log-level": "info"
Для повышения безопасности логи имеет смысл хранить где-то во вне. Их можно направить по syslog. Пример:
{
"log-driver": "syslog",
"log-opts": {
"syslog-address": "tcp://192.xxx.xxx.xxx"
}
}
📌 Если используете подключение к службе Docker по TCP, не забудьте настроить аутентификацию по TLS и ограничьте сетевой доступ.
📌 Используйте параметр no-new-privileges при создании контейнеров, либо добавьте этот параметр в настройку службы по умолчанию.
"no-new-privileges": true
Это предотвратит повышение привилегий в контейнере от пользователя до root. Подробнее тут.
📌 Включите параметр live-restore:
"live-restore": true
Это позволит не останавливать контейнеры в случае остановки самой службы docker, что позволит обновлять её без остановки сервисов. По умолчанию он отключен.
📌 Отключите использование userland-proxy.
"userland-proxy": false
В подавляющем большинстве случаев для проброса портов в контейнеры используется NAT. Отключение прокси уменьшает вектор атак.
📌 Чаще всего файл с настройками
/etc/docker/daemon.json
по умолчанию отсутствует и вы его создаёте сами, когда нужно задать те или иные параметры. Проследите, чтобы доступ на запись к нему имел только root (root:root 644). 📌 Не используйте без крайней необходимости в контейнерах пользователя root. Хорошая практика запускать всё от обычного пользователя.
📌 Ограничивайте использование памяти контейнерами так, чтобы они не могли использовать всю доступную память хоста. Для этого запускайте их с параметром
--memory
и задайте объём, к примеру, 1024m
. 📌 Ограничивайте количество попыток перезапуска контейнера в случае ошибок. То есть не запускайте их с параметром
--restart=always
. Используйте вместо этого --restart=on-failure:5
. Будет сделано 5 попыток запуска в случае ошибки. Было много советов по написанию DockerFile. Не стал их разбирать, так как мне кажется, это отдельная тема, которая к самой службе не имеет отношения. Также было много советов по запуску контейнеров. Например, не запускать там службу sshd, не монтировать системные директории и т.д. Это тоже отдельная тема, пропускал такие рекомендации.
К данной заметке будет актуальна ссылка на автоматическую проверку контейнеров с помощью Trivy и исправление с помощью Copacetic. Я написал небольшую статью:
⇨ Проверка безопасности Docker образов с помощью Trivy
Данный список составил на основе переработки вот этого документа: CIS Docker Benchmark v1.5.0 - 12-28-2022. Там подробное описание с обоснованием всех рекомендаций.
#cis #docker
Рекомендую очень простой и удобный портал для управления запущенными сервисами на Linux — Runtipi. Он позиционирует себя для домашнего использования, что подтверждает набор сервисов. Позволяет очень просто и быстро запускать приложения. А тем, кто с Linux на ВЫ, позволит без особых усилий пощупать руками его возможности в плане использования готовых сервисов.
По своей сути Runtipi обычная веб панель для запуска Docker контейнеров. У неё минимум возможностей и настроек. Есть магазин приложений, которые устанавливаются в пару кликов. Каждое приложение запускается на своём порту, а вы с помощью дашборда Runtipi легко их открываете, запускаете, устанавливаете, делаете базовую настройку, обновляете.
Я развернул у себя и запустил, попробовал. Реально удобно. Под капотом обычный Docker и контейнеры, которые пишет не сам автор, а использует готовые либо от разработчиков, либо от каких-то доверенных издателей, типа linuxserver.io.
Список поддерживаемых приложений можно посмотреть на отдельной странице. Сейчас их там 132 штуки. Некоторые примеры, про которые я писал: Adguard, Pi-Hole, Duplicati, File Browser, Gitea, Grafana, Joplin Server, Minio, n8n, Nextcloud, Portainer, Revolt Chat, Syncthing, Uptime Kuma, ZeroTier, Wireguard.
Все эти приложения легко развернуть, попробовать, удалить и т.д. Я хотел быстренько попробовать клиента для ChatGPT (там есть для него приложение). К сожалению, доступ к API у меня был заблокирован. Возвращает 404 ошибку. Похоже надо прокси использовать. Подскажите, кто как работает с ChatGPT с территории РФ.
⇨ Сайт / Исходники
#docker #linux
По своей сути Runtipi обычная веб панель для запуска Docker контейнеров. У неё минимум возможностей и настроек. Есть магазин приложений, которые устанавливаются в пару кликов. Каждое приложение запускается на своём порту, а вы с помощью дашборда Runtipi легко их открываете, запускаете, устанавливаете, делаете базовую настройку, обновляете.
Я развернул у себя и запустил, попробовал. Реально удобно. Под капотом обычный Docker и контейнеры, которые пишет не сам автор, а использует готовые либо от разработчиков, либо от каких-то доверенных издателей, типа linuxserver.io.
Список поддерживаемых приложений можно посмотреть на отдельной странице. Сейчас их там 132 штуки. Некоторые примеры, про которые я писал: Adguard, Pi-Hole, Duplicati, File Browser, Gitea, Grafana, Joplin Server, Minio, n8n, Nextcloud, Portainer, Revolt Chat, Syncthing, Uptime Kuma, ZeroTier, Wireguard.
Все эти приложения легко развернуть, попробовать, удалить и т.д. Я хотел быстренько попробовать клиента для ChatGPT (там есть для него приложение). К сожалению, доступ к API у меня был заблокирован. Возвращает 404 ошибку. Похоже надо прокси использовать. Подскажите, кто как работает с ChatGPT с территории РФ.
⇨ Сайт / Исходники
#docker #linux
Объясню простыми словами отличия современных систем контейнеризации. Для тех, кто с ними постоянно не работает, не очевидно, что они могут различаться принципиально по областям применения. Акцент сделаю на наиболее популярных Docker и LXC, а в конце немного по остальным пройдусь.
Все контейнеры используют одно и то же ядро операционной системы Linux и работают в его рамках. Это принципиальное отличие от виртуальных машин. А принципиальное отличие Docker от LXC в том, что Docker ориентируется на запуск приложений, а LXC на запуск системы.
Поясню на конкретном примере. Допустим, вам надо запустить в работу веб сервер. Если вы будете делать это с помощью Docker, то на хостовой машине запустите контейнер с Nginx, контейнер с Php-fpm, создадите на хосте локальные директории с файлами сайта и конфигурациями сервисов и пробросите их внутрь контейнеров, чтобы у них был доступ к ним. В самих контейнерах кроме непосредственно сервисов Nginx и Php-fpm практически ничего не будет.
Если ту же задачу решать с помощью LXC, то вы просто запустите контейнер с нужной базовой системой внутри. Зайдёте внутрь контейнера и настроите там всё, как обычно это делаете на отдельной виртуальной машине. То есть LXC максимально повторяет работу полноценной системы, только работает на базе ядра хоста.
☝ Docker - это один контейнер, одна служба, LXC - набор служб для решения конкретной задачи. При этом в образ Docker тоже можно поместить практически полноценную систему, но так обычно никто не делает, хотя и есть исключения.
Исходя из этих пояснений, становятся понятны плюсы и минусы каждого подхода. Плюсы Docker:
◽минимальный объём образов, соответственно, максимальная скорость запуска нужных сервисов;
◽для бэкапа достаточно сохранить непосредственно данные, образы можно опустить, так как они типовые.
Минусы:
◽более сложная настройка по сравнению с обычной виртуальной машиной, особенно что касается сети и диагностики в целом.
Плюсы LXC:
◽настройка практически такая же, как на обычной VM, заходишь внутрь контейнера по SSH и настраиваешь.
Минусы LXC:
◽итоговые образы бОльшего объёма, так как содержат всё окружение стандартных систем.
◽сложнее автоматизировать и стандартизировать разворачивание масштабных сервисов.
LXC отлично подходит как замена полноценной VM. Его удобно настроить, забэкапить в единый образ и развернуть в том же виде в другом месте. Docker идеален для максимальной плотности сервисов на одном сервере. Думаю именно за это он стал так популярен. На больших масштабах это заметная экономия средств, поэтому крупные компании его активно используют и продвигают.
Аналогом Docker в плане подхода в виде запуска отдельных служб в контейнерах является Podman. Там есть незначительные отличия в реализации, но в целом они очень похожи. Это продукт компании RedHat, и они его всячески продвигают.
Ещё упомяну про LXD, который иногда сравнивают с LXC, хотя это разные вещи. По сути, LXD - надстройка над LXC, предоставляющая REST API для работы с контейнерами LXC. Она упрощает работу с ними, стандартизирует и даёт удобные инструменты управления. При этом LXD может работать не только с контейнерами LXC, но и с виртуальными машинами QEMU.
Надеюсь ничего нигде не напутал. Писал своими словами по памяти, так как с Docker и LXC практически постоянно работаю и примерно представляю, как они устроены.
#docker #lxc
Все контейнеры используют одно и то же ядро операционной системы Linux и работают в его рамках. Это принципиальное отличие от виртуальных машин. А принципиальное отличие Docker от LXC в том, что Docker ориентируется на запуск приложений, а LXC на запуск системы.
Поясню на конкретном примере. Допустим, вам надо запустить в работу веб сервер. Если вы будете делать это с помощью Docker, то на хостовой машине запустите контейнер с Nginx, контейнер с Php-fpm, создадите на хосте локальные директории с файлами сайта и конфигурациями сервисов и пробросите их внутрь контейнеров, чтобы у них был доступ к ним. В самих контейнерах кроме непосредственно сервисов Nginx и Php-fpm практически ничего не будет.
Если ту же задачу решать с помощью LXC, то вы просто запустите контейнер с нужной базовой системой внутри. Зайдёте внутрь контейнера и настроите там всё, как обычно это делаете на отдельной виртуальной машине. То есть LXC максимально повторяет работу полноценной системы, только работает на базе ядра хоста.
☝ Docker - это один контейнер, одна служба, LXC - набор служб для решения конкретной задачи. При этом в образ Docker тоже можно поместить практически полноценную систему, но так обычно никто не делает, хотя и есть исключения.
Исходя из этих пояснений, становятся понятны плюсы и минусы каждого подхода. Плюсы Docker:
◽минимальный объём образов, соответственно, максимальная скорость запуска нужных сервисов;
◽для бэкапа достаточно сохранить непосредственно данные, образы можно опустить, так как они типовые.
Минусы:
◽более сложная настройка по сравнению с обычной виртуальной машиной, особенно что касается сети и диагностики в целом.
Плюсы LXC:
◽настройка практически такая же, как на обычной VM, заходишь внутрь контейнера по SSH и настраиваешь.
Минусы LXC:
◽итоговые образы бОльшего объёма, так как содержат всё окружение стандартных систем.
◽сложнее автоматизировать и стандартизировать разворачивание масштабных сервисов.
LXC отлично подходит как замена полноценной VM. Его удобно настроить, забэкапить в единый образ и развернуть в том же виде в другом месте. Docker идеален для максимальной плотности сервисов на одном сервере. Думаю именно за это он стал так популярен. На больших масштабах это заметная экономия средств, поэтому крупные компании его активно используют и продвигают.
Аналогом Docker в плане подхода в виде запуска отдельных служб в контейнерах является Podman. Там есть незначительные отличия в реализации, но в целом они очень похожи. Это продукт компании RedHat, и они его всячески продвигают.
Ещё упомяну про LXD, который иногда сравнивают с LXC, хотя это разные вещи. По сути, LXD - надстройка над LXC, предоставляющая REST API для работы с контейнерами LXC. Она упрощает работу с ними, стандартизирует и даёт удобные инструменты управления. При этом LXD может работать не только с контейнерами LXC, но и с виртуальными машинами QEMU.
Надеюсь ничего нигде не напутал. Писал своими словами по памяти, так как с Docker и LXC практически постоянно работаю и примерно представляю, как они устроены.
#docker #lxc
Предлагаю вашему вниманию любопытный проект по мониторингу одиночного хоста с Docker - domolo. Сразу скажу, что это продукт уровня курсовой работы с каких-нибудь курсов по DevOps на тему мониторинга. Он представляет из себя преднастроенный набор контейнеров на современном стеке.
Domolo состоит из:
◽Prometheus вместе с Pushgateway, AlertManager и Promtail
◽Grafana с набором дашбордов
◽Loki для сбора логов с хоста и контейнеров
◽NodeExporter - для сбора метрик хоста
◽cAdvisor - для сбора метрик контейнеров
◽Caddy - реверс прокси для prometheus и alertmanager
Сначала подумал, что это какая-та ерунда. Не думал, что заработает без напильника. Но, на моё удивление, это не так. Всё заработало вообще сразу:
Идём в Grafana по адресу http://ip-хоста:3000, учётка admin / changeme. Здесь мы можем наблюдать уже настроенные дашборды на все случаи жизни. Там есть буквально всё, что надо и не надо. Loki и сбор логов тоже работает сразу же без напильника. Идём в Explore, выбираем Datasource Loki и смотрим логи.
Если вам нужно мониторить одиночный хост с контейнерами, то это прям полностью готовое решение. Запускаете и наслаждаетесь. Репозиторий domolo удобен и для того, чтобы научиться всё это дело настраивать. Все конфиги и docker-compose файлы присутствуют. На мой взгляд для обучения это удобнее, чем какая-нибудь статья или обучающее видео. Здесь всё в одном месте и гарантированно работает.
Можно разобраться, настроить под себя и, к примеру, добавить туда поддержку внешних хостов. Надо будет добавить новые внешние Datasources и какие-то метки внедрить, чтобы различать хосты и делать общие дашборды. Получится ещё одна курсовая работа.
Сам проект не развивается и не обновляется. Так что ждать от него чего-то сверх того, что там есть, не имеет смысла.
#мониторинг #grafana #docker #prometheus
Domolo состоит из:
◽Prometheus вместе с Pushgateway, AlertManager и Promtail
◽Grafana с набором дашбордов
◽Loki для сбора логов с хоста и контейнеров
◽NodeExporter - для сбора метрик хоста
◽cAdvisor - для сбора метрик контейнеров
◽Caddy - реверс прокси для prometheus и alertmanager
Сначала подумал, что это какая-та ерунда. Не думал, что заработает без напильника. Но, на моё удивление, это не так. Всё заработало вообще сразу:
# git clone https://github.com/ductnn/domolo.git
# cd domolo
# docker-compose up -d
Идём в Grafana по адресу http://ip-хоста:3000, учётка admin / changeme. Здесь мы можем наблюдать уже настроенные дашборды на все случаи жизни. Там есть буквально всё, что надо и не надо. Loki и сбор логов тоже работает сразу же без напильника. Идём в Explore, выбираем Datasource Loki и смотрим логи.
Если вам нужно мониторить одиночный хост с контейнерами, то это прям полностью готовое решение. Запускаете и наслаждаетесь. Репозиторий domolo удобен и для того, чтобы научиться всё это дело настраивать. Все конфиги и docker-compose файлы присутствуют. На мой взгляд для обучения это удобнее, чем какая-нибудь статья или обучающее видео. Здесь всё в одном месте и гарантированно работает.
Можно разобраться, настроить под себя и, к примеру, добавить туда поддержку внешних хостов. Надо будет добавить новые внешние Datasources и какие-то метки внедрить, чтобы различать хосты и делать общие дашборды. Получится ещё одна курсовая работа.
Сам проект не развивается и не обновляется. Так что ждать от него чего-то сверх того, что там есть, не имеет смысла.
#мониторинг #grafana #docker #prometheus
Короткая заметка для тех, кто использует Docker. Вы знаете, как посмотреть параметры, с которыми запускался контейнер? Я лично не знаю и не изучал этот вопрос.
У меня выработалась привычка посла запуска контейнера с кучей параметров записывать команду для запуска либо к себе в заметки, если предполагаю, что она мне ещё пригодится, либо локально на сервере в домашней директории, где он запущен.
То есть запустив что типа этого:
Я сохраню эту команду. А как узнать, с какими параметрами был запущен контейнер, если вы это забыли и не сохранили? Тут поможет runlike. Простое приложение, которое показывает полную команду, с которой был запущен контейнер. Runlike написан на python, так что можно установить через pip:
Либо просто запустить через Docker. Для этого он собран в отдельный контейнер:
Жаль, что вывод сразу не форматируется. На выходе получается однострочная портянка.
Подозреваю, что всю эту информацию можно вытащить из
⇨ Исходники
#docker
У меня выработалась привычка посла запуска контейнера с кучей параметров записывать команду для запуска либо к себе в заметки, если предполагаю, что она мне ещё пригодится, либо локально на сервере в домашней директории, где он запущен.
То есть запустив что типа этого:
# docker run \
--name insentry_watch \
--detach \
--restart unless-stopped \
--network host \
--volume insentry-data:/var/lib \
--volume /etc/timezone:/etc/timezone:ro \
--volume /etc/localtime:/etc/localtime:ro \
--stop-timeout 60 \
cr.yandex/crp5a5q503oamalo3iou/insentry-watch/linux/amd64:23.1.0.27
Я сохраню эту команду. А как узнать, с какими параметрами был запущен контейнер, если вы это забыли и не сохранили? Тут поможет runlike. Простое приложение, которое показывает полную команду, с которой был запущен контейнер. Runlike написан на python, так что можно установить через pip:
# pip install runlike
Либо просто запустить через Docker. Для этого он собран в отдельный контейнер:
# docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike YOUR-CONTAINER
Жаль, что вывод сразу не форматируется. На выходе получается однострочная портянка.
Подозреваю, что всю эту информацию можно вытащить из
docker inspect
, но там слишком много всего. Не знаю, как оттуда вычленить только параметры запуска.⇨ Исходники
#docker
Расскажу про необычный инструмент, который в первую очередь будет полезен тем, у кого рабочая машина на Linux. Он для этого был создан. Возможно где-то и на сервере пригодится, но в основном для тестов. Речь пойдёт про Distrobox. Это надстройка над контейнерами, которая позволяет их прозрачно интегрировать в систему.
Допустим, вам надо запустить какой-то софт, возможно с графическим интерфейсом, но его нет под ваш дистрибутив. У вас вариант либо запустить его в виртуальной машине, либо как-то самому наколхозить нужный контейнер и примапить его к хосту. Distrobox решает эту задачу за вас. Вы просто выбираете нужную систему, запускаете её через Distrobox и работаете там с нужным вам приложением. Оно запускается и ведёт себя так, как будто установлено локально. Пробрасываются каталог пользователя, иксы или wayland, звук, d-bus и udev. Приложение ведёт себя как локальное.
Distrobox для популярных дистрибутивов есть в базовых репозиториях. В свежих Debian и Ubuntu присутствует, так что установка стандартна:
Например, запустим в Debian какую-нибудь программу, которая есть в Fedora. Для этого создаём контейнер с последней Федорой. Делать это нужно под обычным пользователем, не под root. Пользователь должен быть в группе docker. В самой свежей версии, установленной вручную, это уже поправлено и можно под root запускать.
Заходим в контейнер:
При первом входе будет выполнена преднастройка. После её окончания окажетесь в оболочке контейнера. Теперь можно установить какую-нибудь программу:
После установки выполняем экспорт этой программы из консоли контейнера:
Теперь с этой программой можно работать, как будто она установлена на хосте. По умолчанию distrobox захочет положить ярлык на рабочий стол. Если у вас машина без графического окружения, то получите ошибку. Вместо этого можно выгрузить через ключ
Бинарник (а точнее скрипт запуска) запуска программы из контейнера будет положен на хост в директорию
То есть всё это решение просто SHELL обёртка вокруг докера для удобного применения. Используются заранее подготовленные образы. В принципе, Distrobox удобен и для простого и быстрого запуска контейнеров с различными базовыми системами с примапленными ресурсами к хосту. Ими удобно управлять или работать. Смотрим список контейнеров:
Устанавливаем, удаляем:
Можно сделать себе тестовую виртуалку со всеми базовыми системами и заходить в нужную. Все ресурсы у всех систем примаплены к хосту.
⇨ Сайт / Исходники / Как это работает
#linux #docker
Допустим, вам надо запустить какой-то софт, возможно с графическим интерфейсом, но его нет под ваш дистрибутив. У вас вариант либо запустить его в виртуальной машине, либо как-то самому наколхозить нужный контейнер и примапить его к хосту. Distrobox решает эту задачу за вас. Вы просто выбираете нужную систему, запускаете её через Distrobox и работаете там с нужным вам приложением. Оно запускается и ведёт себя так, как будто установлено локально. Пробрасываются каталог пользователя, иксы или wayland, звук, d-bus и udev. Приложение ведёт себя как локальное.
Distrobox для популярных дистрибутивов есть в базовых репозиториях. В свежих Debian и Ubuntu присутствует, так что установка стандартна:
# apt install distrobox
Например, запустим в Debian какую-нибудь программу, которая есть в Fedora. Для этого создаём контейнер с последней Федорой. Делать это нужно под обычным пользователем, не под root. Пользователь должен быть в группе docker. В самой свежей версии, установленной вручную, это уже поправлено и можно под root запускать.
# distrobox-create --name fedora --image fedora:latest
Заходим в контейнер:
# distrobox-enter fedora
При первом входе будет выполнена преднастройка. После её окончания окажетесь в оболочке контейнера. Теперь можно установить какую-нибудь программу:
# sudo dnf install appname
После установки выполняем экспорт этой программы из консоли контейнера:
# distrobox-export --app appname
Теперь с этой программой можно работать, как будто она установлена на хосте. По умолчанию distrobox захочет положить ярлык на рабочий стол. Если у вас машина без графического окружения, то получите ошибку. Вместо этого можно выгрузить через ключ
--bin
, указав явно путь к бинарнику в контейнере:# distrobox-export --bin /usr/sbin/appname
Бинарник (а точнее скрипт запуска) запуска программы из контейнера будет положен на хост в директорию
~/.local/bin
. Она должна существовать. Там же можно посмотреть, как всё это работает:#!/bin/sh
# distrobox_binary
# name: fedora
if [ -z "${CONTAINER_ID}" ]; then
exec "/usr/local/bin/distrobox-enter" -n fedora -- /bin/sh -l -c '/usr/sbin/appname$@' -- "$@"
elif [ -n "${CONTAINER_ID}" ] && [ "${CONTAINER_ID}" != "fedora" ]; then
exec distrobox-host-exec /home/zerox/.local/bin/appname"$@"
else
exec /usr/sbin/appname"$@"
fi
То есть всё это решение просто SHELL обёртка вокруг докера для удобного применения. Используются заранее подготовленные образы. В принципе, Distrobox удобен и для простого и быстрого запуска контейнеров с различными базовыми системами с примапленными ресурсами к хосту. Ими удобно управлять или работать. Смотрим список контейнеров:
# distrobox list
Устанавливаем, удаляем:
# distrobox stop fedora
# istrobox rm fedora
Можно сделать себе тестовую виртуалку со всеми базовыми системами и заходить в нужную. Все ресурсы у всех систем примаплены к хосту.
⇨ Сайт / Исходники / Как это работает
#linux #docker
В Linux есть инструмент для сохранения состояния работающих процессов, в том числе PID, системные права, открытые файлы, используемую память, сокеты, tcp соединения и т.д. То есть полное состояние процесса сохраняется на диск. Делается это с помощью CRIU (Checkpoint Restore In Userspace). Причём работает она в пространстве пользователя, а не ядра ОС.
В свежих версиях Debian и Ubuntu CRIU есть в базовых репозиториях:
Покажу сразу на наглядном примере, как это работает. Создаём скрипт
Запускаем его и наблюдаем работу. Открываем соседнюю консоль. Создадим там директорию, куда сохраним состояние процесса:
Смотрим pid нашего скрипта:
Сохраняем состояние процесса. Это пример для процесса, запущенного в консоли, следовательно с привязкой к shell:
Работающий процесс будет остановлен, а его состояние сохранено в локальную директорию. Можете посмотреть содержимое. Там будет много различных файлов с расширением .img.
Восстанавливаем работу процесса, находясь в директории с состоянием:
Он продолжит работу в открытой консоли. Можно выключить или перезагрузить систему. И после этого восстановить процесс. Он так же продолжит свою работу с момента заморозки.
Я пробовал переносить процесс в другую систему (Debian -> Ubuntu), но там восстановить не получается. Должно быть такое же окружение и системные файлы. У меня он сразу ругался на разные размеры бинарников dash и sleep. Для реальной миграции между системами нужно соблюсти ряд условий, описанных в документации.
Изначально проект был открыт для создания инструмента по заморозке и переноса контейнеров OpenVZ, но сейчас расширил свою работу на LXC/LXD, Docker. Вот пример, как сохранить состояние Docker контейнера и запустить вновь: ⇨ https://criu.org/Docker_External.
Посмотрел немного записей на youtube по этой теме. Люди сохраняют открытые VNC сессии со всем софтом и открытыми TCP соединениями. Пример с открытым видео в браузере. После восстановления, продолжается воспроизведение практически на том же месте. Также инструмент применим для сохранения и восстановления контейнеров в Kubernetes.
⇨ Сайт / Исходники
#linux #docker
В свежих версиях Debian и Ubuntu CRIU есть в базовых репозиториях:
# apt install criu
Покажу сразу на наглядном примере, как это работает. Создаём скрипт
test.sh
, который выводит в консоль текущую дату:#!/bin/sh
while :; do
sleep 1
date
done
Запускаем его и наблюдаем работу. Открываем соседнюю консоль. Создадим там директорию, куда сохраним состояние процесса:
# mkdir ~/criu && cd ~/criu
Смотрим pid нашего скрипта:
# ps -C test.sh
PID TTY TIME CMD
748 pts/1 00:00:00 test.sh
Сохраняем состояние процесса. Это пример для процесса, запущенного в консоли, следовательно с привязкой к shell:
# criu dump -vvvv -o dump.log -t 748 --shell-job
Работающий процесс будет остановлен, а его состояние сохранено в локальную директорию. Можете посмотреть содержимое. Там будет много различных файлов с расширением .img.
Восстанавливаем работу процесса, находясь в директории с состоянием:
# criu restore -vvvv -o restore.log --shell-job
Он продолжит работу в открытой консоли. Можно выключить или перезагрузить систему. И после этого восстановить процесс. Он так же продолжит свою работу с момента заморозки.
Я пробовал переносить процесс в другую систему (Debian -> Ubuntu), но там восстановить не получается. Должно быть такое же окружение и системные файлы. У меня он сразу ругался на разные размеры бинарников dash и sleep. Для реальной миграции между системами нужно соблюсти ряд условий, описанных в документации.
Изначально проект был открыт для создания инструмента по заморозке и переноса контейнеров OpenVZ, но сейчас расширил свою работу на LXC/LXD, Docker. Вот пример, как сохранить состояние Docker контейнера и запустить вновь: ⇨ https://criu.org/Docker_External.
Посмотрел немного записей на youtube по этой теме. Люди сохраняют открытые VNC сессии со всем софтом и открытыми TCP соединениями. Пример с открытым видео в браузере. После восстановления, продолжается воспроизведение практически на том же месте. Также инструмент применим для сохранения и восстановления контейнеров в Kubernetes.
⇨ Сайт / Исходники
#linux #docker