Документация Хаос-инженерия

Хаос-инженерия

Статус: BETA – Эта функция находится в активной разработке. API и поведение могут измениться.

Mockarty предоставляет встроенную платформу хаос-инженерии для Kubernetes. Запускайте контролируемые эксперименты по внедрению сбоев для проверки устойчивости системы. Поддерживается 12 типов сбоев, включая уничтожение подов, сетевые разделения/задержки/потери, нагрузку на ресурсы, нарушение DNS, IO chaos и time chaos.

Хаос — запущенный эксперимент
Хаос — история запусков

Ключевые возможности:

  • 12 типов внедрения сбоев (уничтожение подов, сетевое разделение/задержка/потеря пакетов, перезапуск деплоймента, масштабирование, дрейн нод, нагрузка на ресурсы, нарушение DNS, IO chaos, time chaos)
  • Механизмы безопасности (списки запрещённых пространств имён, ограничение радиуса поражения, автоматический откат)
  • Проверка устойчивого состояния (HTTP-пробы, метрики Prometheus, количество подов)
  • Планирование и автоматизация (повторяющиеся эксперименты по расписанию cron)
  • Отчёты (HTML, JSON)
  • 6 готовых пресетов экспериментов (Chaos Monkey, Network Partition, Scale to Zero и др.)
  • Веб-интерфейс с визуализацией топологии кластера
  • Интеграция с контрактным тестированием для проверки устойчивости наряду с соответствием спецификациям

Требования:

  • PRO-лицензия (хаос-инженерия – функция PRO)
  • Кластер Kubernetes (1.20+)
  • Доступ kubectl или файл kubeconfig

