Cluster 는 이러한 Docker 이미지들을 구동시킬 인스턴스들의 논리적 그룹으로 볼 수 있으며, ECS 의 가장 큰 범주로 볼 수 있다.
위 그림에서 처럼 VPC 안의 최상단에서 컨테이너 인스턴스들을 감싸고 있는 것이 바로 ECS Cluster 이다.
Image 를 실행시키려면 일단 Image 를 구동시킬 인스턴스를 배치할 Cluster 를 만들어야 한다.
Cluster 생성할 때 중요한 것은 Image 를 구동시킬 인스턴스의 사양을 정하는 것이다. 인스턴스 개수는 추후 [Scale ECS Instances] 에서 수정이 가능하다.
1. ECS - Cluster - [Create Cluster]
2. 시작 유형 선택 : Fargate 는 인스턴스를 구성할 필요 없음
3. EC2 의 경우 EC2 인스턴스 타입, Key pair, VPC, security group 등을 설정.
Cluster 생성을 완료하면, ECS Instances 탭에 설정한 만큼의 인스턴스가 생성된 것을 확인할 수 있다. 인스턴스 수를 늘리면 인스턴스가 추가되어 ACTIVE 상태가 되고 인스턴스 수를 줄이면 해당 인스턴스는 수 분 안에 삭제된다. 인스턴스를 ACTIVE 상태에서 DRAINING 으로 전환하면 기존 Task 에 영향을 미치지는 않지만, 해당 인스턴스에는 더 이상 Task 정의가 할당될 수 없으며 다시 ACTIVE 상태로 전환하면 가능해 진다.
ECS 를 시작하기 전에 가장 먼저 어플리케이션을 이미지로 만들어 ECR(Elastic Container Registry) 에 등록을 해 보자. ECR 에 이미지를 등록하는 것은 ECS 와 연계되는 부분이 거의 없으므로 ECS 를 몰라도 상관없다. 이미지 등록에만 집중하자.
ECS 를 몰라도 상관없다고 말했지만, 꼭 집고 넘어가야 할게 있다. ㅜ ECS 를 사용할 때 사용자가 선택할 수 있는 두 가지 선택지가 있다. 하나는 인스턴스로서 EC2 를 사용할지 Fargate 를 사용할지이고 (이를 시작 유형이라고 함), 또 하나는 Docker Registry 를 공개용(public) 으로 구성할지 비공개용(private) 으로 구성할지 이다. Fargate 라는 것은 컨테이너를 위한 EC2 등의 인스턴스를 필요로 하지 않고 컨테이너 자체를 배포하는 아마존의 기술이다. 지금은 몰라도 된다. 하지만 알고 싶다면... EC2 에서 돌아가던 것이 EC2 없이도 어디선가 돌아간다 라고 생각하면 쉽다; 그만큼 EC2 등의 인스턴스를 관리하는 노력이 줄어드니까 더 좋다고도 볼 수 있다. EC2 를 컨트롤 하는 것 처럼 정밀한 제어는 힘들겠지만. 아무튼 좋아보이니 비싸기도 하다. EC2 시작 유형을 사용해보면 Fargate 설정은 훨씬 더 쉬우므로 EC2 시작 유형 기반으로 설명할 것이다. 아마도 대부분이 실전에서는 private 저장소를 사용하게 될텐데, 혹시라도 public 저장소를 사용하게 되면 EC2 인스턴스 유형을 사용할 수 없다. 즉 EC2 인스턴스 유형은 private 저장소만 지원한다. 이를 유념하도록 하고... ECS 에서 Docker Registry 는 ECR 말고도 아마 거의 다 지원할 것이다. Docker Hub, self-hosted registry 등...
여기서는 아마존 패밀리인 ECR 을 사용해 보도록 하겠다.
1. Docker 이미지 생성
docker 이미지를 생성하려면 Docker 를 설치하고 데몬을 실행시켜 docker cli 를 사용할 수 있어야 한다. (여기까지는 알아서 잘 해보자 ㅜ)
그리고 이미지 설정 파일인 dockerfile 을 만들어 필요에 맞게 구성한다.
나는 다음과 같이 tomcat 에서 구동하는 war 파일에 ssl 통신이 가능하도록 이미지화 하는 dockerfile 을 만들었다. (이것도 본인 필요에 맞게 알아서 잘 해보자;)
$ vi dockerfile
FROM tomcat:8.0-jre8-alpine
RUN ["rm", "-rf", "/usr/local/tomcat/webapps/ROOT"]
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 를 선택하게 될 것이다.
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. (얼마나 완벽한 자동화를 만드느냐는 사용자의 몫...)