如何将最新代码推送到 Auto Scaling 组
Posted
技术标签:
【中文标题】如何将最新代码推送到 Auto Scaling 组【英文标题】:How do I push latest code into auto scaling group 【发布时间】:2015-10-26 16:54:21 【问题描述】:我尝试使用 AWS Auto Scaling 框架运行我的生产服务器。
我想知道如何将新发布的代码部署到正在运行的生产服务器中。
目前我不在乎down time
。
我使用nginx
和puma
运行网络服务器
完成这项任务的常用方法是什么?
我想登录 AWS 控制台找到所有服务器 IP 和 SSH 进入它。更新代码库并重新启动 puma Web 服务器不是保持产品质量的好方法
【问题讨论】:
你的问题我不清楚。 我更新了我的问题,你清楚了吗? 【参考方案1】:我创建了一个特殊的 Capistrano 部署环境。它不会像您在那里找到的其他部署服务那样强大,但它可以完成工作。
假设您有一台可以通过 SSH 连接的远程机器来启动部署命令(我想您的服务器没有公共 IP,但您仍然有一个可以通过 SSH 连接的堡垒主机以及可以运行的地方一个capistrano任务)。该机器将获取所有其他机器的 dns,并使用 Capistrano 部署管道部署到它们(我已在其他人的 authorized_keys 中添加了该部署机器的 id_rsa)。
我正在使用亚马逊标签来过滤实例:确保可以使用标签轻松选择自动缩放组的实例。
在下面的代码中,我还为不在自动缩放组内但仍在同一个负载均衡器后面(再次使用标签)的机器生成警告
# config/deploy/remote_production.rb
# [ several lines of capistrano configuration : git repo, branch, etc.]
#
# Deploy to autoscaling machines :
#
# Determine list of instances with aws sdk
require 'aws-sdk'
# Get instances IDs using tags
ec2 = Aws::EC2::Client.new
instances_tagged = ec2.describe_instances(
dry_run: false,
filters: [
name: 'tag:environment',
values: ['production'],
,
name: 'tag:stack',
values: ['rails'],
],
)
dns_tagged = instances_tagged.reservations[0].instances.map(&:private_dns_name)
# Get auto scaling group instance IDs
as = Aws::AutoScaling::Client.new
instances_of_as = as.describe_auto_scaling_groups(
auto_scaling_group_names: ['myApp-autoScale-prod'],
max_records: 1,
).auto_scaling_groups[0].instances
if instances_of_as.empty?
autoscaling_dns = []
else
instances_ids = instances_of_as.map(&:instance_id)
autoscaling_dns = instance_ids.map do |instance_id|
ec2.instances[instance_id].private_dns_name
end
end
# Get private DNS names for each machine
dns = dns_tagged | autoscaling_dns
if (extra_instances = (dns - autoscaling_dns).size) != 0
puts "WARNING : there are #extra_instances more instances that just the ones of the autoscaling group !!"
end
# Set the Capistrano servers to deploy to
dns.each do |instance|
server instance,
roles: %wweb app db,
user: 'ubuntu',
port: 22,
ssh_options:
keys: ['~/.ssh/id_rsa'],
forward_agent: true,
auth_methods: %w(publickey)
end
我只需要这样做
ssh ssh@bastion_host
cd deploy/myApp
cap remote_production deploy
【讨论】:
【参考方案2】:在 Amazon EC2 实例上部署代码的方式有很多选择。事实上,这与在任何普通计算机上部署代码的方式基本相同,但 Amazon EC2 有一些技术可以让这更容易。
选项 1:配置 AMI
启动新的 Amazon EC2 实例时,必须选择 Amazon 系统映像 (AMI)。 AMI 是一个磁盘映像,它复制到新实例的启动磁盘,然后实例使用该映像启动。
因此,部署新代码的一种选择是:
构建新的 AMI(通过配置实例,然后从该实例创建映像) 创建使用新 AMI 的新 Auto Scaling 启动配置 编辑 Auto Scaling 组以使用新的启动配置 在 Auto Scaling 组中启动新实例(例如,增加minimum
的实例数量)
启动新实例后,删除旧实例(例如,减少 minimum
并等待自动缩减过程,或通过降低 desired-capacity
强制减少。旧实例将首先自动删除,具体取决于Auto Scaling Termination Policy
选项 2:用户数据脚本
这类似于选项 1,但不是配置新的 AMI,而是让实例通过启动脚本自行配置。可以通过User Data field 传递脚本,该脚本将在新实例启动时执行。
脚本可以做任何你想做的事情,例如下载和安装软件,使用 Puppet/Chef/Ansible 进行部署,以及启动/停止 Web 服务器。
用户数据脚本应存储在 Auto Scaling 启动配置中(类似于选项 1 中的 AMI)。然后,只需启动新实例(类似于选项 1),它们就会自动使用您的软件的最新版本进行配置。
选项 3:使用部署服务
AWS 有多个系统可以将代码部署到 Amazon EC2 实例,包括:
AWS Elastic Beanstalk AWS OpsWorks AWS CloudFormation AWS CodeDeploy前三个可以部署基础架构和代码。
虽然这些系统比简单地提供脚本更复杂,但它们允许更可重复、更有弹性的架构(例如处理故障和回滚)。
【讨论】:
以上是关于如何将最新代码推送到 Auto Scaling 组的主要内容,如果未能解决你的问题,请参考以下文章
与多个可用区一起使用时,Auto Scaling 如何“放置”实例?
Ansible:将正在运行的 EC2 实例添加到 Auto-scaling 组
部署代码后如何在另一个 Auto Scaling 组上重启 Varnish 服务
Elastic Beanstalk 环境的 Auto Scaling 组