진짜 개발자
본문 바로가기

Software Engineering/CICD (jenkins, etc)

CICD - Codedeploy란? (Codedeploy를 이용한 자동배포(CD) 환경 구축하기)

728x90
AWs CodeDeploy란

이번 포스팅에서는 AWS의 배포서비스인 Code Deploy에 대해서 알아보도록 하겠습니다.

 

 

Code deploy란?

CodeDeploy는 SourceCode를 운영환경에 자동 배포하는 역할을 수행하는 AWS Service입니다. 즉, CD 지속적 배포 서비스입니다.

 

CodeDeploy의 배포대상은, EC2, ECS, Lambda등 여러가지가 존재하지만 이번 포스팅에서는 EC2에 배포하는 방법을 알아보도록 하겠습니다.

 

 

 

 

Code deploy의 구성

 

 

에이전트

ec2에 설치하는 프로그램으로, CodeDeploy에서 해당 ec2를 사용할 수 있도록 하는 프로그램입니다. ec2이외의 배포환경에는 필요하지 않습니다.

 

에이전트는 , 어플리케션 개정, 배포기록, 배포스크립트 등을 EC2의 루트 디렉토리에 저장합니다. Amazon Linux, Ubuntu server, RHEL 인 경우, /opt/codedeploy-agent/deployment-root 에 위치합니다.

 

 

 

 

Code Deploy 과정

우선 codedeploy를 이용하기전 우리가 기존 자동화를 하지 않았을때의 배포 과정은 아래와 같습니다.

  1. 어플리케이션 개발
  2. 어플리캐이션 테스트 및 빌드
  3. 실제 운영환경에 전송
  4. 운영환경에서 기존 실행중이던 프로그램 종료
  5. 새 버전의 프로그램 실행

 

이중 우리가 code deploy를 이용해 자동화 하고자 하는 부분은 3~5 입니다.

 

 

우리가 구축할, 환경은 위 그림과 같습니다. 가용성 보장을 위해서 배포중 최소 한대 이상의 서버가 서비스 가능한 상태를 유지하기를 원합니다. 따라서 EC2 2대를 이용할 것입니다.

 

  • 우선 배포할 소스와 appspec(배포 과정이 정의된 스크립트 정로로 이해하시면 됩니다.)를 압축하여, S3 또는 GitHub에 업로드합니다
  • 배포 대상 서버(EC2, Labmda 등)에서 Source가 다운로드 됩니다.
  • 그 다음 같이 압축했던 appspec 파일에 정의된대로, 배포 라이프사이클에 맞추어 스크립트를 실행합니다.
  • 배포가 완료됩니다.

 

 

 

 

Code deploy를 이용해 자동 배포 환경 구축

 

 

 

1. IAM ROLE 생성

Code deploy 환경 구축에 사용될, code deploy와, EC2에서 사용할 ROLE을 만듭니다.

 

1.1 ec2 role 만들기

IAM 서비스에서 역할 -> 역할만들기로 이동합니다.

 

유형에서 AWS서비스 -> 사용사례 EC2 를 선택합니다.

 

EC2는 code deploy에 의해서, S3로부터 어플리케이션을 가져오도록 지시를 받습니다. 따라서 EC2는 S3에 접근할 권한이 필요합니다.

 

적절한 이름을 부여합니다.

 

 

1.2 code deploy role 만들기

마찬가지로, 역할만들기로 이동한 후, AWS 서비스 -> 사용사례:codedeploy를 선택합니다.

 

Codedeploy의 경우 연결된 정책이 이미 존재하기 때문에, 별도로 추가를 하지 않아도 됩니다.

 

 

적절한 이름을 부여합니다.

 

 

2. 배포 대상 EC2서버 생성

code deploy에서, 새로운 어플리케이션을 배포할 ec2 서버들의 환경을 구축합니다.

 

우선 AmazonLinux 2로 인스턴스를 생성합니다.

 

2.1 인스턴스 구성의 사용자 데이터를 이용해 code deploy 에이전트 설치

codedeploy에서 ec2를 사용하기 위해서는 ec2에 codedeploy-agent가 설치되어 있어야합니다. 또한 추후 배포된 소스코드 실행을 위해서는 jdk가 필요합니다.

 

