'무중단 배포'에 해당하는 글 3건

ECS Deployment strategy

Server/AWS 2018. 8. 27. 02:02

배포 자동화 스크립트를 만들기 전에 가장 궁금했던 것은 배포 전략(?) 이었다.

예를 들어 로드 밸런서에 인스턴스 2 대를 운영 중이라면, 3 가지 정도의 배포 방법을 생각할 수 있다.


  • 인스턴스를 2 대 이용할 경우, A 인스턴스를 중단하고 새로 배포 후, B 인스턴스를 중단하고 새로 배포하는 방법이 있을 수 있다.
  • 인스턴스를 2 대에서 2 대를 추가할 경우, C/D 인스턴스에 새로 배포 후, A/B 인스턴스를 중단하는 방법이 있을 수 있다.
  • 인스턴스를 2 대에서 1 대를 추가할 경우, C 인스턴스에 새로 배포 후에, A 나 B 인스턴스를 중단하든 그 반대로 하든... 아무튼...


Service 설정에 보면 Replica 전략에서 배포구성에 관한 옵션이 두가지 있다. minimumHealthyPercent maximumPercent 인데 이것과 인스턴스 수 조정으로 배포 전략을 결정할 수 있다. minimumHealthyPercent 은 RUNNING 상태인 Task 수를 최소 얼만큼 유지할 것인지를 설정한다. 로드 밸런서를 붙인 상태에서는 동시에 inService 상태 인지도 체크한다. maximumPercent 는 RUNNING 상태이거나 PENDING 상태의 최대 Task 수를 고려하여 설정한다.

(아래는 min / max 로 표현하겠음.)


로드 밸런서를 붙인 상태에서 운영중인 2 대의 인스턴스를 가장 빠르고 안정적으로 배포하기 위한 설정을 위해 다음과 같이 테스트 해 보았다.



A. Instance 2 (+0) 50% 100%


이 설정은 인스턴스 2 대 중, 하나의 인스턴스의 Task(50%) 는 무조건 RUNNING 상태를 유지하게 된다는 것을 예상할 수 있다. 그로 인해 번갈아 가면서 배포가 가능하게 될 것이다.


- Service Log

00:00:00 - 로드밸런스에서 A 인스턴스 등록 해제

00:00:00 - A Task DRAINING 상태 시작

00:00:12 - A Task 중지 완료

00:00:22 - 새로운 A Task 시작

00:00:33 - 로드밸런스에서 A 인스턴스 등록

00:00:54 - 로드밸런스에서 B 인스턴스 등록 해제

00:00:54 - B Task DRAINING 상태 시작

00:01:15 - B Task 중지 완료

00:01:25 - 새로운 B Task 시작

00:01:36 - 로드밸런스에서 B 인스턴스 등록


A Instance -> LB 해제 -> Task 중지 -> Task 시작 -> LB 등록

B Instance                                              -> LB 해제 -> Task 중지 -> Task 시작 -> LB 등록


로그를 보면 Task 를 삭제하거나 실행하는 과정은 간단하다.


1. 로드밸런스에서 인스턴스 등록 해제

2. Task DRAINING 시작

3. Task 중지


4. 새로운 Task 시작

5. 로드밸런스에서 인스턴스 재등록


여기서 max 를 200% 로 둔 다면 하나의 Task 를 DRAINING 으로 변경하며 즉시 여유분의 인스턴스를 찾을 것이므로 경고가 발생한다. 배포는 되겠지만 약간의 딜레이가 발생할 것이다.



B. Instance 2 (+0) 100% 150%


이 설정은 인스턴스 2 대 중, 2 대의 인스턴스의 Task(100%) 가 무조건 RUNNING 상태를 유지하게 되므로 배포할 방법이 없다.

min 을 100% 로 설정하려면 max 값에 대응할 수 있는 추가 인스턴스가 필요하다.

CPU / MEM / PORT 등의 요구사항을 만족하는 인스턴스를 찾지 못했다는 에러 메시지가 나타날 것이다.


- Service Log

00:00:00 - 요구사항에 부합하는 컨테이너 인스턴스가 없으므로 Task 를 실행할 수 없다. 



C. Instance 2 (+1) 50% 150%


- Service Log

