Hateburo: kazeburo hatenablog

SRE / 運用系小姑 / Goを書くPerl Monger

mkr plugin install 時の403 API rate limit exceededエラーを回避する方法

この記事はMackerel Advent Calendar 2021の14日目の記事です。

最近、さくらのクラウドの一部のサービスの監視にmackerelを導入し始めました! そして今年もいくつかのmackerel pluginを作成しています。

ログをメトリクスにするプラグイン

github.com

インターフェイスごとのエラーや送受信したパケットを可視化するプラグイン

github.com

100%上限のCPU使用率グラフ、ロードアベレージをコア数で割ったメトリックを作成するプラグイン

github.com

そのほか、mackerel-plugin-axslogにも新しい機能が増えています。

この記事は既存のサーバにこれらのmackerel pluginをansibleで導入していった際に出たエラーと回避策のお話です。

mkr plugin install時のrate limitエラー

次のようにAnsibleのplaybookを書き、mackerelプラグインのインストールを実行していたところ、

- name: install mkr plugins
  become: yes
  shell: "mkr plugin install --upgrade {{ item }}"
  with_items:
    - kazeburo/mackerel-plugin-linux-memory
    - kazeburo/mackerel-plugin-axslog
    - kazeburo/mackerel-plugin-linux-netdev
    - kazeburo/mackerel-plugin-linux-usage
    - kazeburo/mackerel-plugin-log-counter

GitHubAPIのrate limitに引っかかりました

failed: [192.168.0.1] (item=kazeburo/mackerel-plugin-axslog) => {"changed": true, "cmd": "mkr plugin install --upgrade kazeburo/mackerel-plugin-axslog", "delta": "0:00:00.071010", "end": "2021-11-01 17:12:53.402650", "item": 
"kazeburo/mackerel-plugin-axslog", "msg": "non-zero return code", "rc": 1, "start": "2021-11-01 17:12:53.331640", "stderr": "\u001b[0;31m     error\u001b[0m Failed to install plugin while making a download URL: GET 
https://api.github.com/repos/kazeburo/mackerel-plugin-maxcpu/releases/latest: 403 API rate limit exceeded for 203.0.113.147. (But here's the good news: Authenticated requests get a higher rate limit. Check out the
 documentation for more details.) [rate reset in 12m04s]", "stderr_lines": ["\u001b[0;31m     error\u001b[0m Failed to install plugin while making a download URL: GET https://api.github.com/repos/kazeburo/mackerel-plugin-maxcpu/releases/latest: 403 API 
rate limit exceeded for 203.0.113.147. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.) [rate reset in 12m04s]"], "stdout": "", "stdout_lines": []}

これはmkrがプラグインの’最新のバージョンを調べるために、GitHubAPIにアクセスしているところで発生します。

回避策はmackerelのマニュアルで紹介されています。

mackerel.io

1つはGitHubのアクセストークンを設定する方法

mkr plugin installはGithubから最新のリリースを探すためにGithub APIを利用します。そのため、Githubの設定画面から取得できるアクセストークンを指定しておかなければ、Github APIのRate Limitの制限にあたり、インストールが失敗する可能性があります。

もうひとつは明示的にバージョンを指定する方法です

mkr plugin installではGithub Releasesのリリースタグが明示的に指定された場合、GithubAPIにアクセスしないため、Rate Limitの制限にかかることはありません。そのため、サーバプロビジョニングツールから利用するときは、リリースタグを明示的に指定することをおすすめします。

今回、セットアップしている環境ではすぐに用意できるアクセストークンはなかったため、前者の方法は取りにくく、後者を行うことになります。

- name: install mkr plugins
  become: yes
  shell: "mkr plugin install --upgrade {{ item }}"
  with_items:
    - kazeburo/mackerel-plugin-linux-memory@v0.0.6
    - kazeburo/mackerel-plugin-axslog@v0.3.1

ただ、pluginを作成した直後はバージョンアップ回数が増えるため、都度バージョンをあげるのは面倒です。(今回は自前のプラグインのため最新バージョンでも問題がないことがわかっている前提がありますが、安定した運用のためにはバージョン固定がベストプラクティスです)

そこで、releaseTagを取得してキャッシュするサーバを書きました

releaseTag キャッシュサーバ

readmeもないですが作成しました。

github.com

実行すると次のレスポンスが得られます。

%  curl -sSf 127.0.0.1:8080/kazeburo/chocon|jq .
{
  "release": "v0.12.5",
  "has_error": false,
  "erorr": "",
  "assets": [
    {
      "name": "chocon_0.12.5_checksums.txt",
      "download_url": "https://github.com/kazeburo/chocon/releases/download/v0.12.5/chocon_0.12.5_checksums.txt"
    },
    {
      "name": "chocon_darwin_amd64.zip",
      "download_url": "https://github.com/kazeburo/chocon/releases/download/v0.12.5/chocon_darwin_amd64.zip"
    },
    {
      "name": "chocon_linux_amd64.zip",
      "download_url": "https://github.com/kazeburo/chocon/releases/download/v0.12.5/chocon_linux_amd64.zip"
    },
    {
      "name": "chocon_linux_arm.zip",
      "download_url": "https://github.com/kazeburo/chocon/releases/download/v0.12.5/chocon_linux_arm.zip"
    },
    {
      "name": "chocon_linux_arm64.zip",
      "download_url": "https://github.com/kazeburo/chocon/releases/download/v0.12.5/chocon_linux_arm64.zip"
    }
  ]
}

結果は5分キャッシュされるように作り、mkrのソースコードを参考にGITHUB_TOKENの環境変数がセットされていれば使うようにしています。

サーバは趣味全開で作り、フレームワークgithub.com/gofiber/fiber、キャッシュの有効活用のために golang.org/x/sync/singleflight を使ってます。

gofiber.io

pkg.go.dev

これをさくらのクラウドの Hacobune にデプロイし、Ansibleのplaybookを

- name: install latest mkr plugins
  become: yes
  shell: "mkr plugin install --upgrade {{ item }}@$(curl -fs 'https://example.com/{{ item }}?plain')"
  with_items:
    - kazeburo/mackerel-plugin-linux-memory
    - kazeburo/mackerel-plugin-linux-netdev
    - kazeburo/mackerel-plugin-linux-usage
    - kazeburo/mackerel-plugin-log-counter
    - kazeburo/mackerel-plugin-maxcpu

のようにしました。

これでRate Limitエラーは避けられ、常に新しいバージョンをいれることができました。

まとめ

今後も必要なpluginを揃え、メトリクスを充実させながら、mackerelを使ってクラウドの安定運用やっていきます。