프로필사진

Go, Vantage point

가까운 곳을 걷지 않고 서는 먼 곳을 갈 수 없다.


Github | https://github.com/overnew/

Blog | https://everenew.tistory.com/





티스토리 뷰

반응형

 

 

 

 

 

이전 글에서는 EC2에 동작하는 프로세스를 대상으로 CI/CD를 구현하였다.

https://everenew.tistory.com/419

 

AWS CodePipeline 구성하기 (commit, build, deploy)

CodeCommit, CodeBuild, CodeDeploy를 세팅하고 전체를 하나의 플로우로 구성해 주는 CI/CD 서비스인 CodePipeline을 구성해 보자. 이번 실습에서 업데이트의 대상이 되는 것은 Private subnet에서 autoScaling 되는 Web

everenew.tistory.com

 

컨테이너 실행을 위해 ECS를 사용한다면,

code deploy가 없어도 ECS 자체가 code pipeline의 배포 요소로 사용 가능하다.

컨테이너 환경으로의 배포를 간단하게 구성할 수 있게 된다.

 

EKS는 code deploy 서비스로 지원이 되지 않기 때문에 다른 3-party deploy도구를 사용해야 한다.

 

 

 

 

stack으로 세팅된 기본 구성

 

 

 

cloud9에서 다음 명령어로 AWS CLI 자동 완성 기능 설치

which aws_completer

export PATH=/usr/local/bin:$PATH

source ~/.bash_profile

complete -C '/usr/local/bin/aws_completer' aws

 

 

 

 

 

 

작업을 위한 Cloud9 세팅

 

개인 PC에서도 진행할 수 있지만, 

aws 서비스와 연결이 쉬운 Cloud9을 사용해 보자.

 

 

 

cloud9의 ec2를 위한 role 생성

 

 

ECR과 S3 두 가지 권한을 부여한다.

 

 

 

cloud9의 EC2에 해당 role을 부여한다.

 

 

'

이와 같은 작업으로 ECR과 S3로 접근하는 권한이 부여된 EC2위에서 Cloud9이 동작하게 된다.

(ECR도 결국 S3에 저장되기 때문에 S3 권한도 필요하다.)

 

 

 

cloud9의 Preference로 들어가자.

AWS Setting에서 Credential을 비활성화한다.

(기본적으로 적용된 자격 증명을 비활성화)

 

 

 

#기존 자격 증명 정보를 삭제 

rm -vf ${HOME}/.aws/credentials

 

# 지정한 role 정보를 다시 받아오기

aws sts get-caller-identity

 

 

 

 

ACCOUNT_ID와 AWS_REGION를 환경변수로 저장한다.

 

export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)

export AWS_REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/region)

 

 

환경 변수를 저장한다.

 

echo "export ACCOUNT_ID=${ACCOUNT_ID}" | tee -a ~/.bash_profile

echo "export AWS_REGION=${AWS_REGION}" | tee -a ~/.bash_profile

 

 

 

자격 증명 정보가 아래와 같이 확인된다.

 

aws configure set default.region ${AWS_REGION}

aws configure --profile default list

 

 

 

 

 

 

Amazon ECR에 컨테이너 이미지 저장

 

 

web server container에 필요한 파일을 준비하고, docker file로 빌드해 보자.

 

 

dockerfile의 내용은 다음과 같다.

 

 

이 파일을 토대로 빌드한다.

 

docker build -t front-web .

 

 

이렇게 3가지 이미지를 빌드해서, 각각 ALB의 URL path에 따라서 다른 web container에 접속하도록 만들 것이다.

 

 

 

ECR 리포지토리 생성 & 업로드

 

이제 ECR에 리포지토리를 생성해서 업로드하자.

aws ecr create-repository --repository-name <리포지토리 이름> --image-scanning-configuration scanOnPush=true --region ${AWS_REGION}

 

생성된 repository의 정보

 

 

 

ECR 레지스트리에 현재 작업자를 인증한다.

aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

 

 

 

 

docker tag <빌드한 이미지>:latest ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/<리포지토리 이름>:latest

docker push ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/<리포지토리 이름>:latest

 

 

 

업로드된 Container 이미지가 확인된다.

 

 

 

AWS ECS 클러스터 생성

 

 

ECS 클러스터는 K8S의 클러스터와 유사하다.

K8S의 클러스터 작업자 노드를 묶는 단위로, ECS 클러스터도 컨테이너가 배치될 인스턴스의 그룹을 관리한다.

 

우리는 고가용성을 위해서 두 개의 AZ에 걸쳐 클러스터를 생성하자.

 

 

 

EC2를 선택하자.

컨테이너들이 충분히 생성될 수 있도록, m5.large로 선택해 주었다.

이러한 인스턴스들이 자동으로 autoScaling 되게 auto scaling Group이 생성된다.

 

일단은 두 개의 AZ에 하나씩 배치하기 위해 2개만 설정한다.

 

 

 

 