00:00:00 - 로드밸런스에서 A 인스턴스 등록 해제

00:00:00 - A Task DRAINING 상태 시작

00:00:00 - 새로운 C Task 시작

00:00:20 - A Task 중지 완료

00:00:20 - 로드밸런스에서 C 인스턴스 등록

00:00:31 - 새로운 A Task 시작

00:00:41 - 로드밸런스에서 B 인스턴스 등록 해제

00:00:41 - B Task DRAINING 상태 시작

00:00:41 - 로드밸런스에서 A 인스턴스 등록

00:01:02 - B Task 중지 완료


A Instance -> LB 해제 -> Task 중지 -> Task 시작 -> LB 등록

B Instance                                              -> LB 해제 -> Task 중지

C Instance -> Task 시작 -> LB 등록          



D. Instance 2 (+1) 100% 150%


- Service Log

00:00:00 - 새로운 C Task 시작

00:00:13 - 로드밸런스에서 C 인스턴스 등록

00:00:34 - 로드밸런스에서 A 인스턴스 등록 해제

00:00:34 - A Task DRAINING 상태 시작

00:00:54 - A Task 중지 완료

00:01:05 - 새로운 A Task 시작

00:01:16 - 로드밸런스에서 A 인스턴스 등록

00:01:37 - 로드밸런스에서 B 인스턴스 등록 해제

00:01:37 - B Task DRAINING 상태 시작

00:01:58 - B Task 중지 완료


A Instance                       -> LB 해제 -> Task 중지 -> Task 시작 -> LB 등록

B Instance                                                                    -> LB 해제 -> Task 중지

C Instance -> Task 시작 -> LB 등록



E. Instance 2 (+2) 50% 200%


- Service Log

00:00:00 - 로드밸런스에서 A 인스턴스 등록 해제

00:00:00 - A Task DRAINING 상태 시작

00:00:00 - 새로운 C, D Task 시작

00:00:10 - 로드밸런스에서 C 인스턴스 등록

00:00:21 - 로드밸런스에서 B 인스턴스 등록 해제

00:00:21 - B Task DRAINING 상태 시작

00:00:21 - A Task 중지 완료

00:00:21 - 로드밸런스에서 D 인스턴스 등록

00:00:32 - B Task 중지 완료


A Instance -> LB 해제 -> Task 중지

B Instance                       -> LB 해제 -> Task 중지

C Instance -> Task 시작 -> LB 등록          

D Instance -> Task 시작           -> LB 등록



F. Instance 2 (+2) 100% 200%


- Service Log

00:00:00 - 새로운 C, D Task 시작

00:00:12 - 로드밸런스에서 C, D 인스턴스 등록

00:00:34 - 로드밸런스에서 A, B 인스턴스 등록 해제

00:00:34 - A, B Task DRAINING 상태 시작

00:00:55 - A, B Task 중지 완료


A Instance                       -> LB 해제 -> Task 중지

B Instance                       -> LB 해제 -> Task 중지

C Instance -> Task 시작 -> LB 등록          

D Instance -> Task 시작 -> LB 등록



위와 같이 minimumHealthyPercent / maximumPercent / task 수를 설정하여 다양한 배포 방법들을 테스트 해 보았다. B 를 제외한 A/C/D/E/F 의 배포는 모두 정상적으로 이루어 졌다. 물론 시간이나 순서 등은 각자의 배포물 용량이나 트래픽에 따라 변할 수 있다. 단계가 간결한 F 배포가 가장 빠를 것 같았는데 E 배포가 더 빨랐다는 것은 예상 밖이다. C 나 D 같은 경우는 min 과 max 값이 동시에 모두 가능할 때 어느쪽으로 먼저 배포에 영향을 미치는지를 보고 싶어서 테스트 한 것이었는데 minimumHealthyPercent 가 매우 중요함을 알게 됐다.이번 테스트로 A 방법이 가장 효율적인 것을 알게 되었고, 빠르고 빈도수가 높은 배포는 E/F 방법을 으로 전략을 세우는 것이 효과적임을 알게 됐다.



결론


가성비 좋은 배포는 A, 속도/빈도수 높은 배포는 E/F 를 사용하자.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

Amazon ECS

Server/AWS 2018. 8. 13. 19:50

