【負荷テスト】k6をgithub actionsで試しに動かす

2022年12月23日

最近記事にしている負荷テストツールのk6ですが、github actions上だとどれくらいのrpsで負荷がかけられるか確かめたかったので試してみました。

環境

k6: v0.42

サンプルコードのリポジトリ

今回使用したサンプルは以下のリポジトリに配置しています。

https://github.com/i-shinya/k6-github-actions-sample

k6をgithub actions上で動かす

シナリオファイル

シナリオファイルは以下を使用しています。リクエスト先はlocalhost:80でローカルのnginxに対してのテストです。

import { check } from "k6"
import http from "k6/http"

export const options = {
    // 閾値(設定した条件を満たせないと負荷テストがfailになる)
    thresholds: {
        // リクエストの失敗が1%以内
        http_req_failed: ["rate<0.01"],
        // 90パーセンタイルが500ms以内、95パーセンタイルが1000ms以内のレイテンシ
        http_req_duration: ["p(90)<500", 'p(95) < 1000']
    },
    // テストステージ(順番に実行される)
    stages: [
        // targetは同時実行数、durationは実行時間
        { target: 1000, duration: '10s' },
        { target: 2000, duration: '10s' }
    ]
}

// テストケース
export default function () {
    const res = http.get(
        "http://localhost:80"
    )
    check(res, {
        'is_status_200': (r) => r.status === 200
    })
}

github workflow

actionsのworkflowファイルは以下を使用します。公式からactionが提供されているのですが、こちらを使用するとlocalhostへのテストが行えなかったのでk6をインストールしてそちらを使用しています。(公式のactionを使用する場合は公式ドキュメントを参考にしてください)

トリガーは手動実行にしてrpsをパラメータとして指定するようにしました。

name: k6-load-test
on:
  workflow_dispatch:
    inputs:
      rps:
        description: "k6負荷実行のRPS"
        required: true
        default: 1000
jobs:
  k6test:
    name: Run k6 load test
    runs-on: ubuntu-latest

    services:
      nginx:
        image: nginx:latest
        ports:
          - "80:80"

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: curl nginx
        run: curl http://localhost:80
      - name: Install k6
        run: |
          curl https://github.com/grafana/k6/releases/download/v0.42.0/k6-v0.42.0-linux-amd64.tar.gz -L | tar xvz --strip-components 1
      - name: Run k6 load test
        run: |
          ./k6 run simple-k6-sample.js --rps ${{ github.event.inputs.rps }}

実行する!!

github actionsから手動で実行!!RPSはデフォルトとして設定した1000にしました。

k6の実行結果は以下のようになりました。指定した1000 req/secはほぼほぼでてますね!

running (22.0s), 0000/2000 VUs, 21919 complete and 0 interrupted iterations
default ✓ [ 100% ] 0000/2000 VUs  20s

     ✓ is_status_200

     checks.........................: 100.00% ✓ 21919      ✗ 0     
     data_received..................: 19 MB   850 kB/s
     data_sent......................: 1.7 MB  78 kB/s
     http_req_blocked...............: avg=49.22µs  min=700ns    med=2.1µs    max=58.43ms p(90)=112.29µs p(95)=229.79µs
     http_req_connecting............: avg=39.49µs  min=0s       med=0s       max=58.12ms p(90)=71.59µs  p(95)=179.99µs
   ✓ http_req_duration..............: avg=346.65µs min=127.49µs med=238.89µs max=27.27ms p(90)=463.49µs p(95)=646.7µs 
       { expected_response:true }...: avg=346.65µs min=127.49µs med=238.89µs max=27.27ms p(90)=463.49µs p(95)=646.7µs 
   ✓ http_req_failed................: 0.00%   ✓ 0          ✗ 21919 
     http_req_receiving.............: avg=45.63µs  min=10.7µs   med=30.2µs   max=11.95ms p(90)=75.59µs  p(95)=110.99µs
     http_req_sending...............: avg=18.81µs  min=3.2µs    med=10.9µs   max=11.22ms p(90)=30.3µs   p(95)=45.6µs  
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s      p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=282.2µs  min=90.8µs   med=187.29µs max=27.24ms p(90)=358.89µs p(95)=522.39µs
     http_reqs......................: 21919   996.362275/s
     iteration_duration.............: avg=1s       min=509.89µs med=1s       max=1.99s   p(90)=1.79s    p(95)=1.89s   
     iterations.....................: 21919   996.362275/s
     vus............................: 831     min=17       max=1916
     vus_max........................: 2000    min=2000     max=2000

