如何将最新代码推送到 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

我使用nginxpuma 运行网络服务器

完成这项任务的常用方法是什么?

我想登录 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 组

amazon aws Auto Scaling 组实例名称标签

Auto-Scaling 组不会在启动配置更改时更新