Поэтому, если я правильно понял, вам нужно предоставить 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
.