ЁЯПл The SchoolтА║ЁЯЫая╕П SREтА║ЁЯзп рдзрдбрд╛ 11 тАФ Chaos engineering рдЖрдгрд┐ game days: рдореБрджреНрджрд╛рдо, рдкрдг рдХрд╛рд│рдЬреАрдкреВрд░реНрд╡рдХ рдмрд┐рдШрдбрд╡рд╛
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯзп рдзрдбрд╛ 11 тАФ Chaos engineering рдЖрдгрд┐ game days: рдореБрджреНрджрд╛рдо, рдкрдг рдХрд╛рд│рдЬреАрдкреВрд░реНрд╡рдХ рдмрд┐рдШрдбрд╡рд╛

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 11 ┬╖ рдорд╛рдЧреЗ: lesson-10-overload ┬╖ рдкреБрдвреЗ: lesson-12-production-readiness


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбрд╛ 10, рдЕрдзрд┐рдХ рдзрдбреЗ 07тАУ10 рдордзреАрд▓ designs рддрдкрд╛рд╕рдгрд╛рд░рд╛ рдкреНрд░рдпреЛрдЧ. Chaos experiment рдордзреНрдпреЗ рдПрдХ hypothesis, рдЫреЛрдЯреА blast radius рдЖрдгрд┐ рд▓рд┐рд╣реВрди рдареЗрд╡рд▓реЗрд▓реНрдпрд╛ abort рдЪреНрдпрд╛ рдЕрдЯреА рдЕрд╕рддрд╛рдд. Game day рдореНрд╣рдгрдЬреЗ рддреНрдпрд╛рдЪреАрдЪ, рдЦреЛрд▓реАрдд рд▓реЛрдХ рдЕрд╕рд▓реЗрд▓реА, рдирд┐рдпреЛрдЬрд┐рдд рдЖрд╡реГрддреНрддреА. sre/design.py рдордзреАрд▓ ChaosExperiment рдЖрдгрд┐ sre/demo.py рдордзреАрд▓ chaos().

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рдкрдердХ рдореНрд╣рдгрддреЗ: "рдкреВрд░реНрд╡ рдмрд╛рдЬреВрдЪреА рд╡реАрдЬ рдЧреЗрд▓реА, рддрд░реА рдЙрд░рд▓реЗрд▓реНрдпрд╛ рдмрд╛рдЬреВ рд╕рдЧрд│реЗ рд╡рд░реНрдЧ рдЪрд╛рд▓рд╡реВ рд╢рдХрддрд╛рдд." ЁЯПл рд╣реЗ рдЦрд░реЗ рдЖрд╣реЗ рдХрд╛? рдХреЛрдгрд╛рд▓рд╛рдЪ рдорд╛рд╣реАрдд рдирд╛рд╣реА. рддреНрдпрд╛рдВрдиреА рдХрдзреАрдЪ рдХрд░реВрди рдкрд╛рд╣рд┐рд▓реЗрд▓реЗ рдирд╛рд╣реА.

рдореНрд╣рдгреВрди рддреЗ рдПрдХ test рдард░рд╡рддрд╛рдд. рдкрдг рд╕рдВрдкреВрд░реНрдг рд╢рд╛рд│реЗрд╡рд░ рдирд╛рд╣реА тАФ рдлрдХреНрдд рд╡рд░реНрдЧрд╛рдВрдЪреНрдпрд╛ рдПрдХрд╛ block рд╡рд░, рдореНрд╣рдгрдЬреЗ рджрд╣рд╛рд╡реНрдпрд╛ рднрд╛рдЧрд╛рдЪреНрдпрд╛ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреАрдВрд╡рд░. рддреЗ рдЖрдзреА рд▓рд┐рд╣реВрди рдареЗрд╡рддрд╛рдд: "рдЬрд╡рд│рдЬрд╡рд│ рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдЪрд╛рд▓реВ рд░рд╛рд╣реАрд▓ рдЕрд╢реА рдЖрдордЪреА рдЕрдкреЗрдХреНрд╖рд╛ рдЖрд╣реЗ. 100 рдкреИрдХреА 1 рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рд╡рд░реНрдЧ рдерд╛рдВрдмрд▓реЗ, рддрд░ рдЖрдореНрд╣реА рд▓рдЧреЗрдЪ рд╡реАрдЬ рдкрд░рдд рд╕реБрд░реВ рдХрд░реВ."

рдкрд╣рд┐рд▓реНрдпрд╛ block рдЪреЗ рд╡рд░реНрдЧ рддреАрди рдмрд╛рдЬреВрдВрдордзреНрдпреЗ рдЖрд╣реЗрдд. рддреЗ рдкреВрд░реНрд╡ рдмрд╛рдЬреВрдЪреА рд╡реАрдЬ рдмрдВрдж рдХрд░рддрд╛рдд. рдЙрд░рд▓реЗрд▓реНрдпрд╛ рджреЛрди рдмрд╛рдЬреВ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреАрдВрдирд╛ рд╕рд╛рдорд╛рд╡реВрди рдШреЗрддрд╛рдд. рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдЪрд╛рд▓реВ рд░рд╛рд╣рддреЛ. тЬЕ рдХрд▓реНрдкрдирд╛ рдмрд░реЛрдмрд░ рд╣реЛрддреА.

рджреБрд╕рд▒реНрдпрд╛ block рдЪреЗ рд╡рд░реНрдЧ рдлрдХреНрдд рджреЛрди рдмрд╛рдЬреВрдВрдордзреНрдпреЗ рдЖрд╣реЗрдд. рддреЗ рдПрдХ рдмрдВрдж рдХрд░рддрд╛рдд. рдЬрд╡рд│рдЬрд╡рд│ рдЕрд░реНрдзреЗ рд╡рд░реНрдЧ рдерд╛рдВрдмрддрд╛рдд! рдПрдХрд╛ рдорд┐рдирд┐рдЯрд╛рдЪреНрдпрд╛ рдЖрдд рдХрддрд░рд┐рдирд╛ рд╡реАрдЬ рдкрд░рдд рд╕реБрд░реВ рдХрд░рддреЗ. рдХрд╛рд╣реА рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреАрдВрдирд╛ рдПрдХ рдорд┐рдирд┐рдЯ рддреНрд░рд╛рд╕ рдЭрд╛рд▓рд╛ тАФ рдкрдг рдлрдХреНрдд рдПрдХрд╛ block рдордзреНрдпреЗ, рдЖрдгрд┐ рдЖрддрд╛ рдкрдердХрд╛рд▓рд╛ рдорд╛рд╣реАрдд рдЖрд╣реЗ рдХреА рджреБрд╕рд▒реНрдпрд╛ block рд▓рд╛ рддрд┐рд╕рд░реА рдмрд╛рдЬреВ рд╣рд╡реА, рдЦрд░реА рд╡реАрдЬ рдЧреЗрд▓реНрдпрд╛рд╡рд░ рд╕рдВрдкреВрд░реНрдг рд╢рд╛рд│реЗрд╕рдореЛрд░ рд╣реЗ рд╢рд┐рдХрдгреНрдпрд╛рдЖрдзреАрдЪ.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    h["ЁЯУЭ hypothesis<br/>lose zone B тЖТ success тЙе 99.5%"] --> x["ЁЯТе inject at minute 3<br/>one cell = 10% of users"]
    x --> a["cell A: 6 replicas, 3 zones<br/>800 тЙе 700 req/s тЖТ 100%<br/>hypothesis held"]
    x --> b["cell B: 4 replicas, 2 zones<br/>400 of 700 req/s тЖТ 57%"]
    b --> ab["ЁЯЫС abort (< 99%) at minute 3<br/>fault undone ┬╖ 18,000 failed"]

ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/sre/lesson-diagrams.html#l11

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдХрд╛рд░рдг рдпрд╛ course рдордзреАрд▓ рдкреНрд░рддреНрдпреЗрдХ design рд╣рд╛ рдПрдХ рджрд╛рд╡рд╛ рдЖрд╣реЗ тАФ "N+1 zones" (рдзрдбрд╛ 07), "failover рдЪрд╛рд▓рддреЛ" (рдзрдбрд╛ 09), "рдЖрдореНрд╣реА sheddable рдЖрдзреА shed рдХрд░рддреЛ" (рдзрдбрд╛ 10) тАФ рдЖрдгрд┐ рди рддрдкрд╛рд╕рд▓реЗрд▓реЗ рджрд╛рд╡реЗ рдкрд╣рд╛рдЯреЗ 3 рд╡рд╛рдЬрддрд╛ рдЕрдпрд╢рд╕реНрд╡реА рд╣реЛрддрд╛рдд. рдЦрд░реЗ outages рд╕рд░реНрд╡рд╛рдд рд╡рд╛рдИрдЯ рдХреНрд╖рдг рдЖрдгрд┐ рд╕рдВрдкреВрд░реНрдг blast radius рдирд┐рд╡рдбрддрд╛рдд. рдкреНрд░рдпреЛрдЧ рд╡реЗрд│, рдЖрдХрд╛рд░ рдЖрдгрд┐ рдерд╛рдВрдмрд╡рдгреНрдпрд╛рдЪреЗ рдмрдЯрдг рдирд┐рд╡рдбрддреЛ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

