LXC vs VM для докера и не только

Вышла версия Proxmox VE 9.1

Не зря я обратил внимание на новые опции в lxc

  1. В CT Templates скачиваем образ из OCI репы (аутентификация не поддерживается)
  2. Видим архив с образом
  3. При создании контейнера выбираем
  4. В опциях контейнера видим, что данные параметры были скопированы из контейнера
  5. В настройках сети видим галочку Host-Managed (она автоматически включится при создании контейнера если PVE пойдем, что это OCI образ)
    image
    Дело в том, что docker изначально не поддерживает настройку сети самим контейнером, поэтому, PVE назначает IP адрес самостоятельно и прокидывает в контейнер уже настроенный сетевой интерфейс

Я Обнаружил, что в версии PVE 9.1.1 IPv6 работает не совсем корректно, при попытке включить SLAAC ругается, а при Static и пустых полях должен отсутствовать IPv6 адрес, а он получен по SLAAC, в общем, ждем допиливаний.

  1. Запускаем LXC контейнер и видим
  2. Собственно, мы видим, что не зря нам ранее дали возможность просмотра IP адресов

Это все было в рамках подготовки к запуску Docker контейнеров в LXC

Смотрим на ресурсы, которые потребляет наша LXCшка


a man wearing a white shirt that says la riviera

Думаете все хорошо?

a man wearing a white shirt that says la riviera

В опциях консоль не через tty, а console, что логично

Думаете работает консоль?

На самом деле работает, но не как консоль, а как вывод stdout контейнера без интерактивного режима

Меняем консоль на shell и заводится

Давайте рассмотрим минусы данного решения

  1. Нет docker-compose, нет даже docker cli
  2. Только 1 процесс, нет ssh, нет нескольких контейнеров через docker compose, чтобы все это работало надо добавлять какой-то init процесс, который бы уже был родительским для остальных, т.е. по сути, собирать LXC контейнер
  3. Нет overlayfs, по сути, это подход микротика, когда все слои распаковываются в одно место, все конфиги правятся прямо на лету, т.к. смотрим следующий пункт
  4. Тут нет разделения на контейнер и о образ, если в докере мы делаем docker pull && docker stop && docker rm && docker run, то тут просто удалять LXC контейнер со всеми данными и создавать новый, либо же, написать баш скрипт, который скачивает docker образ куда-то, останавливает и монтирует rootfs контейнера, потом копирует файлы из одного места в другое, но с учетом волюмов (смотрим следующий пункт)
  5. Нет волюмов, по сути, это уже не stateless а stateful контейнер, если надо хранить пользовательские файлы, то пробрасываем каталог стандартной “матрешкой” mp0: /host/path,mp=/container/path
  6. Нет вменяемого API по работе с этим
  7. Ну и в целом, очень много ограничений данного решения, но с другой стороны, это еще один вариант запуска, он может пригодиться кому-то + можно же собирать свои кастомные докер образы, которые будут обновляемые и к какими-то своими фишками.

Есть еще вариант обновления контейнеров

  1. Создаем новый LXC контейнер с новой версией
  2. Удаляем старый LXC контейнер со старой версией

Тут мы понимаем, что все персистентные данные нам надо выносить в точки монтирования

Если мы обращаемся к контейнеру по сети, то надо как-то перенаправить клиентов на новый адрес, тут первое, что приходит в голову, это какой-то service-discovery, но с ними у нас большие проблемы

  1. Из коробки мы имеем только DHCP, в теории можно попробовать как-то его использовать
  2. Consul и прочие не будут работать т.к. нам нужен клиент, а тут не поды, а контейнеры, с подами было бы чуть легче
  3. Docker api у нас тоже нет, можно было бы натравить какой-нить traefik или типа того, реализовать куберовский оператор, в общем
  4. Остаются веб-хуки самого PVE, можно в конфиг добавить вызов скрипта при старте или остановке контейнера, этот скрипт может дергать serivce-discrovery для обновления
  5. Ну и мы же не будем руками создавать и удалять контейнеры? Скорее всего, у нас будет какой-нить terraform или ansible, который будет создавать нам контейнеры, в нем же тогда можно и дергать service-discovery провайдера
  6. Опционально, можно прикрутить скрипт, который будет получать список контейнеров и по тегам раскидывать контейнеры по сервисам
  7. Ну и можно попробовать поковырять SDN + IPAM, тут в рамках 1 проекта/неймспейса можно создать отдельную подсеть с IPAM
  8. Ну и мы должны понимать, что в данном случае у нас контейнеры все будут висеть в одном списке, если в кубере у нас есть несколько уровней организации, то тут только 1, максимум, что можем разные бриджи завести чере SDN

И и главный вопрос тогда: а оно вам надо? по сути, это будет попытка собрать кубер из :shit: и :crutch:

Тогда уже проще поднять кубер и получить все из коробки.

Уточнение

Самый главный момент
Это не запуск Docker напрямую в PVE
Это просто конвертация Docker образа в формат rootfs LXC + мелкие допилы типа кастомного entrypoint вместо /bin/init и передачи переменных окружения

Для себя вижу только 1 вариант: попробовать собрать минималистичную систему для запуска podman на основе libc т.к. пока с LXC шаблонами у меня не очень хорошо пошли дела и насколько я понял из общения с GPT, то там все равно шаблон надо собирать на основе docker образов

