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"]
COPY ["./keystore", "./server.xml", "./web.xml", "/usr/local/tomcat/conf/"]
COPY ./build/libs/WEB-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/ROOT.war
|
cs |
dockerfile 기반으로 hello-world 라는 이미지를 생성하고 확인한다.
$ docker build -t hello-world .
$ docker images --filter reference=hello-world
$ docker run -p 8080:8080 hello-world
|
cs |
해당 포트의 반응이 없을 경우, 서버나 VirtualBox VM 에서 컨테이너 포트에 인바운드 트래픽이 허용되어 있는지 체크한다.
2. ECR 에 저장소 생성
이미지가 정상적으로 생성되었다면, AWS Docker Registry 인 ECR 에 푸시를 해보자.
그 전에 ECR 에 이미지를 푸시하기 위해서는 AWS cli 가 반드시 필요하다. 로그인 및 푸시 명령이 AWS cli 으로만 가능하다. 알아서 cli 를 설치한다. ㅜ
먼저 콘솔이나 cli 로 ECR 에 특정 이름의 저장소를 생성한다.
cli 를 사용할 때는 root 계정을 사용하지 말고 ECS 용 IAM 계정을 새로 생성하고 profile 에 등록하는 편이 낫다. 해당 key 로 profile 에 자격증명 및 리전 등록하는 것은 생략.
$ aws ecr create-repository --repository-name hello-world-repo
{
"repository": {
"registryId": "aws_account_id",
"repositoryName": "hello-world-repo",
"repositoryArn": "arn:aws:ecr:us-east-1:aws_account_id:repository/hello-world-repo",
"createdAt": 1505337806.0,
"repositoryUri": "aws_account_id.dkr.ecr.us-east-1.amazonaws.com/hello-world-repo"
}
}
|
cs |
콘솔을 이용하던 cli 를 이용하던 저장소를 생성하고 나면 이미지를 푸시할 주소인 repositoryUri 를 확인할 수 있다.
repositoryUri 에는 12 자리 숫자의 aws_account_id, 리전, 저장소 이름이 포함되어 있다.
3. ECR 로 이미지 푸시
저장소를 생성했으면 이미지를 푸시하면 되는데, 그러기 위해서는 푸시할 이미지를 repositoryUri 값으로 태그 지정해야 한다.
$ docker tag hello-world aws_account_id.dkr.ecr.us-east-1.amazonaws.com/hello-world-repo
|
cs |
태그 지정을 마쳤으면 푸시를 하기 전에 ECR 에 로그인 과정을 거쳐야 한다.(참 번거롭다.ㅜ)
$ aws ecr get-login --no-include-email
// aws cli v2+ $ aws ecr get-login-password --region xxxx (--profile xxx) | docker login --username AWS --password-stdin xxx(accountId).dkr.ecr.xxx(region).amazonaws.com |
cs |
위 명령을 입력하면 로그인에 필요한 명령어를 포함한 12시간 짜리 토큰이 발급된다.
docker login -u AWS -p ...base64 encoding token...very...long... https://aws_account_id.dkr.ecr.us-east-1.amazonaws.com
|
cs |
이와 같은 형태인데 이 부분을 그대로 복붙했다가는 프로세스 목록(ps) 에 토큰이 다 노출되게 되므로 패스워드 옵션(-p) 전까지만 입력하고 대화형 방식으로 토큰을 입력하던지 eval 명령을 사용한다.
$ eval $(aws ecr get-login --no-include-email)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
|
cs |
마지막으로 repositoryUri 태그가 달린 이미지를 푸시한다.
$ docker push aws_account_id.dkr.ecr.us-east-1.amazonaws.com/hello-world
|
cs |
ECS - Repositories 에서 푸시된 이미지 확인.
나중에 어떤 식으로든 자동화를 해야겠지만 일단 이렇게 번거로운 과정을 거치면 비로소 ECR 에 이미지를 푸시할 수 있게 된다. 수정된 이미지를 다시 푸시할 경우에 토큰이 만료됐다면 위 로그인 과정을 다시 거쳐야 한다.
그럭저럭 쓸만함...
WRITTEN BY
- 손가락귀신
정신 못차리면, 벌 받는다.