URL-адреса в примерах: Во всех примерах используется localhost:5770 как адрес Mockarty по умолчанию. Если ваш экземпляр работает на удалённом сервере, замените localhost:5770 на реальный адрес (например, https://mockarty.company.com или http://192.168.1.50:5770). Подробнее — в разделе Полезные функции и советы.


Быстрый старт

Шаг 1. Подключение к кластеру

cURL

curl -X POST http://localhost:5770/api/v1/chaos/profiles \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"name": "staging", "namespace": "default", "kubeconfig": "/path/to/.kube/config"}'

CLI

mockarty-cli chaos cluster add --name staging --kubeconfig ~/.kube/config
mockarty-cli chaos cluster test

Go

// go get github.com/mockarty/mockarty-go
client := mockarty.NewClient("http://localhost:5770", "YOUR_TOKEN")

profile, err := client.Chaos().CreateProfile(ctx, &mockarty.ChaosProfile{
    Name:       "staging",
    Namespace:  "default",
    Kubeconfig: "/path/to/.kube/config",
})

// Проверка подключения
result, err := client.Chaos().TestProfile(ctx, profile.ID)
fmt.Println("Подключено:", result)

Python

# pip install mockarty
from mockarty import MockartyClient

client = MockartyClient("http://localhost:5770", token="YOUR_TOKEN")

profile = client.chaos.create_profile({
    "name": "staging",
    "namespace": "default",
    "kubeconfig": "/path/to/.kube/config",
})

# Проверка подключения
result = client.chaos.test_profile(profile["id"])
print("Подключено:", result)

Java

// Gradle: implementation "ru.mockarty:mockarty-java:1.0.0"
MockartyClient client = new MockartyClient("http://localhost:5770", "YOUR_TOKEN");

ChaosProfile profile = new ChaosProfile();
profile.setName("staging");
profile.setNamespace("default");
profile.setKubeconfig("/path/to/.kube/config");

ChaosProfile created = client.chaos().createProfile(profile);

// Проверка подключения
Map<String, Object> result = client.chaos().testProfile(created.getId());
System.out.println("Подключено: " + result);

Шаг 2. Запуск пресета эксперимента

cURL

# Создание эксперимента из пресета, затем запуск
EXPERIMENT_ID=$(curl -s -X POST http://localhost:5770/api/v1/chaos/experiments \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "name": "frontend-chaos-monkey",
    "namespace": "my-app",
    "presetName": "chaos-monkey",
    "durationSec": 300,
    "target": {"selector": {"app": "frontend"}, "namespace": "my-app"}
  }' | jq -r '.id')

curl -X POST "http://localhost:5770/api/v1/chaos/experiments/$EXPERIMENT_ID/run" \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

mockarty-cli chaos preset run --preset chaos-monkey \
  --k8s-namespace my-app --selector app=frontend --duration 5m

Go

// Список доступных пресетов
presets, err := client.Chaos().ListPresets(ctx)

// Создание и запуск эксперимента из пресета
exp, err := client.Chaos().Create(ctx, &mockarty.ChaosExperiment{
    Name:        "frontend-chaos-monkey",
    Namespace:   "my-app",
    PresetName:  "chaos-monkey",
    DurationSec: 300,
    Target: mockarty.TargetConfig{
        Selector:  map[string]string{"app": "frontend"},
        Namespace: "my-app",
    },
})
err = client.Chaos().Run(ctx, exp.ID)

Python

# Список доступных пресетов
presets = client.chaos.list_presets()

# Создание и запуск эксперимента из пресета
exp = client.chaos.create({
    "name": "frontend-chaos-monkey",
    "namespace": "my-app",
    "presetName": "chaos-monkey",
    "durationSec": 300,
    "target": {
        "selector": {"app": "frontend"},
        "namespace": "my-app",
    },
})
client.chaos.run(exp["id"])

Java

// Список доступных пресетов
List<ChaosPreset> presets = client.chaos().listPresets();

// Создание и запуск эксперимента из пресета
ChaosExperiment exp = new ChaosExperiment();
exp.setName("frontend-chaos-monkey");
exp.setNamespace("my-app");
exp.setPresetName("chaos-monkey");
exp.setDurationSec(300);

ChaosExperiment created = client.chaos().create(exp);
client.chaos().run(created.getId());

Шаг 3. Просмотр результатов

cURL

curl http://localhost:5770/api/v1/chaos/experiments/EXPERIMENT_ID/report \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

mockarty-cli chaos get EXPERIMENT_ID
mockarty-cli chaos report EXPERIMENT_ID --format html --output report.html

Go

report, err := client.Chaos().GetReport(ctx, "EXPERIMENT_ID")
fmt.Println("Статус:", report.Status)

// Скачать HTML-отчёт
htmlBytes, err := client.Chaos().DownloadReport(ctx, "EXPERIMENT_ID", "html")
os.WriteFile("report.html", htmlBytes, 0644)

Python

report = client.chaos.get_report("EXPERIMENT_ID")
print("Статус:", report["status"])

# Скачать HTML-отчёт
html_bytes = client.chaos.download_report("EXPERIMENT_ID", format="html")
with open("report.html", "wb") as f:
    f.write(html_bytes)

Java

Map<String, Object> report = client.chaos().getReport("EXPERIMENT_ID");
System.out.println("Статус: " + report.get("status"));

// Скачать HTML-отчёт
byte[] htmlBytes = client.chaos().downloadReport("EXPERIMENT_ID", "html");
Files.write(Path.of("report.html"), htmlBytes);

Настройка кластера

Добавление профиля кластера

cURL

curl -X POST http://localhost:5770/api/v1/chaos/profiles \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "name": "production",
    "namespace": "default",
    "kubeconfig": "/home/user/.kube/config",
    "context": "prod-context"
  }'

CLI

mockarty-cli chaos cluster add --name production --kubeconfig ~/.kube/config

# С указанием контекста и ограничениями пространств имён
mockarty-cli chaos cluster add --name production \
  --kubeconfig ~/.kube/config --context prod-context \
  --allowed-namespaces app,test --denied-namespaces kube-system,monitoring

Go

profile, err := client.Chaos().CreateProfile(ctx, &mockarty.ChaosProfile{
    Name:       "production",
    Namespace:  "default",
    Kubeconfig: "/home/user/.kube/config",
    Context:    "prod-context",
})
fmt.Println("Профиль создан:", profile.ID)

Python

profile = client.chaos.create_profile({
    "name": "production",
    "namespace": "default",
    "kubeconfig": "/home/user/.kube/config",
    "context": "prod-context",
})
print("Профиль создан:", profile["id"])

Java

ChaosProfile profile = new ChaosProfile();
profile.setName("production");
profile.setNamespace("default");
profile.setKubeconfig("/home/user/.kube/config");
profile.setContext("prod-context");

ChaosProfile created = client.chaos().createProfile(profile);
System.out.println("Профиль создан: " + created.getId());

Проверка подключения

cURL

curl -X POST http://localhost:5770/api/v1/chaos/profiles/PROFILE_ID/test \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

mockarty-cli chaos cluster test

Go

