카테고리 보관물: Server

.bot 도메인 등록하기

Amazon에서 .bot 도메인을 등록할 수 있도록 해서 등록 방법을 소개하려고 합니다.

.bot 도메인 등록을 대행하는 EnCirca 사이트의 설명을 보면 현재는 Landrush 2 기간으로 .bot 도메인 등록을 아무나 할 수 없고 봇을 운영중인지 확인후 등록할 수 있는 권한을 주는것으로 보입니다. 봇을 운영중인지 확인하는 것은 Amazon Lex, Microsoft Bot Framework, Dialogflow, Pandorabots, Gupshup, Botkit Studio 등 봇 관련 서비스들과의 연동을 통해서만 가능합니다.

아마도 2018년 5월 31일 이후에는 봇을 운영중인지 확인작업 없이 일반 도메인 처럼 등록되지 않을까 싶은데 확실한 정보는 아닙니다.

절차가 좀 길고 복잡한데 영상으로도 촬영 했으니 참고하세요.

.bot 도메인 등록을 위해서 우선 amazon registry 사이트에 접속합니다.

접속후 검색창에 구매하고자 하는 도메인 이름을 입력하고 다음 절차로 이동합니다.

아마존 계정에 로그인 되어 있지 않다면 다음 화면으로 넘어가기전에 아마존 로그인이 필요합니다.

봇을 운영중인지 확인하는 작업이 필요합니다. 목록에 나온 서비스중 본인이 운영중인 봇 서비스를 선택하면 확인작업에 대한 절차가 설명됩니다. 봇을 현재 운영하고 있지 않다고 가정하고 Amazon Lex를 이용해 봇을 생성하고 인증하는 절차를 설명하겠습니다.

Amazon Lex를 선택하면 오른쪽에 봇을 확인하기위해 필요한 절차가 표시됩니다.

준비 작업

아마존 웹서비스 계정에 로그인해서 Cross Account Role을 생성하고 545643940769 계정에 대해 권한을 추가하는 작업이 필요합니다. 그럼 이제부터 Role 을 생성해보겠습니다.

AWS 콘솔에 로그인후 IAM 메뉴에서 Roles 선택하고 Create Role 버튼을 클릭합니다.

Account ID와 External ID 항목에 앞선 .bot 도메인 등록 사이트에서 알려준 정보를 입력합니다.

다음 화면에서는 Role에 부여할 Policy 를 선택해야 되는데요. AmazonLexReadOnly를 선택합니다.

Role 이름은 나중에 알 수 있도록 적당히 잘 정하고 설명에도 잘 적어둡니다. 여기까지는 공식사이트에서 설명하는 절차인데요. 제가 해보니 여기서 한가지가 더 필요합니다.

IAM 콘솔에서 Policies 를 선택하고 Create Policy 버튼을 클립합니다.

JSON 탭을 선택하고 아래 내용을 추가합니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "lex:PostText"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

Policy 를 생성했다면 앞서 생성했던 Role을 선택하고 Attach policy 버튼을 클릭해서 방금 생성한 Policy를 추가합니다.

최종적으로 위와 같은 Role을 얻게 됩니다. 이제 .bot 도메인 등록 사이트로 돌아갑니다.

임시로 Lex 봇 만들기

Amazon에서 제공하는 봇 서비스를 이용해 임시로 봇을 생성하겠습니다.

AWS 콘솔에서 Lex 페이지에 접속해서 새로운 Lex 봇을 생성합니다. Lex 봇을 처음 생성한다면 아마 첫화면에 Get Started 버튼이 보일텐데 해당 버튼을 클릭합니다.

봇 생성을 위한 페이지가 표시되는데 아마존이 제공하는 기본 샘플을 이용하면 코딩을 하지 않아도 됩니다. Try a sample 에서 BookTrip을 선택하고 하단의 COPPA 항목은 No로 선택합니다.

봇 페이지에서 오른쪽 위의 Publish 버튼을 클릭합니다.

alias 는 아무이름이나 입력하고 publish 버튼을 클릭합니다. 배포하는데 1분정도 시간이 걸리니 잠깐 쉬다 오세요.

배포가 완료되면 위와 같이 표시되는데요. 여기서 Bot Name과 Alias를 적어두세요.

