繁体   English   中英

AWS ECS 503服务在部署时暂时不可用

[英]AWS ECS 503 Service Temporarily Unavailable while deploying

我正在为我的应用程序使用带有应用程序负载均衡器的Amazon Web Services EC2容器服务。 当我部署新版本时,我得到503服务暂时不可用大约2分钟。 它比我的应用程序的启动时间多一点。 这意味着我现在无法进行零停机部署。

是否有设置在启动时不使用新任务? 或者我在这里缺少什么?

更新:

ALB的目标组的运行状况检查编号如下:

Healthy threshold:     5
Unhealthy threshold:   2
Timeout:               5 seconds
Interval:              30 seconds
Success codes:         200 OK

健康阈值是'在考虑健康的不健康目标之前所需的连续健康检查成功次数'
不健康的阈值是“在考虑目标不健康之前所需的连续健康检查失败次数”。
超时是'没有响应意味着健康检查失败的时间量,以秒为单位。'
间隔是'单个目标的健康检查之间的大致时间'

更新2:所以,我的集群由两个EC2实例组成,但如果需要可以扩展。 所需和最小计数为2.我为每个实例运行一个任务,因为我的应用程序需要特定的端口号。 在我部署之前(jenkins运行aws cli脚本)我将实例数设置为4.如果没有这个,AWS就无法部署我的新任务(这是另一个需要解决的问题)。 网络模式是桥梁。

因此,问题似乎在于任务定义中容器设置的端口映射。 在我使用80作为主机和8080作为容器端口之前。 我以为我需要使用这些,但主机端口实际上可以是任何值。 如果将其设置为0,则ECS将分配32768-61000范围内的端口,因此可以将多个任务添加到一个实例。 为了实现这一点,我还需要更改我的安全组,让流量从ALB流向这些端口上的实例。
因此,当ECS可以在同一个实例上运行多个任务时,50/200最小/最大健康百分比是有意义的,并且可以在不需要添加新实例的情况下部署新任务修订。 这也确保了零停机时间的部署。

感谢所有提出要求或评论的人!

由于您使用的是AWS ECS,请问服务的“最低健康百分比”和“最高健康百分比”是多少?

确保您的“最大运行状况百分比”为200,“最低运行状况百分比”为50,以便在部署期间不会使所有服务都停止运行。

请查看这两个术语的文档定义:

最大百分比提供部署期间正在运行的任务数的上限,使您可以定义部署批处理大小。

最低运行百分比在部署期间提供运行任务数量的下限,使您无需使用其他群集容量即可进行部署。

“最小健康百分比”限制为50将确保在部署新版本的容器之前,只有一半的服务容器被杀死,即,如果服务的所需任务值是“2”而不是部署时只有旧版本的“1”容器才会被杀死,一旦部署了新版本,第二个旧容器将被杀死并部署一个新版本容器。 这将确保在任何给定时间都有处理请求的服务。

类似地,“最大健康百分比”的限制为200告诉ecs-agent,在部署期间的给定时间,服务的容器可以达到所需任务的最大值的两倍。

如有任何进一步的问题,请告诉我。

使用您的设置,应用程序启动应该花费超过30秒才能使2次健康检查失败并被标记为不健康(假设您的应用程序停机后立即进行首次检查)。 并且至少需要2分钟到3分钟才能再次标记为健康状态(在最佳情况下您的应用程序重新联机后立即进行首次检查,或者在最糟糕的情况下,在应用程序恢复之前立即进行首次检查)。

因此,快速而肮脏的修复是增加不健康的阈值,以便在更新期间不会标记为不健康。 并且可能会降低健康阈值,以便更快地标记为健康。

但是如果你真的想要实现零停机时间,那么你应该使用你的应用程序的多个实例,并告诉AWS按照Manish Joshi的建议进行阶段部署(这样你的ELB背后总会有足够健康的实例来保持你的网站运行)。

我如何解决这个问题是在应用程序根目录中有一个平面文件,ALB将监视该文件以保持健康状态。 在部署之前,脚本将在监视节点时删除此文件,直到它注册OutOfService

