k6란?
k6는 Grafana Labs가 개발한 오픈소스 부하 테스트 프레임워크입니다. JavaScript(ES6+)로 테스트 스크립트를 작성하며, Go로 구현된 런타임 덕분에 높은 성능과 낮은 리소스 사용량을 제공합니다.
주요 특징
- 개발자 친화적 — 익숙한 JavaScript로 테스트 코드 작성
- 경량 & 고성능 — 단일 머신에서 수만 VU(가상 사용자) 실행 가능
- 풍부한 프로토콜 — HTTP/1.1, HTTP/2, WebSocket, gRPC 지원
- CI/CD 통합 — GitHub Actions, GitLab CI, Jenkins와 자연스럽게 통합
- 확장성 — xk6 확장, k6 Cloud로 분산 실행
설치
macOS (Homebrew)
brew install k6bash
Linux (Debian/Ubuntu)
sudo gpg -k
sudo gpg --no-default-keyring \
--keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 \
--recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] \
https://dl.k6.io/deb stable main" \
| sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6bash
Windows (winget)
winget install k6 --source wingetpowershell
Docker
docker pull grafana/k6
docker run --rm -i grafana/k6 run - <script.jsbash
설치 확인:
k6 version을 실행해 버전이 출력되면 설치 완료입니다.첫 번째 테스트
가장 간단한 k6 스크립트입니다. script.js로 저장하세요.
import http from 'k6/http';
import { sleep } from 'k6';
export const options = {
vus: 10, // 동시 가상 사용자 수
duration: '30s', // 테스트 지속 시간
};
export default function () {
http.get('https://test.k6.io');
sleep(1);
}javascript
실행:
k6 run script.jsbash
출력 예시:
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/ .io
execution: local
script: script.js
output: -
scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration
✓ http_req_duration............: avg=210ms min=180ms med=205ms max=380ms
✓ http_req_failed..............: 0.00%
iterations...................: 300 / 300
vus..........................: 10text
핵심 개념
| 개념 | 설명 | 예시 |
|---|---|---|
| VU (Virtual User) | 동시 실행되는 가상 사용자 수 | vus: 100 |
| Duration | 테스트 총 지속 시간 | duration: '5m' |
| Iteration | default 함수 1회 실행 | VU × Duration / sleep |
| Stage | VU 수를 단계적으로 변화 | Ramp-up/Ramp-down |
| Threshold | 테스트 합격/실패 기준 | p(95) < 500 |
| Check | 응답 검증 (어서션) | status === 200 |
테스트 시나리오
1. 부하 테스트 (Load Test)
정상 및 피크 트래픽 조건에서 시스템 성능을 검증합니다.
export const options = {
stages: [
{ duration: '5m', target: 100 }, // Ramp-up: 0 → 100 VU
{ duration: '10m', target: 100 }, // 부하 유지
{ duration: '5m', target: 0 }, // Ramp-down: 100 → 0
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95퍼센타일 < 500ms
http_req_failed: ['rate<0.01'], // 에러율 < 1%
},
};javascript
2. 스트레스 테스트 (Stress Test)
시스템 한계점(breaking point)을 찾기 위해 부하를 점진적으로 증가시킵니다.
export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '5m', target: 100 },
{ duration: '2m', target: 200 },
{ duration: '5m', target: 200 },
{ duration: '2m', target: 300 },
{ duration: '5m', target: 300 },
{ duration: '2m', target: 0 }, // 복구 확인
],
};javascript
3. 스파이크 테스트 (Spike Test)
갑작스러운 트래픽 급증(예: 이벤트, 프로모션)에 시스템이 어떻게 반응하는지 검증합니다.
export const options = {
stages: [
{ duration: '10s', target: 100 }, // 일반 트래픽
{ duration: '1m', target: 100 },
{ duration: '10s', target: 1400 }, // 급격한 스파이크
{ duration: '3m', target: 1400 },
{ duration: '10s', target: 100 }, // 복구
{ duration: '3m', target: 100 },
{ duration: '10s', target: 0 },
],
};javascript
4. 소크 테스트 (Soak Test)
장시간 운영 시 메모리 누수, 커넥션 풀 고갈 등을 탐지합니다. 보통 수 시간 ~ 수일 실행합니다.
export const options = {
stages: [
{ duration: '5m', target: 100 }, // Ramp-up
{ duration: '8h', target: 100 }, // 장시간 유지
{ duration: '5m', target: 0 }, // Ramp-down
],
};javascript
Checks & Thresholds
Checks — 응답 검증
import { check } from 'k6';
import http from 'k6/http';
export default function () {
const res = http.get('https://api.example.com/users');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms':(r) => r.timings.duration < 500,
'body contains users': (r) => r.body.includes('users'),
});
}javascript
Thresholds — 합격 기준
export const options = {
thresholds: {
// 95퍼센타일 응답시간 500ms 미만
http_req_duration: ['p(95)<500', 'p(99)<1000'],
// 에러율 1% 미만
http_req_failed: ['rate<0.01'],
// 특정 check 통과율 99% 이상
'checks{check:status is 200}': ['rate>0.99'],
// 커스텀 메트릭
'my_custom_metric': ['avg<200'],
},
};javascript
Threshold 실패 시: k6는 종료 코드 99를 반환합니다. CI/CD 파이프라인에서 이를 활용해 배포를 차단할 수 있습니다.
HTTP 요청 작성
GET / POST / PUT / DELETE
import http from 'k6/http';
import { check } from 'k6';
const BASE_URL = 'https://api.example.com';
export default function () {
// GET
const listRes = http.get(`${BASE_URL}/users`);
// POST (JSON body)
const payload = JSON.stringify({ name: 'TestUser', email: 'test@example.com' });
const headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer TOKEN' };
const createRes = http.post(`${BASE_URL}/users`, payload, { headers });
check(createRes, { 'created': (r) => r.status === 201 });
// PUT
const userId = JSON.parse(createRes.body).id;
http.put(`${BASE_URL}/users/${userId}`, JSON.stringify({ name: 'Updated' }), { headers });
// DELETE
http.del(`${BASE_URL}/users/${userId}`, null, { headers });
}javascript
세션 유지 (쿠키 / 로그인)
import http from 'k6/http';
import { check } from 'k6';
export default function () {
// 로그인 → 세션 쿠키 자동 유지
const loginRes = http.post('https://api.example.com/login', {
username: 'user@example.com',
password: 'password123',
});
check(loginRes, { 'logged in': (r) => r.status === 200 });
// 이후 요청에 쿠키 자동 첨부
http.get('https://api.example.com/profile');
}javascript
결과 출력 & 리포트
내장 요약 리포트
k6는 실행 후 자동으로 통계 요약을 출력합니다. 파일로 저장:
k6 run --out json=results.json script.jsbash
HTML 리포트 생성
# k6-reporter 설치
npm install -g k6-html-reporter
# JSON 결과를 HTML로 변환
k6-html-reporter --resultFile results.json --reportTitle "부하 테스트 결과"bash
Grafana + InfluxDB 연동
# InfluxDB로 메트릭 전송
k6 run --out influxdb=http://localhost:8086/k6 script.js
# Docker Compose로 환경 구성
# grafana/k6-grafana-dashboard 사용 가능bash
CI/CD 통합
GitHub Actions
name: Performance Test
on:
push:
branches: [main]
pull_request:
jobs:
k6_load_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run k6 load test
uses: grafana/k6-action@v0.3.1
with:
filename: tests/load-test.js
env:
BASE_URL: ${{ secrets.STAGING_URL }}
- name: Upload results
uses: actions/upload-artifact@v3
with:
name: k6-results
path: results.jsonyaml
GitLab CI
k6-test:
stage: test
image: grafana/k6
script:
- k6 run --out json=results.json tests/load-test.js
artifacts:
paths:
- results.json
when: alwaysyaml
팁: Threshold 실패 시 k6 exit code가 99가 되므로 CI 파이프라인이 자동으로 실패 처리됩니다. 별도 조건 체크 없이 배포 게이팅이 가능합니다.
k6 Cloud (분산 실행)
단일 머신을 초과하는 대규모 부하가 필요한 경우 Grafana k6 Cloud를 활용합니다.
# k6 Cloud 로그인
k6 login cloud --token YOUR_TOKEN
# 클라우드에서 실행 (전 세계 여러 지역)
k6 cloud script.js
# 특정 지역 지정
k6 cloud --linger script.jsbash
// 클라우드 전용 옵션
export const options = {
ext: {
loadimpact: {
projectID: 123456,
name: 'My Load Test',
distribution: {
Seoul: { loadZone: 'amazon:kr:seoul', percent: 60 },
Virginia: { loadZone: 'amazon:us:ashburn', percent: 40 },
},
},
},
};javascript
도구 비교
| 항목 | k6 | JMeter | nGrinder |
|---|---|---|---|
| 스크립트 언어 | JavaScript | GUI / Groovy | Groovy / Jython |
| 설치 복잡도 | 매우 간단 | Java 필요 | 컨트롤러+에이전트 |
| CI/CD 통합 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| 분산 테스트 | k6 Cloud | Remote JMeter | 기본 내장 |
| 학습 곡선 | 낮음 | 중간 | 중간 |
| 리소스 사용 | 낮음 | 높음 (JVM) | 중간 |
| GUI | 없음 (CLI) | 풍부한 GUI | 웹 UI |
k6 추천 상황: 개발자가 코드로 테스트를 관리하고, CI/CD 파이프라인에 자동화된 성능 게이팅이 필요한 경우.
더 자세한 내용은 TestForge Docs의 부하 테스트 가이드에서 확인하세요.
더 자세한 내용은 TestForge Docs의 부하 테스트 가이드에서 확인하세요.