我创建了一个特殊的 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: %w{web 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