RCA 2026.11.09 7 min read

이전 이미지 복귀와 신규 이미지 재적용에서 데이터 보존 확인하기

Pod가 새로 뜨는지만으로는 충분하지 않았다. 실행 이미지가 의도한 digest인지, 노드 분산은 유지되는지, 로그인과 API는 동작하는지, 기존 보고서와 DB 스키마 이력은 그대로인지 함께 살펴봤다. 각 단계를 확인한 뒤 다음 단계로 넘어갔다.

Platform Pod를 두 Worker에 한 개씩 배치하도록 수정한 뒤, 실제 이미지 복귀 경로를 시험했다. 승인한 이전 정상 이미지로 돌아갔다가 처음 검증한 신규 이미지를 다시 적용하는 순서였다.

Pod가 새로 뜨는지만으로는 충분하지 않았다. 실행 이미지가 의도한 digest인지, 노드 분산은 유지되는지, 로그인과 API는 동작하는지, 기존 보고서와 DB 스키마 이력은 그대로인지 함께 살펴봤다. 각 단계를 확인한 뒤 다음 단계로 넘어갔다.

전환 대상과 유지할 상태를 먼저 정했다

이번 시험의 변경 대상은 Platform 애플리케이션 image였다. 앞서 수정한 topology 조건은 유지하고, image digest만 이전 값으로 되돌렸다. DB와 PVC, Secret, NFS 설정은 이 전환 범위에 포함하지 않았다.

Argo CD가 관리하는 기존 리소스 여덟 개와 기존 Helm revision 4의 관리 경계도 유지했다. Deployment를 선택해 수동 Sync하는 방식을 사용했으며, 각 단계는 검토한 Git revision을 지정해 진행했다.

이미지 전환 전에 기준으로 남긴 것은 실행 imageID와 Worker별 Pod 배치, 관리 리소스 identity, DB StatefulSet과 PVC 및 PV 상태, 기존 보고서와 migration 메타데이터였다. 변경 후 같은 항목을 다시 확인할 수 있어야 했다.

이전 이미지로 돌아갔다가 동일 신규 이미지를 적용했다

첫 단계에서는 수정된 topology를 유지한 이전 image 참조를 적용했다. 별도 Sync operation이 성공한 뒤 두 Worker에 한 개씩 Ready인 것을 확인했다. 실제 runtime imageID도 이전 digest와 맞았다.

이때 Application의 OutOfSync는 예상한 상태였다. main이 기술하는 대상은 신규 이미지인데, 시험을 위해 실행 상태를 이전 이미지로 바꿨기 때문이다. Health와 Sync 상태를 함께 읽고, 적용한 operation revision과 실제 이미지를 대조했다.

다음 단계에서는 처음 검증했던 동일한 신규 digest를 다시 적용했다. 새로 빌드한 다른 이미지가 아니라 같은 대상이었다. 최종적으로 Worker마다 한 개씩 Ready, 재시작 0, Deployment generation 8과 observedGeneration 8을 확인했다. Application은 Healthy/Synced였다.

두 Worker의 Platform Pod image 참조와 runtime imageID
두 Worker의 Platform Pod image 참조와 runtime imageID.
단계 적용 내용 Deployment 상태와 배치
topology 수정 완료 신규 이미지와 revision별 분산 조건 generation 6, Worker별 한 개
이전 이미지 복귀 topology 유지, image만 이전 digest generation 7, Worker별 한 개 Ready
동일 신규 이미지 재적용 처음 검증한 신규 digest generation 8과 observedGeneration 8, Worker별 한 개 Ready
Argo CD의 현재 건강·Sync·수동 정책 요약
Healthy·Synced, Auto Sync 비활성, 1 Warning.

서비스와 관찰 결과를 함께 남겼다

각 단계에서 HTTPS와 사설 CA 및 SNI 검증, readiness와 DB 연결, React 응답, 로그인과 인증 API를 확인했다. 최종 검사에서 인증한 metrics는 200, 미인증 요청은 401이었고 Secure cookie 설정도 확인했다.

