개발 노트/LocalStack

[LocalStack] LocalStack에서 EC2를 다뤄보자.

j4ko 2024. 5. 7. 01:18
728x90
반응형

목차

     

    개요 

    최근 LocalStack을 결제하지 않고 이것저것 다뤄보는 중이다. EC2에 관련된 데모 영상이 있어 해당 영상을 보고 이것저것 따라 해봤는데 제대로 성공하기까지 꽤나 시간이 걸렸다. 단순 LocalStack을 이용해 EC2를 생성하는 것이라면 짧은 시간 안에 해결했겠지만 LocalStack의 EC2에 ssh 접속이 가능한 걸 보고 성공하기까지 많은 삽질이 있었다.

     

     이 포스팅에서는 LocalStack에서 EC2를 생성하고 EC2에 ssh 접속하기까지 무엇이 필요한지 어떻게하면 되는지를 간단히 기록해보려 한다.

     

    1.  Hobby Plan 준비

    사실 이 부분부터 준비헀으면 그렇게 많은 시간을 소비하지 않았을 것이다. 필자는 LocalStack을 단순히 Community 버전으로 이용하면서 EC2를 생성했고 "SSH 접속이 왜 안되는지" 파고 있었는데 LocalStack의 특정 Plan을 LocalStack의 DashBoard에서 결제를 해야 한다.

     

    "특정 Plan"이란 Hobby Plan을 뜻한다. "결제"라고 해서 비용이 지출되는 건 아니며 LocalStack 측에서 비상업적 용도로 사용하는 개인에게 좀 더 다양한 기능을 제공하기 위한 용도인 듯하다.

     

    Hobby Plan은 https://app.localstack.cloud/pricing에서 하단에 다음과 같은 UI를 통해서 결제가 가능하다.

    "Get started" 버튼을 누르면 다음 화면으로 이동하는데 화면에서도 보이다시피 Total 비용이 0원이기에 지출이 되지 않는다.

     

    Hobby Plan을 세팅하고 EC2를 생성하면 docker instance가 생성되는데 이 instance를 통해 ssh를 접속할 수 있게 만드는 형식이다. 곧 후술 하겠다.

     

    2. EC2를 생성해 보자.

    EC2의 "보안그룹", "서브넷"과 같은 세부 옵션 조정에 대한 부분은 다루지 않을 것이기에 나머지 단계는 간단한다. 단계는 크게 두 개로 나눠지며 다음과 같다.

     

    1. awslocal을 이용해 key-pair 생성

    2. awslocal을 이용한 ec2 생성

     

    2.1 awslocal을 이용해 key-pair 생성하기

    "개요"에서 언급했듯 EC2를 생성하고 SSH 접속까지 하는 것이 목표이므로 key-pair를 생성해 두자.

    awslocal ec2 create-key-pair \
    --key-name my-key \
    --query 'KeyMaterial' \
    --output text | tee key.pem

    이후 chmod를 이용해 권한을 할당해 두자.

    $ chmod 400 key.pem

     

    2.2 awslocal을 이용해 EC2 생성하기

    LocalStack DashBoard에서는 EC2를 생성할 수 있는 UI가 확인되지 않는바 awslocal을 이용해 ec2를 생성하자.

    awslocal ec2 run-instances \
              --image-id ami-df5de72bdb3b \
              --count 1 \
              --instance-type t3.nano \
              --key-name my-key

    여기서 사용된 image-id는 LocalStack 문서에서 명시된 image-id 중 하나이다. LocalStack 문서에서는 다음과 같이 3가지 image-id를 명시하고 있다.

    3가지 다 띄워서 테스트해 본 결과 Ubuntu22.04를 띄웠을 때 sshd가 내부적으로 실행되고 있었고 ssh 접속이 가능했다.

     

     

    3.  생성된 EC2에 ssh로 접속하기

    EC2 생성에 성공한 경우 LocalStack의 Log가 다음과 같이 올라온다.

    C2024-05-06T15:59:47.560  INFO --- [et.reactor-1] l.s.ec2.vmmanager.docker   : Instance i-774691b8691d1404b will be accessible via SSH at: 127.0.0.1:22, 172.17.0.3:22
    2024-05-06T15:59:47.560  INFO --- [et.reactor-1] l.s.ec2.vmmanager.docker   : Instance i-774691b8691d1404b port mappings (container -> host): {'22/tcp': 22}
    j2024-05-06T15:59:47.585  INFO --- [et.reactor-1] localstack.request.aws     : AWS ec2.RunInstances => 200

    해당 Log를 보면 172.17.0.3이라는 IP주소가 보이는데 이는 생성된 EC2와 연계되는 Docker Container의 IP이다. 그러므로 다음과 같이 Docker Container가 하나 생성되어 있는 걸 볼 수 있다.

    172.17.0.3에 대해 ssh command로 접속은 성공하지 못했고 대신 다음과 같이 이용했다.

    재밌는 점은 EC2를 하나 더 생성하게 되면 22번 포트가 아닌 다른 포트를 할당해서 EC2를 생성한다.

     

     

    4. 기타 사용법

    4.1 script파일로 command set을 실행해야한다면

    LocalStack의 문서를 보면 "--user-data"라는 옵션을 통해 특정 명령어가 지정된 script.sh 파일이 실행되는 기능이 설명되어있다.

     

    그러나 이 옵션은 localstack repository의 https://github.com/localstack/localstack/issues/5630 를 참고하니 Pro 버전에서만 지원되는 기능인 듯 하다. 즉 Hobby Plan에서는 위와 같은 사용법은 제한되니 "docker cp"를 이용해 처리해보자.

    CONTAINER ID   IMAGE                                                          COMMAND                  CREATED          STATUS                    PORTS                                                                                              NAMES
    dab0189e0b57   localstack-ec2/ubuntu-22.04-jammy-jellyfish:ami-df5de72bdb3b   "sleep infinity"         2 seconds ago    Up 2 seconds              0.0.0.0:22->22/tcp, 0.0.0.0:8000->8000/tcp                                                         localstack-ec2.i-5237a0d77fdb3f2f9
    
    ╰─$ docker cp ./ec2_script.sh dab0189e0b57:/
    Successfully copied 2.05kB to dab0189e0b57:/

     

    4.2 EC2의 특정 Port를 열어야 한다면

    앞서 "Hobby Plan"에서 EC2를 실행시키면 그에 맞는 docker instance를 띄우는 걸 확인했다. 이 때 docker instance에 ssh port 외에 다른 port 를 개방하려면 보안 그룹을 생성 후 EC2를 실행시키면 가능하다. 아래의 예제에서는 8000 port를 예시로 사용했다.

    $ awslocal ec2 authorize-security-group-ingress --group-id default --protocol tcp --port 8000 --cidr 0.0.0.0/0
    {
      "SecurityGroups": [
        {
          "Description": "default VPC security group",
          "GroupName": "default",
          "IpPermissions": [],
          "OwnerId": "000000000000",
          "GroupId": "sg-41aec5a31a1fd27c4",
          "IpPermissionsEgress": [
            {
              "IpProtocol": "-1",
              "IpRanges": [
                {
                  "CidrIp": "0.0.0.0/0"
                }
              ],
              "Ipv6Ranges": [],
              "PrefixListIds": [],
              "UserIdGroupPairs": []
            }
          ],
          "Tags": [],
          "VpcId": "vpc-8dd44944"
        }
      ]
    }

    이후 "security-group-ids"를 사용해 EC2를 실행시키자.

    awslocal ec2 run-instances \
              --image-id ami-df5de72bdb3b \
              --count 1 \
              --instance-type t3.nano \
              --key-name my-key \
              --security-group-ids 'sg-41aec5a31a1fd27c4'

     

     

    마치며

    시행착오를 거치는데 시간을 많이 들였는데 Hobby Plan이 존재한다는 걸 알았으면 많은 시간을 단축하지 않았을까 싶다.

     

    Hobby Plan이 존재한다는 걸 모르고 LocalStack을 커뮤니티 버전으로 이용할 때는 awslocal의 "ec2 runinstances" 시점에 "내부 docker images를 바라보도록 하면 어떨까"라는 생각이 들었는데 배보다 배꼽이 더 클 것 같아 포기하려던 시점이었다.

     

    그러다 트위터에 이러한 고민을 올려놨는데 운 좋게 LocalStack 관련 개발자로 보이는 분에게서 Hobby Plan이 있다는 걸 알게 되었다. (참고, Hobby Plan은 Trial과 다르다)

    Harsh Mishra는 LocalStack의 Engieer로 보이는데 제품을 만든 장본인에게 조언을 얻는 경험이 신기한 에피소드였던 걸로 남겨야겠다.

    728x90
    반응형