Docker запускает контейнеры в виртуальных сетях:
docker network ls
NETWORK ID NAME DRIVER SCOPE
1234567890ab bridge bridge local
cdef01234567 deployment_default bridge local
890abcdef012 host host local
34567890abcd none null local
Эти сопоставления портов связывают порты на вашем хост-компьютере с контейнерами, работающими в этих сетях.
Думайте о каждом контейнере как о своем локальном хосте свсе доступные ему порты.В этом случае ваш экземпляр MySQL предоставляет порт 3306
в своем контейнере.Это необходимо, потому что двоичный файл в контейнере также работает на 3306
.Это объясняет, почему в контейнере вы видите 3306
.
. Очень удобно, когда вы запускаете контейнер, Docker предоставляет механизм для переназначения портов контейнера (например, 3306
) на другие порты (например,9991
) на вашем хост-компьютере.
Это больше, чем просто удобство.Если вы хотите запустить второй образ контейнера MySQL и он также настроен для 3306
, вы не сможете получить доступ к обоим контейнерам одновременно, поскольку они будут конфликтовать с портом 3306
на вашем хосте.
Итак, вы определяете отображение порта, как вы сделали.В вашем примере с локальной рабочей станции (хоста) вы можете получить доступ к экземпляру контейнера MySQL на localhost:9991
, и Docker переназначит трафик этого порта на порт контейнера MySQL 3306
, и контейнер направит его в двоичный файл MySQL (также на 3306
).
Итак: 0.0.0.0:9991->3306/tcp
означает:
0.0.0.0
(псевдоним для любого адаптера на localhost
) 9991
порткарты трафика на порт этого контейнера 3306
- Использование TCP (еще один протокол, который вы увидите
UDP
)
Три дополнительных примечания:
- Dockerfile этого изображения может включать, например,
EXPOSE 3306
.Это чисто документально и никоим образом не влияет на команду docker run ... --publish=XXXX/3306..
. - Контейнеру не нужно публиковать порты на локальном хосте.Это необходимо сделать только в том случае, если к образу контейнера необходимо получить доступ с хоста.Если вы называете свои контейнеры и размещаете их в пользовательских сетях или используете Docker Compose, один контейнер может получить доступ к портам другого контейнера без доступа к портам для хоста.Предоставление таких портов должно быть (!) Соображением безопасности.
- Когда вы запускаете образ контейнера, Docker использует сеть по умолчанию.Разрешение сопоставления портов (
0.0.0.0:XXXX/YYYY
) на самом деле является комбинацией определения того, какой контейнер (разрешение имени хоста) и какой порт.