image cycle의 readiness 관찰은 10초 간격 43회로, 기록상 약 430초 동안 진행했다. 모든 sample에서 HTTP 200과 DB reachable이 확인됐고 실패는 0회였다. 이는 해당 간격의 요청이 성공했다는 결과로 남겼다. 샘플 사이까지 포함한 연속 가용성으로 확대하지 않았다.

최종 새 Pod 두 개는 Prometheus에서 UP이었다. Kubernetes 세 노드가 Ready이고 pressure가 없는지, 기존 인프라 알림이 inactive인지도 확인했다. Alertmanager 설정 해시는 같았고 운영 Agent는 기존 safe canary를 유지했다.

Prometheus에서 UP으로 표시된 Platform 수집 대상 두 개
RCA Platform 수집 대상 2개 모두 UP.

보고서와 스키마 이력의 보존을 확인했다

기존 보고서 두 개는 canonical hash로 비교했다. 최종 검사에서 변경과 누락은 0개였다. PostgreSQL의 Flyway V1~26 성공 이력과 메타데이터 해시도 유지됐다.

DB StatefulSet의 identity와 generation, Bound 상태의 8Gi PVC, Retain 정책의 PV도 확인했다. 애플리케이션 이미지를 바꾸는 작업이 DB 리소스와 영속 볼륨을 교체하는 작업으로 번지지 않았는지 살펴본 것이다.

PostgreSQL StatefulSet과 8Gi Bound PVC
PostgreSQL StatefulSet과 8Gi Bound PVC.

이 검사 범위는 정해진 보고서와 스키마 메타데이터, 리소스 identity였다. 전체 DB row가 모두 동일하다는 의미는 아니다. 정상적인 애플리케이션 시작이나 스케줄러의 쓰기가 전혀 없었다고 판단한 것도 아니다. 확인한 대상의 보존과 DB 전체의 변경 여부는 구분했다.

이미지 복귀와 백업 복원은 따로 검증해야 했다

DB 백업은 AES-256-GCM으로 암호화해 보관했다. 새 백업은 89,331바이트였고 카탈로그 항목은 168개였다. 인증된 복호화와 PGDMP 형식, pg_restore-list 확인까지 진행했으며 이전 백업도 보존했다.

이 결과는 백업 파일을 만들고 해독해 목록을 읽을 수 있었다는 범위다. 실제 DB에 복원하거나 archive 전체 데이터 블록, VM 부팅까지 시험하지는 않았다. 키는 별도 보호 경로에 보관했으며 실제 복원은 다음 과제로 남겼다.

이번 이미지 복귀는 Helm rollback이나 schema 다운그레이드와도 다르다. 선택한 Deployment를 Sync했으므로 일반 Argo revision history의 ID를 선택하는 절차로 설명하지 않았다. 애플리케이션 이미지를 이전 digest로 바꾸고 그 상태에서 서비스와 데이터를 확인한 시험이었다.

다음 변경에서도 다시 확인할 것

각 전환은 새 preview와 기준 상태, 개별 승인, 고유 operation, 실제 실행 이미지와 서비스 검사로 나눴다. 한 단계의 결과가 불명확하면 다음 단계로 자동 진행하지 않았다.

최종 상태에서는 신규 이미지가 두 Worker에 분산돼 실행됐고 서비스와 정해진 데이터 검사가 통과했다. 다음 배포에서도 이 확인 항목을 사용할 수 있다. 다만 다른 소스와 이미지, DB 변경이 들어가면 그때의 diff와 호환성, 용량을 다시 살펴봐야 한다. 이번 전환의 성공은 다음 변경을 검토할 기준으로 남겼다.

SEARCH JOURNAL

기록 검색

글 제목, 요약, 태그에서 찾습니다.

검색을 준비하고 있어요.

검색어를 입력해 주세요.

    Ctrl/⌘ K 검색 Esc 닫기 ↑ ↓ 결과 이동