如何使docker容器与主机无关

时间:2015-03-28 06:34:35

标签: networking docker

我想要这个配置:

                   webcontainer1
                  /
                 /
haproxy_container 
                 \ 
                  \
                   webcontainer2

所有三个组件都是docker容器。 是的,我可以 - 链接它们,并将容器名称放入haproxy配置中,一切正常,前提是所有3个都在同一主机上。

但是,我希望能够根据需要将我的webcontainers移动到其他主机,而无需更改haproxy的配置。

换句话说,我希望我的配置与我的web容器运行的位置无关:相同的主机与否,我希望它们只是按名称ping。

怎么做?

P.S。我知道如何将端口从容器转发到主机,我知道我可以用我要移动它们的主机的名称替换我的webcontainers的名称 - 这不符合答案。

目标是在不改变任何配置的情况下自由移动事物。

2 个答案:

答案 0 :(得分:0)

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

  1. 我为docker host
  2. 上的所有服务创建ip别名
  3. 然后我运行每个服务将这个ip的端口重定向到容器中,这样每个服务都有自己的静态ip,可以被外部用户和其他容器使用。
  4. 所有容器都使用ips或域名来访问其他容器。
  5. 现在我可以将容器(使用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 aliases是单个接口的附加IP地址。

    作为映射到ip别名的每个容器的必要端口 - 我不需要知道关于容器的任何其他内容,我只是使用ip:port(或name:port)来处理它。额外的好处 - 我有多个容器映射暴露端口80在同一主机 - 我不需要使用代理或不同的端口:http://service1http://service2正在工作 - 因为他们有不同的IP地址(这些是别名,我可以有很多)。

答案 1 :(得分:0)

还有另一种方法可以做到这一点,将主机容器视为子网。如果我理解正确,你想拥有至少两个子网。您需要一种方法来连接这些子网,这意味着您必须更改默认设备docker0的子网。这就是我尝试过的工作:

  1. 停止码头:
    • 主持人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. 选择一个子网:
    • 主持人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. 启动码头工具:
    • 主持人1:service docker start
    • 主持人2:service docker start
  6. 使用新子网的MASQUERADE规则验证POSTROUTING链是否已更新:

    • 主持人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创建群集:

    • 主持人1:serf agent
    • webcontainer1:serf agent -h=webcontainer1
    • 主持人2:serf agent
    • webcontainer2:serf agent -h=webcontainer2
    • haproxy1:serf agent -h=haproxy1
  9. haproxy,您可以使用以下脚本使用主机的ips更新/ etc / hosts。使用serf,您无法使用重复的名称加入群集:
  10. #!/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
    

    我看到你最终配置主机而不是容器的唯一部分是子网部分,但您也可以在具有正确权限的容器中执行此操作。

    我希望有帮助