모니터링도 활성화시켜서 이후에 지표를 확인해 보자.

 

 

이렇게 생성해 준다.

 

 

 

 

이제 EC2에서 확인해 보면, 클러스터에 의해 생성된 인스턴스들이 확인된다.

 

 

Auto Scaling 그룹과 시작 템플릿 또한 자동으로 생성된다.

 

 

 

 

클러스터 EC2 SG 생성

 

 

이제 클러스터의 EC2를 보호하는 SG를 만들자.

 

 

 

 

 

LoadBalancer는 HTTP를 수신한다.

 

클러스터의 EC2는 위의 LB의 SG로의 inbound만 허용한다.

 

 

 

이미 생성된 시작 템플릿 변경을 위해 수정을 해주자.

 

 

 

보안 그룹만 새롭게 설정해 주자.

 

 

이제 변경사항을 적용하기 위해 Auto Scaling 그룹에 시작 템플릿 버전을 수정한다.

 

 

 

 

적용을 바로 시키려면, auto scaling 그룹에서 인스턴스를 새로고침 시키면 된다.

 

 

 

 

이제 클러스터 인스턴스에도 변경된 SG가 적용된다.

 

 

 

 

AWS ECS Task 정의

 

ECS의 Task는 k8s의 pod와 유사하게, 여러 컨테이너의 들이 내부에서 동작할 수 있다.

yaml로 파드를 정의한 k8s처럼, ECS에서는 Task Definition을 작성해 주면 된다.

 

 

 

 

 

EC2를 선택하면, 여러 가지 네트워크 모드가 지원되지만 Fargate는 awsvpc 모드만 가능하다.

 

bridge 모드

태스크가 Docker의 기본 제공 가상 네트워크를 사용하며, 이 네트워크는 각 컨테이너 인스턴스 내에서 실행된다.

 

awsvpc 모드

태스크에 ENI가 할당되며 서비스를 만들거나 태스크 정의로 태스크를 실행할 때, 네트워크 설정을 해야 한다.

 

 

 

컨테이너 이미지의 URI에는 ECR의 리포지터리의 링크를 주면 된다.

:latest 태그도 빼먹지 말자.

 

 

웹 서비스이므로 포트를 열어준다.

 

이대로 생성하면 된다.

 

 

 

 

다른 컨테이너 태스크는 fargate로 만들어보자.

fargate는 awsvpc만이 가능하다.

 

 

 

이렇게 3가지 컨테이너들의 태스크 정의를 완성해 주자.

 

 

기본적으로 적용되고 있는 Task실행 role에 CloudWatch Logs 권한을 추가해 주자.

 

 

 

 

cloudWatch의 권한을 추가한다.

 

 

 

 

 

ALB와 대상그룹 생성

 

일단 ALB의 트래픽을 전달할 기본 대상 그룹을 생성한다.

 

 

별다른 세팅 없이 VPC만 동일하게 만들어 준다.

 

이번에는 로드밸런서를 만들어서, ALB를 public subnet과 연결한다.

 

 

앞서 만든 LB의 보안그룹을 적용한다.

 

 

대상 그룹은 위에서 만든 것을 바로 적용한다.

 

 

 

ECS Service 구성

 

Service는 Task라는 단위를 관리하기 위해 사용한다.

Task가 클러스터 내부에서 원하는 개수만큼 동작하도록 만들 어 줄 수 있고, 이를 통해서 특정 태스크가 fail이 돼도 다시 개수만큼 실행되도록 재생성해 준다.

또한 k8s 서비스와 같이 특정 트래픽을 전달시킬 수 있다.

 

 

 

 

EC2로 설정한 태스크를 위해 service 시작 유형을 EC2로 생성한다.

 

 

 

 

태스크에서 우리가 생성해 둔 태스크를 선택할 수 있다.

태스크 수를 2개로 설정한다.

 

 

 

로드밸런서는 우리가 만든 LB를 선택한다.

 

 

이대로 생성하면 두 개의 task가 실행된다.

 

 

 

 

나머지 컨테이너에 대한 서비스도 생성한다.

 

다른 데스크들은 위와 동일하지만 새로운 대상 그룹으로 생성한다.

이를 통해 특정 경로의 접근을 해당 대상 그룹(태스크들)로 보내줄 수 있다.

 

 

 

또한 fargate로 태스크를 정의한 aws 태스크에 대해서는 fargate로 생성해 준다.

 

 

awsvpc 모드이기 때문에 VPC는 다음과 같이 설정한다.

 

fargate의 awsvpc 모드로 인해 ALB의 연결 호환이 되지 않는다.

 

 

다음과 같이 새로 만들어 준다.

 

 

 

awsvpc 네트워크 모드를 사용하는 태스크는 EC2 인스턴스가 아닌 ENI와 연결되기 때문에 IP를 대상으로 해야 한다.

 

 

 

각 서비스들이 활성화된 모습

 

 

 

