[DevOps] CI/CD, Jenkins에 대한 개념이해하기
개발자로 입사한지 어느덧 6개월차가 되었다.
하지만 경력입사자로 3년차 개발자가 되었고 현재 진행중인 프로젝트가 생각보다 시간이 너무 남아 중간중간 비는 시간에 신입사원 교육을 진행하게 되었다.
처음 시작은 CI/CD에 대한 교육이다.
Jenkins를 선택한 이유
GitLab Runner로 CD만 해봄, Github Actions으로만 CI/CD 해봄
한 번도 안해본 Jenkins로 진행하며 토론식으로 교육을 하고자 한다.
제대로 CI/CD 개념을 학습하고자하며 다음과 같은 학습목표를 세우게 되었다.
- CI/CD 개념에 대해 이해한다.
- Jenkins에 대해 이해 한다.
- Jenkins에 대한 기능과 용어를 정리한다.
- Jenkins를 이용해 CI/CD 파이프라인을 구축한다.
- 배포도구들의 차이점에 대해 정리해본다.
들어가기전
컴파일
프로그래머가 작성한 소스코드를 기계어로 변환하는 과정
빌드
소스 코드 파일을 컴퓨터에서 실행할 수 있는 소프트웨어 산출물로 만드는 과정
배포
빌드의 결과물을 사용자가 접근할 수 있는 환경에 배치하는 것
CI/CD
CI(Continuous Integration, 지속적인 통합)
여러 개발자들이 코드베이스를 계속해서 통합하는 것을 의미한다.
소프트웨어가 거대해지고 복잡해지면서 하나의 프로젝트를 팀 단위로 여러 명이 작업을 하게 되었고 이 과정에서 분업과 협업으로 일을 나눠 작업이 이루어지게 되었다.
그리고 멤버들을 자신이 담당해서 하고 있는 부분의 소스코드를 정기적으로 GIT, SVN과 같은 형상 관리 시스템(SCM, Source Code Management)에 Submit을 진행한다.
CI가 없었을때 어땠을까?
개발자들은 로컬에서 개발을 계속 진행하다 Merge Day를 정해두고 Merge를 하는 과정을 가졌다.
지속적으로 빨리 합치지 않고 10명의 코드를 한 번에 합친다면 오류가 많을 수 밖에 없다.
이러한 과정에서 서비스의 품질을 떨어지고 코드를 하나로 합치는것에 대한 부담은 커질 수 밖에 없다.
CI의 핵심 목표
- 새로운 소프트웨어 업데이트를 릴리즈하는 데 걸리는 시간 단축 : 가능한 최대한 많고 빨리 내 코드를 코드베이스에 안착시키기 위함
- 버그를 신속하게 해결, 소프트웨어 품질 개선 : 테스트 코드 없는 무서운 버그 더미 코드를 애초에 코드베이스에서 쫓아내기 위함
CI 시스템 구축을 위한 핵심 구성요소
- CI Server
- 빌드 프로세스를 관리하는 서버로 Jenkins가 여기에 속한다.
- ex) Jenkins, Travis, CI, etc
- SCM(Source Code Management)
- 소스코드 형상 관리 시스템으로 Git이 여기에 속한다. 소스코드의 개정과 백업 절차를 자동화하여 오류수정 과정을 돕는다. 팀 프로젝트의 경우 각자 수정한 부분을 전체가 자동으로 동기화 할 수 있는 시스템이다.
- ex) Subversion, Git
- Build Tool
- 컴파일, 테스트, 정적 분석 등을 실시해 동작 가능한 소프트웨어를 생성하는 도구로 Maven이 여기에 속한다. 빌드는 형상 관리 시스템에 있는 소스코드를 가져와 컴파일하여 실행 가능한 파일로 만드는 일련의 과정을 일컫는 말이다.
- ex) Maven, Gradle, Ant, make, etc
- Test Tool
- 작성된 테스트 코드에 따라 자동으로 테스트를 수행해주는 도구로 빌드 툴의 스크립트에서 실행되며 JUnit이 여기에 해당한다.
- ex) JUnit, Mocha, etc
빌드 스크립트를 통한 CI 자동화 수행 절차
- 소스코드를 바이너리 파일로 컴파일합니다.
- 바이너리 파일을 배포 형태로 패키징한다.
- 단위 테스트를 수행한다.
- 정적 분석을 수행한다.
- 분석 결과를 리포팅한다.
- 패키징한 파일을 테스트 서버에 배포한다.
CI의 이점
개발자 생산성 향상 : 개발자가 수동 작업에 대한 부담을 덜고 고객에게 제공되는 오류 및 보거 수를 줄이는데 도움이 되는 기능을 활용함으로써 팀의 생산성을 높일 수 있다.
버그를 더 빠르게 발견 및 해결 : 테스트를 좀 더 빈번하게 수행함으로써, 팀에서는 이후에 더 큰 문제로 발전하기 전에 버그를 조기에 발견하고 해결할 수 있다.
업데이트를 빠르게 제공 : 지속적인 통합을 사용하면 팀이 좀 더 빠르고 좀 더 빈번하게 고객에게 업데이트를 제공할 수 있다.
CD(Continuous Delivery/Deployment)
CD는 지속적인 서비스 제공(Continuous Delivery) 및 지속적인 배포(Continuous Deployment)를 의미하며 이 두 용어는 상호 교환적으로 사용된다.
지속적인 서비스 제공(Continuous Delivery)
말 그대로 서비스를 배달한다는 의미로 사용자에게 서비스를 신속하게 제공하여 코드베이스가 항상 배포가능한 상태를 유지하는 것을 의미하며 배포 관련 문제의 위험을 줄이는 동시에 고품질의 소프트웨어의 빠른 릴리즈를 촉진한다.
자세히 알아보면 지속적인 제공은 자동화된 테스트를 통과한 후 코드 변경 사항을 다양한 환경(예: 스테이징 또는 테스트)에 자동으로 제공하여 CI 프로세스를 확장한다.
지속적 제공은 변경 사항을 프로덕션에 자동으로 푸시하지 않는다. 대신 변경 사항이 사용자에게 배포되기 전에 일종의 수동 개입에 의존하는 통제된 릴리즈 프로세스를 제공한다. 이렇게하면 소프트웨어 업데이트가 항상 배포 가능한 상태로 유지, 언제든지 릴리즈를 할 수 있다.
지속적인 배포(Continuous Deployment)
코드베이스를 사용자가 사용가능한 환경에 배포하는 것을 자동화하는 것으로 개발 프로세스 전반에 걸쳐 자동화된 테스트가 일관되게 실행되도록 보장한다.
여기에는 코드 품질과 운용성을 검증하기 위한 단위, 통합, 기능 및 성능 테스트가 포함된다.
개발자에게 실시간 피드백을 제공하여, 개발자가 문제를 즉시 식별하여 해결하도록 돕고 서비스에 신뢰성과 안정성을 유지하도록 지원한다.
CI/CD란 각각의 개발자들이 개발하는 개발환경을 사용자가 사용 가능한 서비스로 전달하는 모든 과정을 지속 가능한 형태로 또 가능하다면 자동으로 해서 개발자와 사용자 사이의 격차를 없애는 것이다. 이러한 과정에서 코드를 빌드하고, 테스트하고 배포하는 활동이 있다.
CI/CD PipeLine
Jenkins
Jenkins는 흔히 CI 툴로 많이 사용되었지만 요새는 점점 CD 영역으로 확대되면서 CI/CD 전반적인 흐름을 관장하는 툴로 성장하게 되었다.
기본적인 언어는 Java 베이스로 Spring 서버를 만들고 연동하기에 좋은 툴이다.
Jenkins 기본 개념
- Java Runtime Environment에서 동작 -> 젠킨스에 도는 서버에 Java Runtime 깔려있어야 하며 도커 이미지로 실행되어야 한다.
- 빌드, 테스트, 배포 등 모든 것을 자동화해주는 자동화 서버
- 다양한 플러그인들을 활용해서 각종 자동화 작업을 처리할 수 있다.
- AWS 배포, 테스트, 도커 빌드 등 각각의 컴포넌트들을 하나의 플러그인으로 모듈화 되어있다.
- 가장 핵심적인 파이프라인, 시크릿 키마저도 플러그인으로 동작시킬 수 있다.
- 일련의 자동화 작업을 순서들의 집합인 Pipeline을 통해 CI/CD 파이프라인을 구축함
Jenkins 컨셉
- 모든 데이터는 파일로 저장하고 있다. (데이터베이스 연동X)
- 저장경로: /var/jenkins_home
- /var/jenkins_home/jobs/{items}
- builds : 빌드 관리를 위한 디렉토리
- config.xml : 구성에 대한 부분을 저장하는 파일
- 백업/복구 방법이 간단
- 백업은 파일 복사
- 복구는 파일 붙여넣기
- 분산 아키텍처로 개발되어 클러스터로 관린된다.
- controller역할을 수행하는 서버를 Master
- 클러스터를 관리하고 할 일(task)생성과 관리
- 소규모에서는 Master가 Controller이면서 Agent역할을 수행
- worker역할을 수행하는 서버를 Agent
- 일을 가져와서 작업을 수행
- controller역할을 수행하는 서버를 Master
- 젠킨스에서 Task는 Job이라는 용어를 사용
- Job은 자식 프로세스로 실행
- 부모 프로세스는 젠킨스 Agent 프로세스
- 즉, 젠킨스는 프로세스로 Job을 수행하고 관리하는 애플리케이션
- 상황에 따라서 외부 애플리케이션에게 위임한다.(예: 쿠버네티스)
- Job은 자식 프로세스로 실행
젠킨스의 대표 Plugins
젠킨스에는 많은 플러그인이 존재한다.
- Credentials Plugin
- Jenkins는 단지 서버이기 때문에 배포에 필요한 각종 리소스에 접근하기 위해서는 여러가지 중요 정보들을 저장하고 있어야 한다.
- 리소스에는 클라우드 리소스 혹은 베어메탈에 대한 ssh 접근 등을 의미한다.
- 베어메탈이란 어떠한 소프트웨어도 담겨 있지 않은 하드웨어를 가르킨다.
- AWS token, Git access token, secret key, ssh등의 정보들을 저장할 때 사용한다.
- 젠킨스는 Private Network에 떠있기 때문에 보안상 걱정하지 않아도 된다.
- Git Plugin
- Jenkins에서 Git에 대한 소스코드를 긁어와서 빌드할 수 있도록 도와줌
- Pipeline
- 핵심 기능인 파이프라인마저도 플러그인
- Docker plugin and Docker Pipeline
- Docker agent를 사용하고 Jenkins에서 도커를 사용하기 위한 플러그인
Jenkins의 Pipeline
- 파이프라인이란 CI/CD 파이프라인을 젠킨스에 구현하기 위한 일련의 플러그인들의 집합이자 구성
- 즉 여러 플로그인들을 이 파이프라인에서 용도에 맞게 사용하고 정의함으로써 파이프라인을 통해 서비스가 배포됨
- 두가지 형태의 Pipeline Syntax가 존재
- Declarative (더 최신이고 가독성이 좋음)
- Scripted Pipeline
Pipeline Section 알아보기
Sections(대카테고리)
- Agent section
- Post section
- Stages section
- Steps section
Agent section
- 젠킨스는 많은 일을 해야하기 때문에 혼자 하기 버겁다.
- 여러 slave node를 두고 일을 시킬 수 있는데, 이처럼 어떤 젠킨스가 일을 하게 할 것인지 지정한다.
- 젠킨스 노드 관리에서 새로 노드를 띄우거나 혹은 docker 이미지를 통해 처리할 수 있다.
- 쉽게 말하면 젠킨스를 이용하여 시종을 여러 명 둘 수 있는데 어떤 시종에게 일을 시킬 것이냐 하는 것을 결정하는 것이다.
- 예를 들어 젠킨스 인스턴스가 서버 2대에 각각 떠있는 경우, 마스터에게 시킬 것인지 slave에게 시킬 것인지를 결정 할 수 있다.
- 젠킨스 노드만 넣을 수 있는 것이 아니라 젠킨스 안에 있는 docker container에 들어가서 일을 시킬 수 있다.
Post section
- 스테이지가 끝난 이후의 결과에 따라 후속 조치를 취할 수 있다.
- 각각의 단계별로 구별하면 다음과 같다.
- 성공 시에 성공 이메일, 실패하면 중단 혹은 건너뛰기 등등, 작업 결과에 따른 행동을 취할 수 있다.
Stage section
- 어떤 일들을 처리할 것인지 일련의 Stage를 정의한다.
- 일종의 카테고리라고 보면 됨.
- ex) 프론트엔드 배포를 위한 스테이지 등
Steps section
- 한 스테이지 안에서의 단계로 일련의 스텝을 보여준다.
- Steps 내부는 여러가지 스텝들로 구성되며 여러 작업들을 실행 가능
- 플러그인을 깔면 사용할 수 있는 스텝들이 생겨남
- 빌드를 할 때 디렉터리를 옮겨서 빌드를 한다던가, 다른 플러그인을 깔아서 해당 플러그인의 메서드를 활용해서 일을 처리한다던지 하는 작업들을 할 수 있다.
- 플러그인을 설치하면 쓸 수 있는 Steps들이 많아진다.
Declaratives 문법 알아보기
Declaratives
- Environment, stage, options, parameters, triggers, when 등의 Declarative가 있음
- 각 stage안에서 어떠한 일들을 할 것인지 정의하는 게 Declarative이다.
Declaratives의 단계
- Enviroment
- Parameter
- 파이프라인 실행 시 파라미터 받음
- Triggers
- 어떤 형태로 트리거 되는가?
- 이 파이프라인이 어떤 주기로 실행이 되는가?
- When
Reference
https://aws.amazon.com/ko/devops/continuous-integration/