Ubuntu Weekly Recipe

第924回Speedtest Trackerで回線速度を自動測定し⁠ネットの遅い時間帯を調べる

インターネット回線の速度が遅いと感じた時、まず試してみるもののひとつがSpeedtestでしょう。Webブラウザーから簡単に回線速度を測定できるため、⁠なんとなく遅い」という感覚を、具体的な数値で確認できます。第768回でも、セルフホストできるSpeedtestサーバーを紹介しました。

図1 WebブラウザーからSpeedtestを実行するのはよくあること

しかし回線速度は常に一定とは限りません。昼間は十分な速度が出ているのに、夜になると遅くなるといったケースもあります。そこで今回は定期的にSpeedtestを実行し、その結果を記録、グラフ化できるSpeedtest TrackerをUbuntu Server上で動かしてみましょう。

Speedtest Trackerとは

Speedtest Trackerは、Ookla Speedtestを定期的に実行し、その結果を保存、可視化するためのWebアプリケーションです。LinuxServer.ioからDockerイメージが公開されているため、Dockerが利用できる環境であれば簡単に導入できます。

インターネット回線の速度を調べるだけであれば、手動でSpeedtestを1回実行するだけでも十分です。しかし回線速度は、時間帯や回線の混雑状況、接続先となるSpeedtestサーバーなどによって変化します。そのため回線品質の傾向を知りたい場合には、同じ条件で継続的に測定することが重要になります。たとえば1時間ごとにSpeedtestを実行しておけば、⁠毎日21時ごろになるとダウンロード速度が低下する」⁠平日と休日で傾向が違う」といったことも確認できます。回線のトラブルをISPに問い合わせるような場合にも、継続的な測定結果があれば状況を説明しやすくなるでしょう。

一般的にSpeedtestは、接続先となるテストサーバーを選択したあと、レイテンシー、ダウンロード速度、アップロード速度を計測します。Speedtest Trackerは簡単に言えば、この処理をOoklaのSpeedtest CLIを利用して自動的に実行し、その結果をデータベースへ保存するものです。さらに計測結果としきい値とを比較し、下回った際に通知を送るといった処理も可能です。概要はドキュメントを参照してください。

Speedtest Trackerのインストール

今回はDocker Composeを使ってSpeedtest Trackerをインストールします。あらかじめ以下のコマンドで、Docker EngineとDocker Composeプラグインをインストールしておいてください。

$ sudo apt install -U -y docker.io docker-compose-v2

Speedtest TrackerのComposeスタック用ディレクトリを作成します。

$ mkdir -p ~/speedtest-tracker
$ cd ~/speedtest-tracker

Speedtest Trackerでは、データの暗号化に使用するAPP_KEYが必要です。これは次のコマンドで生成できます。

$ echo "base64:$(openssl rand -base64 32 2>/dev/null)"
base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

表示された「base64:」から始まる文字列がAPP_KEYです。⁠base64:」の部分も含めて控えておいてください。

続いて、次の内容でcompose.yamlを作成します。

services:
  speedtest-tracker:
    image: lscr.io/linuxserver/speedtest-tracker:latest
    restart: unless-stopped
    container_name: speedtest-tracker
    ports:
      - 8080:80
    environment:
      - PUID=1000
      - PGID=1000
      - APP_KEY=(控えたAPP_KEY)
      - APP_URL=http://サーバーのIPアドレス:8080
      - ADMIN_NAME=Adminユーザーの名前
      - ADMIN_EMAIL=Adminユーザーのメールアドレス
      - ADMIN_PASSWORD=Adminユーザーのパスワード
      - DB_CONNECTION=sqlite
      - TZ=Asia/Tokyo
      - DISPLAY_TIMEZONE=Asia/Tokyo
    volumes:
      - ./config:/config
    healthcheck:
      test: curl -fSs http://localhost/api/healthcheck | jq -r .message || exit 1
      interval: 10s
      retries: 3
      start_period: 30s
      timeout: 10s

Speedtest Trackerのコンテナイメージでは、コンテナの80番ポートでWeb UIが動作します。ここではPortsを指定し、ホストの8080番ポートでコンテナへアクセスできるようにしています。

APP_URLには、WebブラウザーからSpeedtest Trackerへアクセスする際のURLを指定します。たとえばSpeedtest Trackerを動かすUbuntu ServerのIPアドレスが192.168.1.10で、割り当てたポートが8080であれば、次のように指定します。この値は通知メールなどに含まれるリンクの生成にも使用されます。

- APP_URL=http://192.168.1.10:8080

DB_CONNECTIONには使用するデータベースを指定します。Speedtest TrackerはSQLite、PostgreSQL、MySQLに対応していますが、個人で利用する程度であればSQLiteがもっとも手軽でしょう。

DISPLAY_TIMEZONEは、Web UIに表示する時刻のタイムゾーンです。日本で利用する場合はAsia/Tokyoを指定しておくとよいでしょう。またTZはコンテナ自体のタイムゾーンです。後述するように、スケジュールを指定して計測するのであれば、日本時間を指定しておくのが無難です。

