Gán IP tĩnh cho Docker container


205

Bây giờ tôi đang cố gắng gán IP tĩnh 172.17.0.1 khi khởi động bộ chứa Docker.

Tôi sử dụng cổng 2122 làm cổng ssh của container này để tôi cho container này nghe cổng 2122.

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

Lệnh này sẽ chạy một container Docker với một IP ngẫu nhiên như 172.17.0.5, nhưng tôi cần gán một IP cụ thể cho container.

Kịch bản shell sau đây là những gì tôi tham chiếu tài liệu Docker trong cài đặt mạng nâng cao.

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

Kịch bản shell này sẽ gán một IP tĩnh 17,17.0.1 và liên kết với thế giới tốt. Nhưng bất cứ khi nào tôi cố gắng ssh đến container này từ địa phương của tôi, nó đã không hoạt động. Vấn đề gì tôi có thể gặp?


Tôi e rằng không có câu trả lời đơn giản cho câu hỏi đó, xem github.com/docker/docker/issues/6743github.com/docker/docker/issues/1179 và đọc github.com/jpetazzo/pipework
user2915097

@larrylo bạn có thể xác nhận rằng bạn đã bắt đầu một sshd bên trong container không?
Bryan

5
Bạn đang hoàn tác tất cả các định tuyến mà trình nền docker làm cho bạn. Các container không phải là VM.
dùng2105103

Có, tôi xác nhận rằng tôi có thể bắt đầu sshd bên trong container
LarryLo

Câu trả lời:


291

Dễ dàng với Docker phiên bản 1.10.1, xây dựng 9e83765.

