I'm now trying to assign a static IP 172.17.0.1 when a Docker container be started up.
我现在尝试在启动Docker容器时分配一个静态IP 172.17.0.1。
I use port 2122 as the ssh port of this container so that I let this container listen port 2122.
我使用端口2122作为该容器的ssh端口,以便让该容器侦听端口2122。
sudo docker run -i -t -p 2122:2122 ubuntu
This command will run a Docker container with a random IP like 172.17.0.5, but I need to assign a specific IP to the container.
这个命令将运行一个带有随机IP的Docker容器,比如172.17.0.5,但是我需要为容器分配一个特定的IP。
The following shell script is what I reference Docker documentation in advanced network settings.
下面的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
This shell script will assign a static IP 172.17.0.1 and link to the world fine. But whenever I try to ssh to this container from my local, it didn't work. What's the problem possibly I met?
这个外壳脚本将分配一个静态IP 172.17.0.1并链接到WORLD FINE。但每当我尝试从本地用户ssh到这个容器时,它都不起作用。我可能遇到了什么问题?
更多回答
@larrylo can you confirm that you started an sshd inside the container?
@larrio你能确认你在容器内启动了sshd吗?
You are undoing all the routing that the docker daemon does for you. Containers are not VMs.
您正在撤消docker守护进程为您执行的所有路由。容器不是VM。
Yes, I confirm I can start sshd inside the container
是的,我确认我可以在容器内启动sshd
Easy with Docker version 1.10.1, build 9e83765.
轻松使用Docker版本1.10.1,内部版本9e83765。
First you need to create your own docker network (mynet123)
首先,您需要创建自己的扩展坞网络(Mynet123)
docker network create --subnet=172.18.0.0/16 mynet123
then, simply run the image (I'll take ubuntu as example)
然后,只需运行镜像(我将以ubuntu为例)
docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash
then in ubuntu shell
然后在ubuntu外壳中
ip addr
Additionally you could use
此外,您还可以使用
--hostname
to specify a hostname
--add-host
to add more entries to /etc/hosts
Docs (and why you need to create a network) at https://docs.docker.com/engine/reference/commandline/network_create/
Https://docs.docker.com/engine/reference/commandline/network_create/上的文档(以及您为什么需要创建网络)
For docker-compose
you can use following docker-compose.yml
对于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
from host you can test using:
在主机上,您可以使用以下命令进行测试:
docker-compose up -d
curl 172.20.128.2
Modern docker-compose
does not change ip address that frequently.
现代的Dock-Compose不会那么频繁地更改IP地址。
To find ips of all containers in your docker-compose
in a single line use:
要查找坞站中所有集装箱的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
If you want to automate, you can use something like this example gist
如果您想实现自动化,可以使用类似以下示例要点的内容
Not a direct answer but it could help.
这不是一个直接的答案,但它可能会有所帮助。
I run most of my dockerized services tied to own static ips using the next approach:
我使用以下方法运行与自己的静态IPS捆绑在一起的大多数停靠服务:
- I create ip aliases for all services on docker host
- Then I run each service redirecting ports from this ip into container so each service have own static ip which could be used by external users and other containers.
Sample:
示例:
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
...
I stumbled upon this problem during attempt to dockerise Avahi which needs to be aware of its public IP to function properly. Assigning static IP to the container is tricky due to lack of support for static IP assignment in Docker.
我在尝试对接Avahi时偶然发现了这个问题,Avahi需要知道其公共IP才能正常运行。由于Docker不支持静态IP分配,给容器分配静态IP比较麻烦。
This article describes technique how to assign static IP to the container on Debian:
本文介绍了如何在Debian上为容器分配静态IP的技术:
Docker service should be started with DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false"
. I assume that br0
bridge is already configured.
Container should be started with --cap-add=NET_ADMIN --net=bridge
Inside container pre-up ip addr flush dev eth0
in /etc/network/interfaces
can be used to dismiss IP address assigned by Docker as in following example:
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
- Container's entry script should begin with
/etc/init.d/networking start
. Also entry script needs to edit or populate /etc/hosts
file in order to remove references to Docker-assigned IP.
This works for me.
这对我很管用。
Create a network with
docker network create --subnet=172.17.0.0/16 selnet
使用扩展底座网络CREATE--SUBNET=172.17.0.0/16 selnet创建网络
Run docker image
docker run --net selnet --ip 172.18.0.2 hub
运行docker镜像docker run--net selnet--ip 172.18.0.2 Hub
At first, I got
一开始,我得到了
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
Solution: Increased the 2nd quadruple of the IP
[.18. instead of .17.]
解决方案:增加IP的第二个四倍[.18.而不是.17。]
You can set the IP while running it.
您可以在运行时设置IP。
docker run --cap-add=NET_ADMIN -dit imagename /bin/sh -c "/sbin/ip addr add 172.17.0.12 dev eth0; bash"
See my example at https://github.com/RvdGijp/mariadb-10.1-galera
请访问https://github.com/RvdGijp/mariadb-10.1-galera查看我的示例
You can access other containers' service by their name(ping apache
will get the ip or curl http://apache
would access the http service) And this can be a alternative of a static ip.
您可以通过其他容器的名称访问它们的服务(ping apache将获得IP,或者cURL http://apache将访问http服务),这可以是静态IP的替代。
If you want your container to have it's own virtual ethernet socket (with it's own MAC address), iptables, then use the Macvlan driver. This may be necessary to route traffic out to your/ISPs router.
如果您希望您的容器拥有自己的虚拟以太网套接字(具有自己的MAC地址)iptabes,那么使用Macvlan驱动程序。这可能是将流量路由到您的/ISPS路由器所必需的。
https://docs.docker.com/engine/userguide/networking/get-started-macvlan
Https://docs.docker.com/engine/userguide/networking/get-started-macvlan
更多回答
@cantSleepNow for some reason I need just to use my own default created bridge br0 which is created in interfaces file during system boot (so it is NOT created using docker network create), could you suggest me how can I get the same effect of --ip parameter (get fixed IP address for a container) without creating my bridge using docker?
@cantSleepNow由于某些原因,我只需要使用我自己的默认创建的网桥br0,它是在系统引导过程中在接口文件中创建的(因此它不是使用docker Network Create创建的),您能建议我如何在不使用docker创建网桥的情况下获得--ip参数(获取容器的固定IP地址)的相同效果吗?
@MohammedNoureldin I don't fully understand - also sounds like a new question, I think you should ask it as such.
@Mohammed Noureldin我不完全理解--听起来也是一个新问题,我认为你应该这样问。
@cantSleepNow I mean I need to fix the container's IP address though I am NOT using custom bridge (so --ip parameter cannot be used), do you suggest any way to get that?
@cantSleepNow我的意思是,虽然我没有使用自定义网桥(所以不能使用--ip参数),但我需要修复容器的IP地址,您有什么建议可以实现这一点吗?
@MohammedNoureldin I'm not sure. As I said, post your question as question and not as a comment - maybe there is someone that knows the answer.
@Mohammed Noureldin我不确定。就像我说的,把你的问题作为问题发布,而不是评论--也许有人知道答案。
Looks like this will work only in docker-compose v2, v3 broke compatibility.
看起来这只会在对接合成v2,v3中断兼容中起作用。
When using docker-compose v3+ remove ip_range
使用Docker-Compose v3+删除IP_Range时
I don't get the ip_range though. isn't that covered by the subnet? Anyways, thank you! That fixed my "I have to look up the ip of my mongo container again" - issue
不过,我不了解IP_Range。这不是在子网的覆盖范围内吗?无论如何,谢谢你!这解决了我的“我必须再次查找我的Mongo容器的IP”的问题-
is there a way to specify ip address in compose version 3?
在Compose版本3中是否有指定IP地址的方法?
The solution works fine for me without ip_range
. I'm using version: '3.4'.
这个解决方案在没有ip_range的情况下很适合我。我使用的是版本:‘3.4’。
This is a very good solution, I would just attach this link for the new users to learn about aliasing cyberciti.biz/faq/…
这是一个非常好的解决方案,我只想附上这个链接,让新用户了解有关Cyberciti.biz/faq/…的别名
Thank you for nice solution.
谢谢你的好解决方案。
I am not clear how this answer can be useful in the context of the OP. The question is about assigning a static IP address to the container i.e., 172.16.177.20
to the dns
container, but the command here would not work unless dns
container is already assigned 172.16.177.20
. Where is the part that ensures that dns container actually gets the IP address 172.16.177.20
? What am I missing?
我不清楚这个答案在行动的背景下如何有用。问题是如何将静态IP地址分配给容器,即172.16.177.20分配给DNS容器,但除非已经为DNS容器分配了172.16.177.20,否则这里的命令不会起作用。确保DNS容器实际获取IP地址172.16.177.20的部分在哪里?我遗漏了什么?
unfortunately this adds one more IP address, if an IP address was assigned in the process before, this results in having two IP addresses
遗憾的是,这又增加了一个IP地址,如果之前在该过程中分配了IP地址,则会导致拥有两个IP地址
In the docker version of 1.8 this works directly. In the newer version, you must fistly link these containers.
在1.8的docker版本中,这直接起作用。在较新版本中,您必须首先链接这些容器。
This is the best solution, unfortunately summer services require an IP and not a name (along others Home Assistant when configuring trusted proxies)
这是最好的解决方案,不幸的是,夏季服务需要IP而不是名称(在配置受信任的代理时与其他Home Assistant一起)
我是一名优秀的程序员,十分优秀!