
파이프라인은 소스코드 변경이 발생한 뒤, 그 변경 사항이 빌드되고 검증되며 배포 가능한 형태로 변환되고, 최종적으로 특정 환경에 반영되기까지의 절차를 순차적 또는 조건부 단계로 연결한 자동화 흐름이다.
단순히 여러 명령어를 한 줄로 나열한 것이 아니라, 각 단계가 명확한 목적을 가지고 연결되어야 함.
예를 들면 다음과 같은 흐름이다.
Code Commit
↓
Build
↓
Test
↓
Artifact Create
↓
Publish
↓
Deploy
↓
Verify
이 구조에서 중요한 점은 앞 단계의 결과가 다음 단계의 입력이 된다는 것이다.
즉, Build가 실패하면 Test로 가지 않음. Test가 실패하면 Deploy로 가지 않음.
이렇게 해야 불완전한 결과물이 운영 환경까지 흘러가지 않음.
수동 방식에서는 배포 절차가 사람의 기억과 숙련도에 의존함.
하지만 시스템이 커질수록 이 방식은 한계를 드러냄.
예를 들어 다음 문제가 발생할 수 있음.
파이프라인은 이런 문제를 줄이기 위해 배포 과정을 정형화하고 반복 가능하게 만든다.
즉, 파이프라인의 목적은 단순 자동화가 아니라 다음을 보장하는 데 있음.
CI/CD 파이프라인은 조직마다 세부 구성이 조금씩 다르지만, 보통 다음 단계를 중심으로 설명할 수 있음.
→ Source
→ Build
→ Test
→ Package
→ Publish
→ Deploy
→ Verify
각 단계는 이름만 알면 되는 것이 아니라, 무엇을 입력받고 무엇을 출력하는지 이해해야 함.
Source 단계는 파이프라인의 출발점이다.
일반적으로 Git 저장소에 코드 변경이 발생하면 파이프라인이 시작된다.
주요 이벤트는 다음과 같음.
pushpull requestmergetag 생성release 생성즉, 파이프라인은 "누가 언제 어떤 변경을 저장소에 반영했는가"를 기준으로 동작하는 경우가 많음.
보통 GitHub, GitLab, Bitbucket 같은 Git 기반 저장소를 사용함.
어느 브랜치에 변경이 반영되었는지에 따라 파이프라인 동작이 달라질 수 있음.
예:
feature/* 브랜치: 빌드와 단위 테스트만 수행develop 브랜치: 통합 테스트 수행main 브랜치: 운영 배포 후보 생성tag: 릴리스용 아티팩트 생성저장소 변경이 생겼을 때 파이프라인을 어떻게 시작할지 결정해야 함.
실무에서는 대부분 Webhook 기반으로 많이 구성함.
Source 단계의 출력은 보통 다음과 같음.
즉, 아직 "배포 결과물"이 나온 것은 아님.
단지 "이번 파이프라인이 어떤 소스 버전을 기준으로 동작하는가"가 정해진 상태다.
Build는 소스코드를 실행 가능하거나 배포 가능한 형태로 변환하는 단계다.
프로그래밍 언어와 애플리케이션 종류에 따라 Build의 의미는 조금씩 다를 수 있음.
예를 들면:
compile, package즉, Build 단계는 단순히 "컴파일"만 의미하는 것이 아니라, 배포 가능한 산출물을 만들기 위한 준비 과정 전체로 이해하는 것이 좋음.
Build 단계는 코드가 문법적으로나 구조적으로 최소한 실행 가능한 상태인지 확인하는 첫 번째 관문이다.
예를 들어:
이런 오류는 Build 단계에서 빨리 발견돼야 함.
여기서 실패한 결과물이 뒤 단계로 넘어가면 안 됨.
대표적인 산출물은 다음과 같음.
.jar, .war이 산출물은 이후 Test 또는 Publish 단계의 입력이 됨.
Test 단계는 빌드 결과물이나 애플리케이션 소스가 기대한 대로 동작하는지 검증하는 단계다.
CI/CD에서 가장 중요한 품질 보증 단계 중 하나라고 볼 수 있음.
자동화된 테스트가 없다면 파이프라인은 단순한 "자동 빌드 시스템"에 가까워짐.
즉, CI/CD의 품질 가치는 Test 단계에서 크게 결정됨.
가장 작은 단위의 함수나 모듈을 검증함.
속도가 빠르고 문제 위치를 빨리 찾기 쉬움.
여러 모듈 또는 서비스 간 상호작용을 검증함.
예를 들어 애플리케이션과 데이터베이스 연결, API 호출 등을 테스트할 수 있음.
사용자 관점에서 전체 흐름을 검증함.
비용이 높고 시간이 오래 걸리므로 모든 커밋마다 수행하지 않는 경우도 많음.
코드 스타일, 잠재적 오류, 보안 취약 패턴 등을 점검함.
오픈소스 의존성 취약점, 이미지 취약점, 시크릿 노출 여부 등을 검사할 수 있음.
테스트를 파이프라인에 포함하지 않으면 다음 문제가 생김.
즉, DevOps에서 중요한 것은 "빠르게 배포"가 아니라
빠르면서도 검증된 변경만 반영하는 것이다.
품질 게이트는 특정 기준을 통과해야 다음 단계로 넘어가도록 하는 제어 지점이다.
예:
이 기준을 넘지 못하면 파이프라인은 중단됨.
즉, 파이프라인은 단순 전달 시스템이 아니라 통제 시스템이기도 함.
Package 단계는 Build 결과물을 배포 가능한 단위로 정리하는 과정이다.
이 결과물을 보통 Artifact라고 부른다.
Artifact는 다시 빌드하지 않고도 동일한 결과를 다른 환경에 배포할 수 있게 해주는 핵심 개념이다.
즉, dev 환경에서 테스트한 바로 그 결과물을 stage나 prod에 동일하게 전달할 수 있어야 함.
Artifact가 없으면 환경마다 다시 빌드해야 할 수 있음.
이 경우 다음 문제가 생김.
따라서 파이프라인에서는 보통
한 번 생성한 Artifact를 여러 환경으로 승격(promote)하는 구조를 지향함.
Publish는 생성된 Artifact를 저장소나 레지스트리에 업로드하는 단계다.
이 단계가 있어야 배포 시스템이나 다른 파이프라인이 동일한 결과물을 참조할 수 있음.
Artifact는 버전 식별이 가능해야 함.
예:
1.0.01.0.120260317-001commit-sha 기반 태그업로드된 결과물이 손상되지 않았는지 확인해야 함.
어떤 커밋에서 생성된 아티팩트인지 확인 가능해야 함.
동일한 Artifact를 여러 환경에 재사용할 수 있어야 함.
Deploy는 Publish된 Artifact를 실제 실행 환경에 반영하는 단계다.
이 단계부터는 "코드 검증"이 아니라 "서비스 반영"의 영역으로 넘어감.
Deploy 대상은 다음과 같을 수 있음.
보통 하나의 환경만 쓰지 않고 여러 환경을 분리해 운영함.
환경 분리는 매우 중요함.
운영 반영 전에 충분한 검증 단계를 거치기 위함이다.
기존 애플리케이션을 직접 교체함.
구조는 단순하지만 실패 시 영향이 큼.
인스턴스를 하나씩 순차적으로 교체함.
무중단에 가까운 배포가 가능함.
기존 버전과 새 버전을 동시에 두고 전환함.
롤백이 쉬움.
일부 트래픽에만 새 버전을 먼저 적용함.
리스크를 낮출 수 있음.
배포가 끝났다고 해서 작업이 완료된 것은 아님.
실제 환경에서 서비스가 정상적으로 동작하는지 확인하는 절차가 필요함.
이 단계가 Verify다.
즉, Deploy가 "반영"이라면 Verify는 "반영 후 검증"이다.
배포가 성공했다고 표시되더라도 실제 서비스는 실패 상태일 수 있음.
예:
따라서 Deploy와 Verify는 반드시 구분해야 함.
파이프라인을 설계할 때 중요한 전제 중 하나는 실패가 반드시 발생한다는 것이다.
즉, 실패를 예외적인 사건으로 보는 것이 아니라, 파이프라인 내에서 잘 처리해야 할 기본 상황으로 봐야 함.
문제가 발견되면 가능한 한 빨리 멈춰야 함.
예를 들어 Build 실패 상태에서 Deploy까지 가면 안 됨.
어디서 왜 실패했는지 추적 가능해야 함.
실패 시 담당자가 즉시 인지할 수 있어야 함.
일시적 오류는 재시도 가능하게 설계할 수 있음.
운영 반영 후 Verify 실패 시 이전 버전으로 되돌릴 수 있어야 함.
CI/CD를 구성할 때 흔한 오해 중 하나는
"전부 자동화해야 선진적이다"라는 생각이다.
실제로는 조직 성숙도와 서비스 특성에 따라 승인 지점을 둘 수 있음.
즉, 자동화와 통제는 서로 반대 개념이 아님.
적절한 위치에 승인 지점을 두면 더 안전한 파이프라인이 됨.
파이프라인은 저장소 구조와 밀접하게 연결됨.
브랜치 전략이 정리되지 않으면 파이프라인도 혼란스러워짐.
같은 파이프라인을 모든 브랜치에 동일하게 적용하면 비효율이 생길 수 있음.
예:
따라서 브랜치 목적에 따라 파이프라인 수준도 달라져야 함.
환경 승격은 동일한 Artifact를 더 높은 환경으로 이동시키는 개념이다.
예:
여기서 중요한 점은 매 환경마다 다시 빌드하지 않는 것이다.
같은 Artifact를 검증된 상태 그대로 다음 환경으로 올리는 것이 이상적이다.
이 구조가 중요한 이유는 다음과 같음.
CI/CD 파이프라인을 아키텍처 관점에서 보면 다음과 같이 정리할 수 있음.
Developer
↓
Git Repository
↓
CI Pipeline Trigger
↓
Build / Test
↓
Artifact Repository or Container Registry
↓
Deployment Target
↓
Verification / Monitoring
여기서 핵심 구성요소는 다음과 같음.
즉, 파이프라인은 단일 도구가 아니라 여러 구성요소가 연결된 운영 체계다.
애플리케이션 코드뿐 아니라 설정 파일, 인프라 정의, 배포 매니페스트도 파이프라인 대상이 될 수 있음.
모든 검증을 매 커밋마다 수행하면 시간이 너무 오래 걸릴 수 있음.
따라서 빠른 검증과 느리지만 정밀한 검증을 분리하는 설계가 필요함.
소스를 다시 빌드하는 것이 아니라, 검증된 결과물을 이동시키는 구조가 더 안정적임.
배포가 됐다고 해서 모든 사용자에게 즉시 공개되는 것은 아닐 수 있음.
기능 플래그, 카나리 배포 등으로 실제 릴리스 시점을 조절할 수 있음.
운영 반영 이후 확인이 없으면 사실상 배포 완료라고 보기 어려움.