sre/design.py рдордзреНрдпреЗ ChaosExperiment(replicas_per_zone, zones, per_replica_rps, load_rps, hypothesis=0.995, abort=0.99). run(minutes=10, inject_at=3, fault_minutes=5) рдорд┐рдирд┐рдЯрд╛-рдорд┐рдирд┐рдЯрд╛рдиреЗ рдЪрд╛рд▓рддреЗ: рдмрд┐рдШрд╛рдб рдЪрд╛рд▓реВ рдЕрд╕рддрд╛рдирд╛ рдПрдХрд╛ zone рдЪреЗ replicas рдирд╕рддрд╛рдд; success = min(1, capacity ├╖ load). рдПрдЦрд╛рджрд╛ minute abort рд░реЗрд╖реЗрдЦрд╛рд▓реА рдЧреЗрд▓рд╛, рддрд░ рдкреБрдврдЪреНрдпрд╛ minute рдкрд╛рд╕реВрди рдмрд┐рдШрд╛рдб рдЙрд▓рдЯрд╡рд▓рд╛ рдЬрд╛рддреЛ. рддреЗ рдкреНрд░рддреНрдпреЗрдХ minute рдЪреЗ rates, abort рдЪрд╛ minute, рдЕрдпрд╢рд╕реНрд╡реА requests рдЖрдгрд┐ рдирд┐рдХрд╛рд▓ рдкрд░рдд рджреЗрддреЗ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 sre/demo.py chaos
python3 - <<'EOF'
import sys; sys.path.insert(0, "sre"); from design import ChaosExperiment
for load in (600, 700, 800, 900):
    rates, ab, failed, verdict = ChaosExperiment(2, 3, 200, load).run()
    print(f"load {load} req/s, 6 replicas in 3 zones тЖТ worst minute {min(rates):.1%} ┬╖ {verdict} ┬╖ aborted at {ab} ┬╖ failed {failed:,}")
rates, ab, failed, verdict = ChaosExperiment(2, 2, 200, 700, abort=0.5).run()
print(f"abort line lowered to 50% тЖТ aborted at {ab} ┬╖ failed {failed:,} (the fault ran all 5 minutes)")
EOF

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

chaos рд╣реЗ рдЫрд╛рдкрддреЗ:

   6 replicas in 3 zones: minutes 0тАУ9 success 100% 100% 100% 100% 100% 100% 100% 100% 100% 100%
      тЖТ hypothesis held ┬╖ no abort ┬╖ 0 failed
   4 replicas in 2 zones: minutes 0тАУ9 success 100% 100% 100% 57% 100% 100% 100% 100% 100% 100%
      тЖТ hypothesis refuted ┬╖ ABORTED at minute 3, fault undone ┬╖ 18,000 requests failed in the cell

рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:

load 600 req/s, 6 replicas in 3 zones тЖТ worst minute 100.0% ┬╖ hypothesis held ┬╖ aborted at None ┬╖ failed 0
load 700 req/s, 6 replicas in 3 zones тЖТ worst minute 100.0% ┬╖ hypothesis held ┬╖ aborted at None ┬╖ failed 0
load 800 req/s, 6 replicas in 3 zones тЖТ worst minute 100.0% ┬╖ hypothesis held ┬╖ aborted at None ┬╖ failed 0
load 900 req/s, 6 replicas in 3 zones тЖТ worst minute 88.9% ┬╖ hypothesis refuted ┬╖ aborted at 3 ┬╖ failed 6,000
abort line lowered to 50% тЖТ aborted at None ┬╖ failed 90,000 (the fault ran all 5 minutes)

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

