如果要在ELB后面部署新版本的应用程序,如何在AWS中建立维护页面?我们希望在新的自动缩放实例出现时将ELB路由流量提供给维护实例,并且只有在它们完全启动时才“翻转”到新实例。我们使用自动缩放来降低现有实例,并使用具有新代码的新实例。
我们试图避免的情况是让ELB同时为新的EC2实例提供流量,同时提供维护页面。由于我们没有启用粘性会话,因此我们希望防止用户在维护模式页面和部署在EC2实例中的应用程序之间来回切换。我们也不能只扩展(例如从2到4个实例然后再回到2)来引入新实例,因为代码更改可能涉及数据库更改,这将破坏旧代码的更改。
答案 0 :(得分: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
答案 1 :(得分:7)
Route53不是解决此问题的好方法。在维护页面显示之前,DNS条目需要花费大量时间才能到期(然后在维护完成后更新之前需要相同的时间)。我知道在提出这个问题的时候Lambda和CodeDeploy触发器不存在,但是我想让其他人知道Lambda可以用来为这个创建一个相对干净的解决方案,我在博客文章中有详细说明: http://blog.ajhodges.com/2016/04/aws-lambda-setting-temporary.html
解决方案的要点是将Lambda函数订阅到CodeDeploy事件,它会在部署期间用负载平衡器中的静态页面替换您的ASG。
答案 2 :(得分:5)
提出了另一个对我们有用的解决方案。以下是步骤:
app-environment-maintenance
。/error/*
。/error/503-error.html
最后,您可以使用AWS CLI交换环境CNAME,使您的主环境进入维护模式。例如:
aws elasticbeanstalk swap-environment-cnames \
--profile "$awsProfile" \
--region "$awsRegion" \
--output text \
--source-environment-name api-prod \
--destination-environment-name api-prod-maintenance
这会将您的app-prod
环境换成维护模式。它会导致ELB抛出503,因为没有任何正在运行的EC2实例,然后Cloudfront将捕获503并返回相应的503错误页面。
就是这样。我知道有很多步骤,我尝试了很多建议的选项,包括Route53等。但所有这些都与它们如何使用ELB和Cloudfront等有关。
请注意,在交换环境的主机名后,传播大约需要一分钟左右。
答案 3 :(得分:4)
我意识到这是一个古老的问题,但是在今天(2018年12月)面对同样的问题之后,看来还有另一种方法可以解决此问题。
今年早些时候,AWS引入了对redirects and fixed responses to Application Load Balancers的支持。简而言之:
text/plain
或text/html
响应(即您的维护页面HTML)。一旦规则传播到ELB(对我来说大约30秒),当您尝试在浏览器中访问主机时,系统会显示503维护页面。
部署完成后,只需删除添加的规则即可。
答案 4 :(得分:1)
我们的部署过程首先运行一个cloudformation来旋转一个ec2微实例(维护实例),它将预定义的静态页面从s3复制到ec2上。随着微型ec2实例附着的elb提供了cloudformation。然后运行脚本(powershell或cli)从elb离开维护实例中删除Web实例(ec2)。
这样我们就可以在部署过程中切换到维护实例。
在我们的例子中,我们有两个elb,一个用于外部,另一个用于内部。我们的内部elb将不会在此过程中更新,我们是如何进行post prod部署烟雾测试的。 测试完成后,我们运行另一个脚本将Web实例附加回elb并删除维护堆栈。
答案 5 :(得分:1)
据我所知,我们处于上述答案不适用或不理想的情况。
我们有一个Rails应用程序,它在Puma上运行Ruby 2.3,并在64位Amazon Linux / 2.9.0上运行,它似乎带有一个(经典的)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。
仅需要大约15秒钟左右的时间就可以应用beantalk(可能主要是在等待后端的云形成)。