- CI/CD 파이프라인의 기본 개념에 대해서 이해
- 기본적인 운영환경이 어떻게 구성되고 운영되는지 이해
- Jenkins의 기본 개념에 대해 이해
- Jenkins를 통해 기본적인 배포 파이프라인을 직접 구축
- AWS 기반의 클라우드 환경에서 Jenkins 가 어떻게 활용되었는지
1. CI/CD란 무엇인가?
CI는 Continuous Integration으로 지속적인 통합을 이야기합니다. 여기서 목적어는 바로 코드를 이야기한다.
여러 명의 개발자들의 코드 베이스를 계속해서 통합하는 것.
CD는 Continuous Delivery로 지속적인 배달로 우리의 서비스를 배달한다는 의미입니다. 코드 베이이스가 항상 배포 가능한 상태를 유지해 개발자가 코드를 작성하면 누군가가 그 서비스를 사용하는 것을 추구합니다.
요약하자면 CI/CD란 각각의 개발자들이 개발을 하는 개발 환경을 사용 가능한 서비스로 전달하는 모든 과정을 지속적으로 가능하다면 자동으로 해 사용자와 개발자 사이의 격차를 없애는 것. 이 과정에는 빌드, 테스트 , 배포 활동이 존재.
여기서 사용자는 소비자일수도 있지만 내부 사용자일 수도 있다. 다른 분야의 개발자이거나 QA개발자 일 수도 있다.
이 과정을 보통 파이프라인이라 하며 물 흐르듯이 진행된다고 해서 붙여진 이름이다.
BUILD TOOL 같은 경우 Webpack, Tsc Javac ,
테스트는 jest , junit
배포는 ecs update, kubernetes 이러한 툴을 활용할 것이다.
CI를 하는 이유
여러 명의 개발자가 각자 맡은 부분을 열심히 코딩해 합치는 날이 왔다. 그날은 아마 퇴근하지 못할 것이다.
Merge에 대해서 엄청난 crush가 발생할 수 있고 그 격차를 줄이기 위한 의견 조율도 오래 걸릴 것이다.
따라서 안심하고 개발하기 위해 하루 단위나 개발한 즉시 조율을 시도하는 것이다.
그럼 CD는?
그럼 코드를 합친후 서비스를 배포를 하려고 한다. 배포도 마찬가지다 배포 시 수많은 버그가 터질 수 있으며, 이러한 점은 배 포날 발생한다면 배포를 하지 못할 수도 있다. 이러한 과정을 지속적인 배포를 통해 멘털 관리를 잘할 수 있다.
이러한 작업을 사람이 한다면 실수도 나올 수 있고 시간도 오래 소요하니 Jenkins 가 해주겠다는 이야기다.
젠킨스는 기본적으로 java Runtime 위에서 동작하는 자동화 서버이다. 따라서 젠킨스가 도는 서버에는 자바 런타임 환경이 구축되어야 하고, 쉽게는 도커 이미지를 받아서 사용할 수 있다.
젠킨스가 도는 다양한 원리는 여러 플러그인들을 조합해서 각종 자동화 작업을 처리하는 것이다.
- 정말 많은 플러그인이 존재하는데 골라 조합해서 파이프라인에 넣자
- 보통 젠킨스를 사용할 때 private network를 사용해서 보안에 대해서 큰 걱정은 하지 않아도 된다.
Pipeline
파이프 라인이란 CI/CD 파이프라인을 젠킨스에 구현하기 위한 일련의 플러그인들의 집합이자 구성
여러 플러그인들을 이 파이프라인에서 용도에 맞게 정의함으로써 서비스가 물 흐르듯이 배포가 됨.
Pipeline DSL로 작성한다. 쉽게 작업 명세서 같은 것이다. DSL은 Declarative Pipeline syntax를 사용을 권장한다.
여러가 배포 환경에는 어떤 종류가 존재할까?
- 개발자가 개발을 하는 local 환경
- 개발자들끼리 개발 내용에 통합 테스트를 하는 개발 환경
- 개발이 끝나고 QA 엔지니어 및 내부 사용자들이 사용해 보기 위한 QA환경
- 실제 유저가 사용하는 Production 환경
CI/CD 전체 파이프라인 순서
1. 개발자가 로컬 환경에서 개발
2. 다른 개발자랑 코드 차이에 대해서 내부 테스트 (git hooks)
3. dev 브랜치 같은 곳에 다른 개발자랑 공유한다.
4. dev브랜치의 내용을 배포하기 전 테스트 포맷팅, 등을 한다.
5. 빌드 -> 배포
여러 배포 환경의 관리에서 핵심은 인프라를 모듈화 하여 어떤 것이 변수인지 잘 설정하고 설계하는 것이다.
서비스 내부의 변수뿐만 아니라 클라우드 리소스를 많이 활용해서 개발하는 요즘은 클라우드 리소스 내에서 인프라별 키 관리가 매우 중요해서 aws system manager의 parameter store와 같은 키 관리 서비스를 사용하는 걸 추천한다.
중요한 것은 각각의 배포 환경에서 무엇이 차이가 나는가를 잘 정리하는 것이 핵심이다.
* S3
- Simple Storage Service의 약자로 그냥 클라우드 스토리지로 정적 웹사이트 코드 배포에 용이하고 호스팅 기능 제공...
* ECR
- 도커 이미지를 저장하는 프라이빗 레포지토리 그냥 도커 허브에 저장하는 것이 아닌 아마존에 도커 이미지를 저장하는 레포지토리
* ECS
- 도커 컨테이너 기반으로 서비스 운용을 가능하게 해주는 간단한 서비스 서버 분산, 서비스 확장 자동, 무중단 배포 등...
실제 기업에서는 aws계정을 나눠서 환경별 계정이 존재할 수 있고, 네트워크 인터페이스까지 다르게 물리적으로 나누는 경우도 있지만 싸게 가려면 한 개로 간다.
* 린트(lint) 또는 린터(linter)는 소스 코드를 분석하여 프로그램 오류, 버그, 스타일 오류, 의심스러운 구조체에 표시(flag)를 달아놓기 위한 도구들을 가리킨다.
pipeline {
//어떤 젠킨스사용할 것인지
agent any
triggers{
poLLSCM('*/3****')
//Remote Repository에서 3분마다 긁어온다.
//git 설정으로 accesskey발급받아야함
}
//젠킨스 보드에서 credentials 설정으로 전부 연동해주어야함
environment{
//aws 리소스 사용하도록 권한부여함. 이때 aws에 jenkins 유저 생성해야함.
AWS_ACCESS_KEY_ID = credentials('awsAccessKeyId')
//해당 arg이름은 aws에서 설정한 이름
AWS_SERCRET_ACCESS_KEY = credentials('awsSecreatAccessKey')
//지역설정
AWS_DEFAULT_REGION = 'ap-northeast-2'
HOME = '.'
}
stages{
//레포지토리를 다운로드 받음
stage('Prepare'){
agent any
steps{
echo "Let start Long Journey! ENV: ${ENV}"
echo 'Clonning Repository'
git url : 'repository url',
branch : 'master',
credentialsId: 'jenkinsgit'
} //이 단계에서 소스코드를 pull받는 단계
post{
success { echo 'successfully pull repository'}
always {echo 'i tried'}
cleanup {echo 'after all other post condition' }
}
}
//실서비스 용
stage('Only for production'){
when{ //조건에 맞으면 anyOf를 실행해라~
branch 'production'
environment name: 'APP_ENV', value: 'prod'
anyOf{
environment name : 'DEPLOY_TO', value: 'production'
environment name : 'DEPLOY_TO', value: 'staging'
}
}
}
stage('Delpoy Frontend'){
steps {
echo 'Deploying Frontend'
//프론트 엔트 파일들을 s3에 올림, 이전에 반드시 EC2 instance profile을 등록
dir('./website'){
sh '''
aws s3 sync ./ s3://만든 s3의 이름을 써준다.
'''
}//website 디렉터리안의 내용을 s3에 올린다. 버킷만들고 사용.
//lint도하고 프론트엔드 배포작업을 한다.
}
//위 steps이 작동한다음 할것 post
post {
success{ //성공시 메일보낸다.
mail to : 'frontend@gamil.com',
subject : 'deploy Frontend success',
body : 'good'
}//보낼사람에대한 credentials설정
failure{
//실패하면 slack을 보내거나 메일을하거나~
}
}
}
stage('Lint Backend'){
//도커 플러그인, 도커 파이프라인 설치해야 가능
agent{
docker {
image 'node:latest'
}
}
}
stage('test Backend'){
agent{
docker {
image 'node:latest'
}
}
steps {
echo 'test'
dir ('./server'){
sh '''
npm install
npm run test
}
}
}
stage('Build Backend'){
agent any//젠킨스노드에 도커를 설치해줘야된다.
steps {
dir ('./server'){ //도커 컨테이너 생성후 PROD 배포환경으로 생성
sh ''' docker build . -t server --build-arg env=${PROD} '''
}
}
}//post는 steps다음에 실행됨. error 로 파이프라인 중단가능
stage('Deploy Backend'){
agent any
//여기서 쿠버네티스나 ecs update를 함.
//도커 컨테이너 서버 포트연결
}
}
이 글은 www.youtube.com/watch?v=JPDKLgX5bRg 영상을 참고해 작성했다.
댓글