AWS ECS와 S3 버킷의 통신 해결

2024년 1월 15일 월요일

Today I Learned

날짜

2024년 1월 15일 월요일

내용

드으으으으디어 ECS를 해결했다!

ECS 정복 직전

너무 자주 말한듯 하지만.. ECS 클러스터가 S3 버킷에서 환경변수를 가져오지 못하고 있었다.

  • 질문

    I am encountering an issue with my ECS service where tasks are consistently failing during deployment. The specific error message I receive is as follows:

    1
    2
    
      ResourceInitializationError: failed to download env files: file download command: non empty error stream: service call has been retried 5 time(s): RequestCanceled: request context canceled caused by: context deadline exceeded
        
    
    • ECS tasks are configured to download environment files from an S3 bucket.
    • My ECS service is in the Seoul region (ap-northeast-2), and the S3 bucket is in the US East (Ohio) region (us-east-2).
    • The S3 bucket and objects are not set to public access.

    I suspect that the issue might be related to timeout settings, as the error indicates that the request is canceled after multiple retries due to a context deadline being exceeded. I have tried setting the startTimeout and stopTimeout in the task definition JSON to 120 seconds, but this has not resolved the issue.

    Previously, we experienced similar issues, but they were automatically resolved through the retry process, so we did not make any changes. However, after adding a new scheduled task, this task did not operate successfully.

    In an attempt to address this, as mentioned above, I revised the task definition after registering the new scheduled task and deployed it. Unfortunately, the service deployment also failed with the same error. Ultimately, I rolled back to a previous revision by removing the timeout settings from the JSON, which allowed the service deployment to proceed. However, the scheduled task still fails with the same error.

    If you have any opinions on this issue or need additional information, please let me know immediately.

    Please note that I am not a native English speaker, so I apologize for any lack of clarity in my explanation. I appreciate your understanding.

  • 두 가지 답변

    1. 첫 번째 답변

    It could be some networking issue, did you check ECS schedule tasks subnet or security groups where its placed. Subnet should have internet connectivity via IGW or nat gateway.

    • 두 번째 답변
    1
    2
    3
    4
    5
    6
    
      The Error due to below the configuration needs to be checked.
      check Networking configuraton :Ensure that the ECS tasks have the necessary network access to download the environment files. This includes checking security groups, network ACLs, and any other network configurations that might restrict access.
        
      Verify File Location and Permissions: Confirm that the environment files are in the expected location and that the ECS tasks have the appropriate permissions to access them. This might involve checking IAM roles and permissions.
        
      Review Task Execution Role: Ensure that the task execution role assigned to your ECS tasks has the necessary permissions to access the resources it needs, including downloading environment files.
    

