M6 ‐ 배포 검증 및 롤백 프로세스 정립 - 100-hours-a-week/KTB4-4th-wiki GitHub Wiki

목차


1. 목적

Need U의 Frontend, Backend, AI가 정상적으로 배포되었는지 검증하고, 배포 실패 시 이전 버전으로 복구할 수 있는 기준을 정의한다.

  • Docker Image는 Git Commit SHA를 Tag로 사용한다.
  • 배포한 Image와 실제 실행 중인 Image가 같은지 확인한다.
  • Application 기동 실패 시 이전 버전으로 자동 Rollback한다.
  • 배포 이후 문제가 발견되면 직전 버전으로 수동 Rollback한다.
  • 현재/직전 버전과 배포 결과를 기록한다.

이유

Container가 실행 중이라고 해서 Application까지 정상적으로 요청을 처리한다는 의미는 아니다.
따라서 Image → Application 상태 → 실제 서비스 접근 경로 순서로 검증한다.


2. 배포 검증 흐름

Git SHA 입력
↓
Parameter Store 환경변수 로드
↓
ECR Image Pull
↓
대상 Container 재기동
↓
실행 Image SHA 검증
↓
Internal Health Check
├─ 실패 → 이전 버전 자동 Rollback
└─ 성공
     ↓
current / previous Tag 갱신
     ↓
External Health Check
├─ 성공 → 배포 완료
└─ 실패 → 배포 실패 기록
             ↓
          원인 확인
             ↓
       필요 시 수동 Rollback

이유

배포 직후 Application 자체가 실행되지 않는 경우에는 이전 정상 버전으로 빠르게 복구한다.
반면 External Check 실패는 DNS, TLS, Nginx 등 Application 외부 원인일 수 있으므로 자동 Rollback하지 않고 원인을 먼저 확인한다.

근거


3. Image 검증

배포할 때 입력한 Git SHA와 실제 실행 중인 Container Image Tag가 같은지 확인한다.

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

이유

ECR에서 Image를 정상적으로 Pull했더라도 실제 Container가 이전 Image로 실행되고 있다면 원하는 버전이 배포된 것이 아니다.
따라서 Health Check 전에 실제 실행 Image를 먼저 확인한다.


4. Health Check

4-1. Internal Health Check

EC2 내부에서 각 Application이 정상적으로 요청을 처리할 수 있는지 확인한다.

서비스 확인 경로 성공 기준
Frontend http://127.0.0.1:3000/ HTTP 2xx, 3xx
Backend http://127.0.0.1:8080/actuator/health HTTP 2xx
AI http://127.0.0.1:8000/health HTTP 2xx
Redis redis-cli ping PONG

Frontend의 404는 정상으로 판단하지 않는다.

권장 기준:

connect timeout : 2초
request timeout : 5초
retry interval  : 2초
retry count     : 30회

이유

Container 시작 직후에는 Application 초기화가 끝나지 않았을 수 있으므로 즉시 1회 성공을 요구하지 않고 재시도한다.
제한 시간 안에 계속 실패하면 신규 Application이 정상적으로 기동하지 못한 것으로 판단하고 자동 Rollback한다.


4-2. External Health Check

실제 사용자 진입 경로가 정상인지 확인한다.

https://needu.gift/

성공 기준:

2xx / 3xx → 성공
404 / 5xx → 실패

확인 범위:

Internet
↓
Domain / DNS
↓
TLS
↓
Nginx
↓
Frontend

Backend는 /actuator/health로 Application 상태를 확인하고, AI는 외부에 직접 노출되지 않으므로 Internal Check만 수행한다.

이유

Internal Check가 성공해도 DNS, TLS, Nginx 등의 문제로 사용자가 실제 서비스에 접속하지 못할 수 있다.
따라서 실제 사용자 진입 URL을 별도로 확인한다.

단, /가 정상이라고 해서 Backend API와 AI 기능까지 모두 정상이라는 의미는 아니다.
External Health Check는 서비스 진입 경로 확인용으로 사용한다.


5. 실패 처리 기준

상황 처리
Image 검증 실패 자동 Rollback
Internal Health Check 실패 자동 Rollback
External Health Check 실패 원인 확인 후 필요 시 수동 Rollback
배포 후 신규 버전 문제 발견 수동 Rollback
CPU / Memory / DB 등 자원 부족 Recovery 수행

Internal 실패 시 자동 Rollback하는 이유

신규 Application 자체가 정상적으로 실행되지 않은 것이므로 신규 버전을 유지할 이유가 없다.

B1 정상
↓
B2 배포
↓
Internal Check 실패
↓
B1 자동 Rollback

External 실패 시 바로 Rollback하지 않는 이유

External 실패 원인은 Application Image뿐 아니라 다음과 같을 수 있다.

DNS
TLS 인증서
Nginx
Reverse Proxy
외부 Routing

따라서 External Check 실패만으로 Image 문제라고 판단하지 않는다.

External 실패
↓
배포 실패 기록
↓
원인 확인
↓
신규 버전 문제라면 수동 Rollback

근거


