swarm 文档中的 Load Balancing 部分没有说明内部负载均衡器是否也进行健康检查,以及它是否删除了不再运行服务的节点(因为它被杀死或节点被重新启动)。

在以下情况下,我有一个服务,副本为 3,在 3 个节点中的每个节点上运行 1 个实例。

经理:

[root@centosvm ~]# docker ps
CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS               NAMES
a593d485050a        ddewaele/springboot.crud.sample:latest   "sh -c 'java $JAVA_OP"   7 minutes ago       Up 7 minutes                            springbootcrudsample.1.5syc6j4c8i3bnerdqq4e1yelm

节点 1:
[root@node1 ~]# docker ps
CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS               NAMES
d3b3fbc0f2c5        ddewaele/springboot.crud.sample:latest   "sh -c 'java $JAVA_OP"   4 minutes ago       Up 4 minutes                            springbootcrudsample.3.7y1oyjyrifgkmxlr20oai5ppl

节点 2:
[root@node2 ~]# docker ps
CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS               NAMES
ebca8f24ec3a        ddewaele/springboot.crud.sample:latest   "sh -c 'java $JAVA_OP"   7 minutes ago       Up 7 minutes                            springbootcrudsample.2.4tqjad7od8ep047s55485na1t

现在,在 node1 上,我们终止了 docker 容器。该节点将没有服务(swarm 将在几秒钟后在此处重新创建它以保持服务上的 replication=3)
[root@node1 ~]# docker kill d3b3fbc0f2c5
d3b3fbc0f2c5

容器不见了
[root@node1 ~]# docker ps
CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS               NAMES

新建容器
[root@node1 ~]# docker ps
CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS               NAMES
b8c9a7a5cf97        ddewaele/springboot.crud.sample:latest   "sh -c 'java $JAVA_OP"   11 seconds ago      Up 9 seconds                            springbootcrudsample.3.9v4cnhi8dvq7n8afb2kvp28sk

然而,在下面的输出中,当容器 d3b3fbc0f2c5 被杀死时,入口负载均衡器没有检测到这一点,它仍在向节点发送流量(导致连接被拒绝)?

我们应该如何处理这样的场景?对于这种情况,我们是否仍然需要外部负载均衡器,我们应该如何配置它?
[root@centosvm ~]# while :; do curl http://localhost:8080/env/hostname ; echo "" ; sleep 1; done
{"hostname":"d3b3fbc0f2c5"}
{"hostname":"a593d485050a"}
{"hostname":"ebca8f24ec3a"}
{"hostname":"d3b3fbc0f2c5"}
{"hostname":"a593d485050a"}
{"hostname":"ebca8f24ec3a"}
{"hostname":"d3b3fbc0f2c5"}
{"hostname":"a593d485050a"}
{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
curl: (7) Failed connect to localhost:8080; Connection refused

{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
curl: (7) Failed connect to localhost:8080; Connection refused

{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
curl: (7) Failed connect to localhost:8080; Connection refused

{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
curl: (7) Failed connect to localhost:8080; Connection refused

{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
curl: (7) Failed connect to localhost:8080; Connection refused

{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
curl: (7) Failed connect to localhost:8080; Connection refused

{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
{"hostname":"b8c9a7a5cf97"}
{"hostname":"ebca8f24ec3a"}
{"hostname":"a593d485050a"}
{"hostname":"b8c9a7a5cf97"}

最佳答案

François Maturel 所示,在适当的健康检查到位后,Docker Swarm 将考虑容器的健康状态来决定是否将请求路由到它。

对于启用了默认执行器的 Spring Boot 应用程序,将它添加到 Dockerfile 足以进行基本的健康检查。当 Spring Boot 应用程序初始化并启用其 health actuator 时,以下 http 请求将返回有效的 http 200 响应,健康检查将通过。

HEALTHCHECK CMD wget -q http://localhost:8080/health -O /dev/null

这将导致您的 docker 容器能够达到健康状态。当您的 docker 容器启动时,其中运行的服务可能仍在初始化。为了进行适当的负载平衡和检测服务健康状况,Swarm 需要知道何时能够将请求路由到特定的服务实例(节点上的容器)。

所以当 Swarm 启动一个服务副本时,它会启动一个容器,它会一直等到服务的健康状态为“健康”。当您的容器启动时,它将从“开始”过渡:
CONTAINER ID        IMAGE                                                                                                     COMMAND                  CREATED             STATUS                                     PORTS               NAMES
5001e1c46953        ddewaele/springboot.crud.sample@sha256:4ce69c3f50c69640c8240f9df68c8816605c6214b74e6581be44ce153c0f3b7a   "/docker-entrypoin..."   5 seconds ago       Up Less than a second (health: starting)                       springbootcrudsample.2.yt6d38zhhq2wxt1d6qfjz5974

到'健康'。只有这样,Swarm 负载均衡器才会将请求路由到此端点。
[root@centos-a ~]# docker ps
CONTAINER ID        IMAGE                                                                                                     COMMAND                  CREATED              STATUS                        PORTS               NAMES
5001e1c46953        ddewaele/springboot.crud.sample@sha256:4ce69c3f50c69640c8240f9df68c8816605c6214b74e6581be44ce153c0f3b7a   "/docker-entrypoin..."   About a minute ago   Up About a minute (healthy)                       springbootcrudsample.2.yt6d38zhhq2wxt1d6qfjz5974

关于docker - 群负载均衡是否应该对其节点执行健康检查?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43340147/

10-12 05:17