Tetapkan IP statis untuk wadah Docker

205

Saya sekarang mencoba untuk menetapkan IP 172.17.0.1 statis ketika wadah Docker dimulai.

Saya menggunakan port 2122 sebagai port ssh wadah ini sehingga saya membiarkan wadah ini mendengarkan port 2122.

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

Perintah ini akan menjalankan wadah Docker dengan IP acak seperti 172.17.0.5, tapi saya perlu menetapkan IP tertentu ke wadah.

Script shell berikut adalah apa yang saya rujuk dokumentasi Docker dalam pengaturan jaringan lanjutan.

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

Skrip shell ini akan menetapkan IP statis 172.17.0.1 dan tautan ke denda dunia. Tetapi setiap kali saya mencoba ssh ke wadah ini dari lokal saya, itu tidak berhasil. Apa masalah yang mungkin saya temui?

LarryLo
sumber
Saya khawatir tidak ada jawaban sederhana untuk pertanyaan itu, lihat github.com/docker/docker/issues/6743 dan github.com/docker/docker/issues/1179 , dan baca github.com/jpetazzo/pipework
user29150
@larrylo dapatkah Anda mengonfirmasi bahwa Anda memulai sshd di dalam wadah?
Bryan
5
Anda membatalkan semua perutean yang dilakukan oleh daemon buruh pelabuhan untuk Anda. Wadah bukan VM.
user2105103
Ya, saya konfirmasi saya bisa mulai sshd di dalam wadah
LarryLo
5
Kemungkinan duplikat dari Bagaimana cara menetapkan alamat IP statis di wadah Docker?
Michael Hampton

Jawaban:

291

Mudah dengan Docker versi 1.10.1, build 9e83765.

