CAPA — Argo 프로젝트 인증 어소시에이트 · 이벤트 전달과 중복 업무 효과 실험실 · 실습
주문은 하나인데 워크플로는 두 번: 이벤트 장애 실험실
목표
필터·권한·중복 처리의 경계를 실제 이벤트와 Workflow, 주문 장부로 검증합니다.
왜 중요한가
HTTP 200은 업무 완료가 아닙니다. 이 VM은 실제 k3s, Argo Events 1.9.11,
Workflows 4.1.3과 로컬 SQLite 장부를 준비합니다. 학생은 잘못된 Sensor의 필드를
수정하고, 도우미가 보내는 대조 입력의 실제 실행과 업무 효과를 비교합니다.
각 단계는 별도의 Sensor·포트를 사용하므로 2~8단계는 앞 단계를 건너뛰어도 시작할 수 있습니다.
9단계 준비는 손대지 않은 앞 단계 재료만 보충하며 학생의 수정·보고서를 덮지 않습니다.
단계
1. kubectl로 EventSource lesson, EventBus default와 Role sensor-submit을 읽습니다. /root/capa-events/inventory.json에 namespace=argo-events, eventsource=lesson, eventbus=default, submit_account=sensor-submit, workflow_account=workflow-runner, http_is_completion=false를 기록하세요. HTTP 접수와 Workflow 완료는 다른 경계입니다.
2. /root/capa-events/path.yaml에서 첫 data 필터의 path만 body.event.kind에서 body.kind로 바꾸고 도우미 run path를 실행하세요. 도우미가 잘못된 기준선과 수정본에 flat·nested 본문을 보냅니다. 기준선은 nested만, 수정본은 둘 다 실제 Workflow를 만들어야 합니다.
3. /root/capa-events/regex.yaml에서 첫 data 필터의 value만 ["^order[.]created$"]로 바꾸고 run regex를 실행합니다. pre-orderXcreated-tail은 기준선에서 승인되지만 수정 후 거부되고, order.created 대조군은 계속 실행돼야 합니다.
4. /root/capa-events/types.yaml의 기존 data 필터를 유지하고 filters.script에 return type(event.body.enabled) == "boolean" and event.body.enabled == true를 추가합니다. run types로 false·문자열 true·숫자 1·필드 없음·불리언 true를 비교하세요. 수정 후에는 마지막 입력만 실행돼야 합니다.
5. /root/capa-events/logic.yaml의 filters.dataLogicalOperator만 or에서 and로 바꾸고 run logic를 실행하세요. enabled=true인 order.deleted는 수정 후 거부하고 order.created는 실행해야 합니다. 필터 두 개와 다른 설정은 유지합니다.
6. /root/capa-events/repair-binding.yaml의 roleRef.name을 sensor-submit으로 바꿉니다. 이름 sensor-repair, namespace argo-events, kind Role, apiGroup rbac.authorization.k8s.io와 subjects의 argo-events ServiceAccount sensor-repair 하나를 유지하세요. rbac.yaml은 그대로 두고 run rbac를 실행합니다. Role은 Workflow create만 유지하고 추가 바인딩을 만들지 않습니다. 도우미는 무권한 기준선의 실제 forbidden을 보존하고 수정 계정의 새 요청을 확인합니다.
7. /root/capa-events/duplicate.yaml을 유지하고 run duplicate를 실행하세요. 동일 HTTP 본문 두 건에서 서로 다른 arrival 라벨과 Workflow UID 두 개를 확인합니다. 각 Workflow의 order-id는 같은 업무 키여야 하고 실제 파드가 성공 종료해야 합니다. 이 실험은 HTTP 두 요청이며 브로커 재전달 실험이 아닙니다.
8. /root/capa-events/ledger.yaml의 Workflow 컨테이너 args 마지막 URL에서 /naive만 /safe로 바꾸고 run ledger를 실행합니다. 주소·포트·1250 금액·업무 키 전달은 유지하세요. 기준선은 장부 효과 2건, 수정본은 효과 1건이어야 합니다. 두 Workflow는 모두 성공하고 수정본의 결과는 applied와 duplicate입니다. 도우미의 같은 키·다른 금액 요청은 409여야 합니다.
9. 앞선 실험을 완료한 뒤 run boundaries를 실행하세요. 장부 API에 동시 요청 16건, 응답을 읽지 않은 요청, 장부 서비스 재시작 뒤 같은 키의 재요청, 잘못된 금액 5종을 비교합니다. /root/capa-events/report.json에 duplicate_attempt와 boundary_attempt는 해당 현재 실행 ID, workflow_uids는 duplicate의 실제 UID 둘을 오름차순으로 적습니다. http_requests=2, workflow_executions=2, safe_effects=1, concurrent_requests=16, restart_preserved=true, broker_redelivery_proven=false, external_exactly_once_proven=false를 기록하세요. 장부 재시작은 VM·브로커 재시작이 아닙니다.
참고
- 실행:
python3 /opt/fixtures/capa-events/runtime.py run path(path 대신 해당 case). - 상태와 재관측: 같은 도우미의
status path,wait path. 대기 만료는 실패나 재전송의 근거가 아닙니다. - 종료한 동일 제출은 재사용합니다. 정말 새 비교가 필요할 때만
run path --new-attempt를 사용합니다. - 도우미가 가리키는
/var/lib/labhub/capa-events/runs/<attempt>/result.json은 관측 원문입니다. - 결과를 읽은 뒤
kubectl -n argo-events get workflows -l lesson=capa-events -o yaml로 현재 API와 대조합니다. - 실습은 55분입니다. 오래 걸리면 종료 전에 +시간으로 연장하세요. 세션 종료 뒤 파일·장부는 보존되지 않습니다.
- 동시 요청과 응답 미확인 실험은 장부 API 실험입니다. 단일 브로커·단일 VM이며 고가용성,
- [필터 공식 문서](https://argoproj.github.io/argo-events/sensors/filters/data/)
직접 편집하지 말고 after.events, after.executions의 Workflow metadata.uid·labels.arrival을 읽으세요.
브로커 재전달, 외부 결제·메일의 exactly-once를 증명하지 않습니다.
· [서비스 계정](https://argoproj.github.io/argo-events/service-accounts/)
· [SQLite 트랜잭션](https://sqlite.org/lang_transaction.html)
단계 9개
- 접수와 업무 완료의 경계 찾기
- 없는 JSON 경로를 정상 대조군으로 구별
- 정규식의 과대 매칭 막기
- 참 같은 값과 진짜 JSON 불리언 구별
- 조건 하나만 참인 요청 거절
- 실제 forbidden을 최소 권한으로 복구
- 같은 주문의 서로 다른 두 실행 추적
- 두 실행을 하나의 업무 효과로 제한
- 동시 요청·재시작 경계와 미검증 범위 보고