E-AWS KRUG 핸즈온 실습 - ECS

개요

2024-11-03(일) 진행된 2024 AWS Community Day에 진행된 핸즈온 실습 내용을 담고 있다.
https://catalog.us-east-1.prod.workshops.aws/event/dashboard/ko-KR/workshop/01-intro
위 링크는 실습 링크이나, 현재는 볼 수 없을 것이다.

설명

트랙 1 - Amazon ECS를 이용한 컨테이너 활용 완벽 실습
본 실습은 간단한 샘플앱의  컨테이너화/자동 확장 웹 애플리케이션을 빌드하고 배포합니다. 또한 컨테이너 관측성 도구를 구현하고 웹 애플리케이션에서 부하 테스트를 수행하고 결과를 모니터링합니다.

진행자

이지영

워크숍 목표

Pasted image 20241103131521.png
서비스 자체는 3개의 페이지만 있는 웹 서버.
랜딩 페이지에서 고양이와 개를 선택하여 해당 페이지로 넘어가는 방식이다.
Pasted image 20241103133723.png
각각의 애플리케이션을 직접 빌드하여 ECR에 올린다.
고양이는 Fargate에, 개는 EC2에 배포한다.
기본 세팅은 클포를 통해 이뤄진다.
Amazon CloudWatch로 모니터링하고 ASG로 오토스케일링 적용 후 테스트.
AWS CodePipline으로 CICD한다.

마지막에는 AWS Copilot을 활용해 Infrastructure As a Code를 해본다.

실습 준비

주어진 링크를 타고 들어가면 실습 계정을 받을 수 있다.
Pasted image 20241103131246.png
미리 등록해둔 이메일로 진행
Pasted image 20241103131425.png
인증된 사용자만 워크숍 스튜디오를 들어갈 수 있는 모양이다.
이번에 진행할 실습에 대한 내용이 담겨있다.

vscode 서버 구성

첫번째는 클라우드 상의 개발 환경 구성이다.
생각을 해봤는데, 많은 사람이 한꺼번에 다운로드를 받을 때 같은 와이파이를 사용하니 트래픽이 많이 걸릴 것 같아서 미리 진행했다.
Pasted image 20241103133008.png
AWS CloudFormation으로 만들 수 있게 템플릿이 있다.

먼저 시작해보려고 했는데, 권한이 없다고 한다.
확인해보니 지역이 oregon으로 되어있었다.
서울로 바꾸니까 바로 됨

다음 단계에서 ip 주소 관련으로 실패했다.
cidr를 설정하지 않는 게 이슈가 되었나,
템플릿에 그런 제한을 걸어둘 수 없다는 것은 엄청난 단점일 것이라 생각한다.
Pasted image 20241103135506.png
http://ec2-43-202-54-222.ap-northeast-2.compute.amazonaws.com:8080
아웃풋에 링크가 만들어진다.
지정한 비밀번호로 접근한다.
Pasted image 20241103135753.png
해당 vscode에서 aws 리소스에 접근할 수 있게 설정이 필요하다.
Pasted image 20241103140227.png
다음의 과정을 거쳐야 한다.
간단하게 말하자면, ec2가 쓸 롤을 만든다.
이 롤에 폴리시를 부여한다.
그다음 ec2의 인스턴스 프로필을 만들고, 이것을 롤과 연결한다.
이때 ec2인스턴스 id가 필요하다.

이것은 클포로 할 수 없었던 부분인 걸까?
이 모든 과정은 vs코드 서버에서 하는 게 아니라 클라우드쉘로 진행해야만 한다.

Pasted image 20241103140159.png
절차를 잘 수행하면 이렇게 vs코드 서버에서 명령어를 사용할 수 있게 된다.
Pasted image 20241103140417.png
이후에는 레포지토리를 다운 받고, 기본 리전 설정을 넣어준다.

ecr 설정

ecr 만들기

코드를 받았으니 이미지로 빌드해서 ecr에 올린다.
Pasted image 20241103140853.png
cli로 간단하게 ecr 3개를 만든다.

이미지 빌드

이제 실제 이미지를 빌드한다.
Pasted image 20241103140958.png
친절하게 이미 도커파일이 있다.
Pasted image 20241103141239.png
이렇게 경로를 명시해서 편하게 빌드를 진행할 수 있다.
도커파일을 보니까 어차피 내용이 거의 다 같아서, 캐시로 빠르게 수행된다.

이미지 ecr로 푸시

Pasted image 20241103141407.png
먼저 ecr에 로그인을 한다.
그다음 도커로 푸시한다.
태그로 일일히 이름을 지정해줘야만 올릴 수 있는 걸까?
이건 잘 몰랐다.