result, err := client.Chaos().TestProfile(ctx, "PROFILE_ID")
fmt.Println("Статус подключения:", result)

Python

result = client.chaos.test_profile("PROFILE_ID")
print("Статус подключения:", result)

Java

Map<String, Object> result = client.chaos().testProfile("PROFILE_ID");
System.out.println("Статус подключения: " + result);

Просмотр информации о кластере

mockarty-cli chaos cluster info    # Пространства имён, узлы, возможности
mockarty-cli chaos cluster list    # Все настроенные кластеры
mockarty-cli chaos cluster use staging  # Переключить активный кластер

Типы сбоев

Тип сбоя Описание Уровень риска
pod_kill Уничтожение конкретного пода Средний
pod_kill_random Уничтожение случайного пода по селектору Средний
network_partition Блокировка всего сетевого трафика к/от цели Высокий
network_delay Инъекция задержки на сетевых интерфейсах целевых подов (поле latencyMs) Средний
network_loss Потеря заданного процента пакетов на целевых подах (поле lossPercent) Средний
deployment_restart Запуск плавного перезапуска деплоймента Средний
scale Изменение количества реплик (включая масштабирование до нуля) Высокий
node_drain Вытеснение всех подов с узла Высокий
resource_stress Нагрузка CPU/памяти на целевые поды Средний
dns_disruption Нарушение разрешения DNS для целевых доменов Высокий
io_chaos Инъекция файловых сбоев: IO-задержка или IO-ошибки на смонтированном пути (ioLatencyMs, ioErrPercent, ioPath) Высокий
time_chaos Сдвиг часов на целевых подах на заданную дельту (timeOffsetSec) Средний

Режимы выбора цели: one (конкретный под), random_one (по умолчанию), all, fixed_percent.


Запуск экспериментов

Из флагов CLI

mockarty-cli chaos run \
  --type pod_kill_random \
  --k8s-namespace my-app \
  --selector app=frontend \
  --duration 5m \
  --interval 30s \
  --auto-rollback

mockarty-cli chaos run \
  --type network_partition \
  --deployment my-service \
  --k8s-namespace my-app \
  --duration 2m \
  --auto-rollback

Из YAML-файла

# experiment.yaml
name: frontend-resilience-test
namespace: my-app
durationSec: 600

faults:
  - type: pod_kill_random
    intervalSec: 60

target:
  mode: random_one
  selector:
    app: frontend
  namespace: my-app

safety:
  autoRollback: true
  haltOnSteadyFail: true
  denyNamespaces: [kube-system, monitoring]
  maxPodsAffected: 3
  blastRadiusPercent: 30

steadyState:
  checks:
    - name: frontend-health
      type: http
      endpoint: "http://frontend.my-app.svc:8080/health"
      method: GET
      expected: 200
      intervalSec: 10
    - name: min-frontend-pods
      type: pod_count
      query: "app=frontend"
      expected: 2

cURL

curl -X POST http://localhost:5770/api/v1/chaos/experiments \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d @experiment.json

# Затем запуск
curl -X POST http://localhost:5770/api/v1/chaos/experiments/EXPERIMENT_ID/run \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

mockarty-cli chaos run -f experiment.yaml

Go

exp, err := client.Chaos().Create(ctx, &mockarty.ChaosExperiment{
    Name:        "frontend-resilience-test",
    Namespace:   "my-app",
    DurationSec: 600,
    Faults: []mockarty.FaultConfig{
        {Type: "pod_kill_random", IntervalSec: 60},
    },
    Target: mockarty.TargetConfig{
        Mode:      "random_one",
        Selector:  map[string]string{"app": "frontend"},
        Namespace: "my-app",
    },
    Safety: mockarty.SafetyConfig{
        AutoRollback:      true,
        HaltOnSteadyFail:  true,
        DenyNamespaces:    []string{"kube-system", "monitoring"},
        MaxPodsAffected:   3,
        BlastRadiusPercent: 30,
    },
})

// Запуск эксперимента
err = client.Chaos().Run(ctx, exp.ID)

Python

exp = client.chaos.create({
    "name": "frontend-resilience-test",
    "namespace": "my-app",
    "durationSec": 600,
    "faults": [
        {"type": "pod_kill_random", "intervalSec": 60},
    ],
    "target": {
        "mode": "random_one",
        "selector": {"app": "frontend"},
        "namespace": "my-app",
    },
    "safety": {
        "autoRollback": True,
        "haltOnSteadyFail": True,
        "denyNamespaces": ["kube-system", "monitoring"],
        "maxPodsAffected": 3,
        "blastRadiusPercent": 30,
    },
})

