k6+grafana+prometheusで作るパフォーマンス計測環境
タイトルの通りアプリケーションのperformance計測環境を作成する。
計測するアプリケーションは今回
- Nestjs
で作成する。
計測に使用するのは以下のツール
- k6: 負荷テストツール
- Grafana: モニタリング用のダッシュボード
- Prometheus: メトリクス収集して時系列データベースに保存
Nestjsアプリケーションの作成と起動確認
まずはNestjsアプリケーションを立ち上げる部分まで行う。
前提条件として
- nodeがinstallされている
- @nest/cliがinstallされている
とする。
今回のパフォーマンス測定をするfolderを作成する。
適当なfolderでterminalを起動して、以下を実行する。
mkdir performance-insights
cd performance-insights
nest new sample-project --strict
Nestコマンドを実行するとterminal上にpackage-managerの選択画面が出るのでnpmを選択してプロジェクトの作成は完了。
Docker上で動作させたいので
cd sample-project
touch Dockerfile
としてDockerfileに以下の内容を記述する
# ベースイメージ
FROM node:latest
# 作業ディレクトリ設定
WORKDIR /usr/src/app
# 依存関係のインストール
COPY package*.json ./
RUN npm install
# アプリケーションのソースをコピー
COPY . .
# アプリケーションのビルド
RUN npm run build
# ポートのエクスポート
EXPOSE 8080
# アプリケーションの起動
CMD ["npm", "run", "start:prod"]
Nestjsが起動して叩けることを確認したいので、
docker build -t nestjs-app .
docker run -d --cpus="1" --memory="1g" --name nestjs-app -p 8080:8080 nestjs-app
で起動させて、別のterminalを開いて以下を実行する。
curl localhost:8080
これで'Hello World!'とterminalに表示されていればNestjsのproject作成と起動テストは完了。
k6コンテナの作成
k6を実行できるコンテナをDockerで作成する。
# ベースイメージとして Ubuntu を指定
FROM ubuntu:20.04
# k6 のインストールに必要なパッケージを更新・インストール
RUN apt-get update && apt-get install -y \
ca-certificates \
curl \
gnupg \
&& rm -rf /var/lib/apt/lists/*
# Grafana の公式リポジトリを追加して k6 をインストール
RUN curl -fsSL https://dl.k6.io/key.gpg | apt-key add - \
&& echo "deb https://dl.k6.io/deb stable main" | tee /etc/apt/sources.list.d/k6.list \
&& apt-get update \
&& apt-get install -y k6 \
&& rm -rf /var/lib/apt/lists/*
# ENTRYPOINT に bash を設定
ENTRYPOINT ["/bin/bash"]
ファイルを作成したら以下のコマンドでk6コンテナを起動する。
docker build -t k6-image .
docker run -it --name k6-container k6-image
コンテナが起動できたらコンテナのterminalで以下を実行してscriptを作成する
k6 new
defaultでscript.jsのファイルが作成されるので、これを実行して動作テストを行う。
k6 run script.js
terminal上にk6の実行結果が表示されていればOK。
k6 + Grafana + Prometheusのコンテナ郡の作成
k6コンテナでの実行結果を保存して可視化するためにGrafanaとPrometheusとのコンテナ群を作成する。
以下のようにdocker-compose.yamlを作成する
networks:
k6-prometheus:
prometheus-grafana:
services:
k6:
build:
context: ./k6
tty: true
stdin_open: true
volumes:
- type: bind
source: "./scripts"
target: "/scripts"
environment:
- K6_PROMETHEUS_RW_SERVER_URL=http://prometheus:9090/api/v1/write
networks:
- k6-prometheus
prometheus:
image: prom/prometheus:v2.49.1
ports:
- "9090:9090"
volumes:
- type: bind
source: "./prometheus.yml"
target: "/etc/prometheus/prometheus.yml"
- type: bind
source: "./prometheus-data"
target: "/prometheus"
command:
- "--web.enable-remote-write-receiver"
- "--config.file=/etc/prometheus/prometheus.yml"
networks:
- k6-prometheus
- prometheus-grafana
grafana:
image: grafana/grafana:10.3.1
ports:
- "3000:3000"
volumes:
- type: bind
source: "./grafana"
target: "/etc/grafana/provisioning"
networks:
- prometheus-grafana
yamlを作成したらコンテナ群をbuildして立ち上げるために以下のコマンドを実行する
docker compose up -d
コンテナが立ち上がったらlocalhost:3000をブラウザで叩いてgrafanaにアクセスする。
初期のユーザー名とパスワードは両方adminなので、アクセスしたらパスワードを任意のものに変更する。
ログインしたらgrafanaにprometheusのデータを読み込むように接続を行う。
手順としては
- Data sourceとしてPrometheusを設定する
- ダッシュボードを作成し、先ほど設定したPrometheusのデータを表示する
ますは1としてHome画面の左のサイドバーからHome > Connections > Data sourcesへと進み、Add data sourceのボタンを押下する。
追加するData sourceを選択できるので検索欄にPrometheus入力して選択する。
Settingsの画面が出てくるのでNameとConnectionのServer Urlを入力する。
Nameは任意のものでいいがServer Urlはhttp://prometheus:9090を入力する。これはdocker-compose内のネットワークの名前解決で接続するためこのurlになる。
入力が完了したら一番下にあるsave & testのボタンを押下してSuccessfullyのメッセージが出れば1は完了。
2としてHome画面の左のサイドバーからDashboardsを選択し、Create Dashboardボタンを押下する。
ダッシュボードをどの方法で作成するのかの画面が出てくるので、Import a dashboardを選択してそのボタンを押下する。
Import dashboard画面のFind and import dashboards for common applicationの部分で19665のidを入力する。
Loadボタンを押下してdashoboardの画面に移動したら2は完了。
実際にパフォーマンスの測定
実際にアプリケーションの速度を測定する。
まずはNestjsを立ち上げておく。
次に作成したパフォーマンス測定用のコンテナ群を起動して、grafanaの作成したダッシュボード画面を開いておく。
次に実行するscriptファイルを作成する。
docker-composeでscriptsとい名前のフォルダーをbindするように設定しているので、
mkdir scripts
でフォルダーを作成してそこに以下のファイルを作成する。
import http from "k6/http";
import { check, sleep } from "k6";
// Test configuration
export const options = {
thresholds: {
// Assert that 99% of requests finish within 500ms.
http_req_duration: ["p(99) < 500"],
},
// Ramp the number of virtual users up and down
stages: [
{ duration: "30s", target: 10 },
{ duration: "1m", target: 10 },
{ duration: "30s", target: 0 },
],
};
// Simulated user behavior
export default function () {
let res = http.get("http://host.docker.internal:8080");
// Validate response status
check(res, { "status was 200": (r) => r.status == 200 });
sleep(1);
}
次にk6コンテナに以下のコマンドかdocker-desktopのexeタブからterminalに接続する。
コンテナに接続するコマンド
docker exec -it ${container_id} /bin/bash
terminalに接続できたら以下のコマンドを実行してk6による負荷試験を行う。
k6 run -o experimental-prometheus-rw ./scripts/sample.js
ダッシュボードを新規にリロードすると結果が反映されるのを確認したら完了。