도메인 등록하기

이제 준비 작업은 모두 끝났습니다. .bot 도메인 등록 사이트로 가서 아까 보였던 봇 확인 작업창에 앞서 준비했던 내용들을 입력합니다.

AWS cross account role ARN 항목에는 앞서 생성했던 Role의 Role ARN을 입력합니다.

봇 인증이 성공했습니다! 저 같은 경우 이미 해당 도메인에 대해 봇 인증이 되있는 상태라 메시지가 조금 다르게 나왔지만 페이지는 동일합니다.

Continue to registration 버튼을 클릭하면 도메인 등록을 위한 페이지로 이동합니다.

가격이 $75 네요!! Site Builder 옵션은 선택하지 않아도 도메인 등록하는데 문제 없습니다.

실제 도메인 등록은 EnRica 사이트를 이용해서 진행되기 때문에 해당 사이트 가입을 위한 주소 정보를 선택하라고 나올텐데요. 기존 아마존 계정에 있는것을 선택하거나 새로 입력해서 다음 단게로 넘어갑니다.

다음 화면에서는 EnRica 사이트 가입 절차가 나옵니다.

저도 여기 까지만 해봤고 더이상은 진행하지 않았습니다. 하지만 이 다음부터는 일반적인 도메인 등록 절차와 동일할테니 쉽게 할 수 있을겁니다.

정리

아마존에 .bot 도메인을 등록할 수 있게 한다고 해서 호기심에 내 아이디를 선점 해볼까라는 생각이었는데 생각보다 절차가 복잡했고 가격도 $75로 비싼편입니다.

.bot 도메인에 대한 확인 작업은 아마도 2018년 5월 31일 이후에는 없어질것으로 보여서 이 글이 큰 도움이 되지 않을수도 있지만 미리 선점하려는 분들에게 도움이 되었으면합니다.

마지막으로 제가 운영중인 개발관련 유튜브 채널인 달구지코딩 구독 부탁드립니다 ~ AWS 서비스를 포함한 다양한 소프트웨어 개발관련 내용을 업로드 하고 있습니다.

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

Slack 프록시 서버 – slackboard 소개

슬랙(Slack)을 자주 사용하다 보면 여러가지 연동을 하게 됩니다. 서버나 특정 상태에 따라 슬랙에 메시지를 보내는데요. 연동도 쉬워서 사용 할수록 더 많은 연동을 하게 됩니다.

이번에 소개하려는 slackboard는 슬랙에 메시지를 전송할때 아쉬운 부분을 해결해주는 기능을 가지고 있습니다. slackboard의 주요기능은 다음과 같습니다.

  • 커맨드 라인에서 쉽게 메시지 전송
  • 쉘 스크립트가 비정상적으로 종료됬을때 슬랙 메시지 전송
  • 태그 이름만으로 미리 지정한 채널이름, 사용자 이름, 이모지 설정
  • QPS 제어 기능

이중 slackboard를 꼭 써야하는 이유중 하나는 마지막의 QPS 제어 기능입니다. 일반적으로 사용하는 슬랙의 Incoming webhooks의 경우 초당 1건의 메시지로 제한되어 있어서 1초에 메시지를 여러개 전송하면 일부 메시지가 유실될 수 있는데 slackboard의 QPS 제어 기능을 이용하면 메시지가 유실되지 않게 분산해서 전송합니다.

유튜브 영상으로도 촬영 했으니 참고하세요.

그외 장점 및 사용헤 대해서도 하나씩 알아 보기 전에 설치 방법을 알아 보겠습니다.

서버 설치

slackboard는 프록시 서버를 설치해야 하는데요. golang으로 작성되어 있어 사전에 go 언어를 빌드 할 수 있도록 준비해야합니다. go 언어가 설치 됬다면 아래 명령어로 slackboard 를 설치합니다.

$ go get -u github.com/cubicdaiya/slackboard/...

프록시 서버 설정을 위해 환경설정 파일(config.toml)을 생성하고 수정합니다.

[core]
port = "60000"
slack_url = "https://hooks.slack.com/services/XXX/YYY"
qps = 1
max_delay_duration = 5