PUIDとPGIDはSpeedtest Trackerではなく、LinuxServer.ioが提供するコンテナイメージで慣例的に使われる設定です。LinuxServer.ioのコンテナイメージ内には、⁠abc」というユーザーが用意されています。アプリケーションのプロセスは基本的にこのユーザーの権限で動作するため、アプリケーションが書き込むファイルは、当然このユーザーが所有者となります。abcユーザーのUIDとGIDは、ともに「911」となっています。そのためホストのディレクトリをコンテナ内にマウントしている場合、UID 911のユーザーが所有するファイルがホスト上に作られるわけです。

PUID/PGIDを指定すると、コンテナの初期化スクリプト内でabcユーザーのUID/GIDが、指定した値に変更されます。ホスト上のユーザーと同じUID/GIDを指定しておくことで、コンテナ内で作成されたファイルの所有者を、ホストと合わせられるというわけです。Ubuntuでインストール時に作成した一般ユーザーであれば、UIDとGIDはどちらも1000になっています。UID/GIDを確認したい場合は、以下のようにidコマンドを実行してください。表示されたuidをPUIDに、gidをPGIDに指定します。

$ id
uid=1000(mizuno) gid=1000(mizuno) groups=1000(mizuno),4(adm),24(cdrom),27(sudo),30(dip),105(lxd)

ADMIN_NAME、ADMIN_EMAIL、ADMIN_PASSWORDは、初回起動時に作成される管理者ユーザーの情報です。これらはコンテナをはじめて起動した時にのみ使用される値であり、その後のユーザー情報を継続的に上書きするものではありません。したがって初回起動が正常に完了したら、これらの値はcompose.yamlから削除しておきましょう。特にパスワード情報がYAML内に残るのは、セキュリティ上からも好ましくありません。

設定が完了したら、次のコマンドでSpeedtest Trackerを起動します。

$ sudo docker compose up -d

ログインとSpeedtestの実行

Webブラウザーで、APP_URLに指定したURLを開きます。すると以下の画面が表示されますので、⁠Sign In / Admin Panel」をクリックしてください。

図2 Speedtest Trackerの初期画面

ログイン画面が表示されますので、先ほど設定したADMIN_EMAILとADMIN_PASSWORDでログインしてください。なお初期管理者用の環境変数を指定しなかった場合は、メールアドレス「admin@example.com⁠⁠、パスワード「password」でログインできます。

図3 初期ユーザーでのログイン

ログインするとダッシュボードが表示されますが、まだSpeedtestを実行していないため、最初は何も表示されません。

図4 ログイン直後のダッシュボード

Speedtestはダッシュボードから手動で実行できます。右上にある「Speedtest」をクリックすると、対象のサーバーを選択するダイアログが表示されます。プルダウンからサーバーを選択した上で「Start」をクリックしてください。計測を開始すると一般的なSpeedtestと同様に、Ping、ダウンロード速度、アップロード速度などが計測され、その結果がSpeedtest Tracker上に保存されます。

図5 サーバーを選択して計測を開始する

一度でも計測を行った後は、ダッシュボードに結果が表示されます。

図6 手動で計測を1回行った後のダッシュボード。計測回数が1になり、最後の計測結果が表示されている

1回だけでは単なるSpeedtestとそれほど変わりませんが、測定結果が蓄積されると、ダウンロード速度やアップロード速度、Pingなどの推移をグラフで確認できるようになります。右上にある「Metrics」アイコンをクリックすると、過去の計測結果をグラフで表示できます。

Adminパネルでできること

画面右上のメニューからAdminパネルへ移動すると、Speedtest Trackerのさまざまな設定を変更できます。

既に解説しましたが、ダッシュボードでは直近の結果や、これまでに実行した計測回数や失敗回数を確認できます。

「Results」には過去に実行したSpeedtestの計測結果が一覧表示されます。行をクリックすることで個々の測定結果を確認できるほか、不要な結果の削除もできます。たとえば計測中に別のPCが大容量のトラフィックを発生させてしまい、明らかに通常とは異なる結果が記録されてしまった場合などは、グラフ化した際にノイズとなってしまいます。そうした結果はここから削除するとよいでしょう。

図7 過去の計測結果を一覧表示できる

「Users」ではSpeedtest Trackerへログインできるユーザーを管理できます。Speedtest Trackerではユーザーの権限が、管理者である「Admin」と、一般ユーザーである「User」に分かれています。管理者は他のユーザーのアカウント情報などを変更できます。ただし注意点があり、Speedtest Trackerでは、現在ログイン中のユーザー(自分自身)の情報を書き換えることができません。たとえば初回起動時にADMIN系環境変数を設定し忘れてしまい、デフォルトの管理者ユーザーが作られてしまったとしましょう。このユーザーの情報を変更したい場合は、新しく別の管理者ユーザーを作って行う必要があるのです。また管理者は削除できないため、ユーザーを削除する場合は一度Roleを一般ユーザーに変更する必要があります。

図8 ユーザーの管理画面

