Вопрос или проблема
Я использую совместимую ОС RHEL 9.0 в своем домашнем лабораторном окружении, вместе с podman версии 4.0.2 и podman-compose версии 1.0.3. Если вам нужна какая-либо дополнительная информация, пожалуйста, дайте мне знать!
Я пытаюсь перейти от использования контейнеров Docker к безпривилегированным контейнерам podman. С этой целью я перенес довольно простой набор сервисов, которые будут работать на свежей установке Docker на почти любой ОС *nix, которую я пробовал. Просто, да? Нет.
Сначала мне пришлось указать полный путь к моим образам контейнеров, а не просто ссылаться на них по имени, как в библиотеке Docker. Это было не так уж плохо.
Мой файл compose объявляет мостовую сеть, и каждый сервис подключается к этой сети.
Любой другой компьютер в сети может получить доступ к любому сервису, порты которого открыты из контейнера. Порты 8080, 8443, 3306 доступны с моего ноутбука.
Проблема заключается в том, что контейнеры не могут связываться друг с другом. С сетью Docker контейнеры могли разрешать имена друг друга, используя только имя контейнера в качестве имени хоста. Я установил ping на каждый из моих контейнеров и обнаружил, что они могут пинговать себя, ссылаясь на свое собственное имя контейнера, но не могут пинговать другие контейнеры. Это действительно ставит под сомнение мои планы по переходу на безпривилегированные контейнеры.
В моем файле compose я сначала объявляю сеть:
version: 3.1
networks:
neta:
driver: bridge
Каждый сервис объявляет имя контейнера и подключается к этой сети, например:
container_name: httpd
networks:
- neta
...
container_name: mariadb
networks:
- neta
Я не опубликовал свой полный файл compose, потому что считаю, что эта проблема не специфична для моего файла, а связана с безпривилегированной природой podman.
Моя проблема в том, что контейнер httpd не может достучаться до mariadb, и наоборот.
Я не более чем 24 часа в пути к изучению podman, на самом деле, меньше 4 часов. Я просто предполагал, что сетевое взаимодействие контейнеров будет чем-то, что “просто будет работать”, и теперь ошибаюсь.
Буду признателен за любые идеи, ссылки или советы.
Спасибо
Я предлагаю перевести ваш файл docker compose в файл yaml для kubernetes. Таким образом, вы сможете воспользоваться podman play kube. https://docs.podman.io/en/v3.4.1/markdown/podman-play-kube.1.html
В самом файле yaml вы можете определить порты так же, как и в файле docker compose. Поскольку все контейнеры находятся в одном поде, они могут использовать localhost.
- name: container_A
image: docker.io/container_A
ports:
- containerPort: 27017
hostPort: 27017
protocol: TCP
- name: container_B
image: docker.io/container_B
ports:
- containerPort: 8081
hostPort: 8081
protocol: TCP
Ответ или решение
Чтобы понять, как работает сетевая связь между контейнерами в Podman и podman-compose, важно учитывать особенности, связанные с использованием rootless-контейнеров и сетевых драйверов.
Основные моменты сетевого взаимодействия в Podman
-
Rootless-режим: Podman поддерживает запуск контейнеров в режиме без прав суперпользователя (rootless). При этом сетевые настройки могут отличаться от тех, к которым вы привыкли при использовании Docker. В частности, контейнеры, запущенные пользователями без прав суперпользователя, имеют свои уникальные сетевые пространства имен.
-
Сетевые драйверы: Podman использует сеть
bridge
по умолчанию, как и Docker. Однако, в rootless-режиме необходимо убедиться, что такая сеть настроена правильно и контейнеры могут общаться друг с другом. -
Контейнерные имена как хосты: В Docker контейнеры могут обращаться друг к другу по имени. В Podman это может зависеть от конфигурации и версии. Если контейнеры подключены к одной и той же сети, вы должны иметь возможность использовать названия контейнеров для связи.
Решение проблемы
Чтобы устранить возникшие у вас трудности с доступом между контейнерами, попробуйте следующее:
-
Проверьте настройки сети: Убедитесь, что ваши контейнеры действительно находятся в одной сети. Вы можете проверить это с помощью команды
podman network inspect <network_name>
. -
Используйте
podman-compose
правильно: Убедитесь, что вашdocker-compose.yml
файл корректен. Например, ваш файл выглядит правильно:
version: '3.1'
networks:
neta:
driver: bridge
services:
httpd:
image: httpd
container_name: httpd
networks:
- neta
mariadb:
image: mariadb
container_name: mariadb
networks:
- neta
-
Тестирование со связью: Если вы не можете ping’овать контейнеры друг с другом, попробуйте запустить
curl
для тестирования связи на определённые порты — это даст больше информации о том, доступен ли сервис. -
Проверка конфигурации iptables: Важно проверить, нет ли правил iptables, которые могут блокировать трафик между контейнерами. В случае использования rootless-режима, podman будет использовать специальные правила в iptables, чтобы изолировать сетевой трафик.
-
Рассмотрите возможность использования Pod: Поддержка Pod в Podman позволяет группировать контейнеры в одну логическую единицу. Контейнеры в одном Pod могут обращаться друг к другу по
localhost
, что может упростить сетевое взаимодействие.
Дополнительные рекомендации
Если проблемы продолжаются, рассмотрите следующие рекомендации:
-
Обновление Podman и Podman-Compose: Убедитесь, что вы используете последние доступные версии Podman и podman-compose, так как часто выпускаются обновления с исправлениями ошибок и улучшениями.
-
Чтение документации: Подробности можно найти в официальной документации Podman и Podman Compose.
Убедитесь, что вы также проверяете логи контейнеров для получения дополнительной информации о том, почему сети могут не взаимодействовать, как ожидается.