注文は1件、ワークフローは2回:イベント障害実験室
目標
フィルター・権限・重複処理の境界を、実際のイベントとWorkflow、注文帳簿で検証します。
なぜ重要なのか
HTTP 200は、業務の完了ではありません。このVMは、実際のk3s、Argo Events 1.9.11、Workflows 4.1.3と、ローカルのSQLite帳簿を用意します。受講者は、誤ったSensorのフィールドを修正し、ヘルパーが送る対照入力の実際の実行と、業務の効果を比較します。各ステップは、別々のSensor・ポートを使うため、ステップ2–8は、前のステップを飛ばしても開始できます。ステップ9の準備は、手を付けていない前のステップの材料だけを補充し、受講者の修正・レポートを上書きしません。
ステップ
- 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の完了は、別の境界です。
- /root/capa-events/path.yamlで、最初のdataフィルターのpathだけを、body.event.kindからbody.kindに変えて、ヘルパーのrun pathを実行してください。ヘルパーが、誤った基準線と修正版に、flatとnestedの本文を送ります。基準線はnestedだけ、修正版は両方で、実際のWorkflowを作る必要があります。
- /root/capa-events/regex.yamlで、最初のdataフィルターのvalueだけを、["^order[.]created$"]に変えて、run regexを実行します。pre-orderXcreated-tailは、基準線では承認されますが、修正後は拒否され、order.createdの対照群は、引き続き実行される必要があります。
- /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を比較してください。修正後は、最後の入力だけが実行される必要があります。
- /root/capa-events/logic.yamlのfilters.dataLogicalOperatorだけを、orからandに変えて、run logicを実行してください。enabled=trueのorder.deletedは修正後に拒否し、order.createdは実行する必要があります。2つのフィルターと、ほかの設定は維持します。
- /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 1つを維持してください。rbac.yamlはそのままにして、run rbacを実行します。RoleはWorkflowのcreateだけを維持し、追加のバインディングを作らないでください。ヘルパーは、権限なしの基準線の実際のforbiddenを保全し、修正アカウントの新しいリクエストを確認します。
- /root/capa-events/duplicate.yamlを維持して、run duplicateを実行してください。同一のHTTP本文2件から、異なるarrivalラベルとWorkflow UID2つを確認します。各Workflowのorder-idは、同じ業務キーである必要があり、実際のPodが成功して終了する必要があります。この実験は、HTTP2リクエストであり、ブローカーの再配信の実験ではありません。
- /root/capa-events/ledger.yamlのWorkflowのコンテナargsの最後のURLで、/naiveだけを/safeに変えて、run ledgerを実行します。アドレス・ポート・1250の金額・業務キーの受け渡しは維持してください。基準線は帳簿の効果2件、修正版は効果1件である必要があります。2つのWorkflowはどちらも成功し、修正版の結果は、appliedとduplicateです。ヘルパーの、同じキーで金額が違うリクエストは、409である必要があります。
- 前の実験を完了したあとで、run boundariesを実行してください。帳簿APIに、同時リクエスト16件、レスポンスを読まないリクエスト、帳簿サービスの再起動後の同じキーの再リクエスト、誤った金額5種を比較します。/root/capa-events/report.jsonに、duplicate_attemptとboundary_attemptは、該当する現在の実行ID、workflow_uidsは、duplicateの実際のUID2つを昇順で書きます。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は、観測の原文です。直接編集せず、after.events、after.executionsのWorkflowのmetadata.uid・labels.arrivalを読んでください。 - 結果を読んだあとで、
kubectl -n argo-events get workflows -l lesson=capa-events -o yamlで、現在のAPIと照合します。 - ラボは55分です。長くかかる場合は、終了前に「+時間」ボタンで延長してください。セッション終了後、ファイルと帳簿は保持されません。
- 同時リクエストと、レスポンス未確認の実験は、帳簿APIの実験です。単一ブローカー・単一VMであり、高可用性、ブローカーの再配信、外部の決済・メールのexactly-onceを証明するものではありません。
- フィルターの公式ドキュメント・ServiceAccount・SQLiteトランザクション
受付と業務完了の境界を見つける
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と値の比較を、あわせて使います。
条件1つだけが真のリクエストを拒否する
/root/capa-events/logic.yamlのfilters.dataLogicalOperatorだけを、orからandに変えて、run logicを実行してください。enabled=trueのorder.deletedは修正後に拒否し、order.createdは実行する必要があります。2つのフィルターと、ほかの設定は維持します。
各条件の意味が合っていても、2つの条件を組み合わせる演算子が違えば、許可の集合が変わります。
実際の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 1つを維持してください。rbac.yamlはそのままにして、run rbacを実行します。RoleはWorkflowのcreateだけを維持し、追加のバインディングを作らないでください。ヘルパーは、権限なしの基準線の実際のforbiddenを保全し、修正アカウントの新しいリクエストを確認します。
Workflowを作るSensorのアカウントと、作られたWorkflowの実行アカウントは違います。管理者ではなく、既存の最小のRoleを結び付けてください。
同じ注文の、別々の2つの実行を追跡する
/root/capa-events/duplicate.yamlを維持して、run duplicateを実行してください。同一のHTTP本文2件から、異なるarrivalラベルとWorkflow UID2つを確認します。各Workflowのorder-idは、同じ業務キーである必要があり、実際のPodが成功して終了する必要があります。この実験は、HTTP2リクエストであり、ブローカーの再配信の実験ではありません。
ヘルパーの結果パスで、eventsとafter.executionsを比べます。業務キーが同じでも、到着IDと実行UIDは違うことがあります。
2つの実行を、1つの業務効果に制限する
/root/capa-events/ledger.yamlのWorkflowのコンテナargsの最後のURLで、/naiveだけを/safeに変えて、run ledgerを実行します。アドレス・ポート・1250の金額・業務キーの受け渡しは維持してください。基準線は帳簿の効果2件、修正版は効果1件である必要があります。2つの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の実際のUID2つを昇順で書きます。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を使ってください。