这样,所有实时连接都会停止并耗尽。 此时,通过停止节点或应用程序进程来启动部署。 部署之后,通过添加回该平面文件将节点添加回LB,并进行监视,直到它为此节点注册Inservice ,然后再移动到第二个节点以完成上述相同步骤。

我的脚本如下所示

# Remove Health Check target
echo -e "\nDisabling the ELB Health Check target and waiting for OutOfService\n"
rm -f /home/$USER/$MYAPP/server/public/alive.html

# Loop until the Instance is Out Of Service
while true
do
        RESULT=$(aws elb describe-instance-health --load-balancer-name $ELB --region $REGION --instances $AMAZONID)
        if echo $RESULT | grep -qi OutOfService ; then
                echo "Instance is Deattached"
                break
        fi
        echo -n ". "
        sleep $INTERVAL
done

您正在谈论Jenkins ,所以我会回答Jenkins主服务,但我的答案仍然适用于任何其他情况(即使它不是ECS的一个好例子, Jenkins主人不能正确扩展,所以那里可以只有一个实例)。

503糟糕的网关

我经常遇到与负载均衡器失败的健康检查相关的503网关错误(没有健康的实例)。 查看负载均衡器监控选项卡 ,确保健康主机的数量始终高于0。

如果您正在进行HTTP运行状况检查 ,则只有在服务器正常启动并运行时,它才必须返回代码200 (有效代码列表可在负载均衡器设置中配置)。 否则,负载均衡器可能会处置尚未完全运行的处理实例。

如果问题是你总是得到一个503坏网关 ,可能是因为你的实例需要很长时间才能回答(当服务正在初始化时),因此ECS会将它们视为关闭并在初始化完成之前关闭它们。 Jenkins第一次运行时经常出现这种情况。

为了避免最后一个问题,您可以考虑调整负载均衡器ping目标经典负载均衡器的 healthcheck目标 ,应用程序负载均衡器的 侦听 ):

  • 使用应用程序负载均衡器 ,尝试使用始终返回200的内容 (对于Jenkins,它可能是一个公共文件,例如/robots.txt)。
  • 使用经典的负载均衡器 ,使用TCP端口测试而不是HTTP测试 如果您正确打开了端口,它将始终成功。

每个实例一个节点

如果您需要确保每个实例只有一个节点,则可以使用经典的负载均衡器 (它也可以很好地与ECS配合使用)。 使用经典的负载平衡器ECS可确保每台服务器只运行一个实例。 这也是唯一可以访问非HTTP端口的解决方案(例如Jenkins需要80,但奴隶也需要50000)。

但是,由于端口不是动态的经典负载均衡器,您必须进行一些端口映射,例如:

myloadbalancer.mydomain.com:80(负载均衡器的端口80) - >实例:8081(容器的外部端口) - > service:80(容器的内部端口)。

当然,每个服务需要一个负载均衡器。

詹金斯健康检查

如果这是您想要启动的Jenkins服务,您应该使用Jenkins Metrics插件来获得良好的健康检查URL

安装它,并在全局选项中生成一个令牌并激活ping,你应该能够找到如下所示的URL: http//myjenkins.domain.com/metrics/mytoken12b3ad1/ping

只有在服务器完全运行时,此URL才会回答HTTP代码200 ,这对于负载均衡器仅在完全就绪时才激活它非常重要。

日志

最后,如果您想知道实例发生了什么以及它失败的原因,您可以添加日志以查看容器在AWS Cloudwatch中的含义

只需在任务定义(容器配置)中添加:

日志配置: awslogs
awslogs-group: mycompany (将重新组合容器日志的Cloudwatch密钥)
awslogs-region: us-east-1 (你的集群区域)
awslogs-stream-prefix: myservice (创建日志名称的前缀)

它将为您提供有关容器初始化过程中发生的事情的更多信息,如果它只需要太长时间或者它是否失败。

希望能帮助到你!!!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM