스팟 인스턴스의 Terminate 시 자동으로 ECS 클러스터에서 Deregister

ECS와 스팟 인스턴스는 궁합이 비교적 많은 곳에서 권장되지만, 그대로는 강제 Terminate 시에 깨끗하게 ECS 클러스터를 빠질 수 없다는 것은 그다지 잘 알려져 있지 않습니다. (구축·운용한 적이 있는 사람은 곧 깨닫습니다만)
이번에는 간단한 설명과 구체적인 대응을 쓰고 있습니다.

왜 대응이 필요한가?



스팟 인스턴스가 강제 Terminate 될 때 적절한 처리가 이루어지지 않으면 다음과 같은 이벤트가 발생합니다. 그래서 프로덕션에서 이용할 때는 대응은 거의 필수인가라고 생각합니다.
  • 해당 인스턴스의 컨테이너가 ELB에서 연결되어 있으면 Draining되지 않고 중지됩니다.
  • Draining되지 않은 요구가 503 Error가 된다.
  • 상황에 따라서는 충분한 수의 컨테이너가 존재하지 않는 시간대가 발생한다.


  • 어떤 대응이 필요한가?



    공식 문서에도 기재가 있습니다만, 기본적으로는 컨테이너 인스턴스 등록 취소 을 하는 것으로, 이하의 작업이 행해집니다.
  • 해당 인스턴스에서 실행 중인 컨테이너의 ELB에서 Draining
  • 해당 인스턴스에서 실행 중인 컨테이너를 다른 인스턴스로 오프로드합니다.

  • 또, 2분 있으면 충분할 것이라고 생각합니다만 ELB의 Draining의 허용 시간등도 맞추어 재검토하는 편이 좋을까 생각합니다.

    단지, 스스로 설정하는 것은 귀찮아, 그래서 이번에는 CloudFormation 템플릿을 준비했습니다.

    CloudFormation 템플릿



    htps : // 기주 b. 이 m / ma ts16 / 에스 cs 포 t-에서 s s
    기본적으로 여기 템플릿을 실행하면 OK입니다. (리전별로 설정되므로 ECS를 사용하는 리전에서 CFn을 실행하십시오)

    기본적으로는 구성도대로입니다만 아래와 같은 일을 하고 있습니다.
  • CloudWatch Events에서 강제 Termination의 2분 전 통지를 탐지
  • Lambda Function 실행
  • Lambda 내에서 API를 두드리고 해당 인스턴스를 ECS 클러스터에서 Deregister합니다.



    안의 코드를 봐 주시면 알 수 있습니다만, instance_id 로부터 cluster_namecontainer_instance_id 를 직접 참조할 수 있는 API가 없기 때문에, 약간 미묘한 쓰는 방법이 되고 있습니다.

    후기



    이 게시물은 개인의 의견이며 소속 기업이나 단체는 관련이 없습니다. 약속입니다.
    오랜만에 python 써 있었기 때문에 지적이나 기능 요망이 있으면, PullRequest나 Issue 받을 수 있으면이라고 생각합니다.
    (SNS 끼우는 편이 좋다든가, Slack에 통지하고 싶은 등)
  • 좋은 웹페이지 즐겨찾기