# Запуск эксперимента
client.chaos.run(exp["id"])

Java

ChaosExperiment exp = new ChaosExperiment();
exp.setName("frontend-resilience-test");
exp.setNamespace("my-app");
exp.setDurationSec(600);

ChaosExperiment created = client.chaos().create(exp);

// Запуск эксперимента
client.chaos().run(created.getId());

Использование пресетов

Mockarty поставляется с 6 готовыми пресетами:

Пресет Описание Риск Типы сбоев
chaos-monkey Случайное уничтожение пода каждые 5 мин Средний pod_kill_random
network-partition Блокировка входящего/исходящего трафика Высокий network_partition
scale-to-zero Масштабирование деплоймента до 0 реплик Высокий scale
resource-pressure Нагрузка CPU/памяти на цель Средний resource_stress
rolling-restart-storm Повторные перезапуски деплоймента Средний deployment_restart
dns-disruption Нарушение разрешения DNS Высокий dns_disruption

cURL

# Создание эксперимента из пресета и запуск
EXPERIMENT_ID=$(curl -s -X POST http://localhost:5770/api/v1/chaos/experiments \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "name": "chaos-monkey-test",
    "namespace": "my-app",
    "presetName": "chaos-monkey",
    "durationSec": 300,
    "target": {"mode": "random_one", "selector": {"app": "web"}, "namespace": "my-app"}
  }' | jq -r '.id')

curl -X POST "http://localhost:5770/api/v1/chaos/experiments/$EXPERIMENT_ID/run" \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

# Список всех пресетов
mockarty-cli chaos preset list

# Запуск пресета
mockarty-cli chaos preset run --preset chaos-monkey \
  --k8s-namespace my-app --selector app=web --duration 5m

mockarty-cli chaos preset run --preset network-partition \
  --k8s-namespace my-app --selector app=api --duration 3m

mockarty-cli chaos preset run --preset dns-disruption \
  --k8s-namespace my-app --selector app=gateway --duration 2m

Go

// Список всех пресетов
presets, err := client.Chaos().ListPresets(ctx)
for _, p := range presets {
    fmt.Printf("Пресет: %s (%s)\n", p.Name, p.Description)
}

// Создание и запуск эксперимента из пресета
exp, err := client.Chaos().Create(ctx, &mockarty.ChaosExperiment{
    Name:        "chaos-monkey-test",
    Namespace:   "my-app",
    PresetName:  "chaos-monkey",
    DurationSec: 300,
    Target: mockarty.TargetConfig{
        Selector:  map[string]string{"app": "web"},
        Namespace: "my-app",
    },
})
err = client.Chaos().Run(ctx, exp.ID)

Python

# Список всех пресетов
presets = client.chaos.list_presets()
for p in presets:
    print(f"Пресет: {p['name']} ({p.get('description', '')})")

# Создание и запуск эксперимента из пресета
exp = client.chaos.create({
    "name": "chaos-monkey-test",
    "namespace": "my-app",
    "presetName": "chaos-monkey",
    "durationSec": 300,
    "target": {
        "selector": {"app": "web"},
        "namespace": "my-app",
    },
})
client.chaos.run(exp["id"])

Java

// Список всех пресетов
List<ChaosPreset> presets = client.chaos().listPresets();
for (ChaosPreset p : presets) {
    System.out.printf("Пресет: %s (%s)%n", p.getName(), p.getDescription());
}

// Создание и запуск эксперимента из пресета
ChaosExperiment exp = new ChaosExperiment();
exp.setName("chaos-monkey-test");
exp.setNamespace("my-app");
exp.setPresetName("chaos-monkey");
exp.setDurationSec(300);

ChaosExperiment created = client.chaos().create(exp);
client.chaos().run(created.getId());

Безопасность и защитные механизмы

Защита пространств имён

safety:
  denyNamespaces: [kube-system, monitoring, cert-manager, istio-system]
  allowNamespaces: [staging-app, test-env]  # Режим белого списка

Ограничение радиуса поражения

safety:
  maxPodsAffected: 5
  minReplicasAlive: 2
  blastRadiusPercent: 30

Автоматический откат

Автоматическая отмена всех изменений при сбое проверок устойчивого состояния:

