Обмен данными между контейнерами#

Сетевые режимы и уровни#

В Podman существует несколько сетевых режимов:

  • bridge - создает еще один сетевой мост по умолчанию;

  • container:<id> - использует общую сеть с контейнером под идентификатором <id>;

  • host - использует сетевой стек хоста;

  • network-id - использует пользовательскую сеть, созданную командой podman;

  • private - создает новую сеть для контейнера;

  • slirp4nets - создает пользовательский сетевой стек. Используется по умолчанию для контейнеров пользователей без административных полномочий.

Примечание

Режим хоста предоставляет контейнеру полный доступ к локальным системным службам, таким как D-bus, а также системе межпроцессного взаимодействия (IPC), поэтому считается небезопасным.

Проверка сетевых настроек контейнера#

Используйте команду podman inspect с опцией --format для отображения отдельных элементов из выходных данных podman inspect.

  1. Раскройте IP-адрес контейнера:

    podman inspect --format='{{.NetworkSettings.IPAddress}}' <containerName>
    
  2. Отобразите все сети, к которым подключен контейнер:

    podman inspect --format='{{.NetworkSettings.Networks}}' <containerName>
    
  3. Выведите отображенние портов:

    podman inspect --format='{{.NetworkSettings.Ports}}' <containerName>
    

Взаимодействие между контейнером и приложением#

Между контейнером и приложением доступен обмен данными. Порты приложения находятся в состоянии прослушивания или в открытом состоянии. Они автоматически подключаются к сети контейнера и служат для связи с ним. По умолчанию веб-сервер прослушивает порт 80.

Для установления связи контейнера myubi с приложением web-container выполните следующие шаги:

  1. Запустите контейнер с именем web-container:

    podman run -dt --name=web-container docker.io/library/httpd
    
  2. Выведите список всех контейнеров:

    podman ps -a
    

    Пример вывода команды:

    CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS            PORTS       NAMES
    b8c057333513  docker.io/library/httpd:latest  httpd-foreground  4 seconds ago  Up 5 seconds ago              web-container
    
  3. Проверьте контейнер и отобразите его IP-адрес:

    podman inspect --format='{{.NetworkSettings.IPAddress}}' web-container
    

    Пример вывода команды:

    xx.xx.x.x
    
  4. Запустите контейнер myubi и убедитесь, что веб-сервер работает:

    podman run -it --name=myubi ubi9/ubi curl хх.хх.х.х:хх
    

Связь между контейнером и хостом#

По умолчанию сеть podman - это сетевой мост. Это означает, что сетевое устройство образует мост между сетями контейнера и хоста.

Используется информация из сценария «Взаимодействие между контейнером и приложением».

  1. Убедитесь, что мост настроен:

    podman network inspect podman | grep bridge
    

    Пример вывода команды:

        "bridge": "cni-podman0",
        "type": "bridge"
    
  2. Отобразите конфигурацию сети хоста:

    ip addr show cni-podman0
    

    Пример вывода команды:

    6: cni-podman0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether 62:af:a1:0a:ca:2e brd ff:ff:ff:ff:ff:ff
        inet hh.hh.hh.hh/16 brd hh.hh.hh.hh scope global cni-podman0
           valid_lft forever preferred_lft forever
        inet6 fe80::60af:a1ff:fe0a:ca2e/64 scope link
           valid_lft forever preferred_lft forever
    

    IP-адрес web-container - это cni-podman0, а сеть подключена к хосту с помощью моста.

  3. Проверьте web-container и раскройте его IP-адрес:

    podman inspect --format='{{.NetworkSettings.IPAddress}}' web-container
    

    Пример вывода команды:

    xx.xx.x.x
    
  4. Получите доступ к web-container напрямую с хоста:

    curl xx.xx.x.x:xx
    

    Пример вывода команды:

    <html><body><h1>It works!</h1></body></html>
    

Связь между контейнерами с использованием распределения портов(port mapping)#