[log]
access_log = "stdout"
error_log = "stderr"
level = "error"

[[tags]]
tag = "dalguji"
channel = "#general"
username = "seapy"
icon_emoji = ":smile:"
parse = "full"

[[tags]]
tag = "fail"
channel = "#dalguji"
username = "seapy"
icon_emoji = ":warning:"
parse = "full"

slack_url에는 본인의 슬랙 설정에서 얻은 Incoming webhooks 주소를 입력합니다.

[[tag]] 로 시작하는 섹션은 태그를 지정하는 것으로 해당 태그 이름으로 요청이 들어오면 미리 지정된 채널이름, 사용자 이름, 사용자 이모지, 파싱모드를 적용하는것입니다. 태그를 지정해두면 메시지를 보낼때마다 채널과 사용자 이름등을 전달하지 않아도 됩니다.

서버 시작 및 기본 예제 테스트

slackboard 서버 시작 명령어는 다음과 같습니다. 간단하죠

$ slackboard -c config.toml &

실제 운영시에는 systemd 같은 서비스에 등록해두고 사용하면 좋습니다.

테스트 메시지를 보내기 위해 아래 명령어를 사용합니다.

$ echo 'Hi dalguji coding' | slackboard-cli -t dalguji -s localhost:60000

echo 명령어를 이용해 stdout 으로 메시지를 전송했고 slackboard-cli 명령어는 stdout으로 받은 메시지를 dalguji 태그와 함께 localhost:60000 서버로 전송합니다.

메시지를 전송하기만 하는 클라이언트 입장에서는 슬랙의 Incoming webhooks 주소를 이용해 curl 로 보낼수도 있지만 slackboard 설치하고 서버 주소만 알면 간단하게 전송 할 수 있게됩니다.

커맨드가 정상적으로 종료되지 않을 경우 알림

제가 slackboard를 사용하는 이유중 하나인 명령어가 비정상적으로 종료 되었을때 슬랙으로 에러 메시지를 알려주는 기능을 살펴 보겠습니다.

아래 명령어를 실행하면 some-command라는 명령어를 알 수 없다고 하면서 에러가 발생할겁니다.

$ slackboard-log -s localhost:60000 -t fail -- some-command

하지만 에러가 발생하면 localhost:60000 서버의 fail 태그로 어떤 이유로 명령어가 실패 했는지 전송하고 프록시 서버는 이를 슬랙으로 전송합니다.

저는 주로 쉘 스크립트를 정기적으로 실행하는데 실패하면 알림을 받고 싶을때 사용하는데요. 우선 아래와 같은 쉘 스크립트 파일(dalguji.sh)을 하나 만들어 둡니다.

#!/bin/sh
echo "dalguji script"

에러가 발생하지 않을 정상 스크립트 입니다. 이 스크립트가 정상 실행되는지 보겠습니다.

$ slackboard-log -s localhost:60000 -t fail -- dalguji.sh

정상 실행될때는 슬랙에 메시지도 안오고 그냥 echo 만 실행됩니다. 스크립트를 조금 변경해서 에러가 발생하도록 해보겠습니다.

#!/bin/sh
eeeeecho dalguji script

$ slackboard-log -s localhost:60000 -t fail -- dalguji.sh

다시 실행해보면 에러가 발생하고 에러 내역이 슬랙에 표시됩니다.

이러한 작업은 쉘 스크립트만으로도 할 수 있겠지만 이를 구현하려면 내가 만든 쉘 스크립트나 명령어를 감싸서 실패를 체크하고 슬랙으로 전송하는 스크립트를 직접 만들어야 됩니다. 하지만 slackboard는 간단한 설치와 설정으로 쉽게 사용할 수 있습니다.

성공했을때도 보내고… 실패 했을때도 보내고 싶다면?

마지막으로 쉘 스크립트가 성공이나 실패 했을때 모두 결과를 slack으로 전송하고 싶다면 아래와 같은 방법을 사용합니다.

$ dalguji.sh 2>&1 | slackboard-cli -s localhost:60000 -c dalguji

스크립트 실행중 발생한 stderr 출력을 stdout으로 리다이렉트 하고 해당 메시지를 슬랙으로 전송하는 방법입니다.

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

