web-dev-qa-db-fra.com

Comment attribuer un mappage de port à un conteneur Docker existant?

Je ne suis pas sûr d'avoir mal compris quelque chose ici, mais il semble qu'il soit uniquement possible de définir des mappages de ports en créant un nouveau conteneur à partir d'une image. Existe-t-il un moyen d'attribuer un mappage de port à un conteneur Docker existant?

288
Thasmo

Je suis aussi intéressé par ce problème.

Comme mentionné dans @Thasmo , les redirections de ports peuvent être spécifiées UNIQUEMENT avec la commande docker run.
D'autres commandes, docker start n'a pas l'option -p et docker port n'affiche que les transferts en cours.

Pour ajouter des redirections de ports, je suis toujours les étapes suivantes.

  1. stop conteneur en cours d'exécution

    docker stop test01
    
  2. commit le conteneur

    docker commit test01 test02
    

    NOTE: Ce qui précède, test02 est une nouvelle image que je construis à partir du conteneur test01.

  3. re - run à partir de l'image validée

    docker run -p 8080:8080 -td test02
    

Où le premier 8080 est le port local et le second 8080 est le port de conteneur.

350
Fujimoto Youichi

Vous pouvez modifier le mappage de port en modifiant directement le fichier hostconfig.json à l'adresse /var/lib/docker/containers/[hash_of_the_container]/hostconfig.json

Vous pouvez déterminer le [hash_of_the_container] via la commande docker inspect <container_name> et la valeur du champ "Id" est le hachage. 

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

Vous n'avez donc pas besoin de créer une image avec cette approche. Vous pouvez également changer l'indicateur de redémarrage ici.

P.S. Vous pouvez visiter https://docs.docker.com/engine/admin/ pour savoir comment redémarrer correctement votre moteur de menu fixe selon votre ordinateur hôte. J'ai utilisé Sudo systemctl restart docker pour redémarrer mon moteur de docker fonctionnant sous Ubuntu 16.04

173
holdfenytolvaj

Si par "existant" vous voulez dire "en cours d'exécution", il n'est pas (actuellement) possible d'ajouter un mappage de port.

Cependant, vous pouvez ajouter dynamiquement une nouvelle interface réseau avec par exemple Pipework , si vous devez exposer un service dans un conteneur en cours d'exécution sans l'arrêter/le redémarrer.

22
jpetazzo

Vous ne savez pas si vous pouvez appliquer le mappage de port à un conteneur en cours d'exécution. Vous pouvez appliquer une redirection de port lors de l'exécution d'un conteneur, ce qui est différent de la création d'un nouveau conteneur. 

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

va commencer à courir conteneur. Ce tutoriel explique la redirection de port. 

17
rajalokan

Dans l'exemple de Fujimoto Youichi, test01 est un conteneur, alors que test02 est une image.

Avant de procéder à docker run, vous pouvez supprimer le conteneur d'origine, puis lui attribuer le même nom:

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

(Utiliser -P pour exposer les ports à des ports aléatoires plutôt que de les affecter manuellement).

11
Luca

Éditer hostconfig.json semble ne pas fonctionner maintenant. Il ne se termine que lorsque ce port est exposé mais non publié sur l'hôte. Commiter et recréer des conteneurs n'est pas la meilleure approche pour moi. Personne n'a mentionné docker network?

La meilleure solution serait d'utiliser un proxy inversé au sein du même réseau

  1. Créez un nouveau réseau si votre conteneur précédent ne figure dans aucun de ceux nommés.

    docker network create my_network

  2. Joignez votre conteneur existant au réseau créé

    docker network connect my_network my_existing_container

  3. Démarrez un service proxy inversé (par exemple, nginx) en publiant les ports dont vous avez besoin et en rejoignant le même réseau.

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

    Supprimez éventuellement le default.conf dans nginx

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

  4. Créer une nouvelle configuration 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;
        }
    }
    

    Copiez la configuration dans le conteneur nginx.

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

  5. Redémarrez nginx

    docker restart nginx

Avantages : Pour publier de nouveaux ports, vous pouvez en toute sécurité arrêter/mettre à jour/recréer le conteneur nginx à votre guise sans toucher au conteneur commercial. Si vous avez besoin de zéro temps d’arrêt pour nginx, il est possible d’ajouter davantage de services de proxy inversés rejoignant le même réseau. En outre, un conteneur peut rejoindre plusieurs réseaux.

Modifier:

Pour inverser les services proxy non-http, le fichier de configuration est un peu différent. Voici un exemple simple:

upstream my_service {
    server my_existing_container:9000;
}

server {
    listen 9000;
    proxy_pass my_service;
}
6
Sean C.

Si vous exécutez docker run <NAME>, une nouvelle image apparaîtra, ce qui n'est probablement pas ce que vous voulez.

Si vous souhaitez modifier une image actuelle, procédez comme suit:

docker ps -a

Prenez l'identifiant de votre conteneur cible et allez à:

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

Arrêtez le conteneur:

docker stop <NAME>

Changer les fichiers

vi config.v2.json

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

Et changer de fichier 

vi hostconfig.json

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

Redémarrez votre menu fixe et cela devrait fonctionner.

4
docker-noob

nous utilisons des outils pratiques comme ssh pour y parvenir facilement.

J'utilisais ubuntu Host et l'image de menu fixe basée sur Ubuntu.

  1. Openssh-client est installé dans le menu fixe.
  2. En dehors du menu fixe (hôte), le serveur openssh-server est installé.

quand un nouveau port doit être cartographié,

à l'intérieur du menu fixe, exécutez la commande suivante

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

172.17.0.1 était l'adresse IP de l'interface du menu fixe .__ (vous pouvez l'obtenir en exécutant ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" " sur l'hôte).

ici, le port local 8888 était mappé sur l'hôte 8888. Vous pouvez modifier le port si nécessaire.

si vous avez besoin d'un autre port, vous pouvez tuer le SSH et y ajouter une ligne supplémentaire de -R avec le nouveau port.

J'ai testé cela avec Netcat.

3
melchi
  1. Arrêtez le moteur de menu fixe et ce conteneur.
  2. Allez dans le répertoire /var/lib/docker/containers/${container_id} et éditez hostconfig.json
  3. Éditez PortBindings.HostPort que vous voulez changer.
  4. Démarrer le moteur et le conteneur de docker.
1
ezileli

Si vous n'êtes pas à l'aise avec la configuration en profondeur de Docker, IPtables serait votre ami.

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}

Ceci est juste une astuce et non une méthode recommandée, cela fonctionne avec mon scénario car je ne pouvais pas arrêter le conteneur, j'espère vous aider aussi.

1
Mansur Ali

Pour les utilisateurs Windows et Mac, il existe maintenant un autre moyen assez simple et convivial de changer le port de mappage:

  1. télécharger le kitematic

  2. allez dans la page des paramètres du conteneur, dans l'onglet des ports, vous pouvez directement modifier le port publié.

  3. redémarrer le conteneur

0
john

En complément de réponse de @ Fujimoto-Youichi

Vous pouvez également utiliser $ docker run -P CONTAINER pour mapper les ports de manière aléatoire lors de la création de votre conteneur, mais faites attention à la sécurité ascpect!

-P eq à --publish-all: "Il publie tous les ports exposés sur des ports aléatoires",

puis exécutez docker inspect CONTAINER pour mapper les ports, comme indiqué dans l'image ci-dessous:

.  docker inspect for a rabbitmq container show all ports mapping

En savoir plus sur docker run -P dans docker run

0
aitbahaa