如何使docker容器主机不可知的

我想要这样的configuration:

webcontainer1 / / haproxy_container \ \ webcontainer2 

所有这三个组件都是docker集装箱。 是的,我可以 – 将它们连接起来,并将容器名称放入haproxyconfiguration中,并且一切正常,只要所有3个在同一个主机上。

但是,我希望能够根据需要将web容器移动到其他主机, 而无需更改haproxy的configuration。

换句话说,我希望我的configuration对于我的Web容器运行的位置是不可知的:不pipe是否是同一个主机,我都希望它们能够简单地通过名字来ping。

怎么做?

PS我知道如何将端口从容器转发到主机,并且我知道我可以用我将它移动到的主机的名称replace我的web容器的名称 – 这不符合答案。

目标是有自由地移动东西而不改变任何configuration。

我使用下面的方法运行与自己的静态ips关联的大部分dockerized服务:

  1. 我为docker主机上的所有服务创buildip别名
  2. 然后我运行每个服务redirect端口从这个IP到容器,所以每个服务都有自己的静态IP可以被外部用户和其他容器使用。
  3. 所有容器都使用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的子网。 这是我已经尝试和工作的:

  1. 停泊docker:
    • 主机1: service docker stop
    • 主机2: service docker stop
  2. 从POSTROUTING链中删除现有的MASQUERADE规则:
    • 主机1: iptables -t nat -F POSTROUTING
    • 主机2: iptables -t nat -F POSTROUTING
  3. 从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
  4. 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
  5. 开始docker工人:
    • 主机1: service docker start
    • 主机2: service docker start
  6. validation您的新子网的POSTROUTING链已更新MASQUERADE规则:

    • 主机1: iptables -t nat -L -n
    • 主机2: iptables -t nat -L -n
  7. 连接两个主机子网:

    • 主机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
  8. 使用serf创build一个集群:

    • 主持人1: serf agent
    • webcontainer1: serf agent -h=webcontainer1
    • 主持人2: serf agent
    • webcontainer2: serf agent -h=webcontainer2
    • haproxy1:serf serf agent -h=haproxy1
  9. 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主机而不是容器的唯一部分是子网部分,但您也可以在具有正确权限的容器中执行此操作。

我希望有帮助