Faire en sorte que docker utilise IPv4 pour la liaison de port

97

J'ai l'hôte docker et à l'intérieur j'ai un conteneur.

L'hôte docker lie le port uniquement sur l'interface IPv6, pas sur IPv4.

C'est la sortie

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:55082           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::40280                :::*                    LISTEN      -
tcp6       0      0 :::5432                 :::*                    LISTEN      -
tcp6       0      0 :::40122                :::*                    LISTEN      -
tcp6       0      0 :::36378                :::*                    LISTEN      -
tcp6       0      0 :::40543                :::*                    LISTEN      -
tcp6       0      0 :::111                  :::*                    LISTEN      -

Maintenant, j'ai le port 40122 sur l'hôte à relier au port 22 sur le conteneur.

Je veux SSH dans ce conteneur mais je ne peux pas car il est uniquement lié à IPv6

Ceci est ma version docker Docker version 1.5.0, build a8a31ef

docker ps

201bde6c839a        myapp:latest   "supervisord -n"    3 weeks ago         Up 2 hours          0.0.0.0:40122->22/tcp, 0.0.0.0:40280->80/tcp, 0.0.0.0:40543->443/tcp   myapp

J'ai couru en utilisant docker run -d -P -p 40122:22

netstat -tlna

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3031          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::6379                 :::*                    LISTEN

ps aux

root         1  0.0  0.8  52440 16668 ?        Ss   00:53   0:03 /usr/bin/python /usr/bin/supervisord -n
root        49  0.0  0.1  17980  3048 ?        S    01:32   0:00 bash
root        64  0.0  0.1  46632  2712 ?        S    01:32   0:00 su -l vagrant
vagrant     65  0.0  0.1  21308  3760 ?        S    01:32   0:00 -su
root       288  0.0  0.1  17980  3088 ?        S    02:01   0:00 bash
root       304  0.0  0.1  46632  2720 ?        S    02:01   0:00 su -l vagrant
vagrant    305  0.0  0.1  21304  3804 ?        S    02:01   0:00 -su
vagrant    308  0.0  3.7 429616 75840 ?        Sl+  02:01   0:05 python ./manage.py shell_plus
root       654  0.0  0.4  47596  9848 ?        S    03:12   0:01 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       655  0.0  0.3  90280  7732 ?        S    03:12   0:00 nginx: master process /usr/sbin/nginx
www-data   656  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   657  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   658  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   659  0.0  0.2  90940  4500 ?        S    03:12   0:00 nginx: worker process
root       660  0.0  0.2  61372  5332 ?        S    03:12   0:00 /usr/sbin/sshd -D
root       669  0.0  0.4  37004  8892 ?        Sl   03:12   0:01 redis-server *:6379
root       856  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       857  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       858  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       859  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
vagrant    889  0.0  0.1  18692  2508 ?        R+   04:11   0:00 ps aux
user3214546
la source
Quelle commande avez-vous utilisée pour démarrer le conteneur? Publiez également la sortie du docker psmoment où le conteneur est en cours d'exécution.
Daniel t.
Pouvez-vous confirmer que sshd s'exécute réellement sur le conteneur? Exécutez docker exec -ti 201bde6c839a /bin/bash, une fois que vous y êtes, publiez la sortie de ps aux etnetstat -taln
Daniel t.
Dans mon hôte Docker, tous les ports docker écoutent sur IPv6 et n'ont aucun problème à se connecter à ssh sur les conteneurs.
Daniel t.
@Danielt. j'ai ajouté les informations. Je peux ssh en utilisant exec mais je ne peux pas ssh dans le conteneur directement de l'extérieur en utilisant le port hôte 40122 de mac
user3214546
Vous pourriez rencontrer ce problème github.com/docker/docker/issues/2174 , je ne suis pas sûr qu'il soit résolu. Pouvez-vous également partager comment vous essayez de vous connecter via ssh et l'erreur que vous obtenez?
Daniel t.

Réponses:

72

