k6-operator MaxVUs Parallelism Error
문제 상황#
4000 VU 부하테스트 실행 시 즉시 실패:
Status: error (Pod: Succeeded)
Summary not available (test may have ended too quickly)
k6-operator 로그:
k6 inspect: {MaxVUs:1 ...}
ERROR: Parallelism argument cannot be larger than maximum VUs in the script
{"maxVUs": 1, "parallelism": 2, "error": "number of instances > number of VUs"}
원인 분석#
k6-operator 실행 흐름#
1. TestRun CR 생성
↓
2. Initializer Pod 실행
- k6 inspect: 스크립트 분석 (maxVUs 확인) ← 환경변수 없음!
- k6 archive: 스크립트 압축
↓
3. Runner Pod 생성 (VUS, DURATION 환경변수 주입)
↓
4. 테스트 실행
문제 코드#
// scripts.go에서 생성되는 k6 스크립트
const _vus = __ENV.K6_VUS ? parseInt(__ENV.K6_VUS) : (parseInt(__ENV.VUS) || 1);
// ↑
// 기본값 1!
| 단계 | 환경변수 | _vus 값 |
|---|---|---|
| k6 inspect (Initializer) | 없음 | 1 (기본값) |
| k6 run (Runner) | VUS=4000 | 4000 |
k6 inspect는 스크립트의 export const options를 분석해서 maxVUs를 결정함.
환경변수가 없으면 기본값 1이 사용되어 maxVUs=1로 판단됨.
왜 환경변수가 없나?#
설계상 의도된 동작:
k6-operator는 스크립트를 분석해서 리소스 요구사항을 파악한 후 Runner Pod를 생성함. Initializer Pod는 분석 전용이라 VUS 환경변수가 주입되지 않음.
해결#
수정 내용#
k6-controller/services/scripts.go에서 기본값을 충분히 크게 설정:
// Before
const _vus = __ENV.K6_VUS ? parseInt(__ENV.K6_VUS) : (parseInt(__ENV.VUS) || 1);
// After
const _vus = __ENV.K6_VUS ? parseInt(__ENV.K6_VUS) : (parseInt(__ENV.VUS) || 50000);
적용 방법#
cd /path/to/k6-controller
docker build -t ghcr.io/goorm-gongbang/k6-controller:latest .
# 2. 푸시
docker push ghcr.io/goorm-gongbang/k6-controller:latest
# 3. 재시작
kubectl rollout restart deployment/k6-controller -n k6-system
관련 이슈#
ConfigMap 1MB 제한 (15000+ VU)#
대량의 토큰(15000+)을 사용할 때 ConfigMap 1MB 제한에 걸림.
해결: 토큰을 1000개씩 여러 ConfigMap으로 분할
createTokenConfigMaps(): 토큰을 청크로 분할BuildScriptWithMultipleTokenFiles(): 여러 파일에서 토큰 로드
// 여러 파일에서 토큰 로드
const AUTH_TOKENS = new SharedArray('tokens', function() {
let allTokens = [];
try { allTokens = allTokens.concat(JSON.parse(open('/data/tokens-0/tokens.json'))); } catch(e) {}
try { allTokens = allTokens.concat(JSON.parse(open('/data/tokens-1/tokens.json'))); } catch(e) {}
// ...
return allTokens;
});
참고#
- k6-operator GitHub: https://github.com/grafana/k6-operator
- k6 inspect 문서: https://k6.io/docs/misc/k6-inspect/