Как вы знаете, контейнеры — это вещь Linux. Microsoft представила свое [решение] (https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/), но я никогда не видел, чтобы они использовались.


Для использования контейнеров у нас есть в основном две альтернативы: docker и podman. Я предпочитаю последнее по двум причинам. Потому что он имеет архитектуру без демонов и потому что ему не нужны права суперпользователя. Но использовать его с docker-compose в Windows сложно. Именно поэтому я решил написать и поделиться этой историей.


Мотивация


Я думаю, что использование Docker Desktop в Windows — это самый быстрый способ использования контейнеров. Он сам все настраивает. Но, исключая архитектурные предпочтения, я нашел еще две причины избегать этого:


  1. Проблема с лицензией. Docker Desktop требует лицензии на пользователя для коммерческого использования в крупных компаниях.

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

Предпосылки


Использование podman в Windows возможно благодаря WSL2. Microsoft предоставляет инструкции в соответствии с вашей версией Windows. Вы можете найти их здесь: https://docs.microsoft.com/en-us/windows/wsl/install.


Podman поддерживает docker-compose с версии 3.0.0.


TL;DR


Следующие абзацы посвящены проблемам, которые я обнаружил в Debian и Ubuntu. Итак, зачем нам OpenSUSE Tumbleweed в качестве дистрибутива Linux. По этой причине я резюмировал в параграфе Заключение только необходимые шаги.


дистрибутивы Linux


В Microsoft Store есть несколько дистрибутивов Linux. И вот тут начался мой путь.


:::Информация


Общие решения о дистрибутивах находятся в разделе «Устранение неполадок».


Дебиан


Текущий стабильный дистрибутив Debian — это версия 11. Он имеет кодовое название Bullseye, и это первый дистрибутив, который я попытался использовать.


Первое, что нужно проверить, это наличие podman в официальном репозитории. К счастью, это так, и в настоящее время это версия 3.0.1. Итак, он должен работать с docker-compose.


Итак, я обновил систему и установил podman и docker-compose:


``` ударить


$ sudo подходящее обновление


$ sudo подходящее обновление


$ sudo apt установить podman docker-compose


Затем я настроил podman, чтобы избежать использования systemd. На WSL2 мы не можем полагаться на него, потому что система инициализации — это специальное решение Microsoft.


Для этого я скопировал /usr/share/containers/containers.conf в $HOME/.config/containers. Потом поменял последний. В частности, я установил для cgroup_manager значение cgroupfs, а для events_logger значение file:


[двигатель]


cgroup_manager = "cgroupfs"


event_logger = "файл"


Я нашел эти советы на https://www.redhat.com/sysadmin/podman-windows-wsl2.


Затем я попытался запустить простой контейнер:


``` ударить


$ docker run -dp 8080:80 docker.io/httpd


Но я получил: «Ошибка: ошибка инициализации исходного докера… x509: сертификат, подписанный неизвестным центром». Чтобы решить эту проблему, я установил ca-certificates. Затем я попытался снова запустить контейнер:


``` ударить


$ sudo apt установить ca-сертификаты


$ docker-run -dp 8080:80 docker.io/httpd


На этот раз получилось! И хост может добраться до контейнера.


Итак, я попробовал простой docker-compose для проверки связи между двумя контейнерами:


``ямл


версия: "3.7"


Сервисы:


дБ:


изображение: docker.io/mariadb


перезапуск: всегда


Окружающая среда:


MYSQL_ROOT_PASSWORD: пароль


phpmyadmin:


изображение: docker.io/phpmyadmin


перезапуск: всегда


порты:


  • 8080:80

Окружающая среда:


  • PMA_ARBITRARY=1

Но я получил эту ошибку:


``` ударить


$ docker-компоновать


ОШИБКА: не удалось подключиться к демону Docker по адресу http+docker://localhost — он запущен?


Если он находится в нестандартном месте, укажите URL-адрес с переменной среды DOCKER_HOST.


Очевидно, что он не запущен. Итак, я проверил документацию podman, и нам нужно запустить сокет podman вручную. Мы должны сделать это вручную, потому что мы не можем полагаться на службу systemd. Затем мы должны указать расположение сокета для docker-compose.