次はRPSを10000にして実行!10000には届いてないですが、7000 req/secくらいでていますね!(VUsとか調整したらもう少しでるかもしれんけど)

ある程度のアプリであればgithub actions上からの負荷テストで問題ないかもですね。

running (20.1s), 0000/2000 VUs, 139743 complete and 0 interrupted iterations
default ✓ [ 100% ] 0000/2000 VUs  20s

     ✓ is_status_200

     checks.........................: 100.00% ✓ 139743      ✗ 0     
     data_received..................: 119 MB  5.9 MB/s
     data_sent......................: 11 MB   542 kB/s
     http_req_blocked...............: avg=2.26ms   min=500ns    med=1.5µs    max=542.83ms p(90)=2.29µs   p(95)=4.5µs   
     http_req_connecting............: avg=1.96ms   min=0s       med=0s       max=542.31ms p(90)=0s       p(95)=0s      
   ✓ http_req_duration..............: avg=124.76ms min=118.7µs  med=108.86ms max=834.34ms p(90)=243.01ms p(95)=279.66ms
       { expected_response:true }...: avg=124.76ms min=118.7µs  med=108.86ms max=834.34ms p(90)=243.01ms p(95)=279.66ms
   ✓ http_req_failed................: 0.00%   ✓ 0           ✗ 139743
     http_req_receiving.............: avg=2.69ms   min=9µs      med=17.6µs   max=579.62ms p(90)=10.41ms  p(95)=17.64ms 
     http_req_sending...............: avg=1.82ms   min=2.6µs    med=6µs      max=769.89ms p(90)=125.99µs p(95)=6.48ms  
     http_req_tls_handshaking.......: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=120.23ms min=84µs     med=104.8ms  max=775.69ms p(90)=237.26ms p(95)=271.1ms 
     http_reqs......................: 139743  6937.269372/s
     iteration_duration.............: avg=144.11ms min=183.49µs med=130.13ms max=908.72ms p(90)=253.56ms p(95)=326.03ms
     iterations.....................: 139743  6937.269372/s
     vus............................: 1919    min=18        max=1919
     vus_max........................: 2000    min=2000      max=2000

最後に

github actions上での実行でこれくらいrps出せるのは驚きでした!

 

困ったこと

公式actionを使うとlocalhostへ通信できない・・・

上でちらっと書いたのですが、公式actionではlocalhostにアクセスできず以下のようなエラーが表示表示されていました。

ログを見たら公式actionはdockerで動いてるためでした。ログをちゃんと読んでなくて解決までに時間かけてしまいました。

time="2022-12-19T14:57:12Z" level=warning msg="Request Failed" error="Get \"http://localhost:80\": dial tcp 127.0.0.1:80: connect: connection refused"

k6バージョンアップによってエラーが・・・

こちらは原因が謎なのですが、私がgithub actionsを追加し動作確認した翌日にv0.41 –> v0.42へバージョンアップが行われたようでそれによりworkflowが失敗するようになりました。

その際はインストール部分を以下のように記述していましたが、v0.41 –> v0.42へバージョンアップされた結果動かなくなりました。インストール方法を上述したものに変更したら動くようになったものの原因は分からず。

apt-getしたものとcurlで取得したものが何か違うのかもしれないですね。

- name: Install k6
        run: |
          sudo apt-get update
          sudo apt-get upgrade
          sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
          echo "deb https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
          sudo apt-get update
          sudo apt-get install k6

参考

  • 公式のactionドキュメント
    • https://k6.io/blog/load-testing-using-github-actions/
  • k6のインストール手順は以下を参考(公式のものでは動かなかったため)
    • https://www.mindwatering.com/SupportRef.nsf/webpg/6CDCAD1B69566F018525888D005DBF39