결론은 내 Task에서 S3로 접근 가능한지 네트워크나 권한 등 여러가지를 확인해보라는 것이었다. 하나씩 확인했다.

  1. IAM Role

    ecsTaskExcutionRole 이 실행하도록 되어있었는데, 내부 정책에도 S3에 접근할 수 있도록 “s3:Getobject” 가 포함되어 있었다. 따라서 용의선상에서 제외됐다.

  2. 보안그룹

    ec2에서도 여러모로 골치썩이는 녀석인데, 결국 outbound를 확인해야 했다. 보안그룹의 outbound 규칙은 ECS Task가 다른 지역에 있는 S3 버킷에 통신할 수 있도록 설정되어 있어야 했다. 그리고 그렇게 되어있었다. 석방.

  3. VPC 및 서브넷

    이 부분이 가장 의심이 갔는데, 사실 내가 뭔지 모르겠어서 잘 안봤다. 우선 이게 뭔지를 찾아봤다.

    • VPC(Virtual Private Cloud) : AWS에서 우리가 정의한 가상 네트워크다. 따라서 자체적인 IP 주소 범위, 서브넷, 게이트웨이, 보안 설정등을 구성할 수 있다.
    • 서브넷(Subnet) : VPC 내의 IP 주소 범위를 나누어 구성한 네트워크 세그먼트다. VPC를 여러 개의 서브넷으로 나누어 네트워크를 구성한다. public과 private으로 구분되는데, 인터넷 게이트웨이에 연결되어 접근이 가능한지에 따라 나뉜다.
    • 게이트웨이(Gateway)
      • 인터넷 게이트웨이 : VPC와 인터넷을 연결해 주는 게이트웨이. 퍼블릭 서브넷의 리소스는 이것으로 연결
      • NAT 게이트웨이(Network Address Translation) : 프라이빗 서브넷 내의 리소스가 인터넷에 접근할 수 있도록 해주는 게이트웨이. 프라이빗 서브넷은 인터넷에 연결되있지 않아 접근할 수 없기 떄문에 외부 서비스에 접근하려면 필요하다.

    Task에 설정되어 있는 VPN은 4개의 서브넷으로 구성되어 있었다. 2개는 퍼블릭이고, 두개는 프라이빗이다. 이 중 한 개를 선택하게 되는데 퍼블릭이면 그냥 s3 버킷으로 접근할 수 있을것이다. 그럼 프라이빗 서브넷일 때도 접근할 수 있는지 확인해봐야했다. AWS VPC console에서 NAT 게이트웨이 대시보드를 들어가보니 텅 비어있었다.

    이때부터 혹시 드디어 물꼬를 찾았나 싶어 심장이 발작하기 시작했다. NAT 게이트웨이를 생성했다. Task의 region은 서울이고, S3 버킷이 오하이오에 있었기 떄문에 NAT 게이트웨이를 서울에 생성해주었다. Elastic IP(EIP)는 없길래 새롭게 생성해서 할당해주었다.

    이후 라우팅 테이블을 수정해주었다. 기존에 프라이빗 서브넷들의 라우팅 테이블을 선택하고, 라우트 탭에서 새로운 라우트를 추가해주었다. 목적지는 ‘0.0.0.0/0’을 입력하고 대상은 내가 만든 NAT 게이트웨이였다. 이런 방식으로, 프라이빗 서브넷은 NAT 게이트웨이를 통해 인터넷에 접근할 수 있고, S3 버킷에도 접근하여 환경변수를 받아올 수 있다.

    이제 Task들을 다시 실행해봤는데 오류가 바뀌었다!

    Essential container in task exited

    라고 떴는데, Task가 정상적으로 작동된 후 종료되어도 이 메시지가 뜬다고 한다. cron의 로직을 약간 수정하여 메일을 나한테 보내도록 하였더니, 메일이 발송되었다! 드디어 하

    정말 마지막으로 확인하기 위해, 테스트 서버에 리뷰를 추가해주고 내일 아침에 메일이 발송되도록 설정했다. 만약 진짜 내가 고친거라면 내일 아침에 메일이 와있을 텐데..

    제발!

구글 스프레드 시트 연동 API

우리 서비스에서 자주 확인해야할 정보들은 구글 스프레드시트에 연동되도록 되어있었다. 4개월 전부터 작동이 안되었는데, 이 부분을 고치려고 했다.

슬프게도, 기존 로직이 또 cron으로 되어있었기 떄문에 Task 등록을 고치지 않으면 진행할 수 없었다. 하지만 오늘 고쳤으니까 바로 진행했다. Google Cloud에 새로운 프로젝트를 등록하고, 서비스 계정을 생성했다. 연동하고자 하는 spread sheets에 서비스 계정도 편집할 수 있는 권한을 넘기고, 계정의 API 관련 Key 값들을 환경변수로 설정했다. 다행히 이전 프로젝트에서 소셜 로그인을 구현하면서 플랫폼 API를 다루었더니 크게 어렵진 않았다.

Task에 등록했지만 애도 환경변수를 불러올 수 없다고 뜬다. 다른 Task들은 멀쩡한데, 왜 짬도 없는 Task가 말썽일까..

회고

3주 가까이 끌어온 Task가 실마리가 보인다. 이 맛에 개발하지 껄껄

고마워요 sadique

img