Еще вижу еще несколько вопросов:

  1. Нет аутентификации для OCI, тут либо ждать добавления данного функционала в PVE, либо идти по пути (на который намекнули сами Proxmox) подготовки архива своими силами и отправки его в хранилище. Тут я вижу добавление в CI/CD отдельного шага, который будет выполнять что-то типа skopeo copy docker-daemon:my-app:1.2.3 oci:my-app_1.2.3 && tar -czf my-app_1.2.3.tar.gz -C my-app_1.2.3 . && scp my-app_1.2.3.tar.gz proxmox:/var/lib/vz/templates/cache/
  2. В docker-compose (ну и docker) есть restart: unless-stopped/always, непонятно, как поведет себя PVE при вылете entrypoint, по идее просто выставит ошибку контейнеру и не будет пытаться загрузить его снова
  3. Docker менеджеры типа Dockge, Portainer, Komodo, Arcane, DockPort, Watchtower идут лесом, остается Pulse и еще парочка, которых сильно меньше
  4. Sidecar/agents, похоже идут лесом, пока не придумал как организовать
  5. Не совсем понятно, что делать с логами, как их вообще можно смотреть за претелами текущего noVNC буфера

Будем посмотреть

Спасибо большое, но мне к примеру это как иероглифы)

Вдогонку обзор от Техно Тима (можно включить русские субтитры):

Он в ролике несколько раз повторил про “контейнер в контейнере”, что немного неверно. Верно у комментатора выше:

Насколько я помню, у него звучала фраза в духе “вместо запуска контейнера в контейнере теперь есть официальный способ запуска OCI образов в Proxmox”

Я же хотел акцентировать внимание на том, что

  • Докер является контейнером
  • Но контейнер не является докером

В обсуждении на opennet.ru народ прям такой “егегей, а подскажите как docker-compose там запустить? Ща перенесу все свои докер сервисы туда!”

Что в корне не верно, т.к. к докеру эта фича вообще не имеет отношения, и даже используется определение OCI вместо Docker Image

Ну и дополнительно к этому Техно Тим не особо заострил внимание на проблемах с обновлением контейнеров, поэтому, я решил дополнить свой обзор и добавил варианты обновления, граничащие с безумием (показана фраза “а стоит ли игра свеч?”).

Я на финишной черте создания минималистичного окужения для запуска docker-compose в debian13-slim

Всё верно, ведь Docker Image относится к компании докер, а OCI это типо независимый стандарт

Еще видео на тему

Роман, как успехи в создании образа?

Пока забросил это, были проблемы со сборкой, + мне не очень понравилось, что надо ставить галочку “сеть управляется хостом”, поэтому задача ушла вниз по приорирету и в ближайшие месяцы точно не доберусь до нее + жду может быть кто-то выпустит нечто подобное.

@KRom Роман, не переживаете ли Вы за побег из LXC контейнера на сам хост? Почему? Вы хорошо объясняете свою позицию. Мне интересно Ваше мнение по этому поводу, так как у Вас явно больше компетенции, чем у меня.

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

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

В тяжелых корпоративных системах, где цена утечки просто огромна, где увольняют топ менеджеров за то, что они загрузили документы в ИИшный чат, где “все хакеры мира” из “недружественных стран” целенаправленно занимаются взломом конкретного объекта, чтобы потом на весь мир раструбить об этом, в таких системах естественно LXC не используются, там даже Proxmox нет, а специализированные платные гипервизоры типа VmWare (ха-ха)

Я бывал на вебинарах и мастер-классах по побег и там все очень сложно, фактически, без экспойтов и 0-day уязвимостей в софте можно сбежать если админ рукопоп и навалял прав сверх дефолтных, тот же lxc как минимум имеет cgroups + apparmor, которые достаточно сложно обойти, будут ли пытаться взломать именно мою хоумлабу, чтобы скачать мои семейные фотки? сомневаюсь, у меня был опыт взлома корп. сайта на wordpress, сам сайт ломанули, но за пределы docker окружения выйти не смогли (ну я всегда говорил, что wp - не айс)

Поэтому, я исхожу из того, что я могу создать больше изолированных окружений за счет lxc (у меня сейчас уже порядка 115 гостевых систем в кластере) с тюнингом прав и настроек под каждого клиента, так, чтобы каждому конкретному сервису были предоставленны только те ресурсы, которые ему необходимы + я настраиваю безопасное окружение (насколько это возможно и удобно, без паранойи и 100500 замков на каждое действие)

Я не зря тут публиковал пост про Вредные советы - если бояться побега из lxc и ставить 1 виртаулку для всего и

  • не настраивать фаервол
  • использовать дефолтные пароли
  • обновлять docker образы с тегом latest без ревьювинга
  • не следить за уязвимостью
  • не сегментировать фаервол
  • не отслеживать активность и не анализировать логи
  • не тюнить систему (даже для виртуалок ФСТЭК выпустили рекомендации, которые стоит применить, если переживаете, но ряд правок на железе приводит к существенному снижению производительности)
  • не использовать политики и правила по работе с паролями
  • не использовать антивирусы для пользовательских файлов
  • не использовать бэкапирование и системы проверки целостности файлов
  • не применять разделение на работу и аудит с неизменяемыми логами
  • не использовать бастионную защиту и в целом, многоуровневую защиту при доступе извне

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

Ну и с психологической точки зрения, чем больше неадекватных (или адекватных сисеме, но с неадекватными пользователями) требований к безопасности, тем больше вероятность того, что сработает человеческий фактор:

  • зачем полгода согласовывать еще одну виртуалку, если проще по-тиходу подселиться к существующей?
  • зачем запоминать 20 символьный пароль с 4 разными группами каждый месяц если можно записывать его на стикере на клавиатуре или использовать один и тот же пароль, но каждый раз привавлять по 1 в конце?
  • зачем поднимать еще одну виртуалку для тестирования нового сервиса, если есть уже готовая с сайтом на WP?

Поэтому, я лучше сконцентрируюсь на вещах, которые с наибольшей вероятностью могут быть атакованы и скомпрометрированы.