2022년 전에 정리한 문서들
ECS CI/CD Workshop 정리(3) - Rolling Deploy
반가운사람2
2022. 8. 23. 20:55
반응형
이 실습에서는 스테이징 환경에서 실행되는 ECS 서비스에 애플리케이션 코드 변경 사항을 배포하는 데 사용할 수 있는 파이프라인을 구축합니다.
구축 환경 설명
URL에 대한 GET http://<path-to-service>/hello/Bob"Hi Bob" 메시지를 표시하는 HTML 페이지를 반환합니다.
실습 단계 요약
- 1단계: 도커 이미지를 호스팅할 Amazon ECR 리포지토리를 생성합니다.
- 2단계: 애플리케이션 코드를 저장할 AWS CodeCommit 리포지토리를 생성합니다.
- 3단계: 소스 리포지토리를 준비합니다.
파이프라인을 빌드하려면:
- 4단계: ECS 작업을 위한 CloudWatch Log Group을 생성합니다.
- 5단계: ECS 작업 정의를 생성합니다.
- 6단계: ECS 서비스를 생성합니다.
- 7단계: CodeBuild 프로젝트 종속성을 생성합니다.
- 8단계: 파이프라인을 생성합니다(CodeBuild 프로젝트 포함).
파이프라인이 생성되면:
- 9단계: 파이프라인 실행을 관찰합니다.
- 10단계: 서비스를 테스트합니다.
- 11단계: 변경 사항을 커밋하고 서비스에 푸시하여 파이프라인을 다시 트리거한 다음 다시 테스트합니다.
1. 도커 이미지를 호스팅할 Amazon ECR 리포지토리를 생성합니다.
save_var IMAGE_REPO_URI $( \
aws ecr create-repository \
--repository-name hello-server \
--query repository.repositoryUri \
--output text \
)
echo Repo URI: $IMAGE_REPO_URI
#확인
aws ecr describe-repositories --repository-name hello-server
2. 애플리케이션 코드를 저장할 AWS CodeCommit 리포지토리를 생성합니다.
save_var SRC_REPO_URL $( \
aws codecommit create-repository \
--repository-name hello-server \
--query repositoryMetadata.cloneUrlHttp \
--output text \
)
echo New repo created at $SRC_REPO_URL
#확인
aws codecommit get-repository --repository-name hello-server
3. 소스 리포지토리를 준비합니다.
#리포지토리 접근
cd ~/environment
mkdir hello-server
git clone $SRC_REPO_URL hello-server
#출력
Cloning into 'hello-server'...
warning: You appear to have cloned an empty repository.
#CodeCommmit 리포지토리를 사용하여 로컬 리포지토리를 자동으로 설정
cd hello-server
git remote -v
#출력
origin https://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/hello-server (fetch)
origin https://git-codecommit.ap-northeast-2.amazonaws.com/v1/repos/hello-server (push)
#Hello-server App의 Source File를 Local 리포지토리에 복사
cp ~/environment/cicd-for-ecs-workshop-code/app/hello-server/* .
#Dockerfile 수정합니다.
sed -i 's%node\:buster-slim%public.ecr.aws/wizriz/node\:buster-slim%' Dockerfile
cat Dockerfile
#image 저장소 URI로 buildspec을 추가합니다.
cp ~/environment/cicd-for-ecs-workshop-code/lab-1/buildspec-hello-server.yml ./buildspec.yml
#이미지 저장소에 대한 올바른 URI로 파일을 업데이트
sed -i "s%<IMAGE_REPO_URI>%$IMAGE_REPO_URI%" buildspec.yml
#확인 -> cat buildspec.yml
#buildspec.yml 파일 부분에서 중요한 부분은 post_build단계에서 magedefinitions.json 파일을 생성한다는 점을 중요시합니다.
#완료되면 소스 파일을 커밋하고 푸시합니다.
git add .
git commit -m "First commit"
git push -u origin master
- Codecommit 확인
- markdown File을 사용해서 아래 Docker Build 방법을 Codecommit에 표시할 수 있습니다.
4. ECS 작업을 위한 CloudWatch Log Group을 생성합니다.
#/ecs/hello-server LogGroup 생성
aws logs create-log-group --log-group-name /ecs/hello-server
5. ECS 작업 정의를 생성합니다.
#제공된 JSON 템플릿을 사용하여 작업 정의를 생성! > envsubst는 환경 변수의 값을 대체합니다
cd ~/environment
mkdir lab-1
cd lab-1
envsubst < ~/environment/cicd-for-ecs-workshop-code/lab-1/task-definition-hello-server.json.template > task-definition.json
cat task-definition.json
#작업 정의 등록
aws ecs register-task-definition --cli-input-json file://task-definition.json
1. 이미지는 1단계에서 만든 ECR 리포지토리를 참조
2. 로그 그룹은 이전 단계에서 생성한 Cloudwatch Logs Group을 참조합니다.
3. 포트 매핑은 TCP 컨테이너 포트 80을 노출합니다.
6. ECS 서비스를 생성합니다.
#먼저 ECS Service에 대한 ALB Target Group을 생성
save_var STAGING_VPC $( \
aws cloudformation describe-stacks \
--stack-name staging-cluster \
--query "Stacks[0].Outputs[?OutputKey == 'VpcId'].OutputValue" \
--output text \
)
save_var STAGING_TARGET_GROUP_ARN $( \
aws elbv2 create-target-group \
--name hello-server-tg \
--port 80 \
--protocol HTTP \
--health-check-path /ping \
--health-check-timeout-seconds 3 \
--health-check-interval-seconds 5 \
--healthy-threshold-count 2 \
--target-type instance \
--vpc-id $STAGING_VPC \
--query "TargetGroups[0].TargetGroupArn" \
--output text \
)
aws elbv2 modify-target-group-attributes \
--target-group-arn $STAGING_TARGET_GROUP_ARN \
--attributes "Key=deregistration_delay.timeout_seconds,Value=5"
#리소스 경로로 HTTP 요청을 라우팅해야하기떄문에 ALB 리스너에 /hello/* 규칙을 추가합니다.
cat <<EoF >conditions-pattern.json
[
{
"Field": "path-pattern",
"PathPatternConfig": {
"Values": ["/hello/*"]
}
}
]
EoF
cat <<EoF >actions.json
[
{
"Type": "forward",
"ForwardConfig": {
"TargetGroups": [ { "TargetGroupArn": "${STAGING_TARGET_GROUP_ARN}" } ]
}
}
]
EoF
save_var STAGING_LISTENER_ARN $( \
aws cloudformation describe-stacks \
--stack-name staging-cluster \
--query "Stacks[0].Outputs[?OutputKey == 'PublicListener'].OutputValue" \
--output text \
)
save_var STAGING_LISTENER_RULE_ARN $( \
aws elbv2 create-rule \
--listener-arn $STAGING_LISTENER_ARN \
--priority 10 \
--conditions file://conditions-pattern.json \
--actions file://actions.json \
--query "Rules[0].RuleArn" \
--output text \
)
#제공된 JSON 템플릿을 사용하여 스테이징 서비스 사양을 생성
envsubst \
< ~/environment/cicd-for-ecs-workshop-code/lab-1/service-hello-server.json.template \
> staging_service.json
cat staging_service.json
#ECS Service Create
aws ecs create-service --cli-input-json file://staging_service.json
- 로드 벨런서 생성확인
- ECS Service 생성확인
처음에는 계속 Service에 Task가 실행이 실패됩니다. 이유는 아직 ECR에 Image를 Push하지 않았기 때문입니다. 즉, Codepipeline을 구축해서 이 문제점을 해결하도록 하겠습니다.
7. CodeBuild 프로젝트 종속성을 생성합니다.
#Codebuild Log Group Create
aws logs create-log-group --log-group-name /codebuild/hello-server
#Codebuild 프로젝트에 대한 IAM 역할 생성
cat <<EoF > codebuild_trust_policy_doc.json
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EoF
#AmazonEC2ContainerRegistryPowerUser정책을 Codebuild Role에 적용합니다.
save_var CODEBUILD_ROLE_NAME Cloud9-CodeBuild-Role-$(date +%s)
save_var CODEBUILD_ROLE_ARN $( \
aws iam create-role \
--role-name $CODEBUILD_ROLE_NAME \
--assume-role-policy-document file://codebuild_trust_policy_doc.json \
--query Role.Arn \
--output text \
)
aws iam attach-role-policy \
--role-name $CODEBUILD_ROLE_NAME \
--policy-arn arn\:aws\:iam::aws\:policy/AmazonEC2ContainerRegistryPowerUser
8. 파이프라인을 생성합니다(CodeBuild 프로젝트 포함) Console을 이용합니다.
- 먼저 Codepipeline Console(console.aws.amazon.com/codepipeline )에 이동합니다. 그런다음 파이프라인 생성을 선택합니다. 그 후, 아래와 같이 설정합니다. 다음을 선택합니다.
- 마찬 가지로 아래와 같이 설정합니다. 다음을 선택합니다.
- 빌드 공급자에서 Codebuild를 선택한다음 프로젝트 생성을 선택합니다.
- 빌드 프로젝트 이름을 입력합니다.
- 환경을 설정합니다. 아래와 같이 설정해주세용!! IAM은 아까 전에 생성한 Codebuild IAM을 선택합니다.
- 이제 맨 아래 Cloudwatch 부분을 설정합니다.
- CodePipeline으로 계속을 선택합니다.
- Codebuild 생성을 확인을 합니다.
- 배포 단계에서 공급자 배포 중 Amazon ECS를 선택 후 Cluster Name, Service Name을 선택한 후 나머지 필드는 비워둡니다.
- 생성 합니다!! Codepipeline이 성공적으로 실행되신 것을 확인할 수 있습니다.
- 그럼 이제 ECS Service Task가 실행되고 있고 Service에 작업 정의에 Version은 2인 것을 확인합니다.
- Curl 테스트
save_var STAGING_ALB_URL $( \
aws cloudformation describe-stacks \
--stack-name staging-cluster \
--query "Stacks[0].Outputs[?OutputKey == 'ExternalUrl'].OutputValue" \
--output text \
)
curl $STAGING_ALB_URL/hello/bob
9. 마지막 단계입니다. 변경 사항을 커밋하고 서비스에 푸시하여 파이프라인을 다시 트리거한 다음 다시 테스트합니다. 이게 바로 CI/ CD에 꽃입니다. 코드가 업데이트 되자마자 CodePipeline은 감지하고 바로 코드를 수정합니다.
cd ~/environment/hello-server
vi server.js
#Hi Thtre을 Hello로 변경합니다.
#변경사항 Commit -> Push
cd ~/environment/hello-server
git add -u
git commit -m "Changed greeting"
git push origin master
10. curl를 통해 응답이 바뀐 것을 확인합니다.
반응형