
Реализация Chaos Monkey от Netflix для кластеров Kubernetes
kube-monkey — это реализация Chaos Monkey от Netflix для кластеров Kubernetes. Он случайным образом удаляет поды Kubernetes (k8s) в кластере, стимулируя и проверяя разработку отказоустойчивых сервисов.
Присоединяйтесь к нам в #kube-monkey в Kubernetes Slack.
kube-monkey запускается в предварительно настроенный час (run_hour, по умолчанию 8 утра) по будним дням и составляет расписание развёртываний, которые столкнутся со случайной гибелью пода в течение того же дня. Временной интервал в течение дня, когда может произойти случайная гибель пода, настраивается и по умолчанию составляет с 10 утра до 4 вечера.
kube-monkey может быть настроен со списком пространств имён
Чтобы отключить чёрный список, укажите [""] в blacklisted_namespaces config.param.
kube-monkey работает по модели opt-in и планирует удаления только для приложений Kubernetes (k8s), которые явно согласились на удаление своих подов kube-monkey.
Для opt-in установите следующие метки (labels) на приложении k8s:
kube-monkey/enabled: Установите "enabled", чтобы включить участие в kube-monkey
kube-monkey/mtbf: Среднее время между отказами (mean time between failure), задаётся целым числом и единицей измерения: d для дней, h для часов или m для минут. Например,
если установлено "3d", приложение k8s может ожидать удаление пода примерно каждый третий будний день, а если "2h" — потерю пода каждые два часа. Значение без единицы измерения интерпретируется как дни, поэтому "3" и "3d" означают одно и то же. Минимальное среднее время
между отказами — одна минута. Обратите внимание, что все удаления происходят в ежедневном окне выполнения (см. start_hour и end_hour), поэтому при mtbf
меньше дня все удаления этого дня упаковываются в это окно.
: Уникальный идентификатор приложений k8s. Он используется для идентификации подов,
принадлежащих приложению k8s, поскольку поды наследуют метки от своего приложения k8s. Поэтому, если kube-monkey обнаруживает, что приложение записалось в жертвы, kube-monkey будет искать все поды с меткой , чтобы определить, какие поды являются кандидатами на удаление. Рекомендуется устанавливать это значение равным имени приложения.
: По умолчанию kube-monkey убивает только ОДИН под вашего приложения. Вы можете переопределить это поведение, установив одно из следующих значений:
kill-all — если вы хотите, чтобы kube-monkey убил ВСЕ ваши поды независимо от статуса (включая не готовые и не запущенные поды). Не требует kill-value. Используйте эту метку осторожно.fixed — если вы хотите убить определённое количество запущенных подов с помощью kill-value. Если значение будет завышено, будут убиты все запущенные поды и выдано предупреждение.random-max-percent — задаёт максимальный % подов, которые могут быть убиты, с помощью kill-value. В запланированное время будет удалена равномерно случайная указанная % часть запущенных подов.fixed-percent — задаёт фиксированный % подов, которые могут быть убиты, с помощью kill-value. В запланированное время будет удалена указанная фиксированная % часть запущенных подов.kube-monkey/kill-value: Укажите значение для kill-mode
fixed, укажите целое число подов для удаленияrandom-max-percent, укажите число от 0 до 100, чтобы задать максимальный % подов, которые kube-monkey может удалитьfixed-percent, укажите число от 0 до 100, чтобы задать % подов для удаления---
apiVersion: apps/v1
kind: Deployment
metadata:
name: monkey-victim
namespace: app-namespace
spec:
template:
metadata:
labels:
kube-monkey/enabled: enabled
kube-monkey/identifier: monkey-victim
kube-monkey/mtbf: '2'
kube-monkey/kill-mode: "fixed"
kube-monkey/kill-value: '1'
[... omitted ...]
Для более новых версий Kubernetes вам может также понадобиться добавить метки в метаданные приложения k8s.
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: monkey-victim
namespace: app-namespace
labels:
kube-monkey/enabled: enabled
kube-monkey/identifier: monkey-victim
kube-monkey/mtbf: '2'
kube-monkey/kill-mode: "fixed"
kube-monkey/kill-value: '1'
spec:
template:
metadata:
labels:
kube-monkey/enabled: enabled
kube-monkey/identifier: monkey-victim
[... omitted ...]
// TODO: switch to using cluster DNS., возможно, вам потребуется переопределить apiserver.[kubernetes]
host="https://your-apiserver-url.com:apiport"
Планирование происходит один раз в день по будним дням — в это время формируется расписание удалений на текущий день. Во время планирования kube-monkey:
kube-monkey/mtbf. Приложение удаляется 24ч/mtbf раз в день, поэтому mtbf
равный дню или более, даёт не более одного удаления, а меньший — несколькоЭто созданное случайным образом время в течение дня, когда у приложения k8s-жертвы будет убит под. В момент удаления kube-monkey:
Docker-образы kube-monkey можно найти на DockerHub
Клонируйте репозиторий и соберите контейнер.
go get github.com/asobti/kube-monkey
cd $GOPATH/src/github.com/asobti/kube-monkey
make build
make container
kube-monkey настраивается с помощью переменных окружения или toml-файла, размещённого в /etc/kube-monkey/config.toml, и ожидает, что configmap существует до развёртывания kube-monkey.
Ключи конфигурации и их описания можно найти в config/param/param.go
[kubemonkey]
dry_run = true # Terminations are only logged
run_hour = 8 # Run scheduling at 8am on weekdays
start_hour = 10 # Don't schedule any pod deaths before 10am
end_hour = 16 # Don't schedule any pod deaths after 4pm
blacklisted_namespaces = ["kube-system"] # Critical apps live here
time_zone = "America/New_York" # Set tzdata timezone example. Note the field is time_zone not timezone
KUBEMONKEY_DRY_RUN=true
KUBEMONKEY_RUN_HOUR=8
KUBEMONKEY_START_HOUR=10
KUBEMONKEY_END_HOUR=16
KUBEMONKEY_BLACKLISTED_NAMESPACES=kube-system
KUBEMONKEY_TIME_ZONE=America/New_York
Примечание: при этой конфигурации атаки на поды будут продолжаться каждые 60 секунд независимо от того, что вы указали в startHour и endHour.
[debug]
enabled= true
schedule_immediate_kill= true
Kube-monkey поддерживает уведомления и может уведомлять выбранный вами endpoint после атаки. Это может быть Slack webhook или пользовательский API.
[notifications]
enabled = true
reportSchedule = true
[notifications.attacks]
endpoint = "http://url1"
message = "message1"
headers = ["header1Key:header1Value","header2Key:header2/Value"]
Сообщение поддерживает следующие плейсхолдеры:
{$name}: имя жертвы{$kind}: тип (kind) жертвы{$namespace}: пространство имён жертвы{$timestamp}: время атаки в миллисекундах от эпохи Unix{$time}: время атаки{$date}: дата атаки{$error}: ошибка результата, если есть{$kubemonkeyid}: идентификатор kube-monkey (задаётся через переменную окружения KUBE_MONKEY_ID, иначе пусто) message: '{
"what": "Kube-monkey(${kubemonkeyid}) attack of {$name} in {$namespace}",
"who": "{$name}",
"when": {$timestamp}
}'
Заголовок поддерживает специальный плейсхолдер для получения значения переменной окружения. Это полезно при вызове API с защищённым endpoint. Типичный сценарий — передать API-токен в контейнер Kube-monkey; этот токен хранится в Kubernetes Secret, и вы хотите передать его через переменную окружения.
headers = ["api-key:{$env:API_TOKEN}", "Content-Type:application/json"]
{$env:API_TOKEN} будет заменён значением переменной окружения API_TOKEN.
Обратите внимание: если переменная окружения не существует, вызов уведомления НЕ будет отменён. Значение будет преобразовано в пустую строку, и в логах появится предупреждение.
Вручную
kube-monkey-config-map в пространстве имён, в котором вы планируете запускать kube-monkey (например, в пространстве имён kube-system). Убедитесь, что имя ключа задано как config.tomlНапример,
kubectl create configmap km-config --from-file=config.toml=km-config.tomlилиkubectl apply -f km-config.yaml
kube-system).Примеры yaml-файлов Kubernetes см. в каталоге examples/.
kubectl logs -f deployment.apps/kube-monkey --namespace=kube-system здесь deployment.apps/kube-monkey — это k8s deployment для kube-monkey.Helm-чарт
См. Как установить kube-monkey с помощью Helm.
kube-monkey использует glog и поддерживает все возможности командной строки для glog. Чтобы указать собственный уровень v или собственный каталог логов на поде, см. args: ["-v=5", "-log_dir=/path/to/custom/log"] в примере deployment-файла
Стандартизированные уровни glog
grep -r V\([0-9]\) *L0: Нет
L1: Самый высокий уровень — информация о текущем статусе и ошибки при удалениях
L2: Успешные удаления
L3: Более детальная информация о статусе расписания
L4: Отладка подробной информации о расписании и конфигурации
L5: Автоматически разрешённые несущественные проблемы
Дополнительные ресурсы: см. страницу логирования k8s, где предлагаются общепринятые в сообществе соглашения об уровнях серьёзности логирования
git clone https://github.com/asobti/kube-monkey.git
cd examples
oc login http://someserver/ -u system:admin
oc project kube-system
oc create -f configmap.yaml
oc -n kube-system adm policy add-role-to-user -z deployer system:deployer
oc -n kube-system adm policy add-role-to-user -z builder system:image-builder
oc -n kube-system adm policy add-role-to-group system:image-puller system:serviceaccounts:kube-system
oc run kube-monkey --image=docker.io/ayushsobti/kube-monkey:v0.4.0 --command -- /kube-monkey -v=5 -log_dir=/var/log/kube-monkey
oc volume dc/kube-monkey --add --name=kubeconfigmap -m /etc/kube-monkey -t configmap --configmap-name=kube-monkey-config-map
git clone https://github.com/asobti/kube-monkey.git
cd examples
oc login http://someserver/ -u system:admin
oc project kube-system
oc create -f configmap.yaml
oc -n kube-system adm policy add-cluster-role-to-user edit -z default --rolebinding-name kube-monkey-edit
oc run kube-monkey --image=docker.io/ayushsobti/kube-monkey:v0.3.0 --command -- /kube-monkey -v=5 -log_dir=/var/log/kube-monkey
oc set volume dc/kube-monkey --add --name=kubeconfigmap -m /etc/kube-monkey -t configmap --configmap-name=kube-monkey-config-map
См. Как внести вклад
Этот проект лицензирован в соответствии с Apache License v2.0 — подробности см. в файле LICENSE.
kube-monkey/identifierfookube-monkey/identifier: fookube-monkey/kill-mode