Docker swarm:重启后保证高可用性

时间:2017-05-26 19:28:39

标签: docker docker-swarm

我在使用Docker swarm时遇到了问题。

我有一个在Gunicorn上运行的Python Web服务的3个副本。

问题是,当我在软件更新后重新启动swarm服务时,旧的正在运行的服务被终止,然后创建并启动一个新服务。但是在旧服务已经被杀死的短时间内,并且新服务还没有完全启动,网络消息已经被路由到尚未准备好的新实例,导致502坏网关错误(我从nginx代理服务)。

我使用--update-parallelism 1 --update-delay 10s选项,但这并没有消除这个问题,只是略微减少了获得502错误的机会(因为总有至少2个服务正在运行,即使其中一个可能是还在开始)。

2 个答案:

答案 0 :(得分:0)

所以,按照我在评论中提出的建议:

使用Dockerfile的HEALTHCHECK功能:Docs。类似的东西:

HEALTHCHECK --interval=5m --timeout=3s \
  CMD curl -f http://localhost/ || exit 1

知道Docker Swarm在服务更新期间确实遵守了此健康检查,因此零停机部署相对容易。

但正如您所提到的,您拥有高资源的消费者健康检查,并且您需要更长的健康检查间隔。

在这种情况下,我建议您在第一次运行时自定义运行状况检查,并在current_minute % 5 == 0进行连续检查,但运行状况检查本身正在运行/30s

HEALTHCHECK --interval=30s --timeout=3s \
  CMD /service_healthcheck.sh

<强> healthcheck.sh

#!/bin/bash

CURRENT_MINUTE=$(date +%M)
INTERVAL_MINUTE=5

[ $((a%2)) -eq 0 ]
do_healthcheck() {
  curl -f http://localhost/ || exit 1
}

if [ ! -f /tmp/healthcheck.first.run ]; then
  do_healhcheck
  touch /tmp/healthcheck.first.run
  exit 0
fi

# Run only each minute that is multiple of $INTERVAL_MINUTE
[ $(($CURRENT_MINUTE%$INTERVAL_MINUTE)) -eq 0 ] && do_healhcheck
exit 0

请记住COPY healthcheck.sh到/healthcheck.sh(以及chmod +x

答案 1 :(得分:0)

有一些已知的问题(例如moby/moby #30321)在docker swarm中使用当前的17.05及更早版本进行滚动升级(并且看起来并不像所有修复程序将会生成17.06)。这些问题会导致滚动升级期间的连接错误,例如您正在查看。

如果您有一个真正的零停机时间部署要求并且无法通过客户端重试解决此问题,那么我建议您在群组前面放置某种蓝/绿开关并执行滚动升级到非活动容器集,直到docker找到所有方案的解决方案。