将静态IP分配给Docker容器

时间:2015-01-14 06:45:49

标签: docker

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

我使用端口2122作为此容器的ssh端口,以便让这个容器监听端口2122.

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

此命令将运行具有随机IP(如172.17.0.5)的Docker容器,但我需要为容器分配特定的IP。

以下shell脚本是我在高级网络设置中引用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到这个容器时,它都无法正常工作。我遇到的问题是什么?

8 个答案:

答案 0 :(得分:224)

使用Docker 1.10.1版轻松编译9e83765。

首先,您需要创建自己的docker network(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 shell中

ip addr

另外你可以使用

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

文档(以及您需要创建网络的原因)https://docs.docker.com/engine/reference/commandline/network_create/

答案 1 :(得分:61)

对于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

Modern docker-compose将自动为您创建具有静态IP的容器。

要在一行中查找docker-compose中所有容器的静态ips,请使用:

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

如果您想自动化,可以使用类似example gist

的内容

答案 2 :(得分:23)

不是直接答案,但可能有所帮助。

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

  1. 我为docker host
  2. 上的所有服务创建ip别名
  3. 然后我运行每个服务将这个ip的端口重定向到容器中,这样每个服务都有自己的静态ip,可以被外部用户和其他容器使用。
  4. 样品:

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

答案 3 :(得分:3)

这对我有用。

使用以下方法创建网络 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。]

答案 4 :(得分:2)

在尝试将 Avahi 停靠时,我偶然发现了这个问题。 Avahi 需要知道其公共IP才能正常运行。由于Docker中的lack of support for static IP assignment,将静态IP分配给容器非常棘手。

This article介绍了如何在Debian上为容器分配静态IP的技术:

  1. 应使用DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false"启动Docker服务。我假设已经配置了br0网桥。

  2. 应使用--cap-add=NET_ADMIN --net=bridge

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

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

答案 5 :(得分:2)

您可以在运行时设置IP。

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

请参阅https://github.com/RvdGijp/mariadb-10.1-galera

上的示例

答案 6 :(得分:1)

您可以访问其他容器&#39;按名称提供服务(ping apache将获取IP或curl http://apache将访问http服务)这可以是静态IP的替代方案。

答案 7 :(得分:0)

如果您希望容器拥有自己的虚拟以太网套接字(使用自己的MAC地址),iptables,则使用Macvlan驱动程序。这可能是将流量路由到/ ISP路由器所必需的。

https://docs.docker.com/engine/userguide/networking/get-started-macvlan