개발 이야기/인프라

[K6] K6 세팅 가이드 with gRPC

제이온 (Jayon) 2023. 3. 17.

안녕하세요? 제이온입니다.

오늘은 gRPC 서버에 k6를 이용하여 부하 테스트를 진행할 때 세팅 과정을 소개하려고 합니다.

 

K6란?

  • 오픈소스 성능테스트 솔루션입니다.
  • 사용하기가 쉽고, Grafana 등과 연동하여 UI를 구성할 수 있습니다.
  • CLI 툴을 사용하여 성능 테스트를 수행합니다.
  • 로컬 혹은 원격지의 스크립트를 로드하여 테스트 할 수 있습니다.
  • Check/Thresholds 를 제공하여 성능 목표를 다양하게 구성할 수 있습니다.
  • 자바 스크립트 ES6 문법을 지원합니다.

 

K6 세팅 with gRPC

먼저 brew install k6 명령어를 통해 k6를 설치합니다. (https://k6.io/docs/get-started/installation/)

만약 도커로 설치하여 실행하고 싶다면 docker pull grafana/k6 명령어를 수행합니다.

그리고 해당 문서를 참고하여 script.js를 작성합니다.

 

import grpc from 'k6/net/grpc';
import { check, sleep } from 'k6';

const client = new grpc.Client();
client.load(['${protobuf 경로}'], '${proto 파일 명}')

export default() => {
    client.connect('${host}:${port}', {
        plaintext: false,
        timeout: '10s',
    });

    const data = { id: 'id-c4fad211-f583-460e-9302-d4a0e2922ea9' }
    const response = client.invoke('HelloService', data);

    check(response, {
        'status is OK': (r) => r && r.status === grpc.StatusOK,
    });

    console.log(JSON.stringify(response));

    client.close();
    sleep(1);
};

 

작성한 스크립트 기반으로 실제 부하 테스트를 수행할 때는 k6 run script.js 명령어를 실행하면 됩니다.

 

로컬에서 세팅할 때 주의할 점

아마도 로컬에서 gRPC 서버와 통신하기 위해 script.js를 아래와 같이 작성할 것입니다.

 

client.connect('localhost:6565', {
    plaintext: true,
    timeout: '10s',
});

 

gRPC 서버는 기본적으로 HTTP/2.0을 기반으로 작동합니다. HTTP/2.0은 HTTP/1.1과 달리 TCP 연결 이후에 TLS 연결이 필수로 이루어져야 합니다. 즉, 인증서가 필요하다는 뜻입니다.

이때 h2c 프로토콜을 사용하면 비신뢰적인 HTTP/2.0 즉, 인증서 없이 통신이 가능하며 그러한 역할을 하는 것이 바로 위의 plaintext 옵션입니다.

 

하지만 grpc-kotlin 서버를 사용하는 저희 팀에서는 gRPC 서버와 연결을 할 수 없었고, grpc-scala 서버를 사용하는 팀은 성공적으로 gRPC 서버와 연결을 할 수 있었습니다. 내부적으로 어떠한 문제가 있는지는 구체적으로 파악하지는 못했습니다. 또한 해당 이슈와 같이 저와 비슷한 문제를 겪는 사람도 있었습니다.

 

그래서 위 방식이 실패했을 때 확실하게 로컬 환경에서 k6를 세팅하는 방법을 알려 드리겠습니다.

먼저 script.js를 다음과 같이 수정합니다.

 

client.connect('localhost:31400', {
    plaintext: false,
    timeout: '10s',
});

 

그리고 다음 스크립트를 실행합니다.

 

#!/bin/sh

# Installataion
brew install caddy mkcert
mkcert -install

# At run
mkcert --key-file key.pem --cert-file cert.pem localhost
caddy run --adapter caddyfile --config - <<'EOF'
localhost:31400
tls cert.pem key.pem
reverse_proxy h2c://localhost:6565
EOF

 

이 스크립트를 실행했을 때 동작 과정은 다음과 같습니다.

 

  • mkcert 툴을 사용하여 TLS 인증서를 생성합니다.
    • https://github.com/FiloSottile/mkcert
    • mkcert는 로컬 개발 환경에서 사용할 수 있는 간단한 도구로, 로컬 호스트에 대한 신뢰할 수 있는 TLS 인증서를 생성합니다. 이 도구는 자체 루트 인증서를 생성하고 이를 사용하여 로컬 호스트에 대한 인증서를 발급해 줍니다.
    • mkcert가 생성한 인증서를 신뢰할 수 있는 이유는 mkcert가 자체 루트 인증서를 생성하고 이를 로컬 컴퓨터의 신뢰할 수 있는 인증서 저장소에 설치하기 때문입니다. 이로 인해 mkcert로 생성한 인증서는 자체 루트 인증서에 의해 서명되어 있으므로 브라우저나 애플리케이션이 이 인증서를 신뢰할 수 있습니다.
    • 예외적으로 파이어폭스는 파이어폭스만의 인증서 저장소가 있어서 별도의 설정을 추가로 거쳐야 합니다.
  • caddy 웹 서버를 사용하여 TLS 설정 및 리버스 프록시 설정을 합니다.

 

 

k6 run script.js를 수행하면 성공적으로 부하 테스트 결과가 오는 것을 확인하실 수 있습니다!

댓글

추천 글