safety:
  autoRollback: true       # Откат при сбое
  haltOnSteadyFail: true   # Остановка при провале проверки

Флаг CLI: --auto-rollback (включён по умолчанию).

Ручное подтверждение

Для экспериментов с высоким риском можно требовать явное подтверждение:

safety:
  requireApproval: true

Эксперимент переходит в состояние pending и ожидает подтверждения через API или веб-интерфейс.


Проверка устойчивого состояния

Проверка поведения системы до, во время и после экспериментов:

steadyState:
  checks:
    # Проверка HTTP-эндпоинта
    - name: health-check
      type: http
      endpoint: "http://my-service.my-app.svc:8080/health"
      method: GET
      expected: 200
      intervalSec: 10
      timeoutSec: 5

    # Запрос метрик Prometheus
    - name: error-rate
      type: prometheus
      query: "rate(http_requests_total{job='frontend',code=~'5..'}[1m])"
      expected: 0.01
      tolerance: 0.005
      intervalSec: 30

    # Проверка количества подов
    - name: min-pods
      type: pod_count
      query: "app=frontend"
      expected: 2
      tolerance: 0

Мониторинг и отчёты

Просмотр статуса эксперимента

cURL

curl http://localhost:5770/api/v1/chaos/experiments/EXPERIMENT_ID \
  -H "Authorization: Bearer YOUR_TOKEN"

curl "http://localhost:5770/api/v1/chaos/experiments?status=active&limit=10" \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

mockarty-cli chaos get EXPERIMENT_ID
mockarty-cli chaos list --status active --limit 10
mockarty-cli chaos abort EXPERIMENT_ID

Go

// Получить эксперимент по ID
exp, err := client.Chaos().Get(ctx, "EXPERIMENT_ID")
fmt.Println("Статус:", exp.Status)

// Список активных экспериментов
experiments, err := client.Chaos().List(ctx, &mockarty.ChaosListOptions{
    Status: "active",
    Limit:  10,
})

// Прервать выполняемый эксперимент
err = client.Chaos().Abort(ctx, "EXPERIMENT_ID")

Python

# Получить эксперимент по ID
exp = client.chaos.get("EXPERIMENT_ID")
print("Статус:", exp["status"])

# Список активных экспериментов
experiments = client.chaos.list(status="active", limit=10)

# Прервать выполняемый эксперимент
client.chaos.abort("EXPERIMENT_ID")

Java

// Получить эксперимент по ID
ChaosExperiment exp = client.chaos().get("EXPERIMENT_ID");
System.out.println("Статус: " + exp.getStatus());

// Список активных экспериментов
List<ChaosExperiment> experiments = client.chaos().list(null, "active", 10, 0);

// Прервать выполняемый эксперимент
client.chaos().abort("EXPERIMENT_ID");

Получение отчётов

cURL

# JSON-отчёт
curl http://localhost:5770/api/v1/chaos/experiments/EXPERIMENT_ID/report \
  -H "Authorization: Bearer YOUR_TOKEN"

# Скачать в нужном формате: html, json
curl -o report.html \
  "http://localhost:5770/api/v1/chaos/experiments/EXPERIMENT_ID/report/download?format=html" \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

mockarty-cli chaos report EXPERIMENT_ID
mockarty-cli chaos report EXPERIMENT_ID --format html --output report.html
mockarty-cli chaos report EXPERIMENT_ID --format json --output report.json

Go

// Получить JSON-отчёт
report, err := client.Chaos().GetReport(ctx, "EXPERIMENT_ID")

// Получить метрики и события
metrics, err := client.Chaos().GetMetrics(ctx, "EXPERIMENT_ID")
events, err := client.Chaos().GetEvents(ctx, "EXPERIMENT_ID")

// Скачать отчёт в нужном формате: html, json
htmlBytes, err := client.Chaos().DownloadReport(ctx, "EXPERIMENT_ID", "html")
os.WriteFile("report.html", htmlBytes, 0644)

Python

# Получить JSON-отчёт
report = client.chaos.get_report("EXPERIMENT_ID")

# Получить метрики и события
metrics = client.chaos.get_metrics("EXPERIMENT_ID")
events = client.chaos.get_events("EXPERIMENT_ID")

# Скачать отчёт в нужном формате: html, json
html_bytes = client.chaos.download_report("EXPERIMENT_ID", format="html")
with open("report.html", "wb") as f:
    f.write(html_bytes)

Java

