Tag: CI/CD

  • CI/CD 파이프라인 구축: 커밋에서 배포까지 자동화하기

    CI/CD 파이프라인 구축: 커밋에서 배포까지 자동화하기

    배포가 두려운 팀은 배포를 미루고, 미룬 배포는 한 번에 거대한 변경을 몰아 더 위험해집니다. CI/CD의 진짜 가치는 속도가 아니라 ‘작은 변경을 자주, 안전하게’ 내보낼 수 있게 만드는 데 있습니다. 이 글은 빈 저장소에서 시작해 신뢰할 수 있는 파이프라인을 세우는 과정을 다룹니다.

    운영 문제: 수동 배포의 비용

    수동 배포는 단지 느린 게 아닙니다. 사람이 명령을 외워 치는 과정은 재현 불가능하고, 금요일 오후의 실수 한 번이 주말 장애로 번집니다. 자동화의 첫 목표는 ‘누가 눌러도 똑같은 결과’를 보장하는 것입니다.

    아키텍처: CI와 CD의 분리

    CI(지속적 통합)는 코드가 합쳐질 때마다 빌드와 테스트로 품질을 검증하는 단계이고, CD(지속적 배포)는 검증된 산출물을 환경에 안전하게 내보내는 단계입니다. 둘을 명확히 분리해야 ‘CI는 빠르게, CD는 신중하게’라는 서로 다른 리듬을 줄 수 있습니다.

    구현: 파이프라인 정의 예시

    stages:
      - lint-and-test      # 단위 테스트 + 정적 분석
      - build-image        # 컨테이너 이미지 빌드 + 취약점 스캔
      - deploy-staging     # 스테이징 자동 배포
      - smoke-test         # 핵심 경로 통합 검증
      - deploy-prod        # 카나리 10% -> 50% -> 100%

    핵심은 각 단계가 게이트 역할을 한다는 점입니다. 테스트가 깨지면 이미지는 빌드되지 않고, 스모크 테스트가 실패하면 운영 배포는 자동으로 중단됩니다. 사람의 판단이 아니라 파이프라인이 안전을 강제합니다.

    모니터링과 배포 안전장치

    • 배포 빈도와 변경 실패율(DORA 핵심 지표)
    • MTTR(평균 복구 시간)과 자동 롤백 발동 횟수
    • 카나리 단계별 에러율·지연 비교

    카나리 배포는 새 버전을 일부 트래픽에만 노출해 에러율이 기준치를 넘으면 즉시 롤백합니다. 이 한 가지 장치만으로도 잘못된 배포의 영향 범위를 전체 사용자에서 10% 이하로 가둘 수 있습니다.

    정리

    좋은 파이프라인은 배포를 ‘이벤트’에서 ‘일상’으로 바꿉니다. 테스트 게이트로 품질을, 카나리와 자동 롤백으로 안전을 확보하면, 팀은 두려움 없이 하루에도 여러 번 배포하며 빠르게 학습할 수 있습니다.

  • IaC로 인프라를 코드처럼 다루기: 테라폼 운영 패턴

    IaC로 인프라를 코드처럼 다루기: 테라폼 운영 패턴

    콘솔에서 클릭으로 만든 인프라는 누가 무엇을 바꿨는지 기록이 없고, 같은 환경을 다시 만들 수도 없습니다. IaC(Infrastructure as Code)는 인프라를 선언적 코드로 정의해 버전 관리, 리뷰, 재현을 가능하게 만듭니다. 이 글은 테라폼류 도구로 운영할 때의 실전 패턴을 다룹니다.

    운영 문제: 드리프트와 눈송이 서버

    코드로 만든 인프라도 누군가 콘솔에서 손대면 코드와 실제 상태가 어긋나는 ‘드리프트’가 생깁니다. 또 환경마다 미묘하게 다른 ‘눈송이 서버’가 쌓이면 재현성이 무너집니다. IaC의 운영은 결국 이 드리프트를 어떻게 통제하느냐의 문제입니다.

    아키텍처: 상태 파일이 진실의 원천

    테라폼은 상태 파일(state)에 현재 인프라의 모습을 기록하고, 코드와 비교해 차이만 적용합니다. 따라서 상태 파일을 원격 백엔드에 두고 잠금(locking)을 거는 것이 협업의 출발점입니다. 잠금이 없으면 두 사람이 동시에 apply해 상태가 깨집니다.

    terraform {
      backend "s3" {
        bucket         = "infra-state-prod"
        key            = "network/terraform.tfstate"
        dynamodb_table = "tf-lock"   # 동시 실행 잠금
        encrypt        = true
      }
    }

    구성: 모듈과 환경 분리

    • 재사용 단위는 모듈로: VPC, 데이터베이스, 클러스터를 모듈화
    • 환경은 변수로 분리: dev/staging/prod가 같은 모듈에 다른 값
    • plan을 PR에서 리뷰: 무엇이 생성·변경·삭제되는지 먼저 확인
    • apply는 파이프라인에서만: 사람의 로컬 apply 금지

    특히 plan 결과를 코드 리뷰 단계에서 검토하는 습관이 중요합니다. ‘삭제 5개’가 보이는데 누군가 무심코 승인하면 데이터베이스가 통째로 사라질 수 있기 때문입니다.

    모니터링과 비용

    드리프트는 주기적으로 plan을 돌려 코드와 실제의 차이를 감지하는 방식으로 모니터링합니다. 차이가 발견되면 알림을 보내 즉시 원인을 추적합니다. 비용 면에서는 plan 단계에 비용 추정 도구를 붙여, 이 변경이 월 비용을 얼마나 늘리는지 PR에서 미리 보여주면 무심한 고비용 자원 생성을 사전에 막을 수 있습니다.

    정리

    IaC의 핵심 가치는 인프라를 소프트웨어처럼 다루는 규율입니다. 원격 상태와 잠금, 모듈화, PR 기반 plan 리뷰라는 삼각 편대를 갖추면, 인프라 변경은 두려운 클릭이 아니라 추적 가능하고 되돌릴 수 있는 코드 변경이 됩니다.

  • 컨테이너 보안: 이미지부터 런타임까지 막아야 할 빈틈

    컨테이너 보안: 이미지부터 런타임까지 막아야 할 빈틈

    컨테이너는 빠르고 가볍지만, 그 가벼움이 곧 보안 책임의 분산을 뜻합니다. 베이스 이미지의 오래된 라이브러리, 과도한 권한, 노출된 시크릿 등 빈틈은 여러 단계에 흩어져 있습니다. 보안은 한 곳을 막는 게 아니라 빌드부터 런타임까지 층층이 막는 다층 방어(defense in depth)여야 합니다.

    운영 문제: 공격면은 이미지에서 시작된다

    많은 사고가 이미지 단계에서 시작됩니다. 거대한 베이스 이미지에는 수백 개의 패키지가 들어 있고, 그중 하나의 알려진 취약점(CVE)이 침투 경로가 됩니다. 실측해 보면 풀 OS 기반 이미지는 distroless나 슬림 이미지 대비 알려진 취약점이 5배 이상 많은 경우가 흔합니다.

    단계별 방어

    • 빌드: 최소 베이스 이미지, 의존성 고정, 이미지 취약점 스캔
    • 배포: 신뢰된 레지스트리만 허용, 이미지 서명 검증
    • 런타임: 비루트 실행, 읽기 전용 파일시스템, 권한 최소화
    • 네트워크: NetworkPolicy로 파드 간 통신 화이트리스트화

    구현: 안전한 컨테이너의 기본기

    컨테이너가 루트로 실행되면 탈출 시 호스트 전체가 위험해집니다. 비루트 사용자와 권한 축소는 가장 비용 대비 효과가 큰 조치입니다.

    securityContext:
      runAsNonRoot: true
      runAsUser: 10001
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]

    시크릿은 절대 이미지나 환경 변수에 평문으로 넣지 말고, 시크릿 매니저에서 런타임에 주입해야 합니다. 한 번 이미지 레이어에 박힌 시크릿은 삭제해도 히스토리에 남아 유출됩니다.

    모니터링: 런타임 이상 탐지

    아무리 막아도 실행 중 비정상 행위는 발생할 수 있습니다. 컨테이너가 갑자기 셸을 띄우거나 예상치 못한 외부로 연결을 시도하면 런타임 보안 도구가 이를 탐지해 경보합니다. 빌드 시점 스캔과 런타임 탐지를 함께 두어야 알려진 위협과 알려지지 않은 위협 모두를 커버할 수 있습니다.

    정리

    컨테이너 보안에 은탄환은 없습니다. 최소 이미지, 비루트 실행, 시크릿 분리, 네트워크 격리, 런타임 탐지를 층층이 쌓아야 한 겹이 뚫려도 다음 겹이 막습니다. 보안을 배포 후의 점검이 아니라 파이프라인에 내장된 게이트로 만드는 것이 핵심입니다.