Trước tiên, bạn cần tạo mạng docker của riêng bạn (mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

chứ không chỉ đơn giản là chạy hình ảnh (tôi sẽ lấy ubfox làm ví dụ)

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

sau đó trong vỏ Ubuntu

ip addr

Ngoài ra, bạn có thể sử dụng

  • --hostname để chỉ định tên máy chủ
  • --add-host để thêm nhiều mục vào / etc / hosts

Tài liệu (và tại sao bạn cần tạo mạng) tại https://docs.docker.com/engine/reference/commandline/network_create/


1
Câu trả lời tuyệt vời - Chỉ cần thêm một số thông tin bổ sung: blog.jessfraz.com/post/ips-for-all-the-things
Ole

@cantS ngủNow vì một số lý do tôi chỉ cần sử dụng cầu nối được tạo mặc định của riêng mình, được tạo trong tệp giao diện trong khi khởi động hệ thống (vì vậy nó không được tạo bằng cách sử dụng mạng docker), bạn có thể gợi ý cho tôi cách tôi có thể có được hiệu ứng tương tự - -ip tham số (lấy địa chỉ IP cố định cho một container) mà không tạo cầu nối của tôi bằng docker?
Mohammed Noureldin

@MohammedNoureldin Tôi không hiểu hết - cũng giống như một câu hỏi mới, tôi nghĩ bạn nên hỏi nó như vậy.
cantS ngủNow

@cantS ngủNow Ý tôi là tôi cần sửa địa chỉ IP của bộ chứa mặc dù tôi KHÔNG sử dụng cầu tùy chỉnh (vì vậy - không thể sử dụng tham sốip), bạn có đề xuất cách nào để có được điều đó không?
Mohammed Noureldin

@MohammedNoureldin Tôi không chắc. Như tôi đã nói, hãy đăng câu hỏi của bạn dưới dạng câu hỏi chứ không phải bình luận - có thể có ai đó biết câu trả lời.
cantS ngủNow

89

Để docker-composebạn có thể sử dụng sau đâydocker-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

từ máy chủ bạn có thể kiểm tra bằng cách sử dụng:

docker-compose up -d
curl 172.20.128.2

Hiện đại docker-composekhông thay đổi địa chỉ IP thường xuyên.

Để tìm ips của tất cả các container docker-composetrong một dòng sử dụng:

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

Nếu bạn muốn tự động hóa, bạn có thể sử dụng một cái gì đó như ý chính này


2
Có vẻ như điều này sẽ chỉ hoạt động trong docker-compose v2, v3 đã phá vỡ tính tương thích.
Andrzej Rehmann 27/03/18

4
Khi sử dụng docker-compose v3 + removeip_range
Andrzej Rehmann 27/03/18

Tôi không nhận được ip_range mặc dù. không được bao phủ bởi mạng con? Dù sao, cảm ơn bạn! Điều đó đã sửa lỗi "Tôi phải tìm lại ip của thùng chứa mongo của mình" - vấn đề
Ben

1
Có cách nào để chỉ định địa chỉ IP trong soạn thảo phiên bản 3 không?
ealeon

2
Các giải pháp hoạt động tốt cho tôi mà không có ip_range. Tôi đang sử dụng phiên bản: '3,4'.
Mikhail Morfikov

24

Không phải là một câu trả lời trực tiếp nhưng nó có thể giúp đỡ.

Tôi chạy hầu hết các dịch vụ được neo của mình gắn liền với các ips tĩnh bằng cách sử dụng phương pháp tiếp theo:

  1. Tôi tạo bí danh ip cho tất cả các dịch vụ trên máy chủ docker
  2. Sau đó, tôi chạy từng cổng chuyển hướng dịch vụ từ ip này sang container để mỗi dịch vụ có ip tĩnh riêng có thể được sử dụng bởi người dùng bên ngoài và các container khác.

Mẫu vật:

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
...

Cảm ơn ~ tôi biết điều này. Giống như github.com/brandon-rhodes/fopnp/tree/m/playground làm. Tôi sẽ thử nó.
LarryLo

1
Đây là một giải pháp rất tốt, tôi chỉ cần đính kèm liên kết này cho những người dùng mới để tìm hiểu về bí danh cyberciti.biz/faq/
mẹo

Cảm ơn bạn cho giải pháp tốt đẹp.
RavinderSingh13

4

Điều này làm việc cho tôi.

Tạo một mạng với docker network create --subnet=172.17.0.0/16 selnet

Chạy hình ảnh docker docker run --net selnet --ip 172.18.0.2 hub

Lúc đầu, tôi đã nhận

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

Giải pháp: Tăng gấp bốn lần thứ hai của IP [.18. thay vì .17.]


3
Có một câu trả lời tương tự / giống hệt nhau hơn 2 năm ở nơi khác trên trang này: stackoverflow.com/a353359185/694469
KajMagnus

2

Tôi đã vấp phải vấn đề này trong quá trình cố gắng cập bến Avahi , cần phải nhận thức được IP công cộng của nó để hoạt động đúng. Việc gán IP tĩnh cho vùng chứa là khó khăn do thiếu hỗ trợ cho việc gán IP tĩnh trong Docker.

Bài viết này mô tả kỹ thuật cách gán IP tĩnh cho vùng chứa trên Debian :

  1. Dịch vụ Docker nên được bắt đầu với DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". Tôi giả sử rằng br0cây cầu đã được cấu hình.

  2. Container nên được bắt đầu với --cap-add=NET_ADMIN --net=bridge

  3. Container bên pre-up ip addr flush dev eth0trong /etc/network/interfacescó thể được sử dụng để loại bỏ địa chỉ IP được gán bởi Docker như trong ví dụ sau:


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. Kịch bản nhập của Container nên bắt đầu bằng /etc/init.d/networking start. Ngoài ra tập lệnh nhập cần chỉnh sửa hoặc điền /etc/hoststệp để xóa tham chiếu đến IP được gán bởi Docker.

2

Bạn có thể đặt IP trong khi chạy nó.

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

Xem ví dụ của tôi tại https://github.com/RvdGijp/mariadb-10.1-galera


Thật không may, điều này lại thêm một địa chỉ IP, nếu một địa chỉ IP đã được chỉ định trong quy trình trước đó, điều này dẫn đến việc có hai địa chỉ IP
davey

1

Bạn có thể truy cập dịch vụ của các container khác bằng tên của họ ( ping apachesẽ nhận được ip hoặc curl http://apachesẽ truy cập dịch vụ http) Và đây có thể là một thay thế của một ip tĩnh.


3
Trong phiên bản docker 1.8, nó hoạt động trực tiếp. Trong phiên bản mới hơn, bạn phải liên kết chặt chẽ các thùng chứa này.
Guisong He 3/03/2016

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.