Amazon CloudWatch 수집된 지표에 수식계산 Metric Math

아마존 웹서비스를 사용하다보면 사용중인 서비스를 모니터링 하기 위해 CloudWatch 를 한번씩은 사용하게 됩니다. 많은 지표들이 제공되지만 제공되는 지표에 몇가지 더하거나 조합하는 경우 이번에 소개하는 Metric Math 를 이용합니다.

RDS Total IOPS 수치 확인하기

RDS의 모니터링을 예로 들어보면 Read IOPS, Write IOPS라는 지표를 별도로 제공하는데 RDS의 IOPS 제한은 Read와 Write IOPS를 더한값으로 적용됩니다. 그래서 Total IOPS를 알고 있는것이 중요한데 CloudWatch 에서는 Total IOPS를 지표 정보로 제공하지 않습니다.

저 같은 경우 기존에는 Total IOPS를 모니터링 하기 위해 1분마다 Read IOPS와 Write IOPS를 조회하고 다시 Total IOPS라는 새로운 지표로 CloudWatch에 저장하는 작업을 하고 있었습니다. 하지만 Metric Math 기능을 이용하면 더이상 이렇게 할 필요가 없습니다.

CloudWatch 대시보드 혹은 Metrics 에서 RDS 를 선택하고 Read IOPS, Write IOPS를 각자 설정후 Graphed metrics 탭을 선택하고 테이블 상단의 Add a math express 버튼을 클릭합니다.

클릭하면 테이블 목록 상단에 e1 이라는 id를 가진 행이 추가되고 Details에는 SUM(METRICS()) 라고 입력됩니다. 이 수식의 의미는 현재 선택된 지표들을 모두 더한다는 의미입니다. 이 경우 Read IOPS + Write IOPS 인거죠. 수식을 이해하기 쉽게 m1 + m2로 변경해도 동일한 의미가 됩니다. 여기서 m1, m2는 각 행의 id 값입니다.

Total IOPS만 그래프에 표시하기 위해 체크 박스에서 e1 을 제외한 m1, m2는 체크를 해제하면 위와 같이 Total IOPS만 그래프에 표시되는것을 확인할 수 있습니다.

ElastiCache Hit Rate 계산 하기

ElastiCache 의 Hit Rate를 계산하는 것도 Metric Math를 이용하면 유용한 수치입니다. 캐시가 적당하게 잘 되고 있는지 볼 수 있는 유용한 지표가 Hit Rate인데 CloudWatch에서는 제공되지 않습니다.

이제 직접 Hit Rate를 계산해 보겠습니다.

Metrics 에서 모니터링을 원하는 ElastiCache 인스턴스의 Get Hits, Get Misses를 선택하고 앞서 했던 것처럼 Add a math express 버튼을 클릭합니다. 수식 입력란에 (m1 / (m1 + m2)) * 100를 입력하고 m1, m2의 그래프 체크박스를 해제하면 Hit Rate를 볼 수 있습니다.

정리

CloudWatch는 AWS 서비스를 이용하다 보면 한번쯤 접하게 되고 모니터링이나 알림 용도로 자주 사용하게 됩니다. 하지만 제공하지 않는 지표가 있거나 여러 지표를 조합하고자 하는 경우 불편한점이 있었는데 Metric Math 기능으로 인해 사용하기 편해졌습니다.

아쉽게도 현재는 수식이 적용된 지표에 대해서는 알림 기능을 제공하지 않습니다. 알림을 받고 싶다면 기존 방식처럼 별도의 CloudWatch 지표를 매분 마다 생성해야합니다.

이 내용은 제가 운영하는 유튜브 채널인 달구지코딩에서도 확인할 수 있습니다. 구독과 좋아요 부탁드립니다 ^^

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

Capistrano 배포시 HostKeyMismatch 발생 오류 해결

배포를 하는데 HostKeyMismatch 에러가 발생 하면서 서버에 접속 하지 못해 배포가 실패 했습니다. 에러 메시지를 보니 ~/.ssh/known_hosts 파일에서 ec2에 해당하는 항목을 지워서 해결 했지만 앞으로도 계속해서 발생 가능한 문제였습니다.

