4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【kubernetes】k8s上のシステムに負荷試験をしてみる!

Posted at

Kubernetes × k6 で負荷試験を実施してみた!

負荷試験はシステムのスケーラビリティを確認する上で重要な工程です!
今回は Kubernetes上で「k6」を利用して負荷試験を行い、その手順をまとめてみました!

1. 環境構築: ローカルk8sを準備

クラスターの準備

まずローカル環境でk8sを動かせるよう、
Kind を利用してクラスタを作成します。

kind create cluster --name kind-control-plane

オプション情報

[--name] でクラスターの名前を決定可能です!

作成したクラスターを確認

作成されたクラスタを確認しましょう。

kubectl get nodes

こんな感じに出てくるはず・・・!

スクリーンショット 2025-02-22 15.34.44.png

2. 負荷試験シナリオを JS で記述・ConfigMap登録

JSでシナリオを作成

k6 は JavaScript でテストシナリオを記述します。
まず「test-script.js」とでも名付け、JSファイル作成します。

test-script.js
import http from 'k6/http';
import { check, sleep } from 'k6';

export default function () {
    // 作成する環境にHTTPリクエストを送信
    let res = http.get('http://podA-service.default.svc.cluster.local:8080');
    check(res, { 'status is 200': (r) => r.status === 200 });
    sleep(1);
}

configMapのymlを作成

次に、Kubernetes の ConfigMap を作成してシナリオを管理します!

config-map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: k6-script
data:
  test-script.js: |
    import http from 'k6/http';
    import { check, sleep } from 'k6';

    export default function () {
        let res = http.get('http://podA-service.default.svc.cluster.local:8080');
        check(res, { 'status is 200': (r) => r.status === 200 });
        sleep(1);
    }

適用コマンド!!

kubectl apply -f k6-configmap.yml

3. k6 を実行する Job を作成

Kubernetes の Job を利用して負荷試験を実行する Podを作成します。
k6 を Docker で動作させるため、以下の Job を作成します。

job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: k6-load-test
spec:
  template:
    spec:
      containers:
        - name: k6
          image: grafana/k6
          args: ["run", "/scripts/test-script.js"]
          volumeMounts:
            - name: script-volume
              mountPath: /scripts
      restartPolicy: Never
      volumes:
        - name: script-volume
          configMap:
            name: k6-script

適用コマンド:

kubectl apply -f k6-job.yml

4. Job を実行して負荷試験を開始

Job が作成されたことを確認する:

kubectl get pods

ログを確認し、負荷試験の進行状況をチェック:

kubectl logs -f <k6-load-test-pod名>

Jobが起動されると、JSファイルを実行するので
負荷試験が始まっています。

k6の実行結果はこんな感じです↓

     execution: local
        script: test.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 1m0s max duration (incl. graceful stop):
              * default: 1 looping VUs for 30s (gracefulStop: 30s)


     data_received..................: 7.6 MB 248 kB/s
     data_sent......................: 17 kB  561 B/s
     http_req_blocked...............: avg=15.11ms  min=10.9ms  med=13.21ms max=66.61ms  p(90)=21.56ms  p(95)=26.04ms
     http_req_connecting............: avg=14.97ms  min=10.79ms med=13.09ms max=66.45ms  p(90)=21.41ms  p(95)=25.9ms
     http_req_duration..............: avg=127.24ms min=84.23ms med=94.38ms max=770.35ms p(90)=198.65ms p(95)=349.85ms
       { expected_response:true }...: avg=127.24ms min=84.23ms med=94.38ms max=770.35ms p(90)=198.65ms p(95)=349.85ms
     http_req_failed................: 0.00%  0 out of 214
     http_req_receiving.............: avg=42.37ms  min=11.32ms med=18.32ms max=603.41ms p(90)=74.67ms  p(95)=223.57ms
     http_req_sending...............: avg=101.75µs min=26µs    med=87.5µs  max=1.59ms   p(90)=120µs    p(95)=146µs
     http_req_tls_handshaking.......: avg=0s       min=0s      med=0s      max=0s       p(90)=0s       p(95)=0s
     http_req_waiting...............: avg=84.77ms  min=72.53ms med=75.65ms max=190.75ms p(90)=111.3ms  p(95)=144.79ms
     http_reqs......................: 214    7.013214/s
     iteration_duration.............: avg=142.54ms min=95.64ms med=109.7ms max=789.1ms  p(90)=218.03ms p(95)=366.01ms
     iterations.....................: 214    7.013214/s
     vus............................: 1      min=1        max=1
     vus_max........................: 1      min=1        max=1


running (0m30.5s), 0/1 VUs, 214 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  30s

k6のメトリクスを整理しよう

上記結果のサンプルを出してみましたが、それぞれのメトリクスには
こんな意味があります!

メトリクス 説明
data_received サーバーから受信したデータの合計量
data_sent クライアントから送信したデータの合計量
http_req_blocked リクエストがブロックされた時間
http_req_connecting リクエストが接続を確立するのに要した時間
http_req_duration リクエストの完了に要した時間(レイテンシ)
http_req_failed リクエストが失敗した割合
http_req_receiving レスポンスを受信するのに要した時間
http_req_sending リクエストを送信するのに要した時間
http_req_tls_handshaking TLSハンドシェイクが行われた時間
http_req_waiting リクエストがサーバーの応答を待機していた時間
http_reqs リクエストの総数およびリクエストの実行速度(スループット)
iteration_duration イテレーション(1回のテストサイクル)の完了に要した時間
iterations イテレーションの総数およびイテレーションの実行速度
vus 同時に実行されている仮想ユーザー数
vus_max テスト実行中に最大で同時に実行されていた仮想ユーザー数

5. CPU やメモリの負荷を確認

負荷試験中に top コマンドを利用して CPU 負荷を確認できます。

kubectl exec -it [pod名] -- top

topコマンドの見方

topコマンドをk8s上で実施すると、これまた色々な情報が
出てきます。

top - 00:56:07 up 27 min,  1 user,  load average: 0.01, 0.04, 0.01
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s): 26.3 us,  0.3 sy,  0.0 ni, 73.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.2 st 
MiB Mem :   7810.1 total,   6339.4 free,    795.1 used,    851.3 buff/cache     
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   7015.0 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                                                                                    
    831 mysql     20   0 1788052 432308  34944 S  50.7   5.4   1:15.31 mysqld   

上記の簡単な考察

あくまで上の結果はシステムによりますが、上記の場合は・・・

  • 3行目の「%Cpu(%)」はCPUの使用率
  • 一番下の行では、MySQLがCPUを50%程度使用している
    等の情報を読み取ることができます。

少し古いですが、topコマンドの解説記事です!

まとめ

いかがでしたでしょうか?
k8sを例に出しましたが、負荷試験を行うことで

  • ボトルネックの発見に繋がる
  • そもそも何がボトルネックか分かる
  • どの程度の負荷がかかってるか分かる

など・・・
業務でも役立つことが多い負荷試験の一例になると思うので
参考になれば幸いです!

後片付け

podとconfigMapを消しておきましょう。

podの削除

kubectl delete pod [pod名]

configMapの削除

kubectl delete cm [ConfigMap名]

ちゃんと削除できてるかな?

# pod情報が何も表示されなければOK
kubectl get pods

# configMapが何も表示されなければOK
kubectl get cm
4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?