Comme @ daniel-t le souligne dans le commentaire: github.com/docker/docker/issues/2174 concerne l'affichage de la liaison uniquement avec IPv6 dans netstat, mais ce n'est pas un problème. Comme l'indique ce problème github:

Lors de la configuration du proxy, Docker demande l'adresse de bouclage '127.0.0.1', Linux se rend compte que c'est une adresse qui existe dans IPv6 (comme :: 0) et s'ouvre sur les deux (mais il s'agit formellement d'un socket IPv6). Lorsque vous exécutez netstat, il le voit et vous indique qu'il s'agit d'un IPv6 - mais il écoute toujours sur IPv4. Si vous avez un peu joué avec vos paramètres, vous avez peut-être désactivé cette astuce que fait Linux - en définissant net.ipv6.bindv6only = 1.

En d'autres termes, simplement parce que vous le voyez comme IPv6 uniquement, il est toujours capable de communiquer sur IPv4 à moins que vous n'ayez configuré IPv6 pour se lier uniquement sur IPv6 avec le paramètre net.ipv6.bindv6only. Pour être clair, net.ipv6.bindv6only doit être égal à 0 - vous pouvez exécuter sysctl net.ipv6.bindv6onlypour vérifier.

Michael
la source
4
C'est en fait un gros problème. Le cloud public comme Azure ne parle pas très bien IPV6, par exemple, l'équilibreur de charge public Azure tente un IPV4 en tant que backend.
Thomas Decaux
1
Il semble que vous deviez peut-être installer «Docker VM Extension» dans Azure et utiliser Ubuntu 14.04 LTS. Cependant, je ne pense pas qu'il y ait de problème avec ipv6 car il s'agit uniquement de l'hôte local, pas du réseau.
Michael
Vous avez raison, le problème était dans ma config (désactiver IPV6 n'est pas une bonne idée ^^)
Thomas Decaux
1
@bigdong vous voulez que l'ipv6 soit activé.
Michael
1
@Michael Tu es mon gain de temps. :)
lv0gun9
6

Le réglage net.ipv6.conf.all.forwarding=1résoudra le problème.

Cela peut être fait sur un système en direct en utilisant sudo sysctl -w net.ipv6.conf.all.forwarding=1

LuciferJack
la source
Cette réponse a un avantage: elle vous permet de "résoudre" le problème sans avoir à redémarrer le démon docker (la réponse avec le changement de configuration du docker ci-dessous le fait). En ce qui concerne le haut, la réponse sélectionnée: j'ai en fait eu sysctl net.ipv6.bindv6only=0tellement changer cette configuration n'a pas aidé.
pkoperek
2

Par défaut, docker utilise des sockets AF_INET6 qui peuvent être utilisées pour les connexions IPv4 et IPv6. Cela amène netstat à signaler une adresse IPv6 pour l'adresse d'écoute.

Depuis RedHat https://access.redhat.com/solutions/3114021

Gerassimos Mitropoulos
la source
0

Si vous souhaitez que vos ports de conteneur se lient à votre adresse ipv4, il suffit de:

  • trouver le fichier de paramètres
    • / etc / sysconfig / docker-network sur RedHat de même
    • / etc / default / docker-network sur Debian et pareil
  • modifier les paramètres réseau
    • ajouter DOCKER_NETWORK_OPTIONS = -ip = xx.xx.xx.xx
    • xx.xx.xx.xx étant votre véritable ipv4 (et non 0.0.0.0)
  • redémarrer docker deamon

fonctionne pour moi sur docker 1.9.1

Sylvain
la source
1
cela fonctionne-t-il sur Debian? ne devrait-il pas être / etc / default / docker?
Dimitri Kopriwa
1
@BigDong merci pour le commentaire, je suis sur RedHat comme OS donc le chemin est un peu différent d'un OS à l'autre J'ai essayé de refléter votre commentaire dans la réponse
Sylvain
-1

J'ai pu accéder au conteneur docker, après avoir désactivé SELinux

Pour désactiver temporairement SELinux #sudo setenforce 0

Mes conteneurs docker fonctionnaient sur Centos-7

Manjunath N
la source