2017-09-20 114 views
2

我有一台服务器有2个IP,我需要运行3个docker容器。通过docker-compose为Docker容器分配出站IP

一个容器是一个nginx反向代理,它接收第一个IP上的传入连接。

第二个容器使用相同的IP连接外部,我有这部分工作。

我现在需要做的是建立一个网络,让最后一个容器通过第二个IP访问外部服务,但仍然允许nginx容器访问它的端口。

有没有办法在docker-compose中做到这一点?如果我不必这样做,我宁愿不去kubernetes/swarm路径。

version: '2' 
services: 
    nginx: 
    image: jwilder/nginx-proxy 
    environment: 
     - VIRTUAL_PORT=8000 
    volumes: 
     - /var/run/docker.sock:/tmp/docker.sock:ro 
    ports: 
     - "80:80" 


    python: 
    depends_on: 
     - nginx 
    image: python:2.7-slim 
    restart: always 
    working_dir: /usr/src/app/ 
     - VIRTUAL_HOST=python.mydomain.com 
    expose: 
    - "8000" 
    volumes: 
    - "./:/usr/src/app/" 
    command: bash -c "~/do_some_stuff.sh" 

我已经尝试添加一个桥接网络,但我无法得到它的工作,因为它似乎仍然使用我的主要IP。然后我尝试在容器中静态分配IP,但由于路由不起作用,因此无法工作。

这似乎应该是可能的,我只是不知道我是否正在寻找错误的东西或不正确地理解文档。

回答

1

我设法得到这个工作,但它需要一个iptables命令事后。虽然只需提供外发IP,它可以轻松包装在脚本中以实现全自动化。

我添加了一个自定义的网络,并分配了到容器:

version: '2' 
    services: 
     nginx: 
     image: fedora:latest 
     command: /bin/bash -c "curl -s ifconfig.co" # Check our external IP 
     networks: 
      - secondaryIP 


    networks: 
     secondaryIP: 
     driver: bridge 
     ipam: 
      config: 
      - subnet: 103.11.0.0/16 

首先,你应该用得到的网络名称,你可以找到出有:

docker inspect --format '{{ .HostConfig.NetworkMode }}' <ContainerID> 

一旦你有你可以得到容器的IP:

docker inspect --format '{{ .NetworkSettings.Networks.iptest_secondaryIP.IPAddress }}' <ContainerID> 

其中iptest_secondaryIP是n你的网络。这给出了容器的地址。这应该在下面的防火墙一起使用的命令:

sudo iptables -t nat -I POSTROUTING -s $IPADDR -j SNAT --to $SourceIP 
  • 注意:您可以通过网络掩码此替换IP地址,在这个例子中103.11.0.0/16,这将意味着开始所有容器与该网络将使用相同的IP

所以把它包起来都用光的脚本:

#!/bin/bash 
    SourceIP=103.11.1.2 # Outgoing IP to use 

    # Gets IP of last launched docker container 
    CID=$(docker ps -q | head -1) 
    # Gets custom network of docker container 
    NETMAP=$(docker inspect --format '{{ .HostConfig.NetworkMode }}' $CID) 
    # Gets ip address of container 
    IPADDR=$(docker inspect --format "{{ .NetworkSettings.Networks.$NETMAP.IPAddress }}" $CID) 
    # Sets up SNAT iptables rule for docker container to use SourceIP for outgoing traffic 
    sudo iptables -t nat -I POSTROUTING -s $IPADDR -j SNAT --to $SourceIP