如何使docker容器主机不可知的
我想要这样的configuration:
webcontainer1 / / haproxy_container \ \ webcontainer2
所有这三个组件都是docker集装箱。 是的,我可以 – 将它们连接起来,并将容器名称放入haproxyconfiguration中,并且一切正常,只要所有3个在同一个主机上。
但是,我希望能够根据需要将web容器移动到其他主机, 而无需更改haproxy的configuration。
换句话说,我希望我的configuration对于我的Web容器运行的位置是不可知的:不pipe是否是同一个主机,我都希望它们能够简单地通过名字来ping。
怎么做?
PS我知道如何将端口从容器转发到主机,并且我知道我可以用我将它移动到的主机的名称replace我的web容器的名称 – 这不符合答案。
目标是有自由地移动东西而不改变任何configuration。
我使用下面的方法运行与自己的静态ips关联的大部分dockerized服务:
- 我为docker主机上的所有服务创buildip别名
- 然后我运行每个服务redirect端口从这个IP到容器,所以每个服务都有自己的静态IP可以被外部用户和其他容器使用。
- 所有容器都使用ips或域名访问其他容器。
现在我可以将容器(带有ip别名)移动到任何其他的docker主机,所有其他容器将继续使用它 – 无需触摸它们。
样品:
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 ...
回答评论(因为它太长了评论):
1)正确 – 我不需要知道容器的IP – 我使用静态IP地址来处理容器中的服务
2)是的,容器不能ping通,只有必要的端口暴露在那里
3) IP别名是单个接口的附加IP地址。
为每个容器映射到IP别名的必要端口 – 我不需要知道任何关于容器,我只是使用IP:端口(或名称:端口)来处理它。 额外的好处 – 我有多个容器,在同一个主机上映射公开端口80 – 我不需要使用代理或不同的端口: http:// service1和http:// service2正在工作 – 因为他们有不同的IP地址(这是别名,我可以有很多)。
还有一种方法可以做到这一点,把主机容器看作一个子网。 如果我理解正确,你想有至less两个子网。 您需要一种连接这些子网的方法,这意味着您必须更改默认设备docker0的子网。 这是我已经尝试和工作的:
- 停泊docker:
- 主机1:
service docker stop
- 主机2:
service docker stop
- 主机1:
- 从POSTROUTING链中删除现有的MASQUERADE规则:
- 主机1:
iptables -t nat -F POSTROUTING
- 主机2:
iptables -t nat -F POSTROUTING
- 主机1:
- 从Docker桥中删除现有的IP地址:
- 主机1:
ip link set dev docker0 down && ip addr del 172.17.42.1/16 dev docker0
- 主机2:
ip link set dev docker0 down && ip addr del 172.17.42.1/16 dev docker0
- 主机1:
- select一个子网:
- 主机1:
ip addr add 192.168.3.1/24 dev docker0 && ip link set dev docker0 up && ip addr show docker0
- 主机2:
ip addr add 192.168.4.1/24 dev docker0 && ip link set dev docker0 up && ip addr show docker0
- 主机1:
- 开始docker工人:
- 主机1:
service docker start
- 主机2:
service docker start
- 主机1:
-
validation您的新子网的POSTROUTING链已更新MASQUERADE规则:
- 主机1:
iptables -t nat -L -n
- 主机2:
iptables -t nat -L -n
- 主机1:
-
连接两个主机子网:
- 主机1:
ip route add 192.168.3.0/24 via 192.168.1.2 dev eth0
- 主机2:
ip route add 192.168.4.0/24 via 192.168.1.3 dev eth0
- 主机1:
-
使用serf创build一个集群:
- 主持人1:
serf agent
- webcontainer1:
serf agent -h=webcontainer1
- 主持人2:
serf agent
- webcontainer2:
serf agent -h=webcontainer2
- haproxy1:serf
serf agent -h=haproxy1
- 主持人1:
- haproxy,您可以使用以下脚本来更新/ etc / hosts与主机的ips。 对于serf,不能join具有重复名称的集群:
#!/bin/bash updatehosts() { sed -i 's/.\+# serf//' /etc/hosts serf members | sed 's/:.\+$//g' | grep -v `hostname` | awk '{ print $2 " " $1 " # serf" }' >> /etc/hosts } case "${SERF_EVENT}" in member-join) updatehosts ;; member-leave) updatehosts ;; member-failed) updatehosts ;; esac
我看到的最终configuration主机而不是容器的唯一部分是子网部分,但您也可以在具有正确权限的容器中执行此操作。
我希望有帮助