рддреЗрдЪ design (3 zones рдордзреНрдпреЗ 6 replicas) 800 req/s рд╡рд░ pass рд╣реЛрддреЗ рдЖрдгрд┐ 900 рд╡рд░ fail: рдкреНрд░рдпреЛрдЧрд╛рдЪрд╛ рдирд┐рдХрд╛рд▓ рдлрдХреНрдд рддреЛ рдЬреНрдпрд╛ load рд╡рд░ рдЪрд╛рд▓рд▓рд╛ рддреНрдпрд╛рд╕рд╛рдареАрдЪ рдЦрд░рд╛ рдЕрд╕рддреЛ тАФ traffic рд╡рд╛рдвреЗрд▓ рддрд╕рд╛ рддреЛ рдкреБрдиреНрд╣рд╛ рдХрд░рд╛. Abort рдЪреНрдпрд╛ рдЕрдЯреАрдиреЗ рдиреБрдХрд╕рд╛рди 90,000 рдЕрдпрд╢рд╕реНрд╡реА requests (5 рдорд┐рдирд┐рдЯреЗ рдЪрд╛рд▓реВ рдареЗрд╡рд▓реЗрд▓рд╛ рдмрд┐рдШрд╛рдб) рд╡рд░реВрди 18,000 (1 рдорд┐рдирд┐рдЯ) рд╡рд░ рдЖрдгрд▓реЗ, рдЖрдгрд┐ blast radius рдиреЗ рддреЗрд╣реА рджрд╣рд╛рдкреИрдХреА рдПрдХрд╛ cell рдкреБрд░рддреЗ рдорд░реНрдпрд╛рджрд┐рдд рдареЗрд╡рд▓реЗ. рд╣реАрдЪ рд╕рдВрдкреВрд░реНрдг рдкрджреНрдзрдд рдЖрд╣реЗ: рд╕реНрдкрд╖реНрдЯ hypothesis, рдЫреЛрдЯреА blast radius, рдЖрдгрд┐ "start" рджрд╛рдмрдгреНрдпрд╛рдЪреНрдпрд╛ рдЖрдзреА рдард░рд╡рд▓реЗрд▓реЗ рдерд╛рдВрдмрд╡рдгреНрдпрд╛рдЪреЗ рдмрдЯрдг.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд

Kubernetes рд╡рд░ Chaos Mesh тАФ experiment namespace рдордзреАрд▓ timetable рдЪрд╛ рдПрдХ pod рдорд╛рд░рд╛. рдЦрд▒реНрдпрд╛ account рд╡рд░ (рдЦрд░рд╛ cluster, рд╕рд╣рдорддреАрд╕рд╣):

apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata: {name: kill-one-timetable-pod, namespace: chaos-testing}
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces: [timetable-cell-1]
    labelSelectors: {app: timetable}

AWS Fault Injection Service тАФ experiment template рдордзреНрдпреЗ рддреНрдпрд╛рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ stop conditions рдЕрд╕рддрд╛рдд, CloudWatch alarms рд╢реА рдЬреЛрдбрд▓реЗрд▓реНрдпрд╛, рдореНрд╣рдгреВрди abort рдЖрдкреЛрдЖрдк рд╣реЛрддреЛ:

{
  "description": "lose zone B for the timetable cell",
  "stopConditions": [{"source": "aws:cloudwatch:alarm",
                      "value": "arn:aws:cloudwatch:ap-south-1:111122223333:alarm:timetable-success-below-99"}],
  "targets": {"cell1": {"resourceType": "aws:ec2:instance", "selectionMode": "ALL",
                        "resourceTags": {"cell": "1"},
                        "filters": [{"path": "Placement.AvailabilityZone", "values": ["ap-south-1b"]}]}},
  "actions": {"stopZoneB": {"actionId": "aws:ec2:stop-instances", "targets": {"Instances": "cell1"},
                            "parameters": {"startInstancesAfterDuration": "PT5M"}}},
  "roleArn": "arn:aws:iam::111122223333:role/fis-experiments"
}
aws fis start-experiment --experiment-template-id EXT1a2b3c4d5e6f7

LitmusChaos рдЖрдгрд┐ Gremlin рд╣реА рдЗрддрд░ рдиреЗрд╣рдореАрдЪреА tools рдЖрд╣реЗрдд. Game day рд╕рд╛рдареА рдлрдХреНрдд calendar invite, рд▓рд┐рд╣реВрди рдареЗрд╡рд▓реЗрд▓реА hypothesis, abort рдЪрд╛ рдирд┐рдпрдо, рдПрдХ IC рдЖрдгрд┐ рдПрдХ scribe рдПрд╡рдвреЗрдЪ рд▓рд╛рдЧрддреЗ.

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЖрд╣реЗ: рддреБрдордЪреНрдпрд╛ рдорд╛рдЧрдЪреНрдпрд╛ architecture review рдордзреАрд▓ рдПрдХ design рджрд╛рд╡рд╛ рдирд┐рд╡рдбрд╛ ("рддреЛ zone рдЧреЗрд▓рд╛ рддрд░реА рдЯрд┐рдХрддреЛ"). Hypothesis, steady state, blast radius рдЖрдгрд┐ abort рдЪреА рдЕрдЯ рдПрдХрд╛ рдкрд╛рдирд╛рд╡рд░ рд▓рд┐рд╣рд╛. рддреЗ рдкрд╛рди рдореНрд╣рдгрдЬреЗ рддреБрдордЪрд╛ рдкрд╣рд┐рд▓рд╛ game day.