``` ударить


$ системная служба podman --time=0 unix:///home/user/podman.sock &


[1] <число>


$ docker-compose -H unix:///home/user/podman.sock up


Вытягивание изображений...


Создание изображений...


ОШИБКА: для <имя службы> сетевое подключение не включено для контейнеров без рута


ОШИБКА: для <имя службы> сетевое подключение не включено для контейнеров без рута


Я искал ошибку и нашел GitHub [issue] (https://github.com/containers/podman/issues/9169) о podman. Кажется, это ошибка, исправленная в версии 3.2.


Итак, я искал другие поддерживаемые дистрибутивы Linux в надежде найти более новую версию podman.


Убунту


В настоящее время существует три версии Ubuntu:


  • 18.04.5 ЛТС

  • 20.04.4 ЛТС

  • 22.04 ЛТС

Но, как и Debian, они не поддерживают последнюю версию Podman. По этой причине я их вообще не пробовал. И в этот момент я был немного немотивирован. Я был бы признателен за скользящий дистрибутив. И вот когда я вижу OpenSUSE Tumbleweed в магазине Microsoft Store…


Перекати-поле OpenSUSE


OpenSUSE Tumbleweed — это скользящий дистрибутив. Это означает, что он поддерживает последние версии пакетов. Действительно, текущая версия podman — 4.0.3. Еще одна хорошая новость заключается в том, что я использовал Tumbleweed в течение нескольких лет, и это было здорово!


Итак, я обновил систему и установил podman и docker-compose:


``` ударить


$ sudo zypper обновление


$ sudo zypper установить podman docker-compose


На данный момент я настроил podman так, чтобы он не использовал systemd, как Debian.


Я попытался запустить простой контейнер, открывающий порт. И это сработало.


Итак, я запустил сокет podman. Затем я запустил docker-compose с тем же файлом. И два контейнера завелись!


Но когда я попытался подключиться к базе данных из phpmyadmin, я получил следующую ошибку:


Ошибка getaddrinfo: имя или служба неизвестны


Я немного исследовал и обнаружил, что контейнеры не могут обмениваться данными через DNS-имя.


По этой причине я исследовал сеть в Podman 4.x и обнаружил, что они изменили сетевой стек. Но он также должен поддерживать разрешение DNS.


Тем не менее, podman продолжает поддерживать старый сетевой стек (например, cni) по соображениям совместимости. Итак, я проверил, какой стек включен, и это был старый. Итак, я изучил это и разрешение DNS и нашел [официальную статью] (https://podman.io/getting-started/network#using-dns-in-container-networks). Старый стек поддерживает плагины, и один из них касается разрешения DNS-имен: dnsname.


Итак, я искал его в репозитории Tumbleweed, и он был там. Итак, я установил его:


``` ударить


$ sudo zypper установить cni-plugin-dnsname


И на этот раз контейнеры взаимодействовали корректно.


Кроме того, я принудительно добавил старый стек в podman в $HOME/.config/containers/containers.conf:


[сеть]


network_backedn = "cni"


Исправление проблем


Не удалось разрешить DNS в WSL2


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


  • Временная ошибка при разрешении ‘<имя домена>’

  • W: Не удалось получить <URL-адрес>

  • Сообщение об ошибке: Не удалось разрешить хост: <имя хоста>'

Итак, я прочитал файл /etc/resolv.conf, и там был плохой DNS-сервер. К счастью, Microsoft добавила подсказку:


Этот файл был автоматически сгенерирован WSL. Чтобы остановить автоматическое создание этого файла, добавьте следующую запись в /etc/wsl.conf:


[сеть]


generateResolvConf = false


сервер имен


Итак, я написал файл /etc/wsl.conf:


[сеть]


сгенерироватьResolvConf = ложь


Затем я удалил файл /etc/resolv.conf (это была ссылка) и создал правильный:


сервер имен


Вывод


Как видите, запуск podman с docker-compose в Window был путешествием. Мы прошли много шагов. Итак, чтобы упростить и лучше организовать их, я снова написал здесь:


  1. Установите WSL2

  1. Установите OpenSUSE Tumbleweed как дистрибутив Linux.

  1. Исправьте /etc/resolv.conf, если не удается разрешить DNS-имя в раздаче

  1. Обновить раздачу

  1. Установите podman, docker-compose и cni-plugin-dnsname.

  1. Настройте podman, чтобы он не использовал systemd

  1. Настройте podman для использования cni в качестве сетевого сервера.

  1. Запустите сокет podman

  1. Прибыль

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