안녕하세요. OPS의 코미야입니다.
회사 내에 수요가 있는 것 같았다,
Java보다 빠르게 파이썬 도구를 찾았지만 AWSCLI를 찾지 못해 결국 찾아봤습니다.
태그로 판단할 수 없는 자동 판단은 사용하지 않습니다. bkup_num로 세대 수를 지정하면 여러 세대를 얻을 수 있습니다.
이는 인수 1에 인스턴스 ID를, 인수 2에 호스트명을 명시하는 명세입니다.
--재부팅 없음, 즉 실행 중인 인스턴스가 재시작되지 않습니다.
데이터 영역에 EBS가 있더라도, ami 명령어가 스스로 여러 명령을 받는 것 같았기 때문입니다
그것이 OS 장치인지 데이터 장치인지 판단하고 이해하기 쉽게 태그를 달려 보았습니다.
※※주**
--재부팅 없음 AMI를 회수하려는 목표가 MyISAM 스토리지 엔진의 mysql DB 서버였을 때, 데이터가 손상되어 중단되었습니다.
만약 InnoDB가 아니라면 AMI를 정말로 얻고 싶다면, 유지보수 권고를 통해 멈추는 것이 더 나을 것입니다.
*AWS는 비방해적 AMI 획득과 관련된 데이터의 무결성을 보장하지 않습니다.
참고 URL: http://docs.aws.amazon.com/ja\_jp/AWSEC2/latest/UserGuide/creating-an-ami-ebs.html
즉, 스토리지 서버는 주의해야 하며(유지보수 권장) 사용해야 합니다.
・AWSCLI가 포함되어 있지 않으면 설치하세요
넣는 방법: (포함되어 있지 않다면 pip install awscli. Pip는 쉽게 추가됩니다_install)
AWS Command Line Tool for Python | Developers.IOEasy_install Python - Hane @ Diary AWS Command Line Interface(awscli)를 사용해봤는데, 전 RX-7 라이더에게 적합한 날들입니다
AWS 액세스 키와 도메인 설정 파일을 만들어서 스크립트에서 호출하세요.
[shell]# cat /root/.ec2/aws.config ------------ [default] aws_access_key_id=< 접근 키 ID> aws_secret_access_key=<비밀 접근 키 ID> region=ap-northeast-1 ------------[/shell]
·지휘부 조사 (먼저 올릴게요)
[shell]# AWS EC2 복사 이미지 도움말 ------------ copy-image DESCRIPTION 지정된 소스 지역에서 AMI를 요청이 이루어진 지역으로 복사를 시작합니다. 이 복사본은 지역 간 복사이므로 지금은 필요하지 않습니다. ------------ create-image는 실행 중이거나 중단된 Amazon EBS 지원 인스턴스에서 Amazon EBS 지원 AMI를 생성합니다. create-image [--dry-run | --no-dry-run] --인스턴스 ID
AWS EC2 create-image --instance-id i-10a64379 --name "My server" --description "내 서버용 AMI"
결과물:
{ "ImageId": "ami-5731123e" } ------------ describe-image 세대를 관리하고 싶다면, --필터 옵션에서 태그를 검색한 후 나온 imageid나 hostname을 사용하는 것이 좋습니다. ------------ describe-instance 이것은 RootDeviceName을 얻기 위해 사용하는 방법입니다. ------------ deregister-image는 지정된 AMI를 등록 해제합니다. AMI를 등록 해제한 후에는 새 인스턴스를 실행하는 데 사용할 수 없습니다. 개요: deregister-image [--dry-run | --no-dry-run] --image-id
AWS EC2 deregister-image --image-id ami-4fa54026
결과물:
{ "return": "true" } ------------ CREATE 태그 이름 - SIMOPSIS create-tags [--dry-run | --no-dry-run] --resources
AWS EC2 create-tags --resources ami-78a54011 --tags Key=Stack,Value=production
결과물:
{ "return": "true" } ------------ # AWS ec2 delete-snapshot 도움말 NAME delete-snapshot - DESCRIPTION 지정된 스냅샷을 삭제합니다. SYNOMIS delete-snapshot [--dry-run | --no-dry-run] --snapshot-id
# /USR/BIN/컬 -S http://169.254.169.254/latest/meta-data/instance-id I-292A442C ------------[/shell]
・대본 만들기
인자가 있으면 그 인스턴스를 만들 수 있고, 없다면 직접 AMI를 만들어도 됩니다.
return된 imageid를 파일에 넣고 태그를 붙이세요.
이 시점에서 RootDeviceName의 스냅샷이 결정되었는지, 그리고 장치 이름이 태그 이름에 포함되는지 여부로 태그가 OS임을 결정합니다.
hostname filter와 return의 imageid로 검색하면 호스트와 관련된 모든 imageid를 얻고, 날짜와 시간 필드에 따라 내림차순으로 정렬합니다.
과정은 유지하려는 생성의 행을 삭제하고, 대상의 이전 이미지ID를 지우며, deregist와 스냅샷을 삭제하는 것입니다.
세대 수는 bkup_num라는 변수로 정의됩니다.
[shell]# vi /opt/bin/aws_image_bkup.sh ------------ #!/bin/bash # #aws_image_bkup.sh: awscli 백업 AMI # 의존성: AWS 명령어 # 변경 기록: 20140314 - komiyay 생성 # PATH=$PATH:/usr/local/bin AWS_CONFIG_FILE=/root/.ec2/aws.config
만약 [ $# -EQ 0 ]; 그럼 에코 "인스턴스 ID를 지정하지 않으면, 로컬 인스턴스에 대한 AMI 백업을 수행하세요" 에코 "사용: $0 [인스턴스-id] [hostname]" myInstanceID='/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id\' host' host_name='uname -n' 그렇지 않으면 myInstanceID=$1 host_name=$2 fi
## default variables base='dirname "$0"' LOG=/opt/log/bkup.log CurrentImage_LOG=${base}/cimageid_${myInstanceID}.log #OLDimageID='cat ${CurrentImage_LOG}|grep ImageId|awk '{FS=":"; 인쇄 $2}'|sed -e 's/[ "]//g'' current_result=/opt/log/current_result.log today='/bin/date +%Y%m%d' amitime='/bin/date +%Y%m%d_%H%M' datetime='/bin/date +%Y/%m/%d_%H:%M:%S' 메일_to=<목적지 이메일 주소> #mail_to=<목적지 이메일 주소> bkup_num=1
## 체크_param. 만약 [ -z ${myInstanceID} ]; 그러면 에코 "에러: 인스턴스 ID 없음, 스크립트 종료 ${datetime}."| tee -a ${LOG} 출구 1 fi
## 기능 ### 메일_send 메일_send(){ 에코 ${mail_body}|tee -a ${LOG}|mail -s ${mail_title} ${mail_to} }
### create_ami create_ami(){ aws ec2 create-image --instance-id ${myInstanceID} --name "${host_name}_${amitime}" \ --description "${host_name}_${myInstanceID}_${datetime}" --no-reboot |tee ${CurrentImage_LOG} grep ImageId ${CurrentImage_LOG} res_create=$? }
### deregister_ami deregister_ami(){ if [ -z ${OLDimageID} ]; then res_deregister=0 그렇지 않으면 AWS ec2 deregister-image --image-id ${OLDimageID}|tee ${current_result} grep true ${current_result} res_deregister=$? 만약 [ ${res_deregister} -ne 0 ]; then mail_body="NG deregister ami for ${myInstanceID}(${host_name}) at ${datetime}" mail_titile="NG_deregister_ami_${today}" mail_send fi fi }
### delete_snapshot delete_snapshot(){ if [ -z ${OLDimageID} ]; then res_delsnap=0 else snapshot_ids='aws ec2 describe-snapshots --filters Name=description,Values=*${OLDimageID}* \ |grep SnapshotId|awk -F : '{print $2}'|sed -e 's/[ ",]//g'' for i in ${snapshot_ids} do aws ec2 delete-snapshot --snapshot-id ${i}|tee ${current_result} grep true ${current_result} res_delsnap=$? if[ ${res_delsnap} -ne 0 ]; then mail_body="NG delete ami snapshot(${i}) for ${myInstanceID}(${host_name}) at ${datetime}" mail_titile="NG_delete_ami-snapshot_${today}" mail_send fi done fi }
### create_tag create_tag(){ ### create tag for ami CurImageID='cat ${CurrentImage_LOG}|grep ImageId|awk '{FS=":"; print $2}'|sed -e 's/[ "]//g'' AWS EC2 Create-Tags --resources ${CurImageID} --tags "Key=Name,Value=${host_name}_${today}" ### create for snapshots rootDeviceName='aws ec2 describe-instances --instance-ids ${myInstanceID} \ |grep RootDeviceName|awk '{print $2}'|sed -e 's/[",]//g'' 스냅샷_ids='aws ec2 describe-snapshots --filters Name=description,description,값=*${CurImageID}* \ |grep SnapshotId|awk -F : '{print $2}'|sed -e 's/[ ",]//g'' for i in ${snapshot_ids} do volume_id='aws ec2 describe-snapshots --snapshot-ids ${i}|grep VolumeId \ |awk '{print $2}'|sed -e 's/[",]//g'' deviceName='aws ec2 describe-volumes --volume-ids ${volume_id}|grep Device \ |awk '{print $2}'|sed -e 's/"//g'' if [ "${rootDeviceName}" == "${deviceName}" ]; 그럼 AWS EC2 create-tags --resources ${i} \ --tags "Key=Name,Value=AMI_${host_name}_${today}-os_${deviceName}" 그렇지 않으면 AWS ec2 create-tags --resources ${i} \ --tags "Key=Name,Value=AMI_${host_name}_${today}-data_${deviceName}" fi done }
## 메인 이그렉스 >> ${LOG} 이그렉션 2>&1
에코 "AMI 백업 시작. ${datetime}" 생성_ami
## rotate_ami delete_images='aws ec2 describe-images --filters Name=name,Values=*${host_name}* \ |egrep -a 'ImageId| ImageLocation'|sed -e "N; s/\n//" -e 's/[",]//g'|awk '{print $2" "$4}' \ |sort -r -t _ -k 2,3|sed -e "1,${bkup_num}d"|awk '{print $1}'' for i in ${delete_images} do OLDimageID=${i} deregister_ami delete_snapshot 완료
## 오류가 발생하면 메일을 보내세요. 다른 경우에는 태그를 생성하는 경우입니다. [ ${res_create} -ne 0 ]; 그럼 mail_body="NG ami create for ${myInstanceID}(${host_name}) at ${datetime}" mail_titile="NG_create_ami_${today}" mail_send elif [ ${res_create} -eq 0 ]; 그다음 create_tag fi echo "ami 백업 종료. ${datetime}"
## logrotate DAY='date +%m%d' 만약 [ $DAY = "0101" ] 그렇다면 OY='date -d '1년 전' +%Y' mv $LOG $LOG.$OY 찾아 /opt/log -name "$LOG.*" -type f -atime +730 -exec rm -f {} \; fi
출구 0 ------------ # chmod +x /opt/bin/aws_image_bkup.sh[/shell]
한번 활용해 보세요
[shell]# bash -x /opt/bin/aws_image_bkup.sh i-292A442c Komiya-test-mySQL01 # cat /opt/bin/cimageid_i-292a442c.log # cat /opt/log/bkup.log [/shell]
테스트를 실행한 후 문제없이 작동하기 시작했습니다.
예방 차원에서,
AMI_NAME 시작하면 둘 다 계속 사라지는 것 같아서 그렇게 하진 않을 것 같지만, 한 분에 두 번 실행하지 않는 게 낫습니다.
분들을 나누면 AMI를 정상적으로 얻을 수 있습니다.
사용 횟수가 너무 많으면 사용 비용이 오를 것 같아 매일 사용하는 것을 추천합니다.
기존 AMI를 유지하고 싶다면 변수 bkup_num에서 생성 횟수를 정의하세요.
여러 AMI 인스턴스를 받고 싶다면 리스트를 만들고 다음과 같이 루프할 수 있습니다.
[shell]vi bkup-hosts.txt ---- i-xxxxx,hoge-web01 i-yyyyy,hoge-web02 ... ---- i에 대해 'cat bkup-hosts.txt' do instance-id='echo $i|awk -F, '{print $1}'' host-name='echo $i|awk -F, '{print $2}'' /opt/bin/aws_image_bkup.sh ${instance-id} ${host-name} done[/shell]
데이터만 있으면 복구할 수 있고, 백업 비용을 절약할 수 있으며, AMI만 변경할 수 있다는 패턴이 있을 수 있습니다.
자동 스케일링 등 최신 AMI를 원한다면 자동 AMI 백업이 분명히 필요하다고 생각합니다.
백업이 복구 계획에 따라 달라지는 건가요?
이번에 대본을 만들면서 개인적으로 배운 것은 다음과 같습니다
sed -e "N; s/\n//" 홀수 줄 나누기를 제거하세요
장소인가요? 다른 방법도 써봤지만, 키워드를 검색하면 할 수 있을 것 같았어요.
아직 연습을 하지 않은 것 같아.
‧보너스
awscli 셰프 레시피를 올릴게요.
요리책을 만드세요
[shell]칼 요리책 만들어 -o 사이트-요리책[/shell]
awscli.rb라는 레시피를 만들어보세요
[shell]# vi site-cookbooks/aws/recipes/awscli.rb ----------------------------------------------------- node["platform_version"] >= 6 패키지 "python-setuptools" do action : install end bash "pip-awscli-install" do not_if "Which aws" 코드 <-EOC easy_install="" pip="" pip="" install="" awscli="" eoc="" end="" elsif="" node["platform_version"]="">= 5 && node["platform_version"] < 6 bash "python26-pip-awscli-install" do not_if "which aws" code <-EOC yum -y install python26 python26-devel python26-distribute --enablerepo=epel easy_install-2.6 pip pip2.6 install awscli EOC end end
directory "/root/.ec2" do action :create end
awstest1 = Chef::EncryptedDataBagItem.load("awskeys","awstest1") awstest1key_id = awstest1["aws_access_key_id"] awstest1secret_key = awstest1["aws_secret_access_key"] awstest1region = awstest1["region"]
bash "set-aws-config" do not_if "grep access_key /root/.ec2/aws.config" code <-EOC echo="" '[default]'="">> /root/.. ec2/aws.config 에코 "aws_access_key_id=#{awstest1key_id}" >> /root/.ec2/aws.config 에코 "aws_secret_access_key=#{awstest1secret_key}" >> /root/.ec2/aws.config 에코 "region=#{awstest1region}" >> /root/.ec2/aws.config EOC end -----------------------------------------------------[/shell] 접근 키 ID는 data_bags로 관리되어야 하는 것 같습니다.
[shell]awstest1 = Chef::EncryptedDataBagItem.load("awskeys","awstest1") awstest1key_id = awstest1["aws_access_key_id"] awstest1secret_key = awstest1["aws_secret_access_key"] awstest1region = awstest1["region"][/shell]
데이터 등에 AWS 접근 키를 등록하세요_bags
[shell]knife solo data bag 생성 awskeys awstest1 --secret-file ~/.chef/encrypted_data_bag_secret { "id": "awstest1", "aws_access_key_id": "AKIAID4CBY76***", "aws_secret_access_key": "4+saCCqOQL8+CKnzdHOpc2CKg2oWmKRO**", "region": "ap-northeast-1" }
# 나이프 솔로 데이터 가방 표시 awskeys awstest1 --secret-file data_bag_key 경고: knife.rb에 정의된 암호화_data_bag_secret 옵션이 명령줄에 의해 덮어쓰였습니다. aws_access_key_id: AKIAID4CBY76**** aws_secret_access_key: 4+saCCqOQL8+CKnzdHOpc2CKg2oWmKR*** id: awstest1 지역: ap-northeast-1[/shell]
구문 테스트
[shell]# 칼 요리책 테스트 AWS[/shell]
위 내용을 읽어주셔서 감사합니다.</-EOC></-EOC>