群集负载均衡应该在其节点上执行健康检查吗?

时间:2017-04-11 08:05:49

标签: docker load-balancing docker-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会在几秒钟之后在这里重新创建它以保持服务上的复制= 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"}

2 个答案:

答案 0 :(得分:2)

正如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启动服务副本时,它会启动一个容器,它会等到服务的运行状况为#34;健康状态"。当您的容器启动时,它将从"开始" :

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

答案 1 :(得分:0)

@ddewaele是正确的,所以这里还有一些花絮:

  • LB没有直接执行端口连接检查,这是Docker引擎启动健康检查的工作,这可能是一个简单的卷曲或更多。
  • healthchecks对于零停机部署至关重要。特别是如果您的容器在启动或关闭时花费的时间超过亚秒。没有健康检查,docker只知道" Linux是否说该进程正在运行?"
  • 您可以使用docker events看到它在每个容器中启动exec命令,并为其Swarm服务设置了运行状况检查。您还可以看到它如何将任务/容器标记为健康/不健康。
  • 在更新/关闭任务期间,入口负载均衡器发送数据包时出现问题/错误,但截至17.12(刚刚发布)的AFAIK主要/全部已修复。其中一个老问题是LB在容器关闭开始之前可能不会从路由表中删除任务,但人们报告的是最近几个版本的更好结果。 https://github.com/moby/moby/issues/30321