Наиболее удобный способ взаимодействия между двумя контейнерами — использовать публикуемые порты. Порты могут быть опубликованы двумя способами: автоматически или вручную.

  1. Запустите непубликуемый контейнер:

    podman run -dt --name=web1 ubi9/httpd-24
    
  2. Запустите автоматически публикуемый контейнер:

    podman run -dt --name=web2 -P ubi9/httpd-24
    
  3. Запустите вручную публикуемый контейнер и опубликуйте порт контейнера 80:

    podman run -dt --name=web3 -p 9090:80 ubi9/httpd-24
    
  4. Раскройте список всех контейнеров:

    podman ps
    

    Пример вывода команды:

    CONTAINER ID  IMAGE                                            COMMAND               CREATED         STATUS             PORTS                                             NAMES
    f12fa79b8b39  registry.example.ru/ubi9/httpd-24:latest  /usr/bin/run-http...    23 seconds ago  Up 24 seconds ago                                                    web1
    9024d9e815e2  registry.example.ru/ubi9/httpd-24:latest  /usr/bin/run-http...    13 seconds ago  Up 13 seconds ago  0.0.0.0:43595->8080/tcp, 0.0.0.0:42423->8443/tcp  web2
    03bc2a019f1b  registry.example.ru/ubi9/httpd-24:latest  /usr/bin/run-http...    2 seconds ago   Up 2 seconds ago   0.0.0.0:9090->80/tcp                              web3
    

    В выводе представлена информация, что контейнер web1 не имеет опубликованных портов и доступен только по контейнерной сети или мосту. Контейнер web2 автоматически сопоставил порты 43595 и 42423 для публикации портов приложения 8080 и 8443 соответственно. Порт контейнера web3 опубликован вручную. Порт хоста 9090 сопоставлен порту контейнера 80.

    Примечание

    Автоматическое сопоставление портов возможно, потому что образregistry.example.ru./9/httpd-24 содержит команды EXPOSE 8080 и EXPOSE 8443 в Containerfile.

  5. Отобразите IP-адреса контейнеров web1 и web3:

    podman inspect --format='{{.NetworkSettings.IPAddress}}' web1
    podman inspect --format='{{.NetworkSettings.IPAddress}}' web3
    
  6. Свяжитесь с контейнером web1, используя обозначение \<IP>:\<port>:

    curl xx.xx.x.xx:xxxx
    

    Пример вывода команды:

    ...
    <title>Test Page for the HTTP Server</title>
    ...
    
  7. Свяжитесь с контейнером web2, используя обозначения localhost:\<port>:

    curl localhost:43595
    

    Пример вывода команды:

    ...
    <title>Test Page for the HTTP Server</title>
    ...
    
  8. Свяжитесь с контейнером web3 при помощи обозначения \<IP>:\<port>:

    curl hh.hh.hh.hh:<port>
    

    Пример вывода команды:

    ...
    <title>Test Page for the HTTP Server</title>
    ...
    

Связь между контейнерами с использованием DNS#

При включенном DNS-плагине используйте имя контейнера для связи с ним.

  1. Запустите контейнер receiver, подключенный к сети mynet:

    podman run -d --net mynet --name receiver ubi9 sleep 3000
    
  2. Запустите контейнер sender и свяжитесь с контейнером receiver при помощи имени:

    podman run -it --rm --net mynet --name sender alpine ping receiver
    

    Пример вывода команды:

    PING rcv01 (00.00.0.0): 56 data bytes
    64 bytes from 00.00.0.0: seq=0 ttl=42 time=0.041 ms
    64 bytes from 00.00.0.0: seq=1 ttl=42 time=0.125 ms
    64 bytes from 00.00.0.0: seq=2 ttl=42 time=0.109 ms
    ~~~0
    
  3. Для выхода используйте сочетание клавиш CTRL+C.

В выводе представлена информация, что контейнер sender может проверять контейнер receiver с помощью ping-запросов, используя его имя.