6. 버전 관리

서비스별로 현재 실행 버전과 직전 버전을 저장한다.

.frontend-current-tag
.frontend-previous-tag

.backend-current-tag
.backend-previous-tag

.ai-current-tag
.ai-previous-tag

예:

B1 → B2 정상 배포

current  = B2
previous = B1

이유

배포 직후에는 정상이었지만 운영 중 문제가 발견될 수 있다.
직전 버전을 보관하면 새로운 Image를 다시 빌드하지 않고 이전 버전으로 빠르게 복구할 수 있다.


7. Rollback

7-1. 자동 Rollback

Internal Health Check 실패 시 배포 직전 버전으로 자동 복구한다.

B1 실행
↓
B2 배포
↓
Internal Check 실패
↓
B1 재배포
↓
B1 Internal Check
↓
Rollback 완료

Rollback에 성공하더라도 B2 배포 자체는 실패한 것이므로 배포 Workflow는 Failed로 종료한다.

이유

Rollback 성공 여부와 신규 배포 성공 여부는 별개다.
이전 버전으로 복구되었더라도 신규 버전 B2는 정상 배포되지 않았기 때문에 실패로 기록한다.


7-2. 수동 Rollback

배포 이후 문제가 발견되거나 External 실패의 원인이 신규 버전으로 확인된 경우 실행한다.

Backend 예시:

PREVIOUS_TAG="$(cat .backend-previous-tag)"
./deploy-backend.sh "$PREVIOUS_TAG"

기존 배포 스크립트를 다시 사용하므로 Image 검증과 Health Check도 동일하게 수행된다.

이유

External 실패나 운영 중 장애는 신규 Image가 원인이라고 즉시 단정할 수 없다.
원인을 확인한 뒤 신규 버전 문제로 판단되는 경우에만 직전 버전으로 되돌린다.

근거


8. 배포 이력

배포 결과는 다음 파일에 기록한다.

/home/ubuntu/needu/.deployment-history.log

예:

service=backend from=B1 to=B2 result=SUCCESS
service=frontend from=F1 to=F2 result=EXTERNAL_CHECK_FAILED
service=ai from=A1 to=A2 result=INTERNAL_FAILED_ROLLED_BACK

주요 결과:

SUCCESS
EXTERNAL_CHECK_FAILED
INTERNAL_FAILED_ROLLED_BACK
ROLLBACK_FAILED

이유

장애 발생 시 어떤 버전이 언제 배포되었고 Rollback이 발생했는지 추적할 수 있어야 원인 확인과 복구가 쉬워진다.


9. Parameter Store

Application 설정값과 External URL은 Parameter Store에서 관리한다.

/needu/prod/backend
/needu/prod/ai
/needu/prod/deploy

External URL:

/needu/prod/deploy/EXTERNAL_SERVICE_URL
= https://needu.gift/

이유

배포 스크립트에 환경변수와 민감 정보를 직접 저장하지 않고 실행 시 필요한 값을 가져오기 위해 사용한다.

IAM Role에는 필요한 Parameter 경로에 대한 조회 권한만 부여하는 것을 원칙으로 한다.

근거


10. 부하 테스트 장애 Recovery

Rollback은 잘못된 Application 버전을 복구하기 위한 방법이다.

CPU, Memory, DB Connection, Disk I/O 등의 자원 부족으로 서버가 장애 상태가 된 경우에는 이전 Image로 바꿔도 동일한 문제가 발생할 수 있다.

대응 순서:

장애 감지
↓
추가 부하 중단
↓
CPU / Memory / Container / DB 상태 확인
↓
자원 안정화
↓
필요 시 장애 서비스 재기동
↓
Internal / External Health Check
↓
정상 확인
↓
더 낮은 부하부터 테스트 재개

Rollback 기준

신규 버전에서만 다음과 같은 성능 회귀가 확인되는 경우 Rollback한다.

  • 동일한 부하에서 이전 버전은 정상인데 신규 버전만 실패
  • 신규 버전의 CPU / Memory 사용량이 비정상적으로 증가
  • 신규 버전에서 5xx 오류율 증가
  • 신규 버전에서 DB Connection 사용량 증가

반대로 EC2 Capacity 자체가 부족한 경우에는 Rollback이 아니라 Capacity / Architecture 문제로 분류한다.

이유

부하 장애는 코드 버전 문제가 아니라 서버 자원 한계에서 발생할 수 있다.
이 경우 이전 Image로 되돌려도 동일한 부하가 다시 들어오면 같은 장애가 발생할 수 있으므로 먼저 부하를 제거하고 서비스를 복구해야 한다.

구체적인 RPS, VU, P95/P99, Error Rate, 테스트 중단 임계값은 M8 부하 테스트 문서에서 정의한다.

근거


11. 참고 자료

  1. AWS CodeDeploy - Redeploy and roll back a deployment
  2. AWS Systems Manager Parameter Store - Restricting access to parameters
  3. AWS Well-Architected Reliability Pillar - Test reliability
  4. AWS Well-Architected Reliability - Test resiliency using non-functional tests