ec2 인스턴스 구동후 설치를 별도로 해도 되지만, ec2생성시 콘솔에서 사용자 데이터에 실행할 셸 명령어를 입력할수 있습니다. 이곳에서 설치 명령어를 입력합니다.

 

 

에이전트와 jdk 설치를 위해서, Ec2의 사용자 데이터에 위의 명령어를 기입합니다.

 

위 명령어를 통해 실행중인지 확인합니다.

 

2.2 태그 지정



태그는 Code deploy 에서 배포 대상 ec2를 찾는데에 사용됩니다.

 

2.3 보안그룹

모든 대상으로부터 오는 Http트래픽을 허용하는 보안그룹을 생성하여 추가합니다.

 

2.4 IAM 역할 연결

방금 생성한 인스턴스를 선택한뒤 -> 작업 -> 인스턴스 설정 -> IAM역할 연결/바꾸기를 선택합니다.

 

EC2에서 S3로부터 배포할 어플리케이션 소스를 가져올 것이므로, S3에 대한 접근 권한을 가지고 있는 Role을 추가합니다.

 

 

위의 순서대로 또 하나의 인스턴스를 적절히 생성합니다.

 

 

 

3. Code deploy 구축

3.1 배포구성 생성

배포 구성은, 어플리케이션이 배포되는 속도, 배포 성공또는 실패조건을 결정하는 규칙세트를 의미합니다. 예를 들어, 배포중 유지되어야하는 인스턴스숫자, 임계시간 등을 정할 수 있습니다.

 

code deploy 서비스의 -> 배포 -> 배포구성을 클릭한뒤 우측 상단에 보이는 배포 구성 만들기를 클릭합니다.

 

컴퓨팅 플랫폼에서는 ec2/온프레미스를 선택하고, 숫자, 값에는 1을 입력합니다. 이렇게하면 배포중 최소 한대의 인스턴스가 서비스 가능한 상태를 유지하도록 보장합니다.

 

 

3.2 어플리케이션 생성

어플리케이션은 codedeploy에서 배포할 어플리케이션을 일컫는 말입니다.

 

배포 -> 어플리케이션 -> 어플리케이션 생성을 선택합니다.

 

 생성을 완료 합니다.

 

배포그룹 생성

배포 그룹은 배포 대상이 되는 서버들, 배포를 위한 codedeploy의 역할 및 배포 구성설정을 통해, 어떻게 배포할지를 정하는 것 입니다.

 

배포그룹 생성 탭에서 배포그룹 생성을 클릭합니다.

 

서비스 역할에는 맨처음 생성한 Codedeploy의 역할을 연결합니다.

배포 유형은 현재위치 배포를 선택합니다.

 

환경구성에서는 Amazon Ec2 인스턴스를 선택하고, 배포하기 위해 위에서 생성한 2대의 EC2 인스턴스를 선택합니다.

배포설정에서는 앞서 생성한 배포구성을 선택합니다.

로드밸런서저희는 로드밸런싱 환경이 아니기 때문에, 비활성화를 합니다.

 

 

 

 

4. S3에 배포할 소스 업로드

code deploy에서는 배포후 코드 실행등 처리를 위해서, 셸스크립트를 실행하도록 명령할 수 있는 appspec이란 파일을 함께 소스코드와 번들링하여 업로드하도록 되어있습니다. Appspec의 형식은 컴퓨팅 플랫폼에 따라 달라집니다.

 

리포지토리 선택

배포할 코드를 가져올 저장소를 선택해야 합니다. CodeDeploy에서 지원하는 저장소는 아래와 같습니다.

  • Amazon S3
  • GitHub
  • Bitbucket

아키텍쳐에서 사용하기로한, S3를 이용할 것입니다.

 

우선 어플리케이션을 생성하고, app spec을 만든 뒤 배포후 서버에서 처리할 shell script를 만들어 이들을 번들링하고, 마지막으로 s3에 업로드 하도록 하겠습니다.

 

 

 

4.1 간단한 Application 생성

application을 생성한뒤, "/"에 반응하는 핸들러를 생성합니다.

 

gradle의 bootJar 태스크를 실행하여 앱을 빌드합니다.

 

 

 

4.2 shell script 작성

배포된 서버에서 실행할 shell script를 작성해보도록 하겠습니다. 이 스크립트는 .jar와 아래에서 작성할 appspec과 함께 s3에 업로드됩니다.

 

