LabHub
배우기 러닝패스 코스

CAPA — Argoプロジェクト認定アソシエイト

注文は1件、ワークフローは2回:イベント障害実験室

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

필터·권한·중복 처리의 경계를 실제 이벤트와 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·브로커 재시작이 아닙니다.

참고

접수와 업무 완료의 경계 찾기

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 완료는 다른 경계입니다.

kubectl -n argo-events get eventsource lesson -o yaml과 get role sensor-submit -o yaml로 실제 객체를 읽습니다.

없는 JSON 경로를 정상 대조군으로 구별

/root/capa-events/path.yaml에서 첫 data 필터의 path만 body.event.kind에서 body.kind로 바꾸고 도우미 run path를 실행하세요. 도우미가 잘못된 기준선과 수정본에 flat·nested 본문을 보냅니다. 기준선은 nested만, 수정본은 둘 다 실제 Workflow를 만들어야 합니다.

HTTP body와 Argo 이벤트 봉투의 body를 구별하세요. 실행이 없다는 것만 보지 말고 nested 대조군의 성공도 확인합니다.

정규식의 과대 매칭 막기

/root/capa-events/regex.yaml에서 첫 data 필터의 value만 ["^order[.]created$"]로 바꾸고 run regex를 실행합니다. pre-orderXcreated-tail은 기준선에서 승인되지만 수정 후 거부되고, order.created 대조군은 계속 실행돼야 합니다.

점은 기본적으로 임의 문자이고 앵커가 없으면 부분 문자열도 일치할 수 있습니다.

참 같은 값과 진짜 JSON 불리언 구별

/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를 비교하세요. 수정 후에는 마지막 입력만 실행돼야 합니다.

type: bool의 변환 결과만으로 원본 타입을 단정하지 않습니다. Lua의 type과 값 비교를 함께 씁니다.

조건 하나만 참인 요청 거절

/root/capa-events/logic.yaml의 filters.dataLogicalOperator만 or에서 and로 바꾸고 run logic를 실행하세요. enabled=true인 order.deleted는 수정 후 거부하고 order.created는 실행해야 합니다. 필터 두 개와 다른 설정은 유지합니다.

각 조건의 의미가 맞아도 두 조건을 묶는 연산자가 다르면 허용 집합이 달라집니다.

실제 forbidden을 최소 권한으로 복구

/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을 보존하고 수정 계정의 새 요청을 확인합니다.

Workflow를 만드는 Sensor 계정과 만들어진 Workflow의 실행 계정은 다릅니다. 관리자가 아니라 기존 최소 Role을 연결하세요.

같은 주문의 서로 다른 두 실행 추적

/root/capa-events/duplicate.yaml을 유지하고 run duplicate를 실행하세요. 동일 HTTP 본문 두 건에서 서로 다른 arrival 라벨과 Workflow UID 두 개를 확인합니다. 각 Workflow의 order-id는 같은 업무 키여야 하고 실제 파드가 성공 종료해야 합니다. 이 실험은 HTTP 두 요청이며 브로커 재전달 실험이 아닙니다.

도우미 결과 경로에서 events와 after.executions를 비교합니다. 업무 키가 같아도 도착 ID와 실행 UID는 다를 수 있습니다.

두 실행을 하나의 업무 효과로 제한

/root/capa-events/ledger.yaml의 Workflow 컨테이너 args 마지막 URL에서 /naive만 /safe로 바꾸고 run ledger를 실행합니다. 주소·포트·1250 금액·업무 키 전달은 유지하세요. 기준선은 장부 효과 2건, 수정본은 효과 1건이어야 합니다. 두 Workflow는 모두 성공하고 수정본의 결과는 applied와 duplicate입니다. 도우미의 같은 키·다른 금액 요청은 409여야 합니다.

URL은 spec.triggers[0].template.k8s.source.resource.spec.templates[0].container.args에 있습니다. 저장하기 전에 원본 주소를 읽으세요.

동시 요청·재시작 경계와 미검증 범위 보고

앞선 실험을 완료한 뒤 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·브로커 재시작이 아닙니다.

runtime.py status CASE가 가리키는 result.json 원문을 읽습니다. 관측 대기가 끝나지 않았으면 새 실험을 만들지 말고 같은 핸들의 wait를 쓰세요.