CGOA — GitOps 인증 어소시에이트 · 삭제도 배포다: 보존과 승인 사이의 경계 · 실습
지웠는데 남았다: GitOps 삭제 보호 실험
목표
Git 삭제 의도, 객체별 보호, 승인, 빈 목표 거부를 실제 Argo CD와 k3s에서 구별합니다.
왜 중요한가
OutOfSync는 보호가 동작한 결과일 수 있고, Succeeded는 현재 커밋의 결과가 아닐 수 있습니다.
운영 LabHub·외부 저장소·사용자 데이터·PVC는 건드리지 않습니다. 개인 VM의 cgoa-prune-safety Namespace와
전용 Application 두 개만 사용합니다. 실제 삭제 대상은 학습용 문자열을 담은 ConfigMap입니다.
Namespace·Application·공유 컨트롤러는 삭제하지 마세요. 전역 보안 설정이나 권한을 바꾸지 않습니다.
55분 실습입니다. 세션 만료 전에 필요하면 시간을 연장하고 관측을 보관하세요. 종료 시 VM과 파일은 회수됩니다.
준비된 환경과 도우미
/srv/cgoa-prune-safety는 작업 Git, /srv/bare/cgoa-prune-safety.git은 VM 내부 원격 저장소입니다.
Application cgoa-prune-safety는 app 디렉터리, cgoa-prune-safety-empty는 empty 디렉터리를 읽습니다.
main 이름 대신 실제 SHA를 대조하세요. 관측 파일은 /root/cgoa-prune에 있습니다.
과제의 key=value는 설명 표기입니다. JSON 파일에는 형식 예시처럼 키와 문자열에 따옴표를 쓰고 불리언은 true/false로 적으세요.
python3 /opt/fixtures/cgoa_prune_lab.py observe는 현재 Git·Application·ConfigMap을 읽습니다.
같은 도우미의 complete N은 입력을 검토하고 한정된 변경 뒤 실제 관측을 저장합니다.
2·3·4·5단계는 Git 변경, 6단계는 삭제 승인, 7단계는 빈 목표 검토 뒤 정책 변경, 8단계는 기본 정책·Git 복원입니다.
7단계의 preview-empty는 Git에서 마지막 대상만 제거해 보호를 먼저 관측하며, 삭제 허용은 별도 답안과 complete 7이 필요합니다.
git show로 도우미가 만든 변경을 직접 검토하세요. 기존 미완성 Git 변경이나 부분 답안은 덮어쓰지 않고 멈춥니다.
solve N은 정답 보기와 동일하며 없는 현재 답안만 작성합니다. prepare N은 없는 이전 단계만 준비하고 현재 답안은 만들지 않습니다.
grade N은 읽기만 합니다. 완료된 단계를 다시 실행해도 삭제나 관측 생성을 반복하지 않습니다.
단계
1. git -C /srv/cgoa-prune-safety rev-parse HEAD와 baseline.json을 읽으세요. identity.json에 revision=실제 커밋 SHA, namespace=cgoa-prune-safety 문자열을 적고 complete 1을 실행합니다. observation-1.json에서 두 Application의 source.path와 ConfigMap 다섯 개의 소유권·UID를 확인하세요.
2. baseline.json의 configmaps.normal.uid를 확인하세요. normal.json에 remove=normal, uid=확인한 UID 문자열을 적고 complete 2를 실행합니다. 도우미는 app 디렉터리의 normal만 Git에서 제거합니다. git show와 observation-2.json에서 normal만 없어지고 Synced/Succeeded인지, 나머지 UID는 그대로인지 확인하세요.
3. retention.json에 remove=retained, option=Prune=false, expected_sync=OutOfSync 문자열을 적고 complete 3을 실행하세요. Git에서 retained가 없어져도 실제 UID는 유지됩니다. observation-3.json의 operationState.syncResult.resources에서 PruneSkipped를 찾아 Succeeded와 OutOfSync가 함께 있는 이유를 설명하세요.
4. restore.json에 fix_source=git 문자열, same_object=true 불리언을 적고 complete 4를 실행합니다. Git 정의가 되돌아온 뒤 retained가 같은 UID이고 Synced인지 확인하세요. live 객체를 지우거나 다시 만드는 방식은 이 과제의 보존이 아닙니다.
5. pending.json에 remove=confirmed, expected_operation=Running 문자열, approved=false 불리언을 적고 complete 5를 실행하세요. observation-5.json에서 승인 대기 메시지와 requiresPruning 대상이 confirmed 한 개인지 확인합니다. Running을 컨트롤러 장애로 단정하지 마세요.
6. observation-5.json에서 apps.app.uid와 configmaps.confirmed.uid를 읽으세요. approval.json에 approve=true 불리언, app_uid와 target_uid를 해당 UID 문자열로 적고 complete 6을 실행합니다. 도우미는 지금도 검토한 객체·범위인지 대조한 뒤 Application에 승인 시각을 기록합니다. Git 커밋은 그대로인데 confirmed가 삭제되고 Synced/Succeeded가 됐는지 확인하세요.
7. 먼저 preview-empty를 실행하세요. empty 디렉터리의 목표를 유효한 빈 List로 바꾸지만 삭제는 허용하지 않습니다. guard-7.json의 snapshot.revision과 apps.empty.status.operationState.syncResult.revision이 다르고 SyncError이며 disposable UID가 보존됐는지 읽으세요. empty.json에 allow_empty=true, previous_success_is_current=false 불리언, revision=검토한 현재 SHA, target_uid=disposable UID 문자열을 적고 complete 7을 실행합니다. 같은 Git에서 정책만 바뀌어 disposable만 삭제되는지 확인하세요.
8. decision.json에 restore_git=true, allow_empty=false, same_object=false, backup_verified=false 불리언을 적고 complete 8을 실행하세요. 기본 보호를 false로 복원하고 Git 정의를 되돌립니다. observation-8.json에서 disposable은 새 UID, retained와 anchor는 기준 UID인지 확인하세요. 선언 복원과 데이터 백업 검증을 구분하여 보고합니다.
주의와 해석
retained와 anchor는 끝까지 기준 UID·데이터를 유지합니다. disposable은 삭제와 복원 뒤 새 UID여야 합니다.
승인할 대상 UID와 현재 범위가 달라지면 멈춥니다. 승인 주석은 Application 단위라는 사실을 잊지 마세요.
빈 목표는 읽기 실패가 아니라 유효한 List의 items=[]입니다. 거부 메시지뿐 아니라 현재 revision·정책·보존 객체를 함께 확인합니다.
완료 기록의 해시는 실수로 파일을 덮어쓴 것을 탐지합니다. 같은 VM root의 모든 위조를 방지하는 보안 보증이 아닙니다.
pending 저널이 남으면 변경 완료 여부를 추측해 다시 삭제하지 않습니다. 자료를 보관하고 새 실습에서 시작하세요.
채점은 60초, 이전 단계 준비는 90초 예산입니다. 수렴 대기는 complete에서만 합니다.
[Argo CD 동기화 옵션](https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/) ·
[자동 동기화와 빈 목표](https://argo-cd.readthedocs.io/en/stable/user-guide/auto_sync/).
단계 8개
- Git과 객체 수명의 기준선 읽기
- 보호 없는 객체의 실제 삭제 확인하기
- 삭제를 건너뛴 성공과 차이 구별하기
- Git 복원으로 같은 객체 보존하기
- 승인 대기와 삭제 대상 확인하기
- 검토한 UID에 한정하여 승인하기
- 빈 목표 거부를 관측한 뒤 명시적으로 허용하기
- 기본 보호와 Git을 복원하고 한계 보고하기