AWS와 Jenkins로 구축하는 CI/CD [1부]

뿌엑·2022년 9월 9일
0

아무리 봐도 느끼하게 생겼다..

CI/CD가 무엇일까?

Continuous Integration(지속적인 통합(코드))

여러 개발자들의 코드를 계속해서 통합하는 것이다.

Continuous Deployment(지속적 배포)

코드 베이스를 사용자가 사용가능한 환경에 배포하는 것을 자동화한다.

개발한 프로덕트를 내부 사용자, QA 엔지니어, 프론트, 백 엔지니어에 전달하는 것도
CI/CD의 목적이다.

Pipe line은 단순히 배관이란 뜻이다.

빌드/테스트/배포 과정에 쓰이는 주요 툴.

빌드: Webpack, tsc, javac
테스트: jest, Junit
배포: ecs update

만약 CI가 없다면...

  • 10명의 개발자가 열심히 개발
  • 일주일 뒤 Merge...
  • 폭죽처럼 터지는 수많은 오류들!

CI를 사용한다면...

  • 10명의 개발자가 열심히 개발한 뒤 로컬 테스트를 진행하고, 커밋한다.
  • CI를 통해 코드베이스를 Merge하여 작업이 완료된다.

CD가 필요한 이유!

  • 백엔드 코드를 개발한다.
  • 프론트와 협업해야 하니 배포를 요청한다.
  • 오류 폭발!
  • 또는 오류를 발생시킨 원인을 추적하여 해당 코드를 배포한 범인을 색출한다!

반복되는 작업들...

프로덕션 배포시마다 초긴장 상태를 유지하고, 배포 스크립트를 작성하고, AWS 콘솔로 작업하고.. 아니면 베어메탈??

할게 준내 많다...

개발자는 코드만 짜야 한다.
나머지 귀찮은 작업들을 Jenkins가 대신한다.


그래서 Jenkins가 이렇게 역겹게 생긴...

Jenkins

Jenkins는 Java Runtime 위에서 동작한다. 빌드, 테스트, 배포 등 모든 것을 자동화 해주는 자동화 서버이다. 다양한 플러그인을 활용하여 각종 자동화 작업을 처리할 수 있고, 자동화 작업의 순차적 집합인 Pipeline(이 자체도 플러그인)을 통해 CI/CD 파이프라인을 구축한다.

Pipeline

파이프라인은 CI/CD 파이프라인을 Jenkins에 구현하기 위한 일련의 플러그인의 집합이자 구성이다. 여러 플러그인들을 이곳에서 용도에 맞게 사용하고 정의하여 서비스가 배포된다.

Pipeline DSL(Domain Specific Language)

Pipeline은 Pipeline DSL(Domain Specific Language)로 작성한다.
Declarative, Scripted Pipeline 두 가지 형태의 Pipeline syntax가 존재한다. 이 중 Declarative Pipelie syntax가 더 최신이자 가독성 좋은 문법을 가지고 있다.

Pipeline Syntax

Sections

  • Agent section
  • Post section
  • Stages section
  • Steps section

Agent Section

Jenkins는 많은 일을 하기에 혼자 하기 버겁다.

여러 slave node를 두고 일을 시킬 수 있는데, 이처럼 어떤 Jenkins가 일을 하게 할 것인지를 지정한다. Jenkins 노드 관리에서 새로 노드를 띄우거나 docker 이미지 등을 통해 처리할 수 있다.

Post section

스테이지가 끝난 이후의 결과에 따라 후속 조치를 취할 수 있다.
ex) 성공시 성공 이메일, 실패하면 중단 혹은 건너뛰기 등 실행

Stage section

어떤 일들을 처리할 건지 일련의 stage를 정의한다.

Steps Section

한 스테이지 내의 단계로 일련의 스텝을 보인다.

Declaratives

각 스테이지 안에서 어떤 일을 할 건지 정의하는 것
Environment, Stage, Options, Parameters, Triggers, When 등의 Declarative가 있다.

  • Environment: pipeline이나 stage scope의 환경변수 설정
  • Parameter: 파이프라인 실행시 파라미터 받음
  • Triggers: 어떤 형태로 트리거 되는가(일정 주기마다 실행)
  • When: 언제 실행되는가(프로덕션에서만 실행시키기)

