当您的实例落后于ELB时,如何为AWS建立维护页面?

问题描述 投票:30回答:6

当您想在ELB后面部署新版本的应用程序时,如何在AWS中建立维护页面?我们希望在新的自动缩放实例出现时将ELB路由流量提供给维护实例,并且只有在它们完全启动时才“翻转”到新实例。我们使用自动缩放功能将现有实例降低,并使用具有新代码的新实例。

我们试图避免的情况是让ELB同时为新的EC2实例提供流量,同时提供维护页面。由于我们没有启用粘性会话,因此我们希望防止用户在维护模式页面和部署在EC2实例中的应用程序之间来回切换。我们也不能只扩展(例如从2到4个实例然后再回到2)来引入新实例,因为代码更改可能涉及数据库更改,这将破坏旧代码的更改。

amazon-web-services amazon-elb amazon-route53
6个回答
21
投票

AWS上最简单的方法是使用他们的DNS服务Route 53

您可以使用Weighted Round Robin的功能。

“您可以使用WRR将服务器投入生产,执行A / B测试,或平衡不同大小的区域或数据中心的流量。”

有关AWS documentations on this feature的更多信息

编辑:Route 53最近添加了一项新功能,允许DNS故障转移到S3。查看他们的文档以获取更多详细信息:http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-failover.html


7
投票

Route53不是解决此问题的好方法。在维护页面显示之前,DNS条目需要花费大量时间才能到期(然后在维护完成后更新之前需要相同的时间)。我知道在提出这个问题的时候Lambda和CodeDeploy触发器不存在,但是我想让其他人知道Lambda可以用来创建一个相对干净的解决方案,我在博客文章中有详细说明:http://blog.ajhodges.com/2016/04/aws-lambda-setting-temporary.html

解决方案的要点是将Lambda函数订阅到CodeDeploy事件,这将在部署期间用负载平衡器中的静态页面替换您的ASG。


6
投票

想出了另一个对我们有用的解决方案。以下是获取简单503 http响应所需的步骤:

  1. 复制您的EB环境以创建另一个,例如,将其命名为app-environment-maintenance
  2. 更改自动缩放的配置,并将min和max服务器都设置为零。这不会花费您任何EC2服务器,并且环境将变为灰色并位于您的列表中。
  3. 最后,您可以使用AWS CLI交换环境CNAME,使您的主环境进入维护模式。例如: aws elasticbeanstalk swap-environment-cnames \ --profile "$awsProfile" \ --region "$awsRegion" \ --output text \ --source-environment-name app-prod \ --destination-environment-name app-prod-maintenance

这会将你的app-prod环境换成维护模式。这将导致ELB抛出503,因为没有任何正在运行的EC2实例,然后Cloudfront可以捕获503并返回您的自定义503错误页面,如下所述。


使用Cloudfront的自定义错误页面的奖励配置:

我们使用Cloudfront,因为许多人都会使用HTTPS等.Cloudfront有错误页面。这是一项要求。

  1. 使用您的错误页面创建一个新的S3网站托管存储桶。考虑为响应代码创建单独的文件,503等。有关目录要求和路由,请参阅#6。
  2. 将S3存储桶添加到Cloudfront分发中。
  3. 为您的Cloudfront分发添加新行为以获取/error/*等路由。
  4. 在Cloudfront中设置错误页面以处理503响应代码并将其指向S3存储桶路由,如/error/503-error.html

现在,当您的ELB抛出503时,将显示您的自定义错误页面。

就是这样。我知道有很多步骤来获取自定义错误页面,我尝试了很多建议的选项,包括Route53等。但所有这些都与它们如何使用ELB和Cloudfront等有关。

请注意,在交换环境的主机名后,传播大约需要一分钟左右。


5
投票

我意识到这是一个古老的问题,但在今天(2018年12月)遇到同样的问题后,看起来还有另一种方法可以解决这个问题。

今年早些时候,AWS引入了对redirects and fixed responses to Application Load Balancers的支持。简而言之:

  • 在控制台中找到ELB。
  • 查看适当侦听器的规则。
  • 为应用程序的主机名添加固定的503响应规则。
  • 可选择提供text/plaintext/html响应(即您的维护页面HTML)。
  • 保存更改。

一旦规则传播到ELB(对我来说需要大约30秒),当您尝试在浏览器中访问主机时,您将看到503维护页面。

部署完成后,只需删除您添加的规则即可。


1
投票

我们的部署过程首先运行一个cloudformation来生成一个ec2微实例(维护实例),它将预定义的静态页面从s3复制到ec2上。 Cloudformation由elb提供,微型ec2实例连接到elb。然后运行脚本(powershell或cli)从elb离开维护实例中删除Web实例(ec2)。

这样我们就可以在部署过程中切换到维护实例。

在我们的例子中,我们有两个elb,一个用于外部,另一个用于内部。我们的内部elb将不会在此过程中更新,也就是我们如何进行post prod部署烟雾测试。测试完成后,我们运行另一个脚本将Web实例附加回elb并删除维护堆栈。


1
投票

据我所见,我们处于上述答案不适用或不理想的情况。

我们有一个运行Puma的Rails应用程序,运行在64位Amazon Linux / 2.9.0上的Ruby 2.3,它似乎带有(经典)ELB。

所以ALB 503处理不是一个选择。

我们还有各种硬件客户端,我不相信它们始终尊重DNS TTL,因此Route53存在风险。

看起来效果很好的是nginx上的辅助端口,它随平台一起提供。

我把它添加为.ebextensions/maintenance.config

files:
  "/etc/nginx/conf.d/maintenance.conf":
    content: |
      server {
        listen 81;
        server_name _ localhost;
        root /var/app/current/public/maintenance;
      }

container_commands:
  restart_nginx:
    command: service nginx restart

并将https://gist.github.com/pitch-gist/2999707的副本丢入public/maintenance/index.html

现在设置维护我只是将我的ELB监听器切换到指向端口81而不是默认的80.没有额外的实例,s3桶或等待客户端到新的DNS。

适用于beanstalk(可能主要是等待后端的cloudformation)大约需要15秒左右才能应用。

© www.soinside.com 2019 - 2024. All rights reserved.