首页 > 解决方案 > Docker Swarm:绕过负载均衡器并直接向特定容器发出请求

问题描述

我有两个容器在一个集群中运行。每个都暴露了一个/stats我试图抓取的端点。

但是,使用 swarm 端口显然会导致查询被负载平衡,因此统计信息都是混合的:

+--------------------------------------------------+
|                       Server                     |
|    +-------------+             +-------------+   |
|    |             |             |             |   |
|    | Container A |             | Container B |   |
|    |             |             |             |   |
|    +-------------+             +-------------+   |
|                 \              /                 |
|                  \            /                  |
|                 +--------------+                 |
|                 |              |                 |
|                 | Swarm Router |                 |
|                 |              |                 |
|                 +--------------+                 |
|                         v                        |
+-------------------------|------------------------+
                          |                         
                       A Stats                      
                       B Stats                      
                       A Stats                      
                       B Stats                      
                          |                         
                          v                          

我想为应用程序请求保留负载均衡器,但还需要一种直接的方式来向每个容器发出请求以抓取统计信息。

+--------------------------------------------------+
|                       Server                     |
|    +-------------+             +-------------+   |
|    |             |             |             |   |
|    | Container A |             | Container B |   |
|    |             |             |             |   |
|    +-------------+             +-------------+   |
|        |        \              /         |       |
|        |         \            /          |       |
|        |        +--------------+         |       |
|        |        |              |         |       |
|        |        | Swarm Router |         |       |
|        v        |              |         v       |
|        |        +--------------+         |       |
|        |                |                |       |
+--------|----------------|----------------|-------+
         |                |                |
      A Stats             |             B Stats
      A Stats       Normal Traffic      B Stats
      A Stats             |             B Stats
         |                |                |
         |                |                |
         v                |                v

动态解决方案将是理想的,但由于我不打算对每个容器进行任何动态缩放,例如硬编码端口之类的就可以了:

::8080  Both containers via load balancer
::8081  Direct access to container A
::8082  Direct access to container B

这可以用 swarm 完成吗?

标签: dockerload-balancingdocker-swarm

解决方案


从覆盖网络内部,您可以通过tasks.<service_name>DNS 查询获取所有副本的 IP 地址:

; <<>> DiG 9.11.5-P4-5.1+deb10u5-Debian <<>> -tA tasks.foo_test
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19860
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;tasks.foo_test.            IN  A

;; ANSWER SECTION:
tasks.foo_test.     600 IN  A   10.0.1.3
tasks.foo_test.     600 IN  A   10.0.1.5
tasks.foo_test.     600 IN  A   10.0.1.6

这在文档中有所提及。

此外,如果您使用Prometheus抓取这些端点以获取指标,您可以将上述与dns_sd_configs设置目标以抓取(这里是一篇文章如何)。这很容易运行,但功能有些受限(尤其是在大型环境中)。

实现相同目的的更高级方法是使用 dockerswarm_sd_config文档示例配置)。这样,端点列表将通过查询 Docker 守护程序以及一些有用的标签(即节点名称、服务名称、自定义标签)来收集。


推荐阅读