docker -compose - Как указать сеть для прослушивания порта? - PullRequest
0 голосов
/ 26 февраля 2020

Я использую:
docker-compose 3.7
docker engine 18.09.7

В docker -компонентном файле, как мне указать, какую сеть я хочу указать прослушивающий порт c привязан к?
Например:

version: "3.7"
services:
  service-a:
    image: service-a:0.1.0
    networks:
      - network1
  service-b:
    image: service-b:0.1.0
    networks:
      - network1
      - network2
    expose:
      - "8000"
      - "9000"
    ports:
      - target: 8000
        published: 8000
        protocol: tcp
        mode: host
      - target: 9000
        published: 9000
        protocol: tcp
        mode: host
  service-c:
    image: service-c:0.1.0
    networks:
      - network2
networks:
  network1:
  network2:

В этом надуманном примере service-b прослушивает порт 8000 и 9000.
Есть ли способ указать этот порт 8000 доступен только на network1, а 9000 доступен только на network2?

Это было бы наиболее полезно в случае, когда сервер прослушивает, скажем, 0.0.0.0 в качестве хоста.

1 Ответ

1 голос
/ 26 февраля 2020

Поэтому, если я правильно понял, вам нужно предоставить service-a доступ к порту 8000 из service-b, но заблокировать любой доступ от service-a к порту 9000 из service-b. И то же самое для service-c, но наоборот?

Для этого вам сначала нужно узнать, как работает сеть с docker-compose: для каждой сети в разделе networks docker-compose (в этом case) создает виртуальную сеть, подключающую к ней виртуальное сетевое устройство хост-машины, а также виртуальное сетевое устройство каждого контейнера, подключенного к сети. Каждое из этих виртуальных устройств может напрямую взаимодействовать друг с другом в одной и той же виртуальной сети, в то время как различные виртуальные сети обычно изолированы друг от друга.

Ключевое слово expose теперь фактически не обнажает любые порты, но вместо этого только документы намерение, что процесс будет прослушивать этот порт (ы). Вы можете проверить эту информацию о контейнере, используя docker inspect. Кроме того, добавленные метаданные expose на самом деле не делают намного больше, см. документацию . Таким образом, в этом случае он не имеет реального использования.

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

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

Один из способов сделать это - изменить само приложение , чтобы оно не прослушивало 0.0.0.0 с каждым портом, а связывалось только с адресом соответствующая сеть (network1 / network2). Но это требует изменений в специфике приложения c и определения каким-либо образом правильного адреса для каждого порта.

Другим способом является внедрение собственных правил iptables для блокировки нежелательного доступа между контейнерами, см. документы по этому . Недостатком этого является то, что это должно быть сделано полностью за пределами docker и docker-compose.

И, наконец, есть это решение hacki sh: вместо блокировки нежелательного доступа допускаются только явно указанные в белом списке порты :

version: "3.7"
services:
  service-a:
    image: service-a:0.1.0
    networks:
      - network1
  service-b:
    image: service-b:0.1.0
    networks:
      - network2
    ports:
      - 172.101.0.1:8000:8000
      - 172.103.0.1:9000:9000
  service-c:
    image: service-c:0.1.0
    networks:
      - network3
networks:
  network1:
    ipam:
      config:
        - subnet: 172.101.0.0/24
  network2:
  network3:
    ipam:
      config:
        - subnet: 172.103.0.0/24

Это работает путем назначения каждого контейнера в его собственную собственную сеть , полностью изолирующую их друг от друга. Но для network1 / network3 мы явно настраиваем su bnet, чтобы мы знали IP-адреса проходов (172.101.0.1 / 172.103.0.1) из них, которые назначены виртуальным сетевым устройствам хоста .

Теперь мы можем «выставить» порты 8000 / 9000 контейнера service-b на эти IP-адреса хоста, т.е. порт 8000 на 172.101.0.1 будет перенаправлен на порт 8000 из контейнера service-b. 172.101.0.1 принадлежит хосту, но является частью network1 и, таким образом, service-a может получить к нему доступ, предоставляя ему доступ только к одному порту service-b.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...