Amazon Elastic Container Service(ECS) 는 클러스터에서 도커 컨테이너를 손쉽게 실행, 중지 및 관리할 수 있게 해주는 컨테이너 관리 서비스이다.

도커 이미지로 Auto scaling, LB, EC2 등과 통합하여 서비스 하고자 할 때 좋은 선택이 될 수 있으며, 무중단 배포가 간편하다는 가장 큰 장점이 있다.





위 그림은 ECS 의 전반적인 아키텍처를 나타낸 것이다.

요점은 배포할 어플리케이션을 이미지 저장소로부터 가져와서 원하는 수 만큼의 인스턴스(EC2 등) 에 배포한다는 것이다.

Docker 의 Cluster, Stack, Service, Task 등과 거의 같은 기능들을 하지만, 비슷하면서도 다르다... ㅡ.ㅡ;


다시 어플리케이션을 ECS 를 통화 배포하는 세분화된 단계를 보자면,


1. 배포할 어플리케이션을 docker 이미지로 생성한다.

2. 해당 이미지를 어디서든 가져올 수 있도록 docker 레지스트리(ECR, docker hub 등) 에 등록한다.


여기까지는 주로 docker 에 관련된 내용이다. docker 레지스트리는 docker 이미지를 버전관리 할 수 있으며, 버전관리 측면에서 github 와 비슷한 기능을 한다.


3. ECS 의 최상위 리소스인 cluster 를 생성한다. 이 때 VPC 설정으로 네트워크의 영역을 정의하며, 사용할 인스턴스 타입/사양 등을 선택한다.

4. 가장 중요한 task 정의를 생성한다. 이 정의에는 사용할 이미지, 포트, 컨테이너 사양 등을 정의한다.

5. 특정 cluster 에서 task 를 효율적으로 관리할 service 를 생성한다. 이 service 구성에는 실행할 task 정의, 실행할 인스턴스 수, LB, Auto Scaling 등을 설정할 수 있다.


여기까지는 일반적으로 EC2 를 생성할 때 구성했었던 VPC, Subnet, Secure group, Key-pair, LB, Auto scaling 과 ECS 를 구성하는 Cluster, Service, Task 등을 설정했다. Cluster - Service - Task 의 상관 관계가 조금 복잡해 보일 수 있는데,


하나의 Cluster 에는 하나 이상의 Service 를 생성할 수 있으며, 생성된 Service 는 해당 Cluster 에서만 사용된다.

하나의 Service 에는 하나의 task 및 인스턴스 수를 관리할 수 있다.

생성된 Task 정의는 하나 이상의 Cluster 또는 하나 이상의 Service 에서 실행될 수 있다.


ECS 의 완성은 Cluster 에서 Task 정의를 실행하는 것이다. 이것이 곧 배포이다. task 정의는 Service 없이도 Cluster 에서 직접 실행 시킬 수 있지만, Service 를 생성하므로써 더 효율적으로 task 를 관리할 수 있다. LB, Auto scaling, 순차 배포 등. 많은 사용자들이 도커 이미지로 Auto scaling, LB, EC2 등과 통합하여 무중단 배포로 서비스 하기 위해 이 ECS 를 선택하게 될 것이다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

Jenkins vs ECS

Server/AWS 2018. 8. 12. 02:40



Jenkins 가 지속적 통합(CI), 즉 빌드/테스트 및 배포 자동화 도구라고 할 때, ECS 는 Docker 컨테이너를 실행 및 관리하는 AWS 서비스라고 할 수 있다. 이 설명만으로 볼 때 이 둘이 비교가 가능한건지... 비교할 수는 없겠지만 단지 배포 자동화를 중점으로 간략하게 비교해 보고자 한다. 전 세계에서 대부분의 개발자들이 필요로 하고 사용하는 전문적인 서비스들이지만, 나에겐 그저 자동화라는 가면을 쓴 골치아픈 녀석들 일 뿐.