Связь между двумя контейнерами в pod#

Контейнеры в рамках одного pod делят между собой IP-адреса, MAC-адреса и распределяемые порты (port mapping). Для обмена данными между контейнерами в одном pod используется обозначение localhost:port.

  1. Создайте pod с именем web-pod:

    podman pod create --name=web-pod
    
  2. Запустите в pod web-container:

    podman container run -d --pod web-pod --name=web-container docker.io/library/httpd
    
  3. Выведите список всех pods и контейнеров, связанных с ними:

    podman ps --pod
    

    Пример вывода команды:

    CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS            PORTS       NAMES               POD ID        PODNAME
    58653cf0cf09  k8s.gcr.io/pause:3.5                              4 minutes ago  Up 3 minutes ago              4e61a300c194-infra  4e61a300c194  web-pod
    b3f4255afdb3  docker.io/library/httpd:latest  httpd-foreground  3 minutes ago  Up 3 minutes ago              web-container  4e61a300c194  web-pod
    
  4. Запустите контейнер web-pod на основе образа docker.io/library/fedora:

    podman container run -it --rm --pod web-pod docker.io/library/fedora curl localhost
    

    Пример вывода команды:

    <html><body><h1>It works!</h1></body></html>
    

Вывод демонстрирует, что связь с web-container установлена.

Взаимодействия в pod#

При создании pod необходимо публиковать порты для контейнера.

  1. Создайте pod с именем web-pod:

    podman pod create --name=web-pod-publish -p 80:80
    
  2. Раскройте список всех pod:

    podman pod ls
    

    Пример вывода команды:

    POD ID        NAME         STATUS   CREATED        INFRA ID      # OF CONTAINERS
    26fe5de43ab3  publish-pod  Created  5 seconds ago  7de09076d2b3  1
    
  3. Запустите веб-контейнер web-container внутри web-pod:

    podman container run -d --pod web-pod-publish --name=web-container docker.io/library/httpd
    
  4. Выведите список контейнеров:

    podman ps
    

    Пример вывода команды:

    CONTAINER ID  IMAGE                    COMMAND           CREATED             STATUS             PORTS               NAMES
    7de09076d2b3  k8s.gcr.io/pause:3.5                       About a minute ago  Up 23 seconds ago  0.0.0.0:80->80/tcp  26fe5de43ab3-infra
    088befb90e59  docker.io/library/httpd  httpd-foreground  23 seconds ago      Up 23 seconds ago  0.0.0.0:80->80/tcp  web-container
    
  5. Убедитесь, что web-container доступен:

    curl localhost:80
    

    Пример вывода команды:

    <html><body><h1>It works!</h1></body></html>
    

Присоединение pod к сети контейнеров#

Во время создания pod присоедините внутренние контейнеры к сети.

  1. Создайте сеть с именем pod-net:

    podman network create pod-net
    

    Пример вывода команды:

    /etc/cni/net.d/pod-net.conflist
    
  2. Создайте pod web-pod:

    podman pod create --net pod-net --name web-pod
    
  3. Запустите контейнер web-container внутри web-pod:

    podman run -d --pod web-pod --name=web-container docker.io/library/httpd
    
  4. Опционально: Выведите pods, с которыми связаны контейнеры:

    podman ps -p
    

    Пример вывода команды:

    CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS            PORTS       NAMES               POD ID        PODNAME
    b7d6871d018c   registry.example.ru/ubi9/pause:latest                             9 minutes ago  Up 6 minutes ago              a8e7360326ba-infra  a8e7360326ba  web-pod
    645835585e24  docker.io/library/httpd:latest  httpd-foreground  6 minutes ago  Up 6 minutes ago              web-container    a8e7360326ba  web-pod
    
  5. Для проверки работы раскройте список сетей, подключенных к контейнеру:

    podman ps --format="{{.Networks}}"
    

    Пример вывода команды:

    pod-net