Tempo Di Valse

[AWS] ECS 에 Docker 연동하기 -6- (커맨드 실행) 본문

개발/AWS

[AWS] ECS 에 Docker 연동하기 -6- (커맨드 실행)

TempoDiValse 2022. 11. 23. 15:50

이번 포스팅은 "커맨드 실행" 이라는 부제를 가진 포스팅으로, 이것이 뭐냐 하면.... 이런 경우들이가 있다.

NGINX 의 설정 값을 변경했다.
보통의 경우라면,
    - nginx -t 로 테스트
    - nginx -s reload 를 통해 리로드
를 하면 되는데... 접근은 어떻게 하지..?

Laravel 의 .env 설정을 변경했다.
EC2 인스턴스에서 php artisan optimize 를 했다.
File no exist 같은 에러가 웹페이지에 떴다.
Docker 기준으로 된 경로가 EC2 인스턴스로 변경되어버려 페이지를 열 수가 없다.

이 경우를 어떻게 해야 할까.

 

Docker 에서는 GUI 를 통해 컨테이너의 터미널을 직접 사용하거나 docker exec 를 이용하여 변경된 상태 값을 적용할 수 있었지만 내가 지금까지 작성해왔던 포스팅을 따라 했다면, AWS Fargate 의 서버리스 환경이기 때문에 EC2 인스턴스를 따로 등록하지 않은 상태라, 컨테이너에 접근할 수 없는 상태이다. 그러나 docker exec 같은 역할을 하는 방법은 있다. 그래서 docker exec 처럼 "컨테이너 내에다 커맨드를 어떻게 쓸 수 있게 할까?" 에 대해서 작성해보도록 하겠다.


docker exec 는 쓰는데 별 어려움이 없었다. 그러나 ECS 는 AWS 의 복잡한 룰을 따라 사용해야 된다는 탓에 난이도가 조금 큰 작업이 되었었다. 이 방법의 이름은 ECS Exec 로, 더 자세한 사항은 공식문서인 다음 링크에서 확인할 수 있다.

 

디버깅에 Amazon ECS Exec 사용 - Amazon Elastic Container Service

디버깅에 Amazon ECS Exec 사용 Amazon ECS Exec을 사용하면 먼저 호스트 컨테이너 운영 체제와 상호 작용하거나 인바운드 포트를 열거나 SSH 키를 관리할 필요 없이 컨테이너와 직접 상호 작용할 수 있습

docs.aws.amazon.com

 

1. 필요 프로그램 설치

ECS Exec 에서는 터미널 창에서 실행시키는 것이기 때문에 AWS CLI 는 무조건 있어야 하며, Session Manager Plugin 이라는 프로그램을 추가로 설치해 주어야 한다. AWS Session Manager 를 이용하여 콘솔에 접근을 하도록 되어있는 것 같았다. 설치는 다음과 같이 본인의 환경에 맞도록 한다.

 

(옵션) AWS CLI용 Session Manager 플러그인 설치 - AWS Systems Manager

(옵션) AWS CLI용 Session Manager 플러그인 설치 AWS Command Line Interface(AWS CLI)를 사용하여 관리형 노드에 연결하는 세션을 시작 및 종료하려는 경우 먼저, 로컬 시스템에 Session Manager 플러그 인을 설치해

docs.aws.amazon.com

나의 경우에는 EC2 에서 원격으로 부르기 위해서 EC2 인스턴스에 설치를 하였다.

추가적으로 나처럼 EC2 인스턴스에서 AWS CLI로 운용을 하려고 하는 경우에는 'aws version' 을 이용하여 cli 의 버전을 확인해보고, 1버전이라면 aws cli 2 가 되도록 업데이트를 실시해야 한다.

 

최신 버전의 AWS CLI 설치 또는 업데이트 - AWS Command Line Interface

이전 버전에서 업데이트하는 경우 unzip 명령을 실행하면 기존 파일을 덮어쓸지 묻는 메시지가 표시됩니다. 스크립트 자동화와 같은 경우에 이러한 프롬프트를 건너뛰려면 unzip에 대한 -u 업데이

docs.aws.amazon.com

 

그 다음으로는 IAM Role 에 권한을 추가하는 작업이 필요하다.

 

2. IAM 권한 설정

ECR 리포지토리를 생성하는 포스팅에서 CLI 작업을 위해서 IAM 에 CLI 전용 그룹을 만들어놨었다. 그 때에는 아무런 권한을 추가하지 않았지만, ECS Exec 를 사용하기 위해서는 (오지게 많은) 몇 가지의 권한 설정이 필요하다.

 

먼저, IAM 의 사용자 그룹에서 내가 사용하고자 하는 그룹의 권한을 추가하자. 권한 추가에는 일반 정책을 추가하는 방법과 필요한 것들만 골라서 적용할 수 있도록 만든 인라인 정책 두가지 방법이 있다. 둘 중에서 인라인 정책으로 추가하는 방법을 선택해보자.

정책 생성 화면인데, 정책 생성하는 방법에는 시각적 편집기라고 하는 위자드 형태의 툴과 JSON 으로 직접 짤 수 있는 툴을 제공해주고 있다. JSON 은 많이 어렵기 떄문에 시각적 편집기를 통해서 추가를 해본다. 

 

공식 문서에서는 ssmmessage: 계열의 정책만 추가하면 되는 것 처럼 보였지만, 쌉거짓말이라..... 일단 필요하긴 해서 디폴트로 시각적 편집기에서 SSM Message 를 찾아서 모든 권한을 추가하도록 한다.