Pasted image 20241103143206.png
ecr에서는 이미지 취약점 분석을 해준다.
Pasted image 20241103143316.png
설정을 통해 향상된 스캐닝도 가능하다.
이것은 과금이 들어간다.
그리고 이것은 운영 체제와 프로그래밍 언어 패키지에 있는 취약점까지도 분석해준다고 한다.

ecs 사용

ecs 클러스터 생성

먼저 클러스터를 만들고, 모니터링을 위한 정책을 만든다.

보안 그룹 설정

첫번째는 보안그룹 생성.
alb와 클러스터에 설정해줄 보안그룹이다.
Pasted image 20241103142005.png
이건 alb를 위한 것이다.
http로 들어오는 모든 요청을 허용한다.
Pasted image 20241103142109.png
클러스터는 alb에서 오는 요청을 받을 수있게 해준다.

클러스터 생성

Pasted image 20241103142320.png
파게이트와 ec2를 전부 설정할 거라 다음과 같이 세팅한다.
여기에서 asg 설정까지 해야 한다.
ebs 크기도 100으로 지정해준다.

여기에서 실수가 있었는지 한번 실패했다.
인스턴스 롤을 새로 만들도록 설정해야 하는 듯?
Pasted image 20241103142510.png
네트워크 세팅도 필요하다.
여기에서 보안그룹 세팅을 한다.
Pasted image 20241103142546.png
컨테이너 모니터링이 가능하도록, 미리 세팅을 해둔다.
이렇게 하면 클와에서 알아서 수집한다는 것 같다.
Pasted image 20241103145913.png
이렇게 만들어지면 성공이다.
2개의 ec2가 만들어져 있다.

ecs 작업 정의

작업 정의는 서비스에서 이후에 작업으로 실행된다.
여기에서 각종 자원 정보를 설정한다.
Pasted image 20241103143451.png
자세하게는 다음과 같다고 한다.

작업 정의

Pasted image 20241103144201.png
먼저 상세 사양을 정의한다.
ec2를 사용한다.
네트워크 모드는 브릿지(이후에 물어보니 이거 awsvpc로 해도 된다고 한다).
여기에서 태스크 수행 롤을 새로 만들어야 한다.
작업정의는 json 템플릿으로도 만들 수 있으나, 이게 돼야 선행돼야 하므로 처음에는 그냥gui로 마든다.
Pasted image 20241103144325.png
다음에는 어떤 컨테이너를 띄울지 설정.
에센셜을 안 넣으면 어떻게 될까?
Pasted image 20241103144500.png
성공적으로 만들어진 모습

{
    "requiresCompatibilities": [
        "EC2"
    ],
    "family": "catsdef",
    "containerDefinitions": [
        {
            "name": "cats",
            "image": "544825632278.dkr.ecr.ap-northeast-2.amazonaws.com/cats:latest",
            "portMappings": [
                {
                    "name": "cats-80-tcp",
                    "containerPort": 80,
                    "hostPort": 0,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-create-group": "true",
                    "awslogs-group": "/ecs/catsdef",
                    "awslogs-region": "ap-northeast-2",
                    "awslogs-stream-prefix": "ecs"
                }
            }
        }
    ],
    "volumes": [],
    "networkMode": "bridge",
    "memory": "1024",
    "cpu": "512",
    "runtimePlatform": {
        "cpuArchitecture": "X86_64",
        "operatingSystemFamily": "LINUX"
    },
    "executionRoleArn": "arn:aws:iam::544825632278:role/ecsTaskExecutionRole"
}

이제 cats, dogs 작업 정의도 해준다.
여기에서 role, 이미지 url, 리전은 꼭 본인에 맞춰 커스터마이징 한다.
Pasted image 20241103144929.png
들어갈 때는 이런 묘양.
Pasted image 20241103145407.png
지역을 Seoul 이렇게 넣었다가 실수란 걸 깨닫고 다시 만들었다.
definitions에서는 그냥 해제만 되고, 새로 만들면 1이 아니라 2로 만들어진 게 확인된다.
근데 지역을 잘못 넣어도 에러를 띄우지 않아서 처음에 못 깨달았으면 어려울 뻔했다;
로깅 관련이라 옵셔널이고, 태그 설정이라 에러가 안 띄워질 수밖에 없는 것 같다.
달리 말하면 그냥 수정할 수 있는 기능을 찾았으면 삭제까진 안 해도 됐겠다.

ecs iam 롤 설정

