Как работает сетевое взаимодействие между контейнерами в Podman / podman-compose?

Вопрос или проблема

Я использую совместимую ОС 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

  1. Rootless-режим: Podman поддерживает запуск контейнеров в режиме без прав суперпользователя (rootless). При этом сетевые настройки могут отличаться от тех, к которым вы привыкли при использовании Docker. В частности, контейнеры, запущенные пользователями без прав суперпользователя, имеют свои уникальные сетевые пространства имен.

  2. Сетевые драйверы: Podman использует сеть bridge по умолчанию, как и Docker. Однако, в rootless-режиме необходимо убедиться, что такая сеть настроена правильно и контейнеры могут общаться друг с другом.

  3. Контейнерные имена как хосты: В Docker контейнеры могут обращаться друг к другу по имени. В Podman это может зависеть от конфигурации и версии. Если контейнеры подключены к одной и той же сети, вы должны иметь возможность использовать названия контейнеров для связи.

Решение проблемы

Чтобы устранить возникшие у вас трудности с доступом между контейнерами, попробуйте следующее:

  1. Проверьте настройки сети: Убедитесь, что ваши контейнеры действительно находятся в одной сети. Вы можете проверить это с помощью команды podman network inspect <network_name>.

  2. Используйте 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
  1. Тестирование со связью: Если вы не можете ping’овать контейнеры друг с другом, попробуйте запустить curl для тестирования связи на определённые порты — это даст больше информации о том, доступен ли сервис.

  2. Проверка конфигурации iptables: Важно проверить, нет ли правил iptables, которые могут блокировать трафик между контейнерами. В случае использования rootless-режима, podman будет использовать специальные правила в iptables, чтобы изолировать сетевой трафик.

  3. Рассмотрите возможность использования Pod: Поддержка Pod в Podman позволяет группировать контейнеры в одну логическую единицу. Контейнеры в одном Pod могут обращаться друг к другу по localhost, что может упростить сетевое взаимодействие.

Дополнительные рекомендации

Если проблемы продолжаются, рассмотрите следующие рекомендации:

  • Обновление Podman и Podman-Compose: Убедитесь, что вы используете последние доступные версии Podman и podman-compose, так как часто выпускаются обновления с исправлениями ошибок и улучшениями.

  • Чтение документации: Подробности можно найти в официальной документации Podman и Podman Compose.

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

Оцените материал
Добавить комментарий

Капча загружается...