서버 삽질 : 레일스 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) 프로그램에 의해 저에게 일정 금액이 적립될 수 있습니다. ^_____^