// Получить JSON-отчёт
Map<String, Object> report = client.chaos().getReport("EXPERIMENT_ID");

// Получить метрики и события
Map<String, Object> metrics = client.chaos().getMetrics("EXPERIMENT_ID");
Map<String, Object> events = client.chaos().getEvents("EXPERIMENT_ID");

// Скачать отчёт в нужном формате: html, json
byte[] htmlBytes = client.chaos().downloadReport("EXPERIMENT_ID", "html");
Files.write(Path.of("report.html"), htmlBytes);
Формат Применение
JSON Программный анализ, дашборды
HTML Визуальный отчёт для заинтересованных сторон

Планирование

Запуск экспериментов по расписанию:

name: daily-resilience-check
namespace: staging
schedule:
  cronExpr: "0 3 * * *"
  repeatCount: 0        # 0 = бесконечно при установленном cron
  jitter: 30            # случайная задержка в секундах перед запуском
faults:
  - type: pod_kill_random
    intervalSec: 60
target:
  mode: random_one
  selector: { app: api }
  namespace: staging
durationSec: 300
safety:
  autoRollback: true
  denyNamespaces: [kube-system]

Инспекция кластера

Топология и ресурсы

# Топология кластера
curl http://localhost:5770/api/v1/chaos/clusters/CLUSTER_ID/topology \
  -H "Authorization: Bearer YOUR_TOKEN"

# Операции с подами
curl -X DELETE http://localhost:5770/api/v1/chaos/pods/NAMESPACE/POD_NAME \
  -H "Authorization: Bearer YOUR_TOKEN"
curl http://localhost:5770/api/v1/chaos/pods/NAMESPACE/POD_NAME/logs \
  -H "Authorization: Bearer YOUR_TOKEN"

# Операции с деплойментами
curl -X POST http://localhost:5770/api/v1/chaos/deployments/NAMESPACE/DEPLOY/scale \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"replicas": 3}'
curl -X POST http://localhost:5770/api/v1/chaos/deployments/NAMESPACE/DEPLOY/restart \
  -H "Authorization: Bearer YOUR_TOKEN"

Оператор хаоса

Оператор – это деплоймент Kubernetes, обеспечивающий продвинутые типы экспериментов. Он создаёт RBAC-ресурсы и работает внутри кластера.

cURL

curl -X POST http://localhost:5770/api/v1/chaos/operator/install \
  -H "Authorization: Bearer YOUR_TOKEN"
curl http://localhost:5770/api/v1/chaos/operator/status \
  -H "Authorization: Bearer YOUR_TOKEN"

CLI

mockarty-cli chaos operator install
mockarty-cli chaos operator install --namespace my-chaos-ns
mockarty-cli chaos operator status
mockarty-cli chaos operator uninstall

Go

// Проверить статус оператора
status, err := client.Chaos().GetOperatorStatus(ctx, "my-chaos-ns")
fmt.Println("Оператор установлен:", status.Installed)

// Сгенерировать манифест оператора
manifest, err := client.Chaos().GenerateOperatorManifest(ctx, "http://mockarty:5770", "")
fmt.Println(manifest)

Python

# Проверить статус оператора
status = client.chaos.get_operator_status(namespace="my-chaos-ns")
print("Оператор установлен:", status.get("installed"))

Java

// Проверить статус оператора
Map<String, Object> status = client.chaos().getOperatorStatus("my-chaos-ns");
System.out.println("Оператор установлен: " + status.get("installed"));

Интеграция с CI/CD

Пример рабочего процесса GitHub Actions:

name: Chaos Engineering Tests
on:
  schedule:
    - cron: '0 2 * * 1'
  workflow_dispatch:

jobs:
  chaos-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install CLI
        run: curl -fsSL https://mockarty.ru/install.sh | sh
      - name: Configure cluster
        run: mockarty-cli chaos cluster add --name ci --kubeconfig ${{ secrets.KUBECONFIG_PATH }}
      - name: Run experiment
        run: |
          mockarty-cli chaos preset run --preset chaos-monkey \
            --k8s-namespace staging --selector app=api --duration 5m
      - name: Get report
        run: |
          sleep 330
          EXPERIMENT_ID=$(mockarty-cli chaos list --status completed --limit 1 -o json | jq -r '.[0].id')
          mockarty-cli chaos report $EXPERIMENT_ID --format html --output chaos-report.html
          mockarty-cli chaos report $EXPERIMENT_ID --format json --output chaos-results.json
      - uses: actions/upload-artifact@v4
        with:
          name: chaos-report
          path: |
            chaos-report.html
            chaos-results.xml

