
kube-monkey는 Kubernetes 클러스터를 위한 Netflix의 Chaos Monkey 구현체입니다. 클러스터의 Kubernetes(k8s) Pod를 무작위로 삭제하여 장애 복원력이 뛰어난 서비스 개발을 장려하고 검증합니다.
Kubernetes Slack의 #kube-monkey에 참여하세요.
kube-monkey는 평일의 사전 설정된 시간(run_hour, 기본값은 오전 8시)에 실행되며, 같은 날 중 임의의 시점에 무작위 Pod 종료를 겪게 될 Deployment들의 일정을 생성합니다.
무작위 Pod 종료가 발생할 수 있는 시간 범위는 구성 가능하며 기본값은 오전 10시부터 오후 4시까지입니다.
kube-monkey는 네임스페이스 목록을 사용하여 블랙리스트를 구성할 수 있습니다.
블랙리스트를 비활성화하려면 blacklisted_namespaces 구성 매개변수에 [""]를 제공하세요.
kube-monkey는 옵트인(opt-in) 모델로 동작하며, kube-monkey에 의해 Pod가 종료되는 것에 명시적으로 동의한 Kubernetes(k8s) 앱에 대해서만 종료를 예약합니다.
옵트인은 k8s 앱에 다음 라벨을 설정하여 수행합니다:
kube-monkey/enabled: kube-monkey에 옵트인하려면 **"enabled"**로 설정하세요.
kube-monkey/mtbf: 평균 고장 간격(Mean time between failure)을 정수와 단위로 표시합니다: 일(day)은 d, 시간은 h, 분은 m. 예를 들어,
**"3d"**로 설정하면 k8s 앱은 대략 세 번째 평일마다 Pod가 종료될 것으로 예상할 수 있고, **"2h"**로 설정하면
두 시간마다 Pod를 잃을 것으로 예상할 수 있습니다. 단위가 없는 값은 일(days)로 읽히므로 **"3"**과 **"3d"**는 같은 의미입니다. 평균 고장 간격의
최솟값은 1분입니다. 모든 종료는 일일 실행 창(start_hour 및 end_hour 참고) 안에서 발생하므로, 하루보다 짧은 mtbf는
그날의 종료를 해당 창 안에 몰아 넣습니다.
kube-monkey/identifier: k8s 앱의 고유 식별자입니다. Pod는 k8s 앱의 라벨을 상속받으므로, 이 식별자는 특정 k8s 앱에 속한 Pod를 식별하는 데 사용됩니다.
따라서 kube-monkey가 앱 가 피해자로 등록되었음을 감지하면, 라벨을 가진 모든 Pod를 찾아 종료 후보를 결정합니다. 이 값을 앱의 이름과 동일하게 설정하는 것이 좋습니다.
: 기본 동작은 kube-monkey가 앱의 Pod만 종료하는 것입니다. 값을 다음 중 하나로 설정하여 이 동작을 재정의할 수 있습니다:
kill-all: 상태에 관계없이 모든 Pod를 종료하려는 경우(준비되지 않았거나 실행 중이지 않은 Pod 포함). kill-value가 필요하지 않습니다. 이 라벨은 주의해서 사용하세요.fixed: kill-value로 실행 중인 특정 수의 Pod를 종료하려는 경우. 값을 초과 지정하면 실행 중인 모든 Pod가 종료되고 경고가 발생합니다.random-max-percent: kill-value로 종료할 수 있는 최대 %를 지정합니다. 예약된 시간에 실행 중인 Pod의 균일한 무작위 지정 %가 종료됩니다.fixed-percent: kill-value로 종료할 고정 %를 지정합니다. 예약된 시간에 실행 중인 Pod의 지정된 고정 %가 종료됩니다.kube-monkey/kill-value: kill-mode의 값을 지정합니다.
fixed인 경우 종료할 Pod 수를 정수로 제공하세요.random-max-percent인 경우 0-100 사이의 숫자로 kube-monkey가 종료할 수 있는 Pod의 최대 %를 지정하세요.fixed-percent인 경우 0-100 사이의 숫자로 종료할 Pod의 %를 지정하세요.---
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. 메모와 함께 클러스터 DNS를 명시적으로 지원하지 않으므로, apiserver를 재정의해야 할 수 있습니다.[kubernetes]
host="https://your-apiserver-url.com:apiport"
예약은 평일에 하루에 한 번 수행됩니다. 이때 오늘의 종료 일정이 생성됩니다. 예약하는 동안 kube-monkey는 다음을 수행합니다:
kube-monkey/mtbf에서 오늘 종료할 Pod 수를 계산합니다. 앱은 하루에 24h/mtbf 횟수만큼 종료되므로, mtbf가
하루 이상이면 최대 한 번의 종료가 발생하고, 더 짧으면 여러 번 종료됩니다.이것은 피해자 k8s 앱의 Pod가 종료될 날짜 중 무작위로 생성된 시간입니다. 종료 시간에 kube-monkey는 다음을 수행합니다:
kube-monkey의 Docker 이미지는 DockerHub에서 찾을 수 있습니다.
저장소를 클론하고 컨테이너를 빌드하세요.
go get github.com/asobti/kube-monkey
cd $GOPATH/src/github.com/asobti/kube-monkey
make build
make container
kube-monkey는 환경 변수 또는 /etc/kube-monkey/config.toml에 있는 toml 파일로 구성됩니다. 또한 kube-monkey 배포 전에 configmap이 존재해야 합니다.
구성 키와 설명은 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
참고: 이 설정은 startHour와 endHour에 구성한 값과 관계없이 60초마다 Pod를 계속 공격합니다.
[debug]
enabled= true
schedule_immediate_kill= true
Kube-monkey는 알림을 지원하며 공격 후 선택한 엔드포인트에 알림을 보낼 수 있습니다. Slack webhook 또는 사용자 정의 API일 수 있습니다.
[notifications]
enabled = true
reportSchedule = true
[notifications.attacks]
endpoint = "http://url1"
message = "message1"
headers = ["header1Key:header1Value","header2Key:header2/Value"]
메시지에는 다음 플레이스홀더를 사용할 수 있습니다:
{$name}: 피해자 이름{$kind}: 피해자 종류{$namespace}: 피해자 네임스페이스{$timestamp}: Unix epoch 기준 밀리초 단위의 공격 시간{$time}: 공격 시간{$date}: 공격 날짜{$error}: 결과 오류(있는 경우){$kubemonkeyid}: kube-monkey id(KUBE_MONKEY_ID 환경 변수로 설정하며, 그 외에는 비어 있음) message: '{
"what": "Kube-monkey(${kubemonkeyid}) attack of {$name} in {$namespace}",
"who": "{$name}",
"when": {$timestamp}
}'
헤더는 환경 변수의 값을 가져오는 특수 플레이스홀더를 지원합니다. 이는 보호된 엔드포인트를 가진 API를 호출할 때 유용합니다. 일반적인 시나리오는 Kube-monkey 컨테이너에 API 토큰을 전달하는 것입니다. 이 토큰은 Kubernetes Secret에 저장되며 환경 변수를 통해 전달하려는 경우입니다.
headers = ["api-key:{$env:API_TOKEN}", "Content-Type:application/json"]
{$env:API_TOKEN}은 환경 변수 API_TOKEN 값으로 대체됩니다.
참고로 환경 변수가 존재하지 않아도 알림 호출은 취소되지 않습니다. 값은 빈 문자열로 처리되며 로그에 경고가 표시됩니다.
수동 배포
kube-system 네임스페이스)에 예상되는 kube-monkey-config-map configmap을 배포합니다. 키 이름을 config.toml로 정의해야 합니다.예를 들어
kubectl create configmap km-config --from-file=config.toml=km-config.toml또는kubectl apply -f km-config.yaml
kube-system)에서 kube-monkey를 k8s 앱으로 실행합니다.예제 Kubernetes yaml 파일은 examples/ 디렉토리에서 확인하세요.
kubectl logs -f deployment.apps/kube-monkey --namespace=kube-system 명령으로 디버그 로그를 볼 수 있습니다. 여기서 deployment.apps/kube-monkey는 kube-monkey의 k8s deployment입니다.Helm 차트
Helm으로 kube-monkey 설치하는 방법을 참고하세요.
kube-monkey는 glog를 사용하며 glog의 모든 명령줄 기능을 지원합니다. pod에서 사용자 정의 v 레벨 또는 사용자 정의 로그 디렉토리를 지정하려면 예제 deployment 파일의 args: ["-v=5", "-log_dir=/path/to/custom/log"]를 참고하세요.
표준화된 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
기여 방법(How to Contribute)을 참고하세요.
이 프로젝트는 Apache License v2.0에 따라 라이선스가 부여됩니다. 자세한 내용은 LICENSE 파일을 참고하세요.
fookube-monkey/identifier: fookube-monkey/kill-mode