Przypisz statyczny adres IP do kontenera Docker

205

Usiłuję teraz przypisać statyczny adres IP 172.17.0.1 podczas uruchamiania kontenera Docker.

Używam portu 2122 jako portu ssh tego kontenera, dzięki czemu ten kontener może nasłuchiwać portu 2122.

sudo docker run -i -t -p 2122:2122 ubuntu

To polecenie uruchomi kontener Docker z losowym adresem IP, takim jak 172.17.0.5, ale muszę przypisać konkretny adres IP do kontenera.

Poniższy skrypt powłoki odwołuje się do dokumentacji Docker w zaawansowanych ustawieniach sieciowych.

pid=$(sudo docker inspect -f '{{.State.Pid}}' <container_name> 2>/dev/null)
sudo rm -rf /var/run/netns/*
sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
sudo ip link add A type veth peer name B
sudo brctl addif docker0 A
sudo ip link set A up
sudo ip link set B netns $pid
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link delete eth0
sudo ip netns exec $pid ip link set dev B name eth0
sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link set eth0 up
sudo ip netns exec $pid ip addr add 172.17.0.1/16 dev eth0
sudo ip netns exec $pid ip route add default via 172.17.42.1

Ten skrypt powłoki przypisze statyczny adres IP 172.17.0.1 i link do grzywny na świecie. Ale ilekroć próbuję ssh do tego kontenera z mojego lokalnego, to nie działa. Jaki problem prawdopodobnie napotkałem?

LarryLo
źródło
Obawiam się, że nie ma prostej odpowiedzi na to pytanie, zobacz github.com/docker/docker/issues/6743 i github.com/docker/docker/issues/1179 i przeczytaj github.com/jpetazzo/pipework
użytkownik2915097
@larrylo czy możesz potwierdzić, że uruchomiłeś sshd w kontenerze?
Bryan
5
Cofasz cały routing, który wykonuje dla ciebie demon dokera. Kontenery nie są maszynami wirtualnymi.
user2105103
Tak, potwierdzam, że mogę uruchomić sshd w kontenerze
LarryLo
5
Możliwy duplikat Jak ustawić statyczny adres IP w kontenerze Docker?
Michael Hampton

Odpowiedzi:

291

Łatwo dzięki Docker w wersji 1.10.1, kompilacja 9e83765.

Najpierw musisz stworzyć własną sieć dokerów (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

niż po prostu uruchom obraz (wezmę na przykład Ubuntu)

docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash

następnie w powłoce ubuntu

ip addr

Dodatkowo możesz użyć

  • --hostname aby podać nazwę hosta
  • --add-host aby dodać więcej wpisów do / etc / hosts

Dokumenty (i dlaczego musisz utworzyć sieć) na https://docs.docker.com/engine/reference/commandline/network_create/

cantSleepNow
źródło
1
Świetna odpowiedź - Właśnie dodając kilka dodatkowych informacji: blog.jessfraz.com/post/ips-for-all-the-things
Ole
@ cantSleepNow z jakiegoś powodu muszę po prostu użyć własnego domyślnie utworzonego mostu br0, który jest tworzony w pliku interfejsów podczas uruchamiania systemu (więc NIE jest tworzony przy użyciu tworzenia sieci dokującej), czy możesz mi zasugerować, jak mogę uzyskać ten sam efekt - -ip parametr (uzyskać stały adres IP kontenera) bez tworzenia mostu za pomocą okna dokowanego?
Mohammed Noureldin
@MohammedNoureldin Nie do końca rozumiem - brzmi to również nowe pytanie, myślę, że powinieneś je zadać jako takie.
cantSleepNow
@ cantSleepNow Mam na myśli, że muszę naprawić adres IP kontenera, chociaż NIE używam niestandardowego mostu (więc nie można użyć parametru --ip), czy sugerujesz jak to zrobić?
Mohammed Noureldin
@MohammedNoureldin Nie jestem pewien. Tak jak powiedziałem, zamieść swoje pytanie jako pytanie, a nie jako komentarz - być może ktoś zna odpowiedź.
cantSleepNow
89

Dla docker-composemożna używać następującychdocker-compose.yml

version: '2'
services:
  nginx:
    image: nginx
    container_name: nginx-container
    networks:
      static-network:
        ipv4_address: 172.20.128.2
networks:
  static-network:
    ipam:
      config:
        - subnet: 172.20.0.0/16
          #docker-compose v3+ do not use ip_range
          ip_range: 172.28.5.0/24

z hosta możesz przetestować za pomocą:

docker-compose up -d
curl 172.20.128.2

Modern docker-composenie zmienia często adresu IP.

Aby znaleźć Ips wszystkich kontenerów w docker-composejednym wierszu, użyj:

for s in `docker-compose ps -q`; do echo ip of `docker inspect -f "{{.Name}}" $s` is `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $s`; done

Jeśli chcesz zautomatyzować, możesz użyć czegoś takiego jak ten przykład

zainengineer
źródło
2
Wygląda na to, że będzie to działało tylko w wersji dokera-komponowania v2, v3 zepsuła kompatybilność.
Andrzej Rehmann
4
Podczas korzystania z docker-compose v3 + removeip_range
Andrzej Rehmann
Nie dostaję jednak ip_range. czy nie obejmuje to podsieć? W każdym razie dziękuję! To naprawiło moje „Muszę ponownie sprawdzić ip mojego kontenera mangowego” - problem
Ben
1
czy istnieje sposób na podanie adresu IP w wersji 3 do tworzenia?
ealeon
2
Rozwiązanie działa dla mnie dobrze bez ip_range. Używam wersji: „3.4”.
Michaił Morfikow
24

Nie bezpośrednia odpowiedź, ale może pomóc.

Korzystam z większości moich dokowanych usług powiązanych z własnymi statycznymi serwerami IP przy użyciu następnego podejścia:

  1. Tworzę aliasy IP dla wszystkich usług na hoście dokera
  2. Następnie uruchamiam każdą usługę przekierowującą porty z tego adresu IP do kontenera, aby każda usługa miała własny statyczny adres IP, z którego mogliby korzystać użytkownicy zewnętrzni i inne kontenery.

Próba:

docker run --name dns --restart=always -d -p 172.16.177.20:53:53/udp dns
docker run --name registry --restart=always -d -p 172.16.177.12:80:5000 registry
docker run --name cache --restart=always -d -p 172.16.177.13:80:3142 -v /data/cache:/var/cache/apt-cacher-ng cache
docker run --name mirror --restart=always -d -p 172.16.177.19:80:80 -v /data/mirror:/usr/share/nginx/html:ro mirror
...
ISanych
źródło
Dzięki ~ Wiem to. Podobnie jak github.com/brandon-rhodes/fopnp/tree/m/playground . Spróbuję.
LarryLo,
1
To bardzo dobre rozwiązanie, po prostu dołączę
Mohammed Noureldin
Dziękuję za miłe rozwiązanie.
RavinderSingh13
4

To działa dla mnie.

Utwórz sieć za pomocą docker network create --subnet=172.17.0.0/16 selnet

Uruchom obraz dokera docker run --net selnet --ip 172.18.0.2 hub

Na początku mam

docker: Error response from daemon: Invalid address 172.17.0.2: It does not belong to any of this network's subnets.
ERRO[0000] error waiting for container: context canceled

Rozwiązanie: Zwiększono 2. czterokrotność IP [.18. zamiast .17.]

Nils Zenker
źródło
3
Gdzie
2

Natknąłem się na ten problem podczas próby dokowania Avahi, która musi być świadoma swojego publicznego adresu IP, aby działać poprawnie. Przypisywanie statycznego adresu IP do kontenera jest trudne ze względu na brak obsługi przypisywania statycznego adresu IP w Dockerze.

W tym artykule opisano technikę przypisywania statycznego adresu IP do kontenera w systemie Debian :

  1. Usługa dokowania powinna zostać uruchomiona z DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Zakładam, że br0most jest już skonfigurowany.

  2. Kontener powinien zacząć --cap-add=NET_ADMIN --net=bridge

  3. Wewnątrz pojemnika pre-up ip addr flush dev eth0w /etc/network/interfacesmoże być używany do odwoływania adres IP przypisany przez Döcker jak w poniższym przykładzie:


auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    pre-up ip addr flush dev eth0
    address 192.168.0.249
    netmask 255.255.255.0
    gateway 192.168.0.1
  1. Skrypt wejściowy kontenera powinien zaczynać się od /etc/init.d/networking start. Również skrypt wejściowy musi edytować lub wypełniać /etc/hostsplik, aby usunąć odniesienia do adresu IP przypisanego do dokera.
Onlyjob
źródło
2

Możesz ustawić adres IP podczas jego uruchamiania.

docker run --cap-add=NET_ADMIN -dit imagename /bin/sh -c "/sbin/ip addr add 172.17.0.12 dev eth0; bash"

Zobacz mój przykład na https://github.com/RvdGijp/mariadb-10.1-galera

Jak niegrzecznie
źródło
niestety dodaje to jeszcze jeden adres IP, jeśli adres IP został wcześniej przypisany w procesie, skutkuje to posiadaniem dwóch adresów IP
davey
1

Możesz uzyskać dostęp do usługi innych kontenerów po nazwie ( ping apachedostanie ip lub curl http://apacheuzyska dostęp do usługi http). Może to być alternatywa dla statycznego adresu ip.

Guisong He
źródło
3
W wersji 1.8 dokera działa to bezpośrednio. W nowszej wersji musisz połączyć te kontenery na pięści.
Guisong He