개발환경의 종류

개발자가 개발을 하는 Local 환경(자신의 workspace에서 작업함)
개발자들끼리 개발 내용에 대한 통합 테스트를 하는 Development 환경
개발이 끝나고 QA 엔지니어 및 내부 사용자들이 사용해 보기 위한 QA 환경
실제 유저가 사용하는 Production 환경

이를 DEV, QA, PROD로 부를 수 있다.

개발 프로세스

  1. 개발자가 자신의 PC에서 개발을 진행한다.
  2. 다른 개발자가 작성한 코드와 차이가 발생하지 않는지 내부 테스트를 진행한다.
  3. 진행한 내용을 다른 개발자들과 공유하기 위해 git과 같은 SCM에 올린다(흔히 dev 브랜치).
  4. Dev 브랜치의 내용을 개발 환경에 배포하기 전에 테스트와 Lint 등 코드 포맷팅을 한다.
  5. 배포하기 위한 빌드 과정을 거친다.
  6. 코드를 배포한다.
  7. 테스트를 진행한다.
  8. 위 모든 과정을 DEV, QA, PROD 환경에서 수행하고 각각에 맞는 환경에 배포한다.

여러 배포 환경의 관리

배포 환경 관리의 핵심은 인프라를 모듈화하여 어떤 것이 변수인지 잘 설정하고 이를 잘 설계하는 것이다.

APP_ENV처럼 현재 배포하고자 하는 것이 무슨 환경인지 설정하고, 앱 내에서 사용하는 다양한 변수들을 APP_ENV에 맞게 잘 가져다 쓰는 것이 핵심이다.

서비스 내부 변수 뿐 아니라 클라우드 리소스를 많이 활용해서 개발하는 최근엔 리소스 내에서 인프라별 키 관리가 매우 중요해서 aws system manager의 parameter store와 같은 키 관리 서비스를 쓰면 간편하다.

예시 배포 환경

  1. 웹사이트 코드를 작성한다.
  2. 웹사이트 코드를 린트, 웹팩 빌드해서 AWS S3 bucket에 html 파일을 업로드한다.
  3. Node.js 백엔드 코드를 typescript로 작성한다.
  4. 위 코드를 javascript compile하고, 테스트 코드를 돌려 도커 이미지를 만들어 ECR에 올린다.
  5. 업로드한 ECR 이미지로 ECS 서비스를 재시작한다.(rolling deploy)

S3

  • Simple Storage Service의 약자로 클라우드 스토리지를 뜻한다.
  • 정적 웹사이트 코드배포에 용이하다.
  • 정적 웹사이트 호스팅에 필요한 다양한 기능을 제공한다.
  • AWS Cloudfront와 함께 사용해서 최적화가 가능하고 DNS 관리도 가능하다.

ECR

  • Elastic Container Registry
  • 도커 이미지를 저장하는 프라이빗 레포지토리
  • 실제 프로덕션 환경에선 container 기반의 배포(ECS 등을 활용)를 할 것이기에 반드시 repository가 있어야 한다.

ECS

  • Elastic Container Service
  • 도커 컨테이너 기반으로 서비스 운용을 가능하게 해주는 간단한 서비스
  • 사용량에 따라 서버에 부하가 집중되지 않도록 로드를 분산시키는 서비스
  • 무중단 배포(rolling update)를 제공하며 scale up이 가능한 특징
  • 백엔드 서비스를 스케일업 가능한 형태로 배포하는데 최적화
  • 수많은 도커 컨테이너 서버를 띄우고 LB가 이들 사이에 밸런싱을 해줌
  • fargate, ec2 모드가 있어 docker container 리소스만 띄우거나 물리적인 EC2 instance 클러스터로 구성 가능

ECS 혹은 k8s 등을 통해 rolling deploy가 처리되기에 jenkins는 배포 명령만 내리면 된다.
ex) aws ecs update-service '서비스명'


Reference

0개의 댓글