Jenkins 는 배포가 빠르고 간편하다. 소스 저장소에 push 하거나, 목록에서 배포할 서버를 찾아 버튼을 클릭하는 것 만으로 배포를 완료할 수 있다. 사실 서버도 적고 Release 후에 유지보수가 거의 필요없다면 굳이 이런 CI 툴 등은 필요하지 않을 것이다. 공부하고 설치하고 세팅하고 테스트하고 관리비용 내고... 근데 정작 배포할 일은 거의 없고... 그렇다면 그냥 FTP 로 올리는게 여러가지로 맘이 편할지 모른다. 난 처음 Jenkins 를 설치하고 서버별로 각종 세팅을 하는데에 적지 않은 시간을 할애하면서, 이게 자동화인가... 라는 생각을 했다. 다 만들어놨을 때나 자동화지, 자동화를 위해 흘려야 할 피, 땀, 눈물이... 힘들었다. ㅋㅋ 하지만 이렇게 CI 툴을 하나 익혀놓으면 다른 비슷한 툴들도 쉽게 접근할 수 있다. 방식은 거의가 똑같다.


Jenkins 의 단점을 세가지 정도로 쥐어 짜봤다.


  • 하나는 오토 스케일링. 오토 스케일링이 필요하지 않는 서버라면 상관없겠지만... 늘어난 서버를 수대로, 또 수동으로 세팅해 줘야 한다는건 오토 스케일링이 필요한 사람들에게는 꽤나 번거로운 문제.
  • 또 하나는 복원. 나는 주로 태그로 복원하는 편인데, 롤백할 때마다 설정에 태그 붙였다 뗏다 하는 것도 번거로움. (쥐어짠 티가 남;)
  • 마지막으로 무중단 배포. 이건, 글쎄... 불가능 한건 아니지만 수동적인 무중단 배포(?) 라고 설명하면 되려나.


그렇다면 ECS 가 Jenkins 의 이러한 단점들을 극복해 줄 수 있을까. ECS 는 결론만 말하자면 가능하다. 간단하게 오토 스케일링 및 관리가 가능하고, 이전 버전으로의 복구는 가능은 하지만 그닥 편하다고는 볼 수 없다. 그리고 무중단 배포도 가능하다. 서버 수를 원하는대로 늘였다 줄였다 무중단 연속 배포하는... 이 정도면 배포에 있어서는 거의 완벽하다고 볼 수 있다. 


하지만 안타깝게도 ECS 도 단점이 있다. 기능상의 단점이 아닌 사용자의 능력에 따른 자동화라고 해야 하나. ECS 배포 자동화를 위해 알아야 할 것들이 꽤 많은 편이다. 어느 정도 AWS 나 배포 바닥(?) 을 모르는 초보자라면 이것 저것 시간을 꽤 할애해야 한다. Jenkins 는 사실 Jenkins 만 설치하고 약간의 메뉴얼만 보면 쉽게 따라할 수 있다. ECS 는 Docker 기반이다보니 최소 배포할 이미지는 만들 줄 알아야 한다. 또 이미지 저장소인 ECR 에 이미지를 올리기 위해서는 AWS-Cli 를 사용해야만 한다. 그리고 ECS 를 공부해야 한다. cluster-service-task 를 숙지하고 업데이트/복구 배포 전략을 세워야 한다. 쓰고 보니 크게 공부를 하지 않아도 될 거 같은...; Jenkins 는 구성을 크게 달리할 여지가 별로 없고 인터넷만 조금 뒤져보면 원하는 답을 금방 얻을 수 있지만, ECS 는 운용에 있어 아직 사례들이 부족한 편이라 사용자들이 각자의 환경에 맞게 충분히 헤딩을 해보면서 준비해야 한다. 예를 들자면 이미지 업로드를 어떻게 자동화 할 것인지, 이미지가 업데이트 되었을 때 배포는 어떻게 자동화 시킬 것인지 등이다.



정리하자면 이렇다.


무중단배포, 오토 스케일링이 필요 없다면 그냥 알아서... 해당 사항 없음.

서버 수가 변동될 일이 별로 없고, 업데이트가 잦고, 무중단배포(수동) 가 필요하면 Jenkisn.

지금의 Jenkins 운용에 만족한다면 그냥 Jenkins.

서버 수가 급변하고, 업데이트가 잦고, 무중단배포(자동) 이 필요하다면 ECS.

AWS 에 친숙하고 자동 배포의 끝판왕을 만들고 싶다면 ECS. (얼마나 완벽한 자동화를 만드느냐는 사용자의 몫...)




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,