Как назначить сопоставление портов существующим контейнерам Docker?

Я не уверен, что я что-то неправильно понял, но похоже, что можно установить сопоставления портов, создав новый контейнер из изображения. Есть ли способ назначить сопоставление портов существующему контейнеру Docker?

Ответ 1

Я также заинтересован в этой проблеме.

Как упоминалось в @Thasmo, переадресация портов может быть задана ТОЛЬКО командой docker run.
Другие команды, docker start -p не имеет -p а docker port -p отображает только текущие пересылки.

Чтобы добавить переадресацию портов, я всегда следую за этими шагами,

  1. остановить запуск контейнера

    docker stop test01
    
  2. совершить контейнер

    docker commit test01 test02
    

    ПРИМЕЧАНИЕ: выше, test02 - это новое изображение, которое я создаю из контейнера test01.

  3. re- запустить из переданного изображения

    docker run -p 8080:8080 -td test02
    

Где первый 8080 является локальным портом, а второй 8080 является портом контейнера.

Ответ 2

Вы можете изменить отображение портов, напрямую отредактировав файл hostconfig.json адресу /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json

Вы можете определить [hash_of_the_container] с помощью команды docker inspect <container_name> а значение поля "Id" - это хеш.

1) stop the container 
2) stop docker service (per Tacsiazuma comment)
3) change the file
4) restart your docker engine (to flush/clear config caches)
5) start the container

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

PS Вы можете посетить https://docs.docker.com/engine/admin/, чтобы узнать, как правильно перезапустить механизм докера в соответствии с вашим хост-компьютером. Я использовал sudo systemctl restart docker для перезапуска моего механизма докера, который работает в Ubuntu 16.04

Ответ 3

Если по "существующему" вы имеете в виду "запуск", то он (в настоящее время) не может добавить сопоставление портов.

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

Ответ 4

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

$ docker run -p <public_port>:<private_port> -d <image>  

начнет запуск контейнера. В этом руководстве объясняется перенаправление портов.

Ответ 5

В примере Fujimoto Youichi test01 есть контейнер, тогда как test02 - это изображение.

Прежде чем делать docker run, вы можете удалить исходный контейнер, а затем снова присвоить контейнеру одно и то же имя:

$ docker stop container01
$ docker commit container01 image01
$ docker rm container01
$ docker run -d -P --name container01 image01

(Используя -P, чтобы выставлять порты на случайные порты, а не вручную назначать).

Ответ 6

Редактирование hostconfig.json сейчас не работает. Это заканчивается только тем, что этот порт открыт, но не опубликован для хоста. Создание и воссоздание контейнеров - не лучший подход для меня. Никто не упоминал о docker network?

Лучшее решение будет использовать обратный прокси в той же сети

  1. Создайте новую сеть, если ваш предыдущий контейнер не указан ни в одной из них.

    docker network create my_network

  2. Присоедините существующий контейнер к созданной сети

    docker network connect my_network my_existing_container

  3. Запустите службу обратного прокси (например, nginx), публикуя нужные порты и подключаясь к той же сети.

    docker run -d --name nginx --network my_network -p 9000:9000 nginx

    При желании удалите default.conf в nginx

    docker exec nginx rm/etc/nginx/conf.d/default.conf

  4. Создать новую конфигурацию nginx

    server
    {
        listen 9000;
    
        location / {
            proxy_pass http://my_existing_container:9000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
    

    Скопируйте конфиг в контейнер nginx.

    docker cp./my_conf.conf nginx: /etc/nginx/conf.d/my_conf.conf

  5. Перезапустите nginx

    docker restart nginx

Преимущества: Чтобы опубликовать новые порты, вы можете безопасно остановить/обновить/воссоздать контейнер nginx по своему усмотрению, не касаясь бизнес-контейнера. Если вам нужно нулевое время простоя для nginx, можно добавить больше обращенных прокси-сервисов, присоединяющихся к той же сети. Кроме того, контейнер может присоединиться к нескольким сетям.

Редактировать:

Для обратного прокси не-http сервисы, файл конфигурации немного отличается. Вот простой пример:

upstream my_service {
    server my_existing_container:9000;
}

server {
    listen 9000;
    proxy_pass my_service;
}

Ответ 7

И наоборот, если вас не устраивает настройка глубины Docker, IPtables будет вашим другом.

iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT} -j DNAT --to-destination ${CONTAINERIP}:${YOURPORT}

iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source ${CONTAINERIP} --destination ${CONTAINERIP} --dport ${YOURPORT}

iptables -A DOCKER -j ACCEPT -p tcp --destination ${CONTAINERIP} --dport ${YOURPORT}

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

Ответ 8

Если вы запустите docker run <NAME> он создаст новое изображение, которое, скорее всего, не то, что вам нужно.

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

docker ps -a

Возьмите идентификатор вашего целевого контейнера и перейдите к:

cd /var/lib/docker/containers/<conainerID><and then some:)>

