What is CI/CD? DevOps? Pipeline?
- CI/CD 라는 용어는 애자일 소프트웨어 개발 방법론에서 나옴
- 애자일은 요구사항을 스프린트에 맞추어 작게, 유연하게 개발
- DevOps의 핵심은 개발자와 테스터, 고객이 모든 단계에 참여
- CI/CD는 민첩한 개발을 구현하기 위해 올바른 자동 테스트 도구를 사용하는 DevOps 전략
- CI/CD를 하기 위해서는 자동화된 도구가 필요 - 이러한 도구들의 묶음을 CI/CD 파이프라인 이라고함
- 즉, 어플리케이션의 통합 및 테스트 단계에서부터 제공 및 배포에 어플리케이션의 라이프사이클 전체에 걸쳐 자동화와 모니터링을 제공하는 프로세스들의 묶음을 의미
- CI/CD, Agile 및 DevOps는 같은 목표를 가지고 있음 - 짧은 시간에 더 나은 소프트웨어를 만들기!
Continuous Integration
- 개발자를 위한 자동화 프로세스인 지속적인 통합(Continuous Integration)을 의미
- 개발코드를 통합할 때의 문제점을 해결하고, 자동화시켜 지속적으로 유지시키는 방법
- 코드를 커밋만 치면 자동으로 빌드, 통합을 하고, 테스트를 하는 과정을 의미
- 성공적인 CI를 하려면?
- 코드 저장소에 모든것을 넣어야 합니다.
- 코드는 자주 병합되어야 합니다.
- 매일 빌드를 성공적으로 실행해야 합니다.
- 빌드 프로세스는 완전 자동화 되어야 합니다.
- 빌드 실패시 바로 수정이 되어야 합니다.
- 빌드에 번호가 매겨지고, 반복 가능해야 합니다.
- 테스트에 시간이 오래 걸리면 안됩니다.
- CI 결과물로 만들어진 패키지 혹은 컨테이너는 신뢰할 수 있어야 합니다. (테스트 자동화 필수)
Continuous Delivery / Conrinuous Deployment
- 지속적인 서비스 제공 / 지속적인 배포
- 어플리케이션을 항상 신뢰 가능한 수준으로 배포 될수 있도록 지속적으로 관리
- CI가 이루어지고 난 후에 운영환경 까지 배포를 수행하여, 실제 사용자가 사용할 수 있도록 적용하는 단계
- 성공적인 CD를 하려면?
- 개발/스테이징/운영 환경에 동일한 배포 프로세스를 적용
- 모든환경에 동일한 패키지를 사용(환경별 구성과 패키지를 다르게 유지해야 한다는 것을 의미)
- 빠른 롤백이 가능하도록 구성
- 모니터링 할 수 있는 도구 필요
Process Change: 열차 말고 택시를 타라!
- 모놀리식 개발 및 운영환경
- 모놀리식 환견하에서는 큰 개발팀이 하나의 소스코드 레파지토리에 변경 사항을 커밋하므로 코드간 상호 의존도가 높아 신규 개발 및 변경이 어려움
- 작은 변경에도 전체를 다시 테스트/배포하는 구조이므로 통합 스케쥴에 맞춘 파이프라인을 적용하기가 어렵고 Delivery 시간이 과다 소요
- 마이크로 서비스 개발 및 운영 환경
- 작고 분화된 조직에서 서비스를 작은 크기로 나누어 개발하므로 해당 비즈니스 로직에만 집중하게 되어 개발 생산성 향상
- 연관된 마이크로 서비스만 테스트를 수행하므로 개발/테스트/배포 일정이 대폭 축소
Version Contorl, Source Code Management
형상관리 - History
- 형상관리란?: 소스의 변화를 끊임없이 추적하고, 버전별로 관리
- CVS (Concurrent version system)
- 파일 관리나 커밋 중 오류 시 롤백이 되지 않는 불편한 문제점이 있어 이후 SVN으로 대체됨
- SVN (subversion)
- Trunk, Tag, Branch 구조 사용
- 중앙 레파지토리 방식
- 개발자가 자신만의 version history를 가질 수 없음
- GIT
- 개발자가 자신만의 commit history를 가질 수 있음
- 저장소 분리로, 복원이 용이
- 매우 빠른 속도와 분산형 저장소. SVN보다 많은 기능을 지원
빌드 자동화 툴
- 빌드 자동화란?: 자바 소스를 Compile하고 Package해서 Deployo하는 일을 자동화 해주는 것
- Apache Ant
- Java Build Tool, Another Neat Tool
- 2000년 출시
- Base build file: build.xml
- 유연함이 장점이지만 (모든 명령을 직접 작성), 규칙이 없기 때문에 유지보수가 어려움
- Apache Maven
- Java Build를 위한 Ant의 불편함을 해소하고자 2004년 출시
- 규칙을 정하고 Goals라는 사전 정의된 command를 제공
- Base build file: pom.xml
Gradle - 다양한 언어 지원
- Ant와 Maven의 장점을 모아 2012년 출시
- Android OS의 빌드 도구로 채택
- 프로그래밍 언어 형식으로 유연함이 장점 (Groovy 파일로 작성)
- Base build file: build.gradle
Maven 핵심 개념
- Plugin
- 메이븐은 플러그인을 구동해주는 프레임워크이다. 모든 작업은 플러그인에서 수행한다.
- 플러그인은 다른 산출물(artifacts)와 같이 저장소에서 관리된다.
- 메이븐은 여러 플러그인으로 구성되어 있으며, 각각의 플러그인은 하나 이상의 goal(명령, 작업)을 포함하고있다. Goal은 Maven의 실행단위
- 플러그인과 골의 조합으로 실행한다. ex.
mvn <plugin>:<goal> = mvn sping-boot:run
- 메이븐은 여러 Goal을 묶어서 Lifecycle phases로 만들고 실행한다. ex.
mvn <phase> = mvn install
- Lifecyle
- 메이븐 프로젝트 생성에 필요한 단계들 (phases)의 묶음
- clean, default, site 세 가지로 표준 정의
- clean: 빌드 시 생성되었던 산출물을 삭제
- default: 프로젝트 배포 절차, 패키지 타입별로 다르게 정의
- site: 프로젝트 문서화 절차
- mvn compile: Java 소스를 컴파일하여 target 디렉토리에 생성
- mvn test: 생성된 test 코드를 실행하여 target 디렉토리에 생성
- mvn package: target 디렉토리 하위에 jar,war,ear등 패키지 파일을 생성
- mvn install: 로컬 저장소에 배포
- mvn deploy: 원격 저장소에 배포
- Dependency
- 라이브러리 다운로드 자동화
- 참조하고 있는 library까지 모두 찾아서 추가 (의존성 전이)
- USER-HOME/.m2/repository에 저장
- 의존관계 제한 가능
- Scope
- comppile: 기본값, 모든 classpath에 추가
- provided: 컴파일시 필요하나 실행때는 필요없음
- runtime: 실행때는 필요하나 컴파일때는 필요없음
- test: 테스트 때만 사용
- system: jar 파일을 직접 지정
- Dependency management: 직접 참조하지는 않으면서 하위 모듈이 특정 모듈을 참조할 경우, 특정 모듈의 버전을 지정 (예: spring-cloud)
- Excluded dependencies: 임의의 모듈에서 참조하는 특정 하위 모듈을 명시적으로 제외처리 (예: log)
- Profile
- Local, develop, test, production 등 환경에 따라 달라져야할 정보들을 Bulid 타임에 구성한다.
- -P 옵션으로 프로파일을 선택하여 build (mvn package -P dev)
- 환경마다 build 구성이 필요하므로 Spring Profile을 권장
- POM.xml
- POM은 프로젝트 객체 모델(Project Object Model)
- 프로젝트 당 1개
- 프로젝트의 root에 존재
<groupId>, <artifactId>, <version>으로 자원을 식별
<groupId>: 프로젝트의 패키지 명칭
<artifactId>: artifact 이름, groupId 내에서 유일해야 한다.
<packaging>: 패키징 유형(jar,war 등)
<distributionManagement>: artifact가 배포될 저장소 정보와 설정
<dependencies>: 의존성 정의 영역
<repositoryes>: default는 공식 maven repo
<build>: 빌드에 사용할 플러그인 목록을 나열
Test 전략
항상 성공 할 수 있는 것, 항상 동일한 결과를 나오는 것을 테스트 해야함
MSA Test 자동화
- 단위 테스트: 소프트웨어 구성 요소를 개별적으로 테스트
- Unit Test: 응용 프로그램이 제대로 작동하고 있다고 확인할 수 있는 테스트
- 보통 Unit 테스트는 소스코드를 빌드하는 단계에서 같이 실행
- Regression(회귀) Test: 개성 사항 및 버그 수정으로 인해 발생할 수 있는 버그를 발견하는 테스트
- 운영중에 버그가 발생했을 경우 이를 수정하면서 해당 버그를 발견할 수 있는 테스트 케이스를 만들고 이를 테스트 자동화에 적용하는 방법
- 통합 테스트: 소프트웨어 구성 요소를 함께 테스트
- API Test: 개발된 API가 정상 작동하는지 테스트. 테스트를 위한 서비스를 생성 후, 테스트 후, 서비스 제거 방식으로 실행
- Contract Test: 다른 서비스와 계약서를 만든 후에 계약서를 유지시키는 테스트
- E2E 테스트: 모든 소프트웨어 구성 요소가 예상대로 작동하는지 확인
- 테스트 자동화 힘듦: 모든 서비스를 올려야 하고, 브라우저 테스트나 클릭 테스트 등 유저가 직접 테스트를 해야하는 경우가 많아서 비용이 높음
- CasperJS, Testcafe등 별도의 툴을 사용하여 자동화 하여야 함