[英]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网关错误(没有健康的实例)。 查看负载均衡器监控选项卡 ,确保健康主机的数量始终高于0。
如果您正在进行HTTP运行状况检查 ,则只有在服务器正常启动并运行时,它才必须返回代码200 (有效代码列表可在负载均衡器设置中配置)。 否则,负载均衡器可能会处置尚未完全运行的处理实例。
如果问题是你总是得到一个503坏网关 ,可能是因为你的实例需要很长时间才能回答(当服务正在初始化时),因此ECS会将它们视为关闭并在初始化完成之前关闭它们。 Jenkins第一次运行时经常出现这种情况。
为了避免最后一个问题,您可以考虑调整负载均衡器ping目标 ( 经典负载均衡器的 healthcheck目标 ,应用程序负载均衡器的 侦听 器 ):
如果您需要确保每个实例只有一个节点,则可以使用经典的负载均衡器 (它也可以很好地与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.