为Docker容器分配静态IP

我现在试图在Docker容器启动时分配一个静态IP 172.17.0.1。

我使用端口2122作为这个容器的ssh端口,以便让这个容器侦听端口2122。

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

这个命令将运行一个具有随机IP的Docker容器,如172.17.0.5,但我需要为容器分配一个特定的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到这个容器时,它都不起作用。我可能遇到了什么问题?

476201 次浏览

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

我运行我的大部分dockerized服务绑定到自己的静态ip使用下面的方法:

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

我在尝试dockerise Avahi时偶然发现了这个问题,它需要知道它的公共IP才能正常工作。由于Docker中的缺乏对静态IP分配的支持,为容器分配静态IP是很棘手的。

这篇文章描述了如何将静态IP分配给Debian上的容器:

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

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

  3. 在容器/etc/network/interfaces中的pre-up ip addr flush dev eth0可以用来解除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的引用。

Docker 1.10.1版本很容易,build 9e83765。

首先你需要创建你自己的docker网络(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/文件(以及为什么你需要创建一个网络)

您可以在运行时设置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中的示例

你可以通过名称访问其他容器的服务(__abc0将获取ip或curl http://apache将访问http服务),这可以是静态ip的替代方案。

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

如果你想自动化,你可以使用类似例子要点这样的东西

如果你想让你的容器有自己的虚拟以太网套接字(有自己的MAC地址),iptables,那么使用Macvlan驱动程序。这对于将流量路由到您的/ISPs路由器可能是必要的。

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

这对我很有用。

创建网络 docker network create --subnet=172.17.0.0/16 selnet < / p >

运行docker镜像 docker run --net selnet --ip 172.18.0.2 hub < / p >

一开始,我有

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的第二个四倍 (只要。而不是。17.]