可以通过多种方式实现反向代理。一种方法是基于HAProxy创建一个新的镜像(https://hub.docker.com/_/haproxy/)并在其中包含配置文件。如果不同服务的数量相对稳定,那么这将是一个好办法。否则,每次有新服务(不是新版本)时,我们都要使用新配置创建新的镜像。
第二种方法是公开一个卷,这样在需要时可以修改配置文件,而不用构建一个全新的镜像。然而,这也有不利之处,当部署到集群时,我们应该避免在不必要时使用卷。正如你很快就会看到的,代理正是不需要卷的情况之一。顺带说一下,--volume已被替换为docker service的--mount参数。
第三个选择是使用一个专门设计用于Docker Swarm的代理。在这种情况下,我们将使用容器vfarcic/docker-flow-proxy(https://hub.docker.com/r/vfarcic/ docker-flow-proxy/)。它基于HAProxy,并具有额外的功能可以让我们通过发送HTTP请求对其进行重新配置。
让我们试试看。
创建代理服务的命令如下所示:
我们打开了80端口和443端口,它们将用于Internet流量(HTTP和HTTPS)。第三个端口是8080,我们将使用它来向代理发送配置请求。然后将其指定到Proxy网络,这样,由于go-demo也连接到同一个网络,所以代理就可以通过proxy-SDN访问它。
通过刚刚运行的代理,可以观察到网络的routing mesh有一个很酷的功能。proxy运行在哪个服务器上无关紧要,我们可以向任何节点发送请求,Docker网络可确保将其重定向到其中一个代理上。我们很快就会看到这一点。
最后一个参数是环境变量MODE,它可以告诉代理将容器部署到Swarm集群(见图3-4)。有关其他参数组合,请参阅项目README(https://github.com/vfarcic/ docker-flow-proxy)。
请注意,虽然代理运行在其中一个节点内部,图3-4中还是被放在外面以更好地说明逻辑上的隔离性。
在继续之前,让我们确认代理正在运行。
图3-4 使用代理服务的Docker Swarm集群
如果CURRENT STATE是Running,那么可以继续。否则,请等到服务启动并运行。
现在代理部署好了,下面应该让它知道go-demo服务的存在:
发送上面的请求以重新配置代理并指定服务名称go-demo、API的基URL路径/demo以及服务的内部端口号8080。从现在起,所有发送到代理的以/demo开头的请求将被重定向到go-demo服务。这个配置请求是Docker Flow Proxy在HAProxy之上提供的附加功能之一。
请注意,我们把请求发送到了node-1。代理服务有可能运行在任何一个节点内部,可请求还是成功了,这就是Docker的routing mesh起关键作用的地方。稍后我们会更详细地探讨它。现在需要注意的是,我们可以向任何节点发送请求,请求将会被重定向到监听同一端口(本例中为8080)的服务上。
请求的输出如下(格式化以提高可读性):
这里不会详细解释,只需要注意Status是OK,表示代理已正确重新配置。
可以通过发送一个HTTP请求来测试代理确实如预期的那样工作:
curl命令的输出如下。
代理有效!它响应HTTP状态码200并返回API响应hello,world !。如前所述,请求不一定发送到承载服务的节点,而是发送到将其转发给代理的routing mesh。
作为一个例子,让我们发送相同的请求,但是这次发送到node-3:
结果仍然是一样的。
我们来探讨一下代理生成的配置,它会让我们更深入地了解DockerSwarm网络的内部运作原理,还有一个好处,如果你选择自己给出代理方案,那么理解如何配置代理并利用新的Docker网络特性可能会很有用。
首先看下Docker Flow Proxy(https://github.com/vfa rcic/ docker-flow-proxy)为我们创建的配置。可以通过进入正在运行的容器查看文件/cfg/haproxy.cfg。问题是找到一个Docker Swarm运行的容器有点棘手。如果使用Docker Compose进行部署,那么容器名称则是可预测的,它会使用<PROJECT> _ <SERVICE> _ <INDEX>的格式。
docker service命令运行的容器都有一个hash名称。在我的笔记本电脑上创建的docker-flow-proxy名称是proxy.1.e07jvhdb9e6s76mr9ol41u4sn。因此,为了进入使用Docker Swarm部署的正在运行的容器,我们需要使用一个带有镜像名称的过滤器。(www.xing528.com)
首先要找出代理运行在哪个节点上,执行以下命令:
我们列出了代理服务进程(docker service ps proxy)删除首行(tail-n+2),并输出位于第四列的node名称,awk'{print $4}'。输出被存入环境变量NODE中。
现在可以将本地Docker Engine指向代理所在的节点:
最后,唯一剩下的就是找到代理容器的ID。可以使用下面的命令:
现在容器ID已经存储在变量中,可以执行查看HAProxy配置的命令:
配置的重要部分如下:
第一部分frontend对使用过HAProxy的人应该很熟悉。它接受端口80 HTTP和443 HTTPS上的请求。如果路径以/demo开头,它将被重定向到后端go-demo-be。在它内部,请求被发送到地址go-demo的8080端口上。该地址与我们部署的服务的名称相同。由于go-demo与代理属于同一网络,因此Docker将确保请求被重定向到目标容器。很简洁是不是?不再需要指定IP和外部端口。
接下来的问题是如何进行负载均衡。我们应该如何指定代理对所有实例执行,比如,时间片轮转法?我们是否应该使用代理来完成这样的任务?
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。