詳細検索

Capistrano에서 EC2 인스턴스를 서로 다른 AvilabilityZones로 실행하기

아바타
글쓴이 maeno

Capistrano에서 EC2 인스턴스를 서로 다른 AvilabilityZones로 실행하기
日本語에서 번역 • 원문 보기

지난번에,

다음에는 데이터베이스를 만들고 초기 설정을 막판에 삽입한 뒤, 워드프레스 설정 파일을 다시 작성한 뒤 GitHub에서 워드프레스 테마를 다운로드하려고 합니다.

하지만 편리함 때문에 Capistrano3를 사용해 AWS EC2 인스턴스를 만들었기 때문에, 팁을 남기고 싶습니다. 이번에는 배포용 EC2 인스턴스의 공식 AMI를 사용해 각 지역에 서로 다른 가용성 존(AvailabilityZones)을 설정했습니다. 파일럿으로는 최신 인스턴스 유형 "t2.micro"를 지원하는 "Amazon Linux AMI 2014.03.2 (HVM)"을 사용해 도쿄 지역 1a와 1c의 가용성 존에 각각 두 개씩 총 4개의 인스턴스를 동시에 설정할 예정입니다.

  • 예비 준비 단계로, 인스턴스를 설정하려는 AWS 계정에서 VPC나 서브넷 등 EC2 인스턴스를 생성하기 위한 최소한의 설정을 해야 합니다. 특히 이번에는 서로 다른 가용성 존(AvailabilityZones)에 인스턴스를 설정할 예정이므로, 각 존마다 서브넷을 설정해야 합니다.

이제 배포 절차부터 시작해 보겠습니다. 먼저 'config/deploy/test.rb'를 편집하여 배포 환경(서버)을 구성합니다. 이번에는 동적으로 생성된 EC2 인스턴스가 배포 환경이 되므로 서버를 미리 구성할 수 없습니다. 이는 AWS에서 새로 실행된 인스턴스가 ElasticIP가 없기 때문에 PublicIP가 매번 다르고 엔드포인트 URL이 동적으로 변경되기 때문입니다. 따라서 이번에는 인스턴스가 실행된 후 Capistorano 작업에서 대상 서버를 구성할 것입니다. 초기 서버 구성은 더 이상 없으므로 설명은 주석으로 처리하겠습니다. 또한 결국 공통으로 사용되는 것은 SSH 옵션이므로 남겨두겠습니다(하지만 이번 배포 작업에서는 사용하지 않을 것입니다...).

$ vim config/deploy/test.rb
#role :app, %w{deploy@localhost}
#role :web, %w{deploy@localhost}
#role :d b, %w{deploy@localhost}

set :ssh_options, { 
  키: %w(/home/deploy/.ssh/id_rsa), 
  forward_agent: 맞아요, 
}

이번 배포에서는 "AWS SDK for Ruby"를 사용할 예정이므로 SDK를 미리 설치할 예정입니다.

$ sudo gem install aws-sdk

다음으로, 'config/deploy.rb'에서 배포 내용을 설정하세요.

$ vim config/deploy.rb
# config capistrano 3.1에만 유효
락 '3.2.1' 

# 루비용 AWS SDK 로딩 중
'aws-sdk' 요구사항 

# AWS SDK 설정
AWS.config({ 
  :access_key_id => '<AWSアカウントのACCESS key="" id="">',  
  :secret_access_key => '<AWSアカウントのSECRET access="" key="">',  
  :region=> 'ap-northeast-1', # EC2 인스턴스가 생성되는 영역
})

# 아미 image_id
# 아마존 리눅스 AMI 2014.03.2 (HVM)
셋 :ami_image_id, 'ami-29dc9228' 

# 생성할 인스턴스 수
준비 :instance_count, 4

# 생성할 인스턴스 유형
셋 :ec2_instance_type, 't2.micro' 

# 이용 가능 구역 만들기
세트 :availability_zones, [ 'AP-북동-1a', 'AP-북동-1c' ]

# 창조subnet_id
Set :subnet_ids, [ '서브넷-********', '서브넷-********' ]

# Capistrano 기본 작업 삭제
framework_tasks = [:시작, :시작, :업데이트 중, :업데이트, :p유전, :p완성, :마무리, :완료]
framework_tasks.각 두 |t|
  Rake::Task["deploy:#{t}"].clear
끝
레이크::과제[:d에플로이].완료

desc '각 가용성 존별로 EC2 인스턴스를 런칭' 
작업 :실행 실행
  run_locally 그래
    ec2 = AWS::EC2.new

    created_instances = []
    CNT = 0
    CNT < fetch(:instance_count) do
      if cnt.even? then
        current_az = fetch(:availability_zones)[0]
        current_sn = fetch(:subnet_ids)[0]
      else
        current_az = fetch(:availability_zones)[1]
        current_sn = fetch(:subnet_ids)[1]
      end
      i = ec2.instances.create(
        :image_id => fetch(:ami_image_id),  
        :availability_zone => current_az, 
        :서브넷 => current_sn,  
        :instance_type => fetch(:ec2_instance_type),  
        :카운트 => 1
      )
      i.status 동안 10번 자세요 == :p anding
      created_instances < i.id
      cnt += 1
    end
    execute "echo -n #{created_instances} > ~/CREATED_INSTANCES" 

  끝
끝

