ECS란?
- Docker는 최근 각광 받고 있는 컨테이너 기술이다.
- 하지만 Docker를 이용해 서비스를 구축 하려면 여러가지 고려 해야할 사항이 많다.
- 따라서 필연적으로 컨테이너를 적절하게 배치하고 관리할 수 있게 도와주는 컨테이너 오케스트레이션 도구의 필요성을 느끼게 된다.
- AWS의 ECS는 Amazon에서 제공하는 '완전관리형 컨테이너 오케스트레이션 툴'로써,
- Docker 컨테이너를 이용하여 인프라 환경을 좀 더 편리하게 운영,관리 할 수 있게 해주는 서비스이다.
- 비슷한 툴로서는 Kubernetes나 Docker Swarm이 있다.
ECS 구성 요소
- ECRAmazon에서 제공하는 컨테이너 이미지 저장소이다.사용자가 쉽게 컨테이너 이미지를 저장, 관리 공유 및 배포할 수 있는 완전 관리형 컨테이너 레지스트리이다. (이미지를 S3에 저장)
- ECR 리포지토리에서 이미지 URI를 이용해 빌드한 이미지를 푸쉬하고 가져올 수 있다.
- ECR(Elastic Container Registry)
- ECS는 크게 아래와 같은 컴포넌트들로 구성 되어 있다.
- Task definition
- Task
- Service
- Container Instance
- Cluster
- 먼저 이것들에 대해 하나하나 알아보자
- Task / Service 관계
- 1) Task definition
- 원하는 Docker 컨테이너를 생성할 때, 어떤 설정으로 몇 개 이상 생성 할 지를 정의한 Set 이다.
- 컨테이너의 이미지, CPU/메모리 리소스 할당 설정, port 매핑, volume 설정 같은 것들이 포함되며, 기존 docker run 명령에서 가능했던 대부분 옵션이 설정 가능하다.
- 컨테이너 오케스트레이션에서는 컨테이너가 필요에 따라서 자동적으로 실행되거나 종료될 수 있다.
- 따라서 매번 이러한 설정들을 지정하기보다는, 미리 설정들의 집합을 하나의 단위로 정의해놓고 사용한다.
- 이 단위가 바로 Task definition이다.
- 한 번 Task definition을 만들면 이 Task definition을 기반으로 특정 설정을 변경할 수 있다.
- Task definition 에는 한 개 이상의 컨테이너에 대해 정의가 가능하며, Task definition 내부에 정의된 컨테이너 사이는 link 설정으로 연결이 가능하다.
- Task definition 에서 정의된 대로 실제 생성된 container set 들을 Task 라고 부르게 된다.
- 원하는 Docker 컨테이너를 생성할 때, 어떤 설정으로 몇 개 이상 생성 할 지를 정의한 Set 이다.
- 2) Task
- Task definition 에서 정의된 대로 배포된 Container Set을 Task라고 부른다.
- 즉, Task 안에는 한 개 이상의 컨테이너들이 포함되어 있으며 ECS에서 컨테이너를 실행하는 최소 단위는 Task이다.
- Task는 Cluster에 속한 Container instance(EC2 Instance)에 배포되게 된다.
- 또한, Task는 여러 Container instance(EC2 Instace)에 배포 가능하다.
- Task definition 에서 정의된 대로 배포된 Container Set을 Task라고 부른다.
- 3) Service
- Task 들의 Life cycle 을 관리하는 부분을 Service 라고 한다.
- 각 Task 들은 각자 다른 서비스이다.
- Task 를 Cluster에 몇 개나 배포할 것인지 결정하고, 실제 Task 들을 외부에 서비스 하기 위해 ELB 에 연동 되는 부분을 관리하게 된다.
- (ELB : Elastic Load Balancer)
- 만약 실행 중인 Task 가 어떤 이유로 작동이 중지 되면 이것을 자동으로 감지해 새로운 Task를 Cluster에 배포 하는 고가용성에 대한 정책도 Service 에서 관리한다.
- 즉, 오토스케일링과 로드밸런싱을 관리하는 역할이다.
- 4) Container Instance (EC2 instance)
- ECS 는 Container 배포(Task 배포)를 EC2 instance 기반에 올리도록 설계 되어 있다.
- Task를 올리기 위해 등록된 EC2 instance 를 Container Instance 라고 부른다.
- ECS를 처음 시작하면 생성되는 Default Cluster 에는 Container instance를 자동으로 할당 시켜 주기도 하지만 새롭게 Cluster 를 생성하게 되면 직접 Container instance 를 만들어야 한다.
- Container instance 용 AMI 이미지는 AWS 측에서 제공해 주기 때문에 어렵지 않게 생성이 가능하다.
(Amazon Machine Image, AMI)는 EC2 안에 가상머신을 생성하기 위해 사용.즉, EC2 인스턴스를 이미지로 만들어 놓고, 이미지로 여러 개의 EC2 인스턴스를 만들 수 있는 것이다. 오토 스케일링에 사용! - EC2를 사용하여 배포하는 서비스의 디플레이의 기본 단위 역할을 한다.
- 하나의 Container Instace 내부에는 각각의 다른 Task가 여러 개 있을 수 있다.
- 5) Cluster
- Task 가 배포되는 Container Instance 들은 논리적인 그룹으로 묶이게 되는데 이 단위를 Cluster 라고 부른다.
- Task 를 배포하기 위한 instance 는 반드시 Cluster 에 등록되어야 한다
Cluster, Container Instance와 Task, Service의 관계의 도식화
핵심 요약
Container Instance : 클러스터에서 속한 인스턴스. 클러스터에 서비스나 태스크 실행을 요청하면 클러스터에 속한 컨테이너 인스턴스 중 하나에서 실행된다.
Container Instance 들을 하나로 묶은 것이 Cluster.
Cluster는 ECS의 가장 기본적인 단위. 서비스나 태스크가 실행되는 공간을 나누는 논리적인 공간
각각의 Container들의 set이 Task. (Task Definition에 따라 생성됨)
Task는 ECS에서 컨테이너 실행의 최소 단위.
Service가 1. Cluster에 Task를 얼마나 배포할 지 결정, Task와 ELB 연동 관리(로드밸런싱을 관리)
Service는 2. Task 중지를 자동 감지하여 오토스케일링 실시
Docker : 컨테이너 가상화 도구.
Dockerfile : 도커의 이미지 생성 과정을 정의한 DSL 형식으로 작성된 파일.
따라서 다음과 같은 순서로 작업
- 컨테이너의 이미지를 저장소(ECR)에 커밋
- task definition에서 사용할 이미지 및 시작 유형, 리소스 정의
- cluster 생성
- service가 task definition을 참고하여 task 생성
- elb에 들어온 요청에 따라 오토 스케일링 및 로드 밸런싱
ECS의 구조적 특징 및 주의사항
- 1) ECS의 Docker host 역할은 EC2 Instance가 담당한다.
- 컨테이너는 보통 물리 서버에 Docker daemon 을 설치하고, 그 위에 컨테이너를 하나씩 배포하게 되는데, Hypervisor 기반에서 동작되는 VM 보다 훨씬 더 많은 서비스를 올릴 수 있는게 큰 장점 중 하나이다.
- 하지만, AWS는 ECS를 위한 container 전용 서버팜을 따로 구성하지 않고, VM 형태의 EC2 instance 에서 container 를 동작시키는 방법을 택했다.
- Why? - 다른 AWS 서비스와의 연계를 위함
- AWS의 전체 서비스 설계를 보면 EC2 instance를 중심으로 다양한 서비스들이 연계되는 모양새를 갖추고 있다. 이는 AWS의 가장 큰 장점이기도 하다.
- Network 서비스인 VPC와 ELB, EIP 에서 부터 Auto scaling, Cloud Formation 등 수십가지의 서비스가 조직적으로 엮여 있으며 이 중심에는 사용자들이 가장 많이 사용하는 EC2 instance 가 있다.
- 만약, AWS가 ECS 서비스를 위해 새로운 Container 서버팜 환경을 구성하고 설계했다면, 기존 EC2 를 중심으로 한 다양한 서비스들과의 연계에 대하여 굉장히 많은 고민을 할 수 밖에 없을 것이다.
- 차라리 컨테이너를 EC2 instance에 올림으로서, EC2 중심으로 엮여 있는 기존의 서비스를 이용하는 장점을 흡수하는게 훨씬 이득이 많았을 거라 생각한다.
- 2) Overlay network가 아닌 ELB를 이용한 Network 구조
- Docker 를 사용하려는 사람들이 늘어나면서 컨테이너를 대규모로 운영하려는 시도가 점점 많아지고, 자연스럽게 다수의 Docker host 를 clustering 형태로 통합 관리하려는 필요성이 커지게 되었다.
- host 에 container 를 어떻게 배포할 것인지에 대한 스케줄링 관련 문제, 다른 host에 배포된 container 사이의 통신 문제, 동일 Port 를 사용 하는 컨테이너들을 동시 수용할때의 host 포트 맵핑 이슈 등이 대표적인 문제들이다.
- 최근 주목 받고 있는 컨테이너 orchestration 시스템인 Kubernetes나 Docker swarm의 경우 위와 같은 이슈를 해결하기 위해 overlay network 구조를 추가해 이런 문제를 해결하고 있다.
- host간 네트워크를 논리적으로 묶어서 연결해 주는 overlay network 는 컨테이너 orchestration 을 위한 중요 구성 요소로 고려되고 있는 추세이다.
- 그렇다면 ECS 의 host clustering 을 위한 network 구조는 어떠할까??
- ECS의 Cluster 는 매우 단순하다.
- Cluster는 docker host 의 논리적 묶음일 뿐이지, 이를 위해 추가적인 network 설계 구조가 들어가지 않은 것으로 보인다.
- Overlay network 가 없다면, 다른 host에 상주한 컨테이너 사이에는 컨테이너에 할당된 Private IP 를 이용해 native 하게 통신하게 어려우며, 대신 외부 통신과 동일하게 각 host IP로 컨테이너에 맵핑된 port 를 이용하는 방법 밖엔 없다.
- 이는 컨테이너간 통신을 빈번히 요구 하는 application 을 올리는 경우에 상당히 어려움을 겪을 수 있다.
- host 사이를 논리적으로 묶어줄 network 구조가 없다면, 결국 컨테이너 사이 통신을 위해서는 각 컨테이너가 상주한 host의 정보를 추가로 알아야만 통신이 가능하기 때문이다.
- 하지만, ECS 는 이러한 문제를 기존 서비스 중 하나로 어느정도 해소하였다. 바로 ELB 이다
- 결론 : 다수의 Docker host 를 clustering 형태로 통합 관리하기 위해 overlay network 구조를 추가하는 다른 컨테이너 orchestration 시스템들과 달리 ELB를 사용한다.
- ECS는 service 내부에 여러개의 task 가 배포될 때 ELB 의 밸런싱 그룹에 task 들이 자동으로 들어가도록 설계되어 있다.
- 즉, service 사이의 통신은 ELB를 통해 통신을 함으로서 task의 life cycle 을 유연하게 관리할 수 있게 만든 구조이다.
- 물론, 같은 service 에 속한 task 들이 다른 host에 있게 된다면 이들 사이의 통신은 여전히 어렵다는 한계는 있지만, 굳이 동일한 service 안에 동일한 task 끼리 통신할 일은 많지 않을 것이기에 큰 문제는 없을 것으로 보인다.
- ( 보통 web 서버가 was 나 DB 와 통신하지, 굳이 동일한 일을 하는 web 서버 끼리는 통신을 주고 받을 일이 없다)
- 나머지는 참고만 해도 될 듯합니다!
- 3) 하나의 Host에는 한 개의 Task만 수용 가능하다.
- 사실 ECS에서 가장 안타까운 점이라고 생각한다.
- 컨테이너가 host의 특정 port 를 점유 해야만 하는 구조는, 결국 같은 port로 서비스 하려는 컨테이너가 한 host 에 한 개 밖에 올라갈 수 없다는 의미이다.
- ECS 구조적 측면에서 보면, service 안에 task 를 올릴수 있는 최대 숫자는 cluster에 등록된 container instance 개수 이상이 될 수 없다는 것이다.
- 예를 들어, service 안에 apache 컨테이너가 정의된 task 를 2개 올리고 싶다면, 반드시 host 는 두대 이상이 필요하다는 말이다.
- 이는 컨테이너 집적도가 그만큼 낮아질 수 밖에 없는 구조적 한계이다.
- Kubernetes 의 경우 Overlay network 과 Pods / Service 라는 논리적 개념으로 이러한 문제를 해결한 것과 비교하면 아쉬운 부분임이 분명하다.
- 대신 host 마다 다른 task 들이 공존하도록 만들어 집적도를 올리는 방법이 그나마 단점을 상쇄하는 방법으로 보인다.
- 아래와 같이 Container instance 는 두 대이지만, 각각 다른 포트를 사용하는 service를 여러 개 올려 컨테이너 집적도를 높일 수 있다.
- 4) ECS 특성에 맞는 Application 설계가 필요하다.
- ECS 기반으로 Application을 잘 운영하려면, Task 와 Service 개념의 구조적 특징을 이해하고 Application을 설계 해야 한다.
- 아래는 ECS 설계적 관점에 따른 몇가지 유의 사항이다.
- 4-1) Task definition 에는 단일 Tier 속성의 컨테이너만 정의하는게 유리하다.
- 사실 Task 에는 여러 컨테이너를 정의할 수 있다.
- 하지만, 최소 배포 단위가 Task 단위 이므로 단일한 속성의 컨테이너 하나만 정의하는 게 좋은 설계 방향일 것이다.
- 예를 들어, Task definition 에 Web / WAS / DB 컨테이너를 한꺼번에 정의했다고 가정해 보자.
- 만약 task 가 하나인 상황에서는 큰 문제가 없을것이다. 하지만 task 를 추가로 늘리려고 한다면, task에 속한 Web / WAS / DB 셋이 한꺼번에 늘어나게 된다.
- 보통 서비스에 부하가 일어나면, 각 tier 별로 어떤 구간에서 스트레스를 받는지 판단 후 해당 tier 의 서버만 추가하여 LB에 넣는 방식으로 해결한다. ( = Scale-out )
- 하지만, task에 모든 tier 를 혼합시켜 구성하면 scale-out 형태의 증설은 불가능할 것이다.
- 따라서, task 의 Scale-out 구조를 고려하여 task 를 tier 단위로 분리해서 정의하는게 좋다.
- 4-2) 용도에 맞게 Container Instance 를 VPC로 구분해 사용하면 보안성을 높일 수 있다.
- 컨테이너를 올릴 host 는 EC2 를 사용함으로 EC2 에 적용되는 다양한 서비스들을 그대로 이용할 수 있다.
- 따라서 VPC 와 같은 기능을 이용하여, 컨테이너가 올라가게 될 EC2 를 구분해 사용한다면 더욱 보안성을 높일 수 있다.
- 예를 들어, Cluster A 는 외부로 노출할 Web 컨테이너들을 배포하고, Cluster B 에는 외부 노출을 하지 않는 WAS 컨테이너를 배포한다고 가정해 보자.
- 이때, Cluster A 에 속하는 EC2 instance 들은 VPC의 public subnet 에 속하도록 하고, Cluster B 에 속하는 EC2 instance 들은 VPC 의 private subnet 에 속하도록 구성할 수 있다.
- 단, private subnet 에 배포된 EC2 instance 들은 외부 통신과 단절되게 되므로, ECS 를 사용하려면 NAT Gateway 와 같은 서비스를 이용해 outbound 트래픽에 대한 처리를 추가해 주어야 한다.
- 4-3) 컨테이너 특성상 DB 와 같은 stateful 한 서버는 컨테이너 보다는 EC2 나 RDS 를 이용해 연계해서 사용한다.
- 컨테이너는 기존의 인프라 방식에 비해 생성과 소멸에 좀 더 유연하다.
- 바꿔 말하면 컨테이너는 언제든 삭제 될 수 있음을 전제로 해야 한다.
- 그러므로 data store 가 목적인 DB 는 컨테이너의 컨셉과는 상반된 형태임을 고려해야한다.
- 따라서, 컨테이너의 특성상 stateless 한 성격의 web 이나 was 서버에 이용하기를 권장한다.
- DB 의 경우 AWS의 RDS 와같은 서비스를 이용해 컨테이너와 함께 쓴다면 안전하면서도 유연한 인프라 구성을 갖출 수 있을 것으로 생각된다.
- 4-4) ECR 과 같은 컨테이너 서비스들과 연계하여 사용하면 좋다.
- AWS 에는 ECS 말고도 컨테이너 이미지 Repository 서비스인 ECR 도 서비스 하고 있다.
- 이를 ECS 와 엮어서 사용한다면 더욱 좋을 것으로 생각 된다.
- 3) 하나의 Host에는 한 개의 Task만 수용 가능하다.
- Cluster 생성 → ECR 생성 → ELB 생성 → Dockerfile 작성 또는 수정
→ Docker Image ECR에 푸시 → Task Definition -> Update Service
- Docker 를 사용하려는 사람들이 늘어나면서 컨테이너를 대규모로 운영하려는 시도가 점점 많아지고, 자연스럽게 다수의 Docker host 를 clustering 형태로 통합 관리하려는 필요성이 커지게 되었다.
실습
- 실습 요약
- ECS 작업 정의 만들기
A. 작업 정의 이름 TD-sample-web
B. 컨테이너 구성(컨테이너 이름 : containersampleapp)
- 클러스터 생성(클러스터 이름 : cluster-sample)
- 작업 실행 및 테스트
A. 작업 정의 TD-sample-web
B. 보안 설정 이름 SG-sample-web
VPC와 ELB를 이용하여 확장 가능한 웹 애플리케이션을 실습을 진행한다.
1) ECS 작업 정의 만들기
콘솔에 ECS 검색 > 작업 정의 > 새 작업 정의 생성 > "FARGATE" 선택
ECS는 크게 EC2상에서 작동하는 방식과 호스트에 대한 관리 없이 실행되는 FARGATE가 있다.
네트워크 모드는 호스트 PC와 컨테이너 간 네트워크 설정을 해줄 수 있지만 FARGATE는 호스트 PC가 없기 때문에 VPC와 직접 연결되는 AWSVPC만 사용할 수 있다.
작업 역할은 도커 인스턴스 애플리케이션을 위한 역할이며,
작업 실행은 도커 인스턴스를 게시하기 위한 역할이며,
작업 실행 역할은 로그를 기록하기 위한 역할이다.
"컨테이너 추가"를 클릭하여 아래 설정을 진행한다.
명령에는 저자가 제공한 예제 파일을 복사하여 붙여 넣었다.
이 스크립트는 따로 개발한 웹서버가 없기 때문에 테스트를 위해 제공하는 내용이다.
"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground"
설정을 다 마쳤다면 "추가"를 클릭하여 컨테이너를 생성한다.
그리고, "생성"을 클릭해 "작업 정의"를 생성한다.
2) 클러스터 생성
도커 컨테이너들을 실행할 수 있는 공간인 클러스터를 만든다.
클러스터 > 클러스터 생성 > 네트워크 전용 AWS Fargate 제공
VPC 생성에 체크표시하여 설정되는 기본값을 따르고 "생성" 버튼을 클릭
클러스터를 생성하는 과정에서 VPC와 서브넷만 설정했지만, 인터넷 게이트웨이와 라우팅 테이블도 함께 정의되었다.
클러스터 리소스 VPC 이름을 잘 기록한다.
작업 > 새 작업 실행
생성된 VPC 선택 > 서브넷은 나타나는 2개 모두 선택
자동 할당 퍼블릭은 IP는 "ENABLED" 선택되어 있으면 Fargate에 직접 IP가 할당되는 형태로 작동한다.
보안 그룹 "편집" 클릭 > HTTP의 소스가 "위치 무관" 인지 확인 후 "저장" 클릭 > "작업 실행" 클릭
우측 "업데이트" 버튼을 클릭하여 마지막 상태와 원하는 상태가 "RUNNING" 으로 변경되면 서버가 정상적으로 실행된 것이다.
상태가 계속해서 "STOPPED" 로 나타나는 오류(?)가 나타나는 경우가 있는데, 이런 경우에는 "클러스터 생성"이 아닌 "시작하기" 버튼을 클릭하여 클러스터를 생성
( 로드밸런서 유형 : Application Load Balancer , 나머지는 "다음" 클릭하여 생성 )
클러스터 생성이 완료되면 "서비스"와 "작업"에 클러스터가 생성되고, 위의 과정과 똑같이 "작업" 을 클릭하여 퍼블릭 IPv4 주소로 접속하여 확인해 볼 수 있다.
지금까지 작업 정의를 이용하여 클러스터에 도커 컨테이너를 실행시키고, 직접 컨테이너에 IP를 할당하여 웹 브라우저로 접속해보았다.
ECS로 구축한 도커 컨테이너 서비스가 잘 실행되는 것을 확인했다면, "중지"를 클릭하여 컨테이너를 중지시킨다.
실습 성공시
참고자료
https://tech.cloud.nongshim.co.kr/2021/08/30/소개-amazon-ecs란/
'기타 > AWS' 카테고리의 다른 글
AWS RDS 구축 (0) | 2021.07.10 |
---|---|
AWS에 Nginx, php, Mysql 구축 (0) | 2021.07.04 |