Kill_process.sh

이 스크립트는 기존에 동작하고 있던 서버를 종료하기위해 필요한 셸스크립트입니다.

 

run_java.sh

https://docs.aws.amazon.com/codedeploy/latest/userguide/troubleshooting-deployments.html#troubleshooting-long-running-processes

java를 실행하는 스크립트를 작성하기 이전, 위 글의 Long-running processes can cause deployments to fail부분을 읽고 오시기 바랍니다.

 

간단히 말씀드려, 저희 application은 실행이 끝나는 프로세스가 아니라, 계속해서 실행되며 유저의 요청을 처리하는 프로세스 입니다. 따라서, codedeploy가 run_java.sh 의 실행이 끝났음을 알 수 없습니다. 따라서 해당 어플리케이션의 표준 입출력, 에러/dev/null로 리다이렉팅 시켜야합니다. 결과 sh는 아래와 같습니다.

 

이 스크립트는 배포된 jar를 실행하는 스크립트입니다.

 

 

 

 

4.3 appspec 생성(https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure.html)

appspec은 배포 후, 배포된 서버에서 처리할 명령들을 code deploy에게 추가적으로 지시할 수 있는 파일입니다.

 

  • ec2인스턴스용 appspec파일의 이름은 반드시 appspec.yml이어야 합니다.
  • appsepc.yml은 application code의 root에 위치해야합니다.
  • appspec을 source코드에 추가한 뒤에는, 이를 zip, tar 등으로 압축한뒤, codedeploy가 지정한 리포지토리(S3 or gitHub)에 업로드합니다.

기본적으로 위의 조건을 만족해야 합니다.

 

appspec.yml

https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-server

정확한 appspec을 작성하기 위해서는 hooks의 각 라이프사이클에대해 정확히 알아야합니다. 위 링크를 통해 알 수 있습니다.

 

각각의 설명은 위 파일의 주석에 자세히 적어놓겠습니다.

 

 

이제 생성한 파일들을 압축해 하나의 파일로 만듭니다.

 

 

4.4 업로드

s3서비스에서 버킷을 생성하기 위해 버킷만들기를 클릭합니다.

 

임의로 버킷을 생성합니다.

 

버킷에 방금 생성한 압축파일을 업로드합니다.

 

 

 

5. Code deploy로 배포 하기

이제 code deploy를 이용해 배포를 진행해보도록 하겠습니다. 절차는 간단합니다. 실제로 우리가 배포를 진행하는것을 리마인드 하며, 진행해보면 더욱 이해가 쉽습니다.

 

 

Codedeploy 서비스의 -> 어플리케이션 탭에서, 생성했던 cicd-app을 클릭한뒤, 배포를 클릭합니다. 그후 우측에 보이는 배포만들기를 선택합니다.

 

 

생성한 배포그룹을 선택하고, 계정 유형에서 S3에 저장을 선택합니다. 그후 개정의 위치에, s3업로드된 zip파일의 위치를 기입합니다.(개정위치 입력창 아래의 형식을 그대로 따라하시면 됩니다.)

그 후 , 하단의 배포만들기를 클릭하면 완료입니다.

 

배포 탭을 클릭하신뒤, 배포 ID를 클릭하시면 해당 배포의 상세내역을 확인하실 수 있습니다.

 

 

확인


이제 각각의 ec2인스턴스로 접근(ssh -i $ssl인증서$ ec2-user@IP)하여, application이 실행중인지 확인(sudo netstat -nlp |grep java)합니다.

 

 

 

 

Code deploy의 Error

The overall deployment failed because too many individual instances failed deployment, too few healthy instances are available for deployment, or some instances in your deployment group are experiencing problems.

/var/log/aws/codedeploy-agent/codedeploy-agent.log 를 확인하자.

 

Missing credentials - please check if this instance was started with an IAM instance profile

=> EC2에 Role을 제거합니다. 그후 다시 알맞은 Role을 연결합니다. 해당 인스턴스의 codedeploy-agent를 재시작합니다.(sudo service codedeploy-agent restart)

 

 

느린 배포 속도

https://serverfault.com/questions/757262/is-there-a-way-to-speed-up-aws-codedeploy