Pasted image 20241103145813.png
iam에서 태스크실행 롤에다가 클와 접근 권한도 허용해준다.
아마 ecs쪽에서 클와로 보내는 권한인듯.
이래야 성공적으로 로깅과 모니터링이 가능할 것으로 생각된다.
Pasted image 20241103150032.png
이건 말실수인가?

ecs 서비스 실행

alb 생성

alb는 퍼블릭에 둔다.
멀티 리전 설정에서 잘 확인하자.
Pasted image 20241103150358.png
alb를 생성하며 타겟그룹도 만든다.
타겟그룹에서 인스턴스를 선택하는데, 이것은 ec2를 설정할 때 브릿지 모드를 선택해서 가능하다고 한다.
이거 따로 물어봤는데, 브릿지 모드가 아니어도 인스턴스로 설정이 가능하다고 한다.
Pasted image 20241103150600.png
타겟그룹 리뷰는 일단 건너뛰고, 이제 alb에서 타겟그룹을 선정한다.
타겟그룹은 서비스를 생성할 때 알아서 들어가게 된다.
Pasted image 20241103150656.png

서비스 생성

이제 ecs에서 서비스를 생성한다.
Pasted image 20241103150805.png
웹 자체는 ec2로 만들거니까 위에서도 그리 설정한다.
여기에서 태스크는 잡 형태로 실행하는 동작들에 대해서 사용하는 옵션이다.
Pasted image 20241103150916.png
옵션에 로드밸런서 설정을 한다.
이미 만든 녀석들이 있으니 이것들로 설정해야 한다.
리스너와 타겟그룹을 꼭 이걸로 하자.
Pasted image 20241103151035.png
서비스가 생성되고 있다.
처음에는 failed상태였으나, 프로비저닝 되면서 띄워지는 것 같다.
Pasted image 20241103151315.png
다음은 고양이 차례.
이쪽은 ec2로 하는데, 이제부터는 로밸 설정시 타겟그룹을 새로 만든다.
Pasted image 20241103151535.png
개는 파게이트로 만든다.
Pasted image 20241103151642.png
네트워크 설정이 필요하다.
Pasted image 20241103151754.png
여기도 타겟그룹을 두는데, evaluation order를 2로 설정햇다.
이게 기억 상으로 로드 밸런싱 우선 순위 설정인데
Pasted image 20241103151906.png
점차 만들어지는 게 확인된다.
보니까 만들어지는 속도는 파게이트 쪽이 훨씬 느린 것 같았다.

확인

Pasted image 20241103152122.png
다 만들어지면 alb 도메인으로 들어갈 수 있게 된다.
각각의 버튼을 눌러서 확인해봤는데, 고양이 쪽은 사진 렌더링이 느리다.
파게이트라서 그런 걸까?
아마도 다른 사이트의 이미지를 긁어 오는 걸텐데 거기에서 문제가 생기는 걸까?

아, 고양이가 느린 이유는 고양이 사진이 크기 때문이었다.
그냥 고양이쪽은 크기가 1메가 이다.
실습 준비한 사람이 고양이를 좋아하는 게 틀림 없다.

의문

혼자 하면서 들었던 의문들.
대부분 물어보면서 해결했다.

Pasted image 20241103152705.png
알아서 타겟들이 잡혔다.
또 파게이트쪽은 ip로 그룹이 잡힌 게 확인된다.
인스턴스가 아니고 노출되는 것은 ip밖에 없어서 그렇다고 한다.

인스턴스는 브릿지 모드로 해야만 이렇게 설정할 수 있는 것인가?
Pasted image 20241103153528.png
여기에서 awsvpc로 해도 가능하다고 한다.
이건 컨테이너 네트워크를 완전히 vpc 상에서 관리하겠다는 것이다.
그래서 vpc에서 ip를 받을 때 그러하듯이 모든 컨테이너에 eni가 하나씩 붙게 된다.
파게이트를 설정하면 이걸 설정할 수 없는데, 무조건 awsvpc로 설정이 된다.

eks에서의 cni와 비슷한 것인가도 궁금했는데, 그런 것과는 연관이 없다고 한다.

모니터링

이제 클와의 컨테이너 인사이트, 로그를 써보자.
파이어렌즈라는 것도 있는데 이것은 컨테이너용 로그 라우터이다.
아마 내부에 설치해서 사용하는 방식인 것 같다.

컨테이너 사이트

