HAProxy 2.0 (-dev7) の prometheus サポート拡張機能を利用してマルチスレッドの統計情報を exporter なしで正しく取得する

f:id:kyagi:20190616100100p:plain

HAProxy 1.7 から 2.0 へ移行

前回 試した通り、HAProxy 1.7 + haproxy-exporter の組み合わせではマルチプロセス時に統計情報が正しく取得できない。代替案として prometheus サポートが提供される HAProxy 2.0 (dev7) を試してみた結果、こちらでうまくいきそうなので置き換えることにした。2.0 は 2019 年夏リリースの予定の LTS(Long Term Support) 版となっており、この記事を書いている時点でも開発は終盤に差し掛かっているようだ。

バージョン 並行処理 統計情報 prometheus対応 その他
1.7 マルチプロセス それぞれのプロセスで統計情報を持つ 別途 exporter が必要 マルチプロセス時、特定のプロセスに統計情報を固定する手段はない。haproxy-exporter は counter を gauge として扱ってしまう
2.0 マルチスレッド それぞれのスレッドの統計情報は統合 内部機能で prometheus サポートを提供 追加コンポーネントとして EXTRA_OBJS に prometheus.o を指定して独自ビルドする必要がある

www.haproxy.com

kubernetes 環境で 1.7 を動かしていた場合 2.0 に移行する場合の変更点

  • 1.7 から 2.0 へのアップグレード
    • haproxy 1.7 から 2.0-dev7(2019/06/11 release) にアップグレードした。
    • 起動オプションとして -Ds (Start in systemd daemon mode, keeping a process in foreground.) がなくなっていたので、YAML から削除した。また global parameter の daemon を削除して foreground で起動させるようにした。
  • prometheus サポートに伴う変更
  • マルチスレッドモデルへの切り替え
    • マルチプロセスからマルチスレッドになるため nbthread=4 を追加した。

haproxy1.7.yaml (-Ds オプションを使用して foreground で起動)

        command:
          - /usr/local/sbin/haproxy           
          - -f
          - /conf/haproxy.cfg
          - -f
          - /conf/frontend.cfg
          - -f
          - /conf/backend.cfg
          - -f
          - -Ds   

haproxy2.0.yaml (-Ds オプションはすでに廃止されていたため、グローバルパラメータの daemon を外して foreground で起動。stats が frontend の設定として独立)

        command:
          - /usr/local/sbin/haproxy           
          - -f
          - /conf/haproxy.cfg
          - -f
          - /conf/frontend.cfg
          - -f
          - /conf/backend.cfg
          - -f
          - /conf/stats.cfg

-Ds オプションについては man ページから削除してもらう PR を出したところ 1 時間も経たずにマージされた。(^_^)/

github.com

$ rg -H -- '-D' {haproxy-1.7.0,haproxy-2.0-dev7}/src/haproxy.c
haproxy-2.0-dev7/src/haproxy.c
493:        "        -D goes daemon ; -C changes to <dir> before loading files.\n"

haproxy-1.7.0/src/haproxy.c
460:        "        -D goes daemon ; -C changes to <dir> before loading files.\n"
823:                if (flag[1] == 's')  /* -Ds */
2038:                /* it's OK because "-Ds -f x" is the shortest form going here */