Справочник API

Пресеты

Метод Эндпоинт Описание
GET /api/v1/chaos/presets Список доступных пресетов

Примечание: Для запуска пресета создайте эксперимент с полем presetName через POST /api/v1/chaos/experiments, затем запустите его через POST /api/v1/chaos/experiments/:id/run.

Эксперименты

Метод Эндпоинт Описание
GET /api/v1/chaos/experiments Список экспериментов (фильтры: namespace, status, limit, offset)
GET /api/v1/chaos/experiments/:id Получить детали эксперимента
POST /api/v1/chaos/experiments Создать эксперимент
PUT /api/v1/chaos/experiments/:id Обновить эксперимент
DELETE /api/v1/chaos/experiments/:id Удалить эксперимент
POST /api/v1/chaos/experiments/:id/run Запустить эксперимент
POST /api/v1/chaos/experiments/:id/abort Прервать активный эксперимент
GET /api/v1/chaos/experiments/:id/metrics Получить метрики эксперимента
GET /api/v1/chaos/experiments/:id/events Получить журнал событий
GET /api/v1/chaos/experiments/:id/report Получить отчёт (JSON)
GET /api/v1/chaos/experiments/:id/report/download Скачать отчёт (format: html, json)
GET /api/v1/chaos/experiments/:id/snapshot Получить снимок эксперимента

Профили

Метод Эндпоинт Описание
GET /api/v1/chaos/profiles Список профилей кластеров
POST /api/v1/chaos/profiles Создать профиль кластера
PUT /api/v1/chaos/profiles/:id Обновить профиль кластера
DELETE /api/v1/chaos/profiles/:id Удалить профиль кластера
POST /api/v1/chaos/profiles/:id/test Проверить подключение
POST /api/v1/chaos/profiles/:id/connect Подключиться к кластеру
POST /api/v1/chaos/profiles-test Проверить подключение (встроенная конфигурация)

Оператор

Метод Эндпоинт Описание
POST /api/v1/chaos/operator/manifest Сгенерировать манифест оператора
POST /api/v1/chaos/operator/install Установить оператор
GET /api/v1/chaos/operator/status Получить статус оператора

Инспекция кластера

Метод Эндпоинт Описание
GET /api/v1/chaos/clusters/:id/topology Получить топологию кластера
GET /api/v1/chaos/queue/:clusterId Получить очередь экспериментов
DELETE /api/v1/chaos/pods/:namespace/:name Удалить под
GET /api/v1/chaos/pods/:namespace/:name Получить детали пода
GET /api/v1/chaos/pods/:namespace/:name/logs Получить логи пода
POST /api/v1/chaos/deployments/:namespace/:name/scale Масштабировать деплоймент
POST /api/v1/chaos/deployments/:namespace/:name/restart Перезапустить деплоймент
GET /api/v1/chaos/deployments/:namespace/:name Получить детали деплоймента
GET /api/v1/chaos/configmaps/:namespace Список configmap
GET /api/v1/chaos/configmaps/:namespace/:name Получить configmap
PUT /api/v1/chaos/configmaps/:namespace/:name Обновить configmap
GET /api/v1/chaos/services/:namespace Список сервисов
GET /api/v1/chaos/crds Список CRD
GET /api/v1/chaos/crds/:group/:version/:resource Получить экземпляры CRD
GET /api/v1/chaos/events/:namespace Получить события пространства имён

Интеграция с контрактным тестированием

Хаос-инженерия и контрактное тестирование работают вместе для обеспечения комплексной надёжности:

  • Перед хаос-экспериментами: Запустите контрактные тесты, чтобы убедиться, что моки и спецификации синхронизированы. Это устанавливает базовый уровень корректности перед внедрением сбоев.
  • Во время хаос-экспериментов: Используйте steady-state HTTP-проверки, направленные на валидированные контрактами эндпоинты, чтобы тестировать против заведомо корректных контрактов.
  • После хаос-экспериментов: Повторно запустите контрактные тесты, чтобы убедиться, что внедрение сбоев или восстановление не привело к дрейфу.

Эта комбинация обнаруживает как функциональный дрейф (контрактное тестирование), так и пробелы в отказоустойчивости (хаос-инженерия), обеспечивая сквозную уверенность в вашей сервисной сети.


Связанная документация