为Docker容器分配静态IP


205

我现在正尝试在启动Docker容器时分配静态IP 172.17.0.1。

我将端口2122用作此容器的ssh端口,以便让此容器侦听端口2122。

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

该命令将运行具有172.17.0.5之类的随机IP的Docker容器,但是我需要为该容器分配特定的IP。

以下外壳脚本是我在高级网络设置中引用的Docker文档的内容。

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

这个shell脚本将分配一个静态IP 172.17.0.1并链接到世界。但是,每当我尝试从本地通过ssh到该容器时,它都无法正常工作。我可能遇到什么问题?



@larrylo您可以确认您在容器内启动了sshd吗?
Bryan 2015年

5
您正在撤消docker守护程序为您执行的所有路由。容器不是VM。
user2105103 2015年

是的,我确认可以在容器内启动sshd
LarryLo 2015年

Answers:


291

使用Docker 1.10.1版轻松构建9e83765。

首先,您需要创建自己的码头工人网络(mynet123)

docker network create --subnet=172.18.0.0/16 mynet123

而不是简单地运行映像(我将以ubuntu为例)

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

然后在ubuntu外壳

ip addr

另外,您可以使用

  • --hostname 指定主机名
  • --add-host 向/ etc / hosts添加更多条目

网址https://docs.docker.com/engine/reference/commandline/network_create/的文档(以及为什么需要创建网络)


1
好的答案-只需添加一些其他信息:blog.jessfraz.com/post/ips-for-all-the-things
Ole

@cantSleepNow由于某种原因,我只需要使用我自己的默认创建的桥接器br0,该桥接器在系统引导过程中在interfaces文件中创建(因此它不是使用docker network create创建的),您能建议我如何获得相同的效果- -ip参数(获取容器的固定IP地址)而不使用docker创建我的网桥?
Mohammed Noureldin

@MohammedNoureldin我不太了解-听起来像是一个新问题,我想您应该这样问。
cantSleepNow

@cantSleepNow我的意思是尽管我没有使用自定义网桥,但我需要修复容器的IP地址(因此无法使用--ip参数),您是否建议采取任何方法?
Mohammed Noureldin

@MohammedNoureldin我不确定。如我所说,将您的问题作为问题而不是评论发表-也许有人知道答案。
cantSleepNow

89

对于docker-compose您可以使用以下docker-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

从主机可以使用以下命令进行测试:

docker-compose up -d
curl 172.20.128.2

现代 docker-compose不经常更改IP地址。

docker-compose在一行中查找所有容器中的ip,请使用:

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

如果要自动化,可以使用类似以下示例的内容


2
看起来这仅适用于docker-compose v2,v3破坏了兼容性。
安德烈·雷曼

4
使用docker-compose v3 +时,移除ip_range
Andrzej Rehmann

我没有ip_range。子网不覆盖吗?无论如何,谢谢!这固定我“我得再看看我的蒙戈容器的IP” -问题

1
有没有一种方法可以在撰写版本3中指定IP地址?
yeeon '18年

2
解决方案对我来说很好,没有ip_range。我正在使用版本:“ 3.4”。
米哈伊尔·莫尔菲科夫

24

这不是一个直接的答案,但可能会有所帮助。

我使用以下方法运行与自己的静态ip绑定的大多数dockerized服务:

  1. 我为Docker主机上的所有服务创建ip别名
  2. 然后,我运行每个服务,将端口从此ip重定向到容器中,以便每个服务都有自己的静态ip,供外部用户和其他容器使用。

样品:

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

谢谢〜我知道 就像github.com/brandon-rhodes/fopnp/tree/m/playground一样。我会尝试。
LarryLo 2015年

1
这是一个非常好的解决方案,我只想附上此链接为新用户了解别名cyberciti.biz/faq/...
穆罕默德Noureldin

谢谢您的解决方案。
RavinderSingh17年

4

这对我有用。

创建一个网络 docker network create --subnet=172.17.0.0/16 selnet

运行docker镜像 docker run --net selnet --ip 172.18.0.2 hub

一开始,我得到了

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

解决方案:增加IP的第二个四倍[.18。而不是.17。]


3
此页面上其他地方有2年之久的类似/相同答案:stackoverflow.com/a/35359185/694469
KajMagnus

2

在尝试对Avahi进行docker化时,我偶然发现了这个问题,该Avahi需要了解其公共IP才能正常运行。由于缺乏对 Docker中静态IP分配的支持,因此向容器分配静态IP非常棘手。

本文介绍了如何为Debian上的容器分配静态IP的技术:

  1. Docker服务应以开头DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false"。我认为br0网桥已经配置好了。

  2. 容器应以 --cap-add=NET_ADMIN --net=bridge

  3. 内部容器 pre-up ip addr flush dev eth0中的内容/etc/network/interfaces可用于关闭Docker分配的IP地址,如以下示例所示:


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. 容器的输入脚本应以 /etc/init.d/networking start。输入脚本还需要编辑或填充/etc/hosts文件,以删除对Docker分配的IP的引用。


1

您可以按名称访问其他容器的服务(ping apache将获取ip或curl http://apache访问http服务),这可以替代静态ip。


3
在1.8的docker版本中,可以直接使用。在较新的版本中,必须首先链接这些容器。
Guisong He

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.