Pasted image 20241103154108.png
클와에 인사이트쪽 보면 있다.
Pasted image 20241103154128.png
클러스터 전체의 값도 볼 수 있다.
Pasted image 20241103154213.png
어떻게 연결됐는지도 확인된다.
리소스를 누르면 각각의 리소스에 대한 것도 확인할 수 있다.
Pasted image 20241103154348.png
태스크 별로 확인해봤다.
서비스 별로 확인해도 다르지는 않다.
개가 왜 이리 높을까?
직접 실험을 해보고는 싶은데, 어떻게 저런 상황이 나왔는지 아직 잘 모르겠다.
Pasted image 20241103155047.png
다만 내가 혼자 웹도 들어가보고 개도 들어가봤는데 이렇게 표시된다.
열심히 눌렀는데도 저정도인데, 왜 저렇게 높이 치솟았을까.

로그 그룹

Pasted image 20241103154758.png
아까 로깅 설정을 했기 에 이미 ecs 전체에 로깅이 걸린다.
Pasted image 20241103154846.png
파게이트 로그를 들어가보면 이렇게 생겼다.
Pasted image 20241103154948.png
로그 인사이트에 들어가서 쿼리를 날려보는 것도 가능

stats avg(CpuUtilized), avg(MemoryUtilized) by bin (30m) as period, TaskDefinitionFamily, TaskDefinitionRevision 
| filter Type = "Task" | sort period desc, TaskDefinitionFamily
field @timestamp, TaskId, TaskDefinitionFamily, CpuUtilized, CpuReserved, MemoryUtilized, MemoryReserved, StorageReadBytes, StorageWriteBytes

| filter (Type = "Task" and TaskDefinitionFamily = "webdef")

| sort @timestamp

| limit 20

위의 쿼리들도 날려보면서 확인해보자.

로그로 실제로 가장 많이 남게 되는 것은 컨테이너 헬스체크.
레벨 설정을 잘해서 불필요한 녀석들은 잘 걸러서 저장하게 만들어야 한다.
이런 놈들은 엄청 많으니 저장을 지양하는 게 좋다.

발표자 왈, 로그양이 많거나 모니터링이 많이 필요하다면 프메 그파나 낫다고 한다.
그러나 간단하게 볼 거면 그냥 이런 걸로 하면 편하다.
저장 기간을 무제한으로 하면 비용을 무시 못한다...
로그는 생각보다 비용이 많이 나오니 서비스니까 조심해서 사용해야 한다.

나와있는 바로.
알람 설정도 가능하다고 한다.
보관은 나중에 s3로 꼭 내보내기.
파이어렌즈를 통해 로그를 라우팅해서 저장 분석할 수 있다고 한다.

오토스케일링

두가지 스케일링이 있다.
서비스에 대해서, 클러스터에 대해서
Pasted image 20241103155526.png
예전에 이거 궁금했는데 내용이 있다.

서비스 오토스케일링

웹 서비스를 누르고, 업데이트를 누른다.
Pasted image 20241103155756.png
옵셔널 설정에서 오토스케일링 하기
Pasted image 20241103155915.png
여기에서 각종 설정을 넣는다.
타겟별 alb 리퀘스트량을 본다.
10개의 요청이 들어가면 스케일링 하는 건가.

wget https://hey-release.s3.us-east-2.amazonaws.com/hey_linux_amd64
chmod 755 hey_linux_amd64 
sudo mv hey_linux_amd64 /usr/local/bin/hey

vs코드에 들어가서 이걸 설치한다.
부하 테스트를 주는 녀석이다.

hey -z 10m http://demogo-alb-367108384.ap-northeast-2.elb.amazonaws.com/

Pasted image 20241103160748.png
부하를 주어서 설정하려는 알람은 이 녀석이다.
Pasted image 20241103160939.png
부하를 걸자 이렇게 바뀌었다.
Pasted image 20241103161342.png
나는 빨간 줄을 넘는 게 문제라고 생각했는데, 어느 순간에 갑자기 alarm 상태로 바뀌었다.
Pasted image 20241103161446.png
ecs의 서비스 이벤트에 다음과 같은 내용이 찍힌다.
desired state도 8개로 바뀌었다.
Pasted image 20241103161551.png
근데 왜 6개만 켜졌을까?
Pasted image 20241103161726.png
6개만으로 충분했다는 뜻일지도 모르겠다.
Pasted image 20241103162013.png
근데 다음 거 진행하는 와중에 또 스케일링이 일어났다.
역시 오토스케일링은.. 속도가 매우 느린 것 같다.
ecs쪽에서도 이런단 말인가.

클러스터 오토스케일링

Pasted image 20241103161847.png
이번엔 인프라 쪽에서 업데이트를 진행한다.
Pasted image 20241103161923.png
이쪽 설정을 해준다.
근데 나는 그냥 되어있던데, 디폴트인가?
Pasted image 20241103162237.png
이후에는 서비스에 들어가 다시 수정한다.
force를 먼저 한다.
Pasted image 20241103162255.png
그리고 해당 블록에서 compute options 설정을 한다.
인프라 관련 설정을 한 것에 대해 적용을 하는옵션인 것 같다.