тПня╕П рдкреБрдвреЗ

рд╢реЗрд╡рдЯрдЪрд╛ рдзрдбрд╛ рдкреНрд░рддреНрдпреЗрдХ рдзрдбрд╛ рдПрдХрд╛ рдЖрдврд╛рд╡реНрдпрд╛рдд рдЖрдгрддреЛ тАФ рдЬреЛ рдкрдердХ рдПрдЦрд╛рджреНрдпрд╛ service рдЪрд╛ pager рдШреЗрдгреНрдпрд╛рдЖрдзреА рддрд┐рдиреЗ рдкрд╛рд░ рдХрд░рд╛рдпрд▓рд╛рдЪ рд╣рд╡рд╛.

git checkout lesson-12-production-readiness

ЁЯзп Lesson 11 тАФ Chaos engineering and game days: break it on purpose, carefully

ЁЯУН You are here: Lesson 11 of 12 ┬╖ Previous: lesson-10-overload ┬╖ Next: lesson-12-production-readiness


ЁЯУж What's in this branch

Lesson 10, plus the experiment that checks the designs from lessons 07тАУ10. A chaos experiment has a hypothesis, a small blast radius and written abort conditions. A game day is the planned, people-in-the-room version. ChaosExperiment in sre/design.py and chaos() in sre/demo.py.

ЁЯзТ Explain like I'm 5

The crew says: "If the east wing loses power, the other wings can still run all the classes." ЁЯПл Is that true? Nobody knows. They have never tried.

So they plan a test. But not on the whole school тАФ just on one block of classrooms, one tenth of the pupils. They write down first: "We expect nearly every class to keep going. If more than 1 class in 100 stops, we switch the power back on at once."

Block one has classrooms in three wings. They cut the east wing's power. The other two wings take the pupils. Every class keeps going. тЬЕ The idea was right.

Block two has classrooms in only two wings. They cut one. Nearly half the classes stop! Within a minute, Katrina switches the power back on. Some pupils were bothered for one minute тАФ but only in one block, and now the crew knows block two needs a third wing, before a real power cut teaches them in front of the whole school.

ЁЯЧ║я╕П Diagram

flowchart LR
    h["ЁЯУЭ hypothesis<br/>lose zone B тЖТ success тЙе 99.5%"] --> x["ЁЯТе inject at minute 3<br/>one cell = 10% of users"]
    x --> a["cell A: 6 replicas, 3 zones<br/>800 тЙе 700 req/s тЖТ 100%<br/>hypothesis held"]
    x --> b["cell B: 4 replicas, 2 zones<br/>400 of 700 req/s тЖТ 57%"]
    b --> ab["ЁЯЫС abort (< 99%) at minute 3<br/>fault undone ┬╖ 18,000 failed"]

ЁЯЧ║я╕П Drawn version + a lab: https://school-edh.pages.dev/sre/lesson-diagrams.html#l11

тЭУ What

ЁЯдФ Why

Because every design in this course is a claim тАФ "N+1 zones" (lesson 07), "failover works" (lesson 09), "we shed sheddable first" (lesson 10) тАФ and untested claims fail at 3 a.m. Real outages pick the worst moment and the whole blast radius. An experiment picks the time, the size and the stop button.

ЁЯФз How (in this repo)

ChaosExperiment(replicas_per_zone, zones, per_replica_rps, load_rps, hypothesis=0.995, abort=0.99) in sre/design.py. run(minutes=10, inject_at=3, fault_minutes=5) goes minute by minute: while the fault is on, one zone's replicas are gone; success = min(1, capacity ├╖ load). If a minute falls below the abort line, the fault is undone from the next minute. It returns the per-minute rates, the abort minute, the failed requests and the verdict.

ЁЯзк Try it