Pertama, Anda perlu membuat jaringan buruh pelabuhan Anda sendiri (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

daripada hanya menjalankan gambar (saya akan mengambil ubuntu sebagai contoh)

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

lalu di shell ubuntu

ip addr

Selain itu Anda bisa menggunakan

  • --hostname untuk menentukan nama host
  • --add-host untuk menambahkan lebih banyak entri ke / etc / hosts

Documents (dan mengapa Anda perlu membuat jaringan) di https://docs.docker.com/engine/reference/commandline/network_create/

tidak bisa tidur
sumber
1
Jawaban yang bagus - Hanya menambahkan beberapa info tambahan: blog.jessfraz.com/post/ips-for-all-the-things
Ole
@cantSleepNow untuk beberapa alasan saya hanya perlu menggunakan jembatan buatan saya sendiri yang dibuat br0 yang dibuat dalam file antarmuka selama boot sistem (jadi TIDAK dibuat menggunakan pembuatan jaringan docker), bisakah Anda menyarankan saya bagaimana saya bisa mendapatkan efek yang sama dari - parameter -ip (dapatkan alamat IP tetap untuk wadah) tanpa membuat jembatan saya menggunakan buruh pelabuhan?
Mohammed Noureldin
@MohammedNoureldin Saya tidak sepenuhnya mengerti - juga terdengar seperti pertanyaan baru, saya pikir Anda harus bertanya seperti itu.
cantSleepNow
@cantSleepNow Maksudku, aku harus memperbaiki alamat IP kontainer meskipun saya TIDAK menggunakan jembatan kustom (jadi - parameter parameter tidak dapat digunakan), apakah Anda menyarankan cara untuk mendapatkannya?
Mohammed Noureldin
@MohammedNoureldin saya tidak yakin. Seperti yang saya katakan, posting pertanyaan Anda sebagai pertanyaan dan bukan sebagai komentar - mungkin ada seseorang yang tahu jawabannya.
cantSleepNow
89

Untuk docker-composeAnda dapat menggunakan mengikutidocker-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

dari host Anda dapat menguji menggunakan:

docker-compose up -d
curl 172.20.128.2

Modern docker-composetidak sering mengubah alamat ip.

Untuk menemukan ips dari semua kontainer di docker-composedalam satu baris Anda gunakan:

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

Jika Anda ingin mengotomatisasi, Anda dapat menggunakan sesuatu seperti intisari contoh ini

zainengineer
sumber
2
Sepertinya ini hanya akan berfungsi di docker-compose v2, v3 rusak kompatibilitas.
Andrzej Rehmann
4
Saat menggunakan docker-compose v3 + hapusip_range
Andrzej Rehmann
Saya tidak mendapatkan ip_range. bukankah itu tercakup oleh subnet? Bagaimanapun, terima kasih! Itu memperbaiki saya "Saya harus mencari ip wadah mongo saya lagi" - masalah
Ben
1
apakah ada cara untuk menentukan alamat ip dalam menulis versi 3?
ealeon
2
Solusinya bekerja dengan baik bagi saya tanpa ip_range. Saya menggunakan versi: '3.4'.
Mikhail Morfikov
24

Bukan jawaban langsung tetapi bisa membantu.

Saya menjalankan sebagian besar layanan buruh pelabuhan saya yang terikat dengan ips statis menggunakan pendekatan berikut:

  1. Saya membuat alias ip untuk semua layanan pada host buruh pelabuhan
  2. Kemudian saya menjalankan setiap layanan yang mengalihkan port dari ip ini ke dalam wadah sehingga setiap layanan memiliki ip statis sendiri yang dapat digunakan oleh pengguna eksternal dan wadah lainnya.

Sampel:

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
sumber
Terima kasih ~ saya tahu ini. Sama seperti github.com/brandon-rhodes/fopnp/tree/m/playground . Saya akan mencobanya.
LarryLo
1
Ini adalah solusi yang sangat baik, saya hanya akan melampirkan tautan ini bagi pengguna baru untuk belajar tentang aliasing cyberciti.biz/faq/…
Mohammed Noureldin
Terima kasih atas solusi yang bagus.
RavinderSingh13
4

Ini bekerja untuk saya.

Buat jaringan dengan docker network create --subnet=172.17.0.0/16 selnet

Jalankan gambar buruh pelabuhan docker run --net selnet --ip 172.18.0.2 hub

Awalnya, saya mengerti

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

Solusi: Meningkatkan quadruple ke-2 dari IP [.18. bukannya 0,17.]

Nils Zenker
sumber
3
Ada 2 tahun lebih tua jawaban serupa / identik di tempat lain pada halaman ini: stackoverflow.com/a/35359185/694469
KajMagnus
2

Saya menemukan masalah ini selama upaya untuk merebus Avahi yang perlu menyadari IP publiknya berfungsi dengan baik. Menetapkan IP statis ke wadah rumit karena kurangnya dukungan untuk penetapan IP statis di Docker.

Artikel ini menjelaskan teknik cara menetapkan IP statis ke wadah di Debian :

  1. Layanan Docker harus dimulai dengan DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Saya berasumsi br0jembatan itu sudah dikonfigurasi.

  2. Kontainer harus dimulai dengan --cap-add=NET_ADMIN --net=bridge

  3. Wadah pre-up ip addr flush dev eth0di dalam /etc/network/interfacesdapat digunakan untuk mengabaikan alamat IP yang diberikan oleh Docker seperti dalam contoh berikut:


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. Skrip entri wadah harus dimulai dengan /etc/init.d/networking start. Juga skrip entri perlu mengedit atau mengisi /etc/hostsfile untuk menghapus referensi ke IP yang ditugaskan Docker.
Onlyjob
sumber
2

Anda dapat mengatur IP saat menjalankannya.

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

Lihat contoh saya di https://github.com/RvdGijp/mariadb-10.1-galera

Kasar sekali
sumber
sayangnya ini menambahkan satu alamat IP lagi, jika alamat IP ditugaskan dalam proses sebelumnya, ini menghasilkan dua alamat IP
davey
1

Anda dapat mengakses layanan kontainer lain dengan nama mereka ( ping apacheakan mendapatkan ip atau curl http://apacheakan mengakses layanan http) Dan ini bisa menjadi alternatif dari ip statis.

Guisong He
sumber
3
Dalam versi buruh pelabuhan 1,8 ini bekerja secara langsung. Di versi yang lebih baru, Anda harus menautkan wadah-wadah ini dengan salah.
Guisong He