Остановить контейнер:

docker stop <NAME>

Изменить файлы

vi config.v2.json

"Config": {
    ....
    "ExposedPorts": {
        "80/tcp": {},
        "8888/tcp": {}
    },
    ....
},
"NetworkSettings": {
....
"Ports": {
     "80/tcp": [
         {
             "HostIp": "",
             "HostPort": "80"
         }
     ],

И изменить файл

vi hostconfig.json

"PortBindings": {
     "80/tcp": [
         {
             "HostIp": "",
             "HostPort": "80"
         }
     ],
     "8888/tcp": [
         {
             "HostIp": "",
             "HostPort": "8888"
         } 
     ]
 }

Перезагрузите докер, и он должен работать.

Ответ 9

мы используем удобные инструменты, такие как ssh, чтобы легко это сделать.

Я использовал образ хоста Ubuntu и основанный на Ubuntu образ докера.

  1. Внутри докера установлен openssh-клиент.
  2. На внешнем докере (хосте) установлен сервер openssh-server.

когда новый порт необходимо отобразить,

внутри докера выполните следующую команду

ssh -R8888:localhost:8888 <username>@172.17.0.1

172.17.0.1 был ip интерфейса докера (вы можете получить это, запустив ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" " на хосте).

здесь у меня был локальный порт 8888, сопоставленный с хостами 8888. Вы можете изменить порт при необходимости.

если вам нужен еще один порт, вы можете убить ssh и добавить к нему еще одну строку -R с новым портом.

Я проверил это с Netcat.

Ответ 10

  1. Остановите двигатель докера и этот контейнер.
  2. Перейдите в каталог /var/lib/docker/containers/${container_id} и отредактируйте hostconfig.json
  3. Отредактируйте PortBindings.HostPort, который вы хотите изменить.
  4. Запустите двигатель докера и контейнер.

Ответ 11

Для пользователей Windows и Mac теперь есть еще один довольно простой и удобный способ изменить порт отображения:

  • скачать kitematic

  • Перейдите на страницу настроек контейнера, на вкладке портов, вы можете напрямую изменить опубликованный порт там.

  • снова запустите контейнер

Ответ 12

В качестве дополнения к ответу @Fujimoto-Youichi

Вы также можете использовать $ docker run -P CONTAINER для случайного отображения портов при создании контейнера, но будьте осторожны с аспектами безопасности!

-P eq to --Publish-all: "Он публикует все открытые порты на случайных портах",

затем запустите docker inspect CONTAINER на соответствие портов Fin, как показано на рисунке ниже:

docker inspect for a rabbitmq container show all ports mapping

Узнайте больше о docker run -P в docker run -P Run

Ответ 13

Я нашел так решение:

$ docker stop container_name
$ docker commit container_name image_name
$ docker rm container_name

тогда вы можете создать новый контейнер из изображения:

$ docker run -d -P --name container_name_the_same_or_new image_name'''

и сейчас работает.

Ответ 14

Краткий ответ: Вы не можете назначить сопоставление портов существующему контейнеру Docker.

Ответ 15

Если вы просто хотите изменить порт запущенного контейнера, выполните следующие действия:

  • остановить существующий контейнер

    sudo docker stop NAME

  • теперь перезагружается с новым сопоставлением портов

    sudo docker run -d -p 81:80 NAME

где as:

"- d" для фона /deamon the docker

"- p" включить отображение портов

"81" внешний (открытый) порт, который вы используете для доступа в своем браузере.

"80" внутренний порт прослушивания контейнера док-станции