python3 sre/demo.py chaos
python3 - <<'EOF'
import sys; sys.path.insert(0, "sre"); from design import ChaosExperiment
for load in (600, 700, 800, 900):
    rates, ab, failed, verdict = ChaosExperiment(2, 3, 200, load).run()
    print(f"load {load} req/s, 6 replicas in 3 zones тЖТ worst minute {min(rates):.1%} ┬╖ {verdict} ┬╖ aborted at {ab} ┬╖ failed {failed:,}")
rates, ab, failed, verdict = ChaosExperiment(2, 2, 200, 700, abort=0.5).run()
print(f"abort line lowered to 50% тЖТ aborted at {ab} ┬╖ failed {failed:,} (the fault ran all 5 minutes)")
EOF

тЬЕ Verify тАФ what you should see

chaos prints:

   6 replicas in 3 zones: minutes 0тАУ9 success 100% 100% 100% 100% 100% 100% 100% 100% 100% 100%
      тЖТ hypothesis held ┬╖ no abort ┬╖ 0 failed
   4 replicas in 2 zones: minutes 0тАУ9 success 100% 100% 100% 57% 100% 100% 100% 100% 100% 100%
      тЖТ hypothesis refuted ┬╖ ABORTED at minute 3, fault undone ┬╖ 18,000 requests failed in the cell

Your snippet prints:

load 600 req/s, 6 replicas in 3 zones тЖТ worst minute 100.0% ┬╖ hypothesis held ┬╖ aborted at None ┬╖ failed 0
load 700 req/s, 6 replicas in 3 zones тЖТ worst minute 100.0% ┬╖ hypothesis held ┬╖ aborted at None ┬╖ failed 0
load 800 req/s, 6 replicas in 3 zones тЖТ worst minute 100.0% ┬╖ hypothesis held ┬╖ aborted at None ┬╖ failed 0
load 900 req/s, 6 replicas in 3 zones тЖТ worst minute 88.9% ┬╖ hypothesis refuted ┬╖ aborted at 3 ┬╖ failed 6,000
abort line lowered to 50% тЖТ aborted at None ┬╖ failed 90,000 (the fault ran all 5 minutes)

ЁЯПБ What you just proved

The same design (6 replicas in 3 zones) passes at 800 req/s and fails at 900: an experiment's result is only true for the load it ran under тАФ repeat it as traffic grows. The abort condition cut the damage from 90,000 failed requests (fault left on for 5 minutes) to 18,000 (1 minute), and the blast radius kept even that to one cell of ten. That is the whole method: a clear hypothesis, a small blast radius, and a stop button you decided on before you pressed "start".

тЪая╕П Common mistakes

ЁЯПн In production

Chaos Mesh on Kubernetes тАФ kill one timetable pod in the experiment namespace. On a real account (a real cluster, with agreement):

apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata: {name: kill-one-timetable-pod, namespace: chaos-testing}
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces: [timetable-cell-1]
    labelSelectors: {app: timetable}

AWS Fault Injection Service тАФ the experiment template carries its own stop conditions, tied to CloudWatch alarms, so the abort is automatic:

{
  "description": "lose zone B for the timetable cell",
  "stopConditions": [{"source": "aws:cloudwatch:alarm",
                      "value": "arn:aws:cloudwatch:ap-south-1:111122223333:alarm:timetable-success-below-99"}],
  "targets": {"cell1": {"resourceType": "aws:ec2:instance", "selectionMode": "ALL",
                        "resourceTags": {"cell": "1"},
                        "filters": [{"path": "Placement.AvailabilityZone", "values": ["ap-south-1b"]}]}},
  "actions": {"stopZoneB": {"actionId": "aws:ec2:stop-instances", "targets": {"Instances": "cell1"},
                            "parameters": {"startInstancesAfterDuration": "PT5M"}}},
  "roleArn": "arn:aws:iam::111122223333:role/fis-experiments"
}
aws fis start-experiment --experiment-template-id EXT1a2b3c4d5e6f7

LitmusChaos and Gremlin are other common tools. A game day needs only a calendar invite, a written hypothesis, an abort rule, an IC and a scribe.

ЁЯПн Why this matters in production: pick one design claim from your last architecture review ("it survives a zone loss"). Write the hypothesis, the steady state, the blast radius and the abort condition on one page. That page is your first game day.

тПня╕П Next

The last lesson puts every lesson into one review тАФ the one a service must pass before the crew takes its pager.

git checkout lesson-12-production-readiness
тЖР PreviousoverloadNext тЖТproduction readiness

This page is the lesson's README from the lesson-11-chaos-engineering branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.