「API Tokens」では、Speedtest TrackerのAPIへアクセスするためのトークンを発行できます。トークンには結果の読み込み、計測の実行、サーバーの一覧表示といった権限を個別に割り当てることが可能で、ほかのプログラムから測定結果を取得したい場合などに利用できます。

図9 API Tokenの管理画面

例えば結果の表示権限のあるトークンを以下のように使うと、JSONで計測結果を受け取ることが可能です。

$ TOKEN='トークン文字列'
$ URL='http://サーバーのIPアドレス:8080'
$ curl -s \
    -H "Authorization: Bearer $TOKEN" \
    -H "Accept: application/json" \
    "$URL/api/v1/results/latest" | jq

「Data Integration」では、計測結果を外部のシステムへ連携します。たとえば結果をInfluxDBへ送り、Grafanaから可視化したり、Prometheus向けにエクスポートするなどです。すでにPrometheusとGrafanaを運用している環境なら、Speedtest Trackerのダッシュボードを使うよりも、Grafana上で監視するのが便利かもしれません。

「Notifications」では、通知の設定が行えます。通知先はDiscord、Slack、Gotifyなどが選べます。ただしSpeedtest Trackerでは現在、さまざまな通知サービスを統一的に扱えるAppriseとの統合が進められており、Slackなど従来の個別通知チャネルは非推奨とされています。将来的に削除される予定のため、注意してください。

図10 SlackのWebhookを設定し、計測時に通知を投げた例。ただし現在でも動くものの、非推奨となっている

もうひとつ便利なのが、測定値にしきい値を設定できることです。⁠Thresholds」ではダウンロード速度、アップロード速度、Ping値に対してしきい値を設定できます。そしてダウンロード/アップロード速度が設定値を下回った場合や、Ping値が設定値を上回った場合には、計測結果に異常として記録されます。また前述の通知と組み合わせれば、しきい値に抵触した場合のみ通知を送れます。つまり単に回線速度を記録するだけでなく、⁠普段と比べて明らかに状態が悪い時だけ通知する」という監視ツールとしても使えるわけです。

図11 しきい値の設定
図12 ダウンロード速度がしきい値の4Gbpsを下回ったため、Slackに通知が行われた

Speedtestを定期的に自動実行する

Speedtest Trackerの本領は定期的な自動実行と記録にあります。定期実行にはSPEEDTEST_SCHEDULE環境変数に、Cron形式でスケジュールを指定します。たとえば6時間ごとにSpeedtestを実行するなら、compose.yamlのenvironmentへ次の行を追加してください。

      - SPEEDTEST_SCHEDULE=0 */6 * * *

1時間ごとであれば次のようになります。

      - SPEEDTEST_SCHEDULE=0 * * * *

この際、追加で設定したいのがSPEEDTEST_SERVERSです。通常のSpeedtestでは、その時点で適切と判断されたSpeedtestサーバーが利用されます。しかし回線速度の変化を長期間比較するのであれば、接続先を固定したほうが条件を揃えやすくなります。この接続先を固定するには、環境変数SPEEDTEST_SERVERSにSpeedtestサーバーのIDを指定してください。もしも複数指定したい場合は、カンマで区切って列挙できます。複数のIDを指定した場合、Speedtest Trackerはその中から利用するサーバーを選択します。

近隣のSpeedtestサーバーは、LinuxServer.ioのコンテナイメージを利用して次のように確認できます。

$ sudo docker run -it --rm \
    --entrypoint /bin/bash \
    lscr.io/linuxserver/speedtest-tracker:latest \
    list-servers
図13 サーバーの一覧を取得する

使用するサーバーを決めたら、そのIDをcompose.yamlへ追記してください。これで毎回同じSpeedtestサーバーを使用して測定できます。

      - SPEEDTEST_SERVERS=50686

設定を変更したら、スタックを再起動します。

$ sudo docker compose up -d

今後は指定したスケジュールに従ってSpeedtestが自動実行され、その結果が蓄積されていきます。

図14 定期実行をスケジュールすると、メトリクスのページに次回の実行時間が表示されるようになる

下記は筆者宅の例です。下りはおおむね4Gbps前後出ていることや、夕方から深夜にかけては2Gbps程度まで速度が低下するといった傾向がわかります。またPingにばらつきがなく、パケットロスもないことから、回線自体は安定していることもうかがえます。このように継続して計測値を蓄積することで、本当に回線の速度が落ちているのかを定量的に確認できるわけです。

図15 1時間ごとに行った計測結果を、直近24時間ぶん表示した例

ただし、Speedtestそのものがそれなりの通信量を発生させる点には注意してください。高速なインターネット回線で数分おきに実行するような設定は、回線やSpeedtestサーバーに余計な負荷をかけます。回線品質の傾向を見るのが目的であれば、まずは1日に数回程度でも十分でしょう。

自宅のインターネットが「夜だけ遅い気がする」⁠最近不安定になった気がする」と感じた時、その感覚が本当に正しいのかを数字で確認することは大切です。もしDockerを常時稼働させているUbuntu Serverがあるなら、動かしておくと意外に役立つサービスのひとつかもしれません。

おすすめ記事

記事・ニュース一覧