使用docker容器作为代理

时间:2017-12-26 10:22:58

标签: docker proxy reverse-proxy iptables devops

通常,我尝试使用docker容器作为同一网络覆盖中的其他docker容器的HTTP代理。 让我们调用这个代理容器网关。假设网关配置了所有必需的CA证书,该网关假设将其收到的HTTP请求更改为HTTPS请求,并将其转发给外部世界。

现在让我们获取具体信息,我使用docker swarm和services + replicas,网关在端口80上提供一些api,容器使用Gateway的服务名称+端口80以请求此api(这与我需要的代理没有关系)例如:

http://gateway:80/api/logout

我想将此端口也用于代理,这意味着其他容器可以将HTTP请求发送到端口80上的某些IP(而不是DNS),并且此请求将通过网关,而网关将查看http请求,看到此消息不适用于"他",它将执行http S (在端口443上)对实际外部服务器的请求。

我无法在下面的链接中使用Docker代理的解决方案:

https://docs.docker.com/engine/admin/systemd/#httphttps-proxy

因为HTTP代理的这种解决方案仅适用于已经运行的代理,而不是已经停靠的代理。 (如果我使用它,docker将无法从repo获取图像,因为它将寻找一个不存在的代理,因为docker本身还没有启动Gateway容器)。 / p>

所以,这让我想到了这个问题。如何在不使用网关服务名称的情况下将内部容器请求转发到网关。

我认为 iptables 是唯一的选择,但如何?我无法使用网关IP,因为网关是3个虚拟机上的副本,并且IP发生变化,无论如何,任何发送 http://some_external_server_ip:80/some_api 的容器都需要以某种方式通过网关

TLDR

我可以在iptables中执行某些操作(可能使用docker链和PREROUTING链)将端口80上的所有数据包(由其覆盖网络中的容器发送)转发到名为Gateway的服务容器中,同时忽略目标IP吗? (仅通过端口识别数据包并将其转发给特定的contianer)

希望这很清楚...... =)

1 个答案:

答案 0 :(得分:0)

所以,我通过一些tcpdump调查找到了答案。

在此链接中使用docker的HTTP_PROXY配置时:https://docs.docker.com/engine/admin/systemd/#httphttps-proxy 它不在同一网络内的容器上工作,因为上面的链接描述了外部通信的代理(代理到覆盖网络之外)。

因此,假设 Container A 是代理容器,容器B 是一些其他容器,它向某些外部ip运行HTTP请求,并假设这两个容器都是位于同一个docker的覆盖网络(docker的某个内部网络)。然后,为了从容器B 发出的HTTP请求将通过容器A ,我们需要在容器B 中定义环境变量:

  1. http_proxy - 此环境变量将包含代理容器的名称和端口,例如: http_proxy = containerA:8080 注意:( containerA 容器A的服务名称
  2. no_proxy - 此环境变量将包含不应通过代理的所有ips。 例如,您不希望容器B 的内部网络通信将通过容器A ,例如,如果容器B 想要在HTTP上与容器C 交谈,假设它们都在同一个覆盖网络上,那么,你希望它们能够"通话"没有容器A 充当代理人。在这种情况下,你将把覆盖网络的子网(所有容器都位于其中)放在no_proxy环境变量(以及localhost访问)中,在我的例子中它是这样的: no_proxy = 10.0.0.0 / 24,本地主机,127.0.0.1 即可。
  3. 当在容器B 上设置这两个环境变量时,容器B 的所有外部 HTTP通信将通过容器A

    注意:"外部沟通"表示使用一些未知的泊坞服务名称的外部IP。