그 다음, 하단에 있는 권한추가 버튼을 눌른 후,

  • 서비스: Elastic Container Service
  • 작업: ExecuteCommand
  • 리소스: 이 계정의 모든 항목에 체크 표시 (클러스터, 태스크)

선택 한 후 정책 검토를 눌러 작업을 완료 한다. 이름은 아무렇게나 작성한다

 

여기까지 하게 되면 CLI 에서 커맨드를 입력할 수 있는 자격이 생긴다. 하지만 컨테이너에서는 커맨드를 받을 준비가 되지 않아서 컨테이너가 가지고 있는 ECS 역할에 대해서도 추가가 필요하다.

 

IAM 콘솔의 왼쪽 메뉴에서 '역할'로 이동하게 되면 역할 리스트 중에 ECS 에서 기본으로 만들어 준 'ecsTaskExecutionRole' 이 보인다. 이 역할 안에 ssmmessage:* 의 권한을 넣어준다. ExecuteCommand 는 클라이언트에서 ECS 에 접근할 때 필요한 권한이기 때문에 넣을 필요는 없으며 ssmmessage 권한만 추가시켜주면 된다. 

3. 태스크 업데이트

포스팅만 따라하게 되었다면, 태스크의 속성에 "태스크 실행 역할"은 있지만 "태스크 역할"은 없음으로 되어 있을 것이다. 그리고, ECS Exec 가이드에서는 태스크를 만들 때 옵션하나를 추가하는 걸 권장하는 문구도 같이 힜다. 

 

먼저, 태스크 역할을 추가해보자. JSON 으로 만져진 태스크 였다면 콘솔에서 클릭만으로 설정 변경이 되지 않을 수 있다. 그래서 JSON 상태의 편집기에서 값을 추가해야 한다. JSON 편집기를 보게 되면 "executionRoleArn" 을 찾을 수 있는데 이것은 "태스크 실행 역할" 에 해당되는 속성이고 역할의 ARN 을 값으로 받는다. 그 위에 태스크 역할을 맡는 키 값인 "taskRoleArn" 을 추가한다.  ARN 값은 나 같은 경우에는 별 다른 설정이 있지 않아서 executionRoleArn 값을 복사해서 집어넣었다.

 

다음으로, ECS Exec 에서 추가 권장하는 파라미터를 집어넣어본다. containerDefinition 속성 안에 다음처럼 값을 넣어준다.

containerDefinition: {
    ...
    "linuxParameters": {
        "initProcessEnabled": true
    },
    ...
}

해당 옵션이 갖는 역할에 대해서는 공식문서에 설명이 나와있지만 딱히 이해가 되는 설명은 아니라서 패스하도록 한다. 입력이 완료되었다면 클러스터로 가서 서비스를 새로운 태스크 개정으로 올려준다.

 

4. 서비스 업데이트

 이번에는 터미널 환경에서 서비스가 커맨드를 받을 수 있도록 설정을 변경해주어야 한다. 콘솔에서는 커맨드 허용에 대한 항목이 없기 떄문에 터미널을 통해 접근하여 허용을 시켜주어야 한다. 서비스가 만들어지지 않은 경우에는 create-service 를 사용하며, 이미 만들어져 있는 서비스가 있는 경우에는 update-service 를 사용하도록 한다.

aws ecs update-service \
--cluster ${cluster_name} \
--service ${service_name} \
--enable-execute-command

요즘은 --enable-execute-command 플래그를 통해서 커맨드를 허용하느냐 마느냐에 대한 설정을 하는 것이다. 설정에 성공을 하였다면, JSON 문으로 서비스에 대한 상세 내용이 출력이 될 것이고, 제일 마지막 줄에 enableExecuteCommand 라는 란이 true 로 되어있는 것을 확인하면 된다.

 

5. 커맨드 실행

자 이제 터미널 환경에서 다음의 커맨드를 이용하여 신호를 보내보자

aws ecs execute-command \
--cluster ${cluster_name} \
--task ${task_id|task_arn} \
--interactive \
--command "/bin/sh"

성공을 하게 되면, 커맨드가 /bin/sh 를 실행시키는 것이기 때문에 컨테이너를 쉘로 이용할 수 있을 것이다. 만약에 컨테이너 내에 다른 커맨드를 사용하게 되면 커맨드가 실행되고 바로 종료 될 것이다. 

 

6. 그래도 안되는 경우 ㅠㅠ

 셋팅하는 방법이 어렵다보니 이렇게 해도 ECS 에 접근할 수 없다 하는 경우가 있다. 그럴 때 어느 부분이 잘 못되었는지 확인 시켜주는 프로그램이 있는데 바로 다음의 깃허브에 있는 배시 쉘 프로그램이다

 

GitHub - aws-containers/amazon-ecs-exec-checker: 🚀 Pre-flight checks for ECS Exec

🚀 Pre-flight checks for ECS Exec. Contribute to aws-containers/amazon-ecs-exec-checker development by creating an account on GitHub.

github.com

여기에서 직접 클론으로 다운 받는 것보다 다음 커맨드로 실행하는 방법이 훨씬 간편하다.

$ bash <( curl -Ls https://raw.githubusercontent.com/aws-containers/amazon-ecs-exec-checker/main/check-ecs-exec.sh ) <YOUR_ECS_CLUSTER_NAME> <YOUR_ECS_TASK_ID>

클러스터 명과 클러스터에 띄워진 서비스의 태스크 ID 입력만으로 어느 부분이 제대로 셋팅되어있지 않은 지 확인할 수 있다. 예시와 대처방법이 전부 깃허브 페이지에 작성되어있기 때문에 빨간색이 나온 부분은 확인해서 조치하면 될 것이다.

반응형
Comments