웹서버를 운영하다보면 AWS의 스팟 인스턴스를 이용해서 많은 트래픽에도 유연하게 대처하는 경우가 있습니다. 스팟 인스턴스의 특성상 서버가 새로 투입되었다가 필요 없어지면 삭제하기를 반복합니다.

서버의 추가와 삭제를 반복하다보면 새로 추가한 서버의 자동 생성된 도메인 이름이나 IP가 예전에 사용했던 서버와 같은 경우가 발생할 수 있습니다. AWS의 자동 생성된 도메인 이름은 다음과 같은 형식입니다.

ec2-00-111-222-333.ap-northeast-2.compute.amazonaws.com

그래서 좀 찝찝 하지만 ec2의 자동 생성된 호스트 이름에 대해서는 known_hosts에 추가하지 않고 관련 체크도 하지 않도록 capistrano 설정에서 아래와 같이 추가했습니다.

server 'ec2-??.ap-northeast-2.compute.amazonaws.com', 
   roles: %{app web}, 
   ssh_options: { verify_host_key: false }

verify_host_key 옵션을 추가한 서버에 배포 할때는 known_hosts 에 추가하지 않고 체크도 하지 않습니다.(capistrano 예전 버전에서는 verify_host_key대신 paranoid 였습니다.)

이렇게 하더라도 서버에 직접 접속 할때면 여전히 know_hosts에 관련된 내용을 추가하려고 하는데요. 이것이 싫다면 .ssh/config에서 특정 호스트에 대해 체크하지 않도록 할 수 있습니다.

Host ec2-*.ap-northeast-2.compute.amazonaws.com
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null

저는 이 옵션을 사용하지 않습니다. 서버 배포는 자주 해서 문제가 발생할 여지가 높고 배포를 급하게 해야될때 이런 문제가 발생하면 당황하게 되지만 서버에 ssh로 접속하는 상황에서는 중복되더라도 known_hosts 파일에서 지워주는게 귀찮지 않았거든요.

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

AWS EC2 디스크 크기 늘리기

EC2를 사용하다보면 처음 예상과는 다르게 디스크 공간이 부족한 경우가 생깁니다.

EC2에서 EBS 볼륨을 사용한다면 서버를 중지하지 않고도 디스크 크기를 쉽게 늘릴수 있습니다. 현재 세대 인스턴스(t2, m3, m4, c3, c4, r3, r4등)만 가능하고 이전세대 인스턴스(m1, m2, c1, c2, t1 등) 를 사용하는 경우 인스턴스를 중지하고 작업해야합니다.

  1. AWS 콘솔에 접속후 크기를 늘리고자 하는 EC2 인스턴스의 볼륨을 선택
  2. ‘Modify Volume’ 을 눌러서 새로운 디스크 크기를 입력
  3. 볼륨의 상태정보중 “State” 값이 in-uses-optimizing 으로 변경된후 다음 작업 진행
  4. EC2 인스턴스에 SSH로 접속

lsblk 명령어를 입력해서 현재 상태를 확인

ubuntu@myserver:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 60G 0 disk
└─xvda1 202:1 0 30G 0 part / 

여기서 보면 xvda 디스크 크기는 새로 변경한 60G 인데 그 밑에 있는 파티션은 아직 바뀌지 않아서 30G로 되어 있습니다.

파티션을 늘리기 위해 다음 명령어를 입력

$ sudo growpart /dev/xvda 1
$ sudo resize2fs /dev/xvda1

여기서 주의할점은 처음 명령어에서는 /dev/xvda 라는 디스크 이름을 적고 공백 다음에 숫자 1을 입력했는데 두번째 명령어에서는 /dev/xvda1 으로 파티션 이름을 입력했다는점 입니다.

다시 lsblk 명령어를 실행하면 파티션의 크기도 60G로 늘어난것을 확인할 수 있습니다.

ubuntu@myserver:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda 202:0 0 60G 0 disk
└─xvda1 202:1 0 60G 0 part / 

df -h 명령어를 이용해서 디스크 용량을 볼때도 늘어나 있습니다.