이후에는 asg에 가서 max를 4로 바꾼다.
그리고 cooldown 값도 10으로 수정한다.
빠르게 스케일링 확인을 하기 위해서ㄷ이다.

cicd

깃헙 연결

sudo dnf install 'dnf-command(config-manager)' -y
sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
sudo dnf install gh --repo gh-cli -y

vscode 인스턴스에서 진행
Pasted image 20241103162742.png
하고 gh auth login하면 이렇게 세팅이 가능하다!
신기..
Pasted image 20241103162840.png
해당 방법을 사용하니 웹으로 로그인하고, 폰으로 인증하고 뭔가 뚝딱 했다.
Pasted image 20241103163017.png
그럼 이렇게 cli로 github에 레포지토리 만들고, 그걸 가져올 수 있게 된다.. ㄷㄷ
Pasted image 20241103163100.png
레포지토리가 성공적으로 만들어졌다.

코드 파이프라인 설정

Pasted image 20241103163259.png
개 레포에서 이렇게 파일을 넣어준다.
리전과 aws 계정은 명시해서 넣어준다.
그리고 푸시
Pasted image 20241103163727.png
그다음에는 파이프라인을 하나 만든다.
이쪽이 생각보다 과정이 많다.
간단하게는 깃헙과 연동하는 과정이다.
Pasted image 20241103163823.png
과정이 또 많다.
빌드 제공자를 코드 빌드로 정한다.
Pasted image 20241103163928.png
그럼 코드빌드 프로젝트를 하나 만들어야 한다.
추가 설정칸에서 privileged는 넣다.
그리고 아래에서 buildspec은 깃헙에 올린 그 파일 이름을 지정한다.
Pasted image 20241103164129.png
설정할 게 많다.
이제 디플로이될 녀석이 무엇인지 지정한다.
우린 ecs의 dogs를 배포할 것이다.
Pasted image 20241103164311.png
막상 해보면 이 단계에서 실패한다.
Pasted image 20241103164345.png
권한이 없기 때문으로, 코드 빌드 롤에 ecr에 접근권한을 주자.
Pasted image 20241103164543.png
처음 파이프라인을 만들었을 때는 실패했지만..
Pasted image 20241103164635.png
다음 놈은 잘 되는 게 확인된다.
참고로 도그 레포지토리의 index.html 파일을 조금 수정했다.
근데 이것도 생각보다 시간이 오래 걸린다.
Pasted image 20241103164820.png
상태를 보니 롤링 업데이트를 하고 있는 것 같다.
Pasted image 20241103164848.png
중간에 해보니까 버전이 번갈아 나오기는 햇다.
Pasted image 20241103165142.png
여기 보니까 무려 4분의 시간이 걸렸다.
왜 이렇게까지 시간이 걸린 것일까?
이 부분은 aws에서 확인 절차를 거치기 때문에 그렇다고 한다.
이것은 eks와 비교했을 때 확실히 아쉬운 부분이라고 할 수 있을 것 같다.

파게이트도 시간은 비슷하게 걸린다는 듯.
그래도 프로비저닝 시간이 오래 걸린다는 점은 있다.
그럼 파게이트는 비용도 비싸고, gpu도 못 쓰고, 시간도 오래 걸리는 놈이라는 것이다..
심지어 파게이트도 결국 인스턴스를 활성화시켜서 사용하는 개념이라 최소 단위가 존재하기까지 한다.
작은 작업을 잠깐 쓸 때는 조금 의미가 있지 않을까 싶다.

정리

코드 파이프라인을 통해 cicd를 진행할 수 있다.
Pasted image 20241103170706.png
여기에서 각각의 상태를 지정할 수 있는데,
간단하게 파이프라인 쪽에서 전체를 설정할 수 있다.
소스의 경우에는 현재 깃헙으로 연결해두었다.
빌드의 경우에는 일단 프로젝트를 만들기는 했다.
근데 ec2를 사용하도록 지정했고, 깃헙에 있는 buildspec파일을 지정했다.
디플로이는 ecs로 되도록 지정했다.

https://docs.aws.amazon.com/codepipeline/latest/userguide/approvals.html
이걸로 추가 절차를 부여할 수 있다고 한다.

마무리

일단 여기에서 실습 작업은 끝이 난다.
추가 과제로 iac를 진행해볼 수도 있따.
이건 집에 가면서 해보면 좋을 것 같다.

추가 사항 구현 - IaC