desc '새 인스턴스의 활성화 상태 확인' 
작업 :체크 하기
  created_instances_list = 'CREATED_INSTANCES' 

  run_locally 그래
    ec2 = AWS::EC2.new

    시작
      테스트 "[ -f ~/#{created_instances_list} ]" 
        created_instances = 캡처("CD ~; 고양이 #{created_instances_list}").씹어
        ci = created_instances.gsub(/(\[|\s|\])/, '').split(',')
        target_instances = ec2.instances.select { |i| i.exists? && i.status == :running && ci.include?( i.id) }.map(&:p rivate_ip_address)
        만약 target_instances.length == 0이라면,
          "생성된 인스턴스 없음" 
        끝
        target_instances.each { |var| 
          Server var, user: 'ec2-user', roles: %w{web app}
        }
      끝
    구조 => e
      정보 E
      퇴장
    끝

  끝
끝

작업 :d eploy => :체크 Do
  run_locally 그래

    정보 역할(:전부)
    정보 '다음 작업 – 새로운 인스턴스에서 배포' 

    # 전개 시작

  끝
끝

실제로 인스턴스를 실행하세요.

$ 캡 테스트 발사
INFO[10af60ae] localhost에서 /usr/bin/env echo -n ["i-7497be72", "i-01c31718", "i-4d94bd4b", "i-00c31719"] > ~/CREATED_INSTANCES
DEBUG[10af60ae] 명령어: echo -n ["i-7497be72", "i-01c31718", "i-4d94bd4b", "i-00c31719"] > ~/CREATED_INSTANCES
INFO[10af60ae] 0.003초 만에 완주했고, 출구 상태 0(성공). 

위 로그는 출력된 것이고, 인스턴스 실행도 완료된 것으로 보이므로 AWS 관리 콘솔에서 확인해 보세요.

AWSのマネージメント・コンソールで新規インスタンスを確認

네 개의 인스턴스가 서로 다른 가용성 구역에서 번갈아 실행된 것은 사실입니다. 이는 이상적인 이동입니다. AWS 인스턴스의 런치 시간은 환경에 따라 다르기 때문에, 위의 "런칭" 태스크는 EC2 인스턴스의 런치 상태를 확인하지 않고 종료됩니다. 하지만 이런 상태가 계속되면 다음 Capistorano의 태스크가 실행될 때 인스턴스 정보가 이어지지 않아, "런치" 태스크에서 실행된 인스턴스의 ID가 "CREATED_INSTANCES"라는 파일에 기록되어 종료됩니다. 다음 태스크에서는 "CREATED_INSTANCES"로 작성된 인스턴스 ID를 찾아 인스턴스의 시작 상태를 확인하고, 상태가 ":running"이면 배포할 서버로 설정하려고 합니다. 또한 "check" 작업은 상태 ":running"이 있는 새 인스턴스의 사설 IP 주소를 목적지 서버의 호스트명으로 사용하지만, 새 인스턴스에 공인 IP 주소가 할당되고 공인 DNS가 설정되어 있다면 이를 '{}.map(&:d ns_name)'로 빼도 괜찮습니다.

후속 업무를 실행해 보세요.

$ 캡 테스트 배포
DEBUG[79c503fb] localhost에서 /usr/bin/env [ -f ~/CREATED_INSTANCES ] 실행 중
DEBUG[79c503fb] 명령어: [ -f ~/CREATED_INSTANCES ]
DEBUG[79c503fb] 종료 시간은 0.003초였고, 종료 상태 0(성공). 
DEBUG[9dd1f93d] /usr/bin/env cd 실행 중~; localhost에서 cat CREATED_INSTANCES
디버그[9dd1f93d] 명령어: cd ~; 캣 CREATED_INSTANCES
DEBUG[9dd1f93d] [i-7497be72, i-01c31718, i-4d94bd4b, i-00c31719]
DEBUG[9dd1f93d] 종료 시간은 0.002초였고, 종료 상태 0(성공). 
정보[#<Capistrano::Configuration::Server:0x0000000189a7c8 @user="ec2-user", @hostname="176.34.61.80", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x00000001899238 @properties={}, @roles=#<Set: {:web,="" :app}="">>>, #<Capistrano::Configuration::Server:0x000000018a3a08 @user="ec2-user", @hostname="176.34.62.168", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x000000018a3080 @properties={}, @roles=#<Set: {:web,="" :app}="">>>, #<Capistrano::Configuration::Server:0x000000018a0d58 @user="ec2-user", @hostname="176.34.62.75", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x000000018a6910 @properties={}, @roles=#<Set: {:web,="" :app}="">>>, #<Capistrano::Configuration::Server:0x000000018a8ee0 @user="ec2-user", @hostname="176.34.61.75", @port=nil, @properties=#<Capistrano::Configuration::Server::Properties:0x000000018b3818 @properties={}, @roles=#<Set: {:web,="" :app}="">>>]
INFONext 새로운 인스턴스에 배포 작업

이전 작업에서 생성된 인스턴스의 정보는 상속되어 배포할 서버로 성공적으로 설정되었습니다. 다음 작업(이 경우 "배포" 작업)에서는 각 새 인스턴스마다 Apache, PHP 또는 MySQL 파일을 설치하면 이전 WordPress 배포에 연결할 수 있습니다.

결국, Capistrano 명령어를 2~3번 입력하기만 하면 서버를 만들고 워드프레스를 동시에 배포할 수 있는 꿈같은 배포 환경을 만들 수 있습니다.

참고 사이트

Related Articles