ubuntu@myserver:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            3.9G   12K  3.9G   1% /dev
tmpfs           799M  484K  798M   1% /run
/dev/xvda1       59G   22G   35G  39% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
none            5.0M     0  5.0M   0% /run/lock
none            3.9G     0  3.9G   0% /run/shm
none            100M     0  100M   0% /run/user

참고정보

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

서버 삽질 : 레일스 puma 서버 무한 재시작 `require’: : cannot load such file

회사 서버를 ansible 을 이용해서 설치하기 위해 전환하던중 찾기 어려운 오류를 만나게 되서 정리합니다.

현상

puma 웹서버를 실행하면 puma_error 에러 로그에 아래와 같은 에러가 출력되면서 계속해서 재시작됩니다. puma를 클러스터 모드로 시작하게 했는데 마스터 프로세스는 그대로 인데 워커 프로세스가 계속 재시작했습니다.

/yyy/xxx/~/.rbenv/versions/2.3.3/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'/yyy/xxx/.rbenv/versions/2.3.3/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': : cannot load such file -- bundler/setupcannot load such file -- bundler/setup ( (LoadErrorLoadError)

서버가 시작되려고 하는데 bundler 에서 원하는 젬을 찾지 못하고 있었습니다. 아무리 봐도 bundler 설정이나 rbenv 설정은 잘 되 있어서 puma 설정을 바꾸면서 테스트 하다보니 prune_bundler 옵션이 있는 경우에만 이런 오류가 발생하는것을 알게 되었습니다.

해결

rbenv 설치할때 ansible galaxy에서 받은 zzet/rbenv 를 사용하고 있었는데 이걸 직접 만든 role을 이용해 설치하는 방법으로 변경했더니 오류가 사라졌습니다.

zzet/rbenv 롤을 살펴보니 아마도 문제가 되었던것은 rbenv 플러그인중 rbenv-default-gems 때문이었던거 같아서 플러그인을 설치하지 않게 하려고 직접 만든 ansible role을 사용했습니다.

rbenv-default-gems는 루비 설치후 자동으로 설치될 gem을 설정하는건데 이중에 bundler도 있었고 이로 인해 어디선가 오류가 발생했었던거죠. 굳이 이것을 사용하지 않아도 되서 직접만든 ansible 롤을 사용하면서 해결되었습니다.

삽질지수

이번 삽질의 삽질 지수는 4입니다. (삽질지수 범위 1 ~ 5 단계) 서버 삽질은 항상 최고의 삽질 지수를 자랑합니다. 그 이유는 원인을 찾는데도 오래 걸리고 재현하는것도 오래 걸리기 때문이죠.

이번 삽질의 원인을 파악하기 위해 vagrant 에서 루비를 처음부터 다시 설치하기를 20번도 넘게 했습니다. 루비 설치는 시간이 정말 오래 걸려서 한번 설치해두고 다른거 하다가 와서 배포 하면 루비젬 설치하느라 또 시간 걸리고 기껏 해보면 이거 때문이 아니었고… 시간을 많이 잡아 먹는게 힘들었습니다.

마무리

dockerfile 을 이용할때도 마찬가지지만 인프라 설정에서는 공용모듈을 사용한다는게 쉽지 않다는것을 다시한번 느끼게 되었습니다. 소프트웨어 개발에서는 중복되는 코드를 라이브러리 형태로 만들고 다른 사람들과 공유해서 사용해도 문제가 많이 없는데 인프라쪽은 설치 스크립트를 공유한다는게 장점이 많지 않은것 같습니다.

dockerfile도 누군가가 만든 이미지를 상속 받아서 사용하다가 보면 나중에 결국 본인만의 dockerfile을 만들어서 사용하게 되듯이 ansible 의 롤도 처음에는 가져다 사용하다가 서버 상태에 맞는 롤을 결국 직접 만들어 사용하게 되겠다는 생각을 했습니다. 새로운 롤을 만들면서 기존에 공개된 롤을 많이 참고하면서 도움이 되었던 점을 보면 공개된 롤이 쓸모없는것은 아닙니다.

 

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

AWS elasticsearch 에서 스냅샷 생성 및 복원

AWS elasticsearch 에서는 자동백업을 지원하지만 이걸 복원하려면 AWS Support에 직접 요청하는 방식이라 원하는 시점에 복원하지 못할 수 도 있습니다. 또한 elasticsearch 버전을 올리기위해 마이그레이션을 할때는 새로운 elasticsearch를 생성하고 직접 백업 및 복원을 해야합니다.

그래서 이번 글은 AWS elasticsearch 스냅샷 생성 및 복원에 대해 처음부터 끝까지 적어봤습니다. IAM Role 설정같은데서 헷갈려서 제가 좀 헤맨 부분이 있어 다른분들한테도 도움이 될것 같네요.

사전작업

  1. 백업파일이 위치할 S3 파일을 생성
  2. IAM Role 생성
  3. IAM Policy 생성후 2번에서 생성한 Role에 추가

1. S3 버킷 생성

my-es-snapshot 버킷을 생성. 이건 그냥 버킷만 생성하면 됩니다 ~ 될수 있으면 elasticsearch 와 같은 region 으로 맞춰주는게 좋겠지요?

2. IAM Role 생성

IAM 메뉴 접속후 “Role > Create New Role” 을 이용해 새로운 Role을 생성. Role 이름은 아무거나 정하고 여기서는 “esSnapshotRole”로 지정. “Select Role Type”에서는 “Amazon EC2” 선택. 그다음 Attach Policy 에서는 아무것도 선택하지 않고 “Next Step”

이렇게 하면 Role 이 생성됩니다.

3. IAM Policy 생성후 연결

IAM 메뉴 접속후 “Policies > Create Policy” 버튼을 클릭.
“Create Your Own Policy”를 선택하고 “Policy Document”에 다음 내용을 붙어녛기 합니다

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListBucket"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::my-es-snapshot"
            ]
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject",
                "iam:PassRole"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::my-es-snapshot/*"
            ]
        }
    ]
}

여기서 my-es-snapshot 은 S3 버킷 이름으로 본인의 상황에 맞게 변경합니다

이렇게 생성된 Policy 의 상세화면에 들어가서 “Attached Entities” 에서 Attach 버튼을 클릭해 앞서 생성한 IAM Role에 연결합니다

스냅샷 저장소 생성

AWS Elasticsearch 같은경우 스냅샷 저장소 생성은 curl 명령어를 이용해서는 불가능합니다. 맥의 경우를 가정하면 터미널을 실행후 아래 명령어를 실행합니다.(윈도우 사용자분들은 알아서 자알 ~ 파이썬 설치하고 pip 뭐 이런거 동작하게 설치하면 될거에요)

$ sudo pip install boto

이 다음에 snapshot.py 라는 파일을 만들고 아래 내용을 붙여넣기후 저장

from boto.connection import AWSAuthConnection

class ESConnection(AWSAuthConnection):

    def __init__(self, region, **kwargs):
        super(ESConnection, self).__init__(**kwargs)
        self._set_auth_region_name(region)
        self._set_auth_service_name("es")

    def _required_auth_capability(self):
        return ['hmac-v4']

if __name__ == "__main__":

    client = ESConnection(
            region='ap-northeast-2',
            host='search-xxx-yyyy.ap-northeast-2.es.amazonaws.com',
            aws_access_key_id='xxxxx',
            aws_secret_access_key='yyyyy', is_secure=False)

    print 'Registering Snapshot Repository'
    resp = client.make_request(method='POST',
            path='/_snapshot/s3_repository',
            data='{"type": "s3","settings": { "bucket": "my-es-snapshot","region": "ap-northeast-2","role_arn": "arn:aws:iam::xxxx:role/esSnapshotRole"}}')
    body = resp.read()
    print body
region, host, aws_access_key_id, aws_secret_access_key, path, data 등은 본인의 상황에 맞게 변경합니다.
  • region=’ap-northeast-2′
    • 이건 서울의 경우. 다른 지역에 있는 elasticsearch 라면 변경이 필요
  • host=’search-xxx-yyyy.ap-northeast-2.es.amazonaws.com’
    • AWS elasticsearch 주소
  • aws_access_key_id=’xxxxx’, aws_secret_access_key=’yyyyy’
    • AWS elasticsearch 에 접근권한이 있는 계정의 인증정보
  • path=’/_snapshot/s3_repository’
    • elasticsearch 에 생성할 스냅샷 저장소 경로. s3_repository 부분을 원하는 이름으로 변경
  • “bucket”: “my-es-snapshot”
    • 앞서 생성한 S3 버킷 이름
  • “region”: “ap-northeast-2”
    • S3 버킷의 region
  • “role_arn”: “arn:aws:iam::xxxx:role/esSnapshotRole”
    • 앞서 생성한 IAM Role의 ARN 문자열. Role 상세페이지에서 “Role ARN” 속성으로 확인가능
설정을 본인에 맞게 변경후 터미널에서 다음 명령어를 실행합니다
$ python snapshot.py

실행후 별다른 에러 없으면 스냅샷 저장소 생성 성공 ~

맥의 경우에는 파이썬이 설치되어 있어서 별도의 파이썬 설치가 필요없지만 윈도우라면 알아서 잘 설치하고 진행하면 됩니다.

스냅샷 생성

아래 명령어를 터미널에서 실행해서 새로운 스냅샷을 생성합니다.
$ curl -XPUT 'https://search-xxx-yyy.ap-northeast-2.es.amazonaws.com/_snapshot/s3_repository/first_snapshot'

위의 명령어는 앞서 생성한 s3_repository 스냅샷 저장소에 first_snapshot 이라는 스냅샷을 생성합니다.

위 명령어의 결과는 바로 반환되고 뒤에서는 스냅샷을 생성하고 있다. 완료여부를 확인하려면 다음 명령어를 실행합니다.

$ curl -XGET 'https://search-xxx-yyy.ap-northeast-2.es.amazonaws.com/_snapshot/s3_repository/first_snapshot'
이거의 반환값의 “state” 항목이 “SUCCESS” 이면 스냅샷 생성이 완료된것입니다. 참고로 스냅샷 생성이 완료되지 않았을때는 아무런 에러없이 오랫동안 반환이 안되요

스냅샷 복원

아래 명령어를 이용해 복원을 시작한다
$ curl -XPOST 'https://search-xxx-yyyy.ap-northeast-2.es.amazonaws.com/_snapshot/s3_repository/first_snapshot/_restore'

스냅샷 생성때와 마찬가지로 실행하자마자 반환값이 나오지만 뒤에서 계속 복원이 진행중인 상태입니다.

복원이 진행중일때는 클러스터 상태가 Red 이고 완료되면 원래의 클러스터 상태로 돌아오므로 클러스터 상태를 통해 복원이 완료되었는지 확인할 수 있습니다

아래 명령어가 클러스터 상태 확인하는 명령어

$ curl -XGET 'https://search-xxx-yyyy.ap-northeast-2.es.amazonaws.com/_cluster/health'

다른 elasticserach 로 스냅샷을 복원하는 경우

elasticsearch 를 마이그레이션 하거나 다른 elasticsearch 클러스터에 복원하려는 경우 새로운 elasticserach 에 스냅샷 저장소만 생성하면 됩니다. 스냅샷 저장소를 앞서 생성한 스냅샷 저장소와 동일한 옵션으로 생성하면 같은 S3를 바라보게 되므로 복원도 바로 됩니다

참고자료

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^

맥에 설치된 도커(Docker) 삭제하기

도커를 맥에서 사용하는 방법으로 Docker Toolbox, Docker for Mac 두가지가 있는데, Docker Toolbox는 생긴지 좀 오래 되었고 Docker for Mac은 좀더 편하게 사용하기 위해 가장 최근에 나온 방법이다.

지금 도커를 맥에서 설치한다면 Docker for Mac을 이용해 설치하는것이 좋은데, 이미 Docker Toolbox로 설치된 도커가 있다면 다음과 같은 방법으로 삭제한다.

터미널을 실행해서 다음 명령어로 삭제 스크립트 파일을 다운로드 받는다.

$ curl -O https://raw.githubusercontent.com/docker/toolbox/master/osx/uninstall.sh

다운로드 받은 파일에 실행 권한을 추가하고 실행하면 도커가 깔끔하게 삭제 된다 ^^

$ chmod +x uninstall.sh
$ ./uninstall.sh

 

게시글의 아마존, iTunes 링크들을 통해 구매를 하시면 제휴(Affiliate) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^