이제 LB의 리스너 규칙이 각 대상 그룹(각각의 태스크)으로 나타나 있다.

 

 

 

이 LB의 주소로 접근하자.

 

 

 

하단의 이미지들을 누르면 각각의 서비스로 이동된다.

(LB 주소/aws/ 는 aws 컨테이너들로 전송됨.)

 

 

 

 

 

 

ECS CI/CD 적용하기

 

 

code commit 리포지토리를 생성해 주자.

 

 

 

아래와 같은 링크이다.

https://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/myweb

 

 

 

작업을 할 cloud9의 역할에 code commit의 접근 권한을 추가해 주자.

 

 

 

 

 

cd ~/environment/ecsdemoapp/mzc     #작업 폴더로 이동

git config --global user.name "username"

git config --global user.email "email"

 

# 초기화 

git init -b main

git remote add origin https://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/myweb

 

 

# commit후 push

git add *

git commit -m "Initial commit"

git push -u origin main

 

 

레포지토리에서 확인이 된다.

 

 

 

 

이제 파이프라인을 만들어서 전체적인 CI/CD를 자동화해보자.

 

 

 

 

 

소스는 방금 작업한 code commit 리퍼지토리이다.

 

 

 

 

Build는 아래처럼 만든다.

 

 

 

 

 

 

buildspec.yaml 을 사용해서 빌드하도록 세팅하자.

 

 

 

생성을 완료하면 생성된 build 프로젝트가 선택된다.

 

 

 

 

배포는 ECS의 클러스터에서 수행하도록 만들 수 있다.

 

이대로 파이프라인을 생성한다.

 

 

build의 역할에 권한을 추가해 주자.

 

 

 

ECR에 접근하기 위한 권한을 추가해 주었다.

 

 

 

 

이제 build에 필요한 build spec 파일을 레포지토리의 최상위 경로 생성해 주자.

 

 

웹 데이터도 조금 바꾸어 주었다.

 

 

docker file의 이미지 경로도 ecr을 사용하게 바꾸어 본다.

 

 

 

변경점을 업로드한다.

 

 

 

업로드 시에 소스의 변경을 감지한 code pipeline에 의해 자동으로 ci/cd가 진행된다.

 

 

 

 

 

빌드 완료 시 새로 빌드된 이미지가 보인다.

 

 

 

배포까지 완료되면 접근 시 업데이트가 반영된 것이 확인된다.

변경한 Version2가 보인다.

 

 

 

 

ECS Task auto scaling 구성

 

웨트래픽이 많아지면, task 개수를 더 늘리는 Task를 대상의 auto scaling이 필요하다.

따라서 서비스를 update 한다.

 

 

스케일 정책에서 최대 태스크 개수를 8로 늘려주고, 조정 정책의 대상이 ALB의 요청 개수가 되도록 설정한다.

 

 

 

 

부하 테스트

 

눈으로 Task 개수가 늘어나는 것을 확인하기 위해 cloud9에 부하 테스팅 툴을 설치한다.

 

sudo yum -y install siege

 

siege는 웹 서비스 성능 테스트할 수 있는 부하 생성 툴이다.

(자신의 서비스가 아니면, Dos 공격을 하는 게 되는 것이므로 주의하자..)

 

 

 

아래의 명령어로 부하를 진행한다.

 

siege -c 200 -i <LB의 주소>

 

 

 

이에 대해서 CloudWatch의 경보가 발생한다.

 

 

 

 

 

이제 부하에 따라 auto scaling이 되므로, 메인 페이지를 담당하는 front-web 태스크의 개수가 늘어난다.

 

 

 

 

 

 

클러스터 AutoScaling

 

최대 개수로 제시한 8개까지 늘어나지 않는 이유는 클러스터의 EC2에 리스소 한계가 있기 때문이다.

이를 위해서는 클러스터 오토스케일링을 적용해서 컨테이너가 동작할 클러스터 인스턴스를 개수에 오토스케일링을 적용한다.

이로 인해 수요에 맞춰 scale in/out 할 수 있게 된다.

 

 

클러스터 업데이트를 누르자.

 

 

인프라의 용량 공급자(클러스터 생성 시 자동 생성됨)를 업데이트한다.

 

 

조정 정책에서 조정이 켜진 것을 확인해 주자.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

서비스 업데이트 진행한다.

 

 

 

시작 유형에서 용량 공급자로 변경해 준다.

 

 

 

생성된  Auto Scaling 그룹도 편집해 주자.

 

 

 

클러스터 인스턴스 개수가 최대 4개까지 생성되도록 만들어주자.

 

 

 

 

휴지 기간 10초로 설정하면 빠르게 결과를 볼 수 있다.

 

 

 

다시 cloud9에서 부하를 주면

이제 컨테이너 인스턴스도 증가된다.

2개에서 3개로 늘어 났다.

 

 

 

반응형
댓글
반응형
인기글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함