これは、なにをしたくて書いたもの?
HAProxyに、実行中の情報をコマンドラインやWeb UIで見たり、また操作したりできるみたいなので、ちょっと試してみようかと。
環境
今回利用したHAProxyは、こちら。
$ haproxy -v HA-Proxy version 1.8.8-1ubuntu0.4 2019/01/24 Copyright 2000-2018 Willy Tarreau <willy@haproxy.org>
バックエンドのサーバーには、nginxを3つ用意しました。
それぞれ、IPアドレスは以下とします。
- HAProxy … 172.17.0.2
- nginx … 172.17.0.3〜5
HAProxyのベースの設定は、以下から始めます。
/etc/haproxy/haproxy.cfg
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend http
bind *:80
default_backend servers
backend servers
balance roundrobin
mode http
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server server1 172.17.0.3:80
server server2 172.17.0.4:80
server server3 172.17.0.5:80
コマンドラインから見る
HAProxyの操作を、ソケットファイルやTCPソケットで行うことができます。
ドキュメントは、こちら。
ドキュメントにも記載がありますが、この機能を利用するためにはglobalセクションにソケットの定義をする必要があります。
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats socket ipv4@localhost:9999 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
この部分ですね。
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats socket ipv4@localhost:9999 level admin
stats timeout 30s
ソケットファイルのみでいい場合は、こんな感じに。
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
こちらは、TCPソケットを使う場合です。ローカルアドレスにのみバインドしてあります。
stats socket ipv4@localhost:9999 level admin
設定したら、HAProxyを再起動します。
使い方ですが、ソケットファイルを使う場合はsocatコマンドと組み合わせます。
例えば、以下のように入力すると
$ sudo socat stdin /var/run/haproxy/admin.sock
待ち状態になるので「show info」と入力してみます。
show info
すると、現在の情報が表示されます。
Name: HAProxy Version: 1.8.8-1ubuntu0.4 Release_date: 2019/01/24 Nbthread: 1 Nbproc: 1 Process_num: 1 Pid: 358 Uptime: 0d 0h21m05s Uptime_sec: 1265 Memmax_MB: 0 PoolAlloc_MB: 0 PoolUsed_MB: 0 PoolFailed: 0 Ulimit-n: 4041 Maxsock: 4041 Maxconn: 2000 Hard_maxconn: 2000 CurrConns: 0 CumConns: 37 CumReq: 37 MaxSslConns: 0 CurrSslConns: 0 CumSslConns: 0 Maxpipes: 0 PipesUsed: 0 PipesFree: 0 ConnRate: 0 ConnRateLimit: 0 MaxConnRate: 0 SessRate: 0 SessRateLimit: 0 MaxSessRate: 0 SslRate: 0 SslRateLimit: 0 MaxSslRate: 0 SslFrontendKeyRate: 0 SslFrontendMaxKeyRate: 0 SslFrontendSessionReuse_pct: 0 SslBackendKeyRate: 0 SslBackendMaxKeyRate: 0 SslCacheLookups: 0 SslCacheMisses: 0 CompressBpsIn: 0 CompressBpsOut: 0 CompressBpsRateLim: 0 ZlibMemUsage: 0 MaxZlibMemUsage: 0 Tasks: 5 Run_queue: 0 Idle_pct: 100 node: 6ebd8af752eb
ドキュメントによると、以下のようにしてもOKみたいです。が、手元の環境では、どうもうまく動かず…。
$ echo 'show info' | sudo socat stdin /var/run/haproxy/admin.sock
また、「stdin」の部分を「readline」にすると、対話モードで実行することができます。
「prompt」コマンドを実行しても、対話モードに入ることができます。
$ sudo socat stdin /var/run/haproxy/admin.sock prompt >
TCPソケットをリッスンしている場合は、ncコマンドで行うとよいでしょう。
$ echo 'show info' | nc localhost 9999 Name: HAProxy Version: 1.8.8-1ubuntu0.4 Release_date: 2019/01/24 Nbthread: 1 Nbproc: 1 Process_num: 1 Pid: 358 Uptime: 0d 0h23m09s Uptime_sec: 1389 Memmax_MB: 0 PoolAlloc_MB: 0 PoolUsed_MB: 0 PoolFailed: 0 Ulimit-n: 4041 Maxsock: 4041 Maxconn: 2000 Hard_maxconn: 2000 CurrConns: 0 CumConns: 38 CumReq: 38 MaxSslConns: 0 CurrSslConns: 0 CumSslConns: 0 Maxpipes: 0 PipesUsed: 0 PipesFree: 0 ConnRate: 0 ConnRateLimit: 0 MaxConnRate: 0 SessRate: 0 SessRateLimit: 0 MaxSessRate: 0 SslRate: 0 SslRateLimit: 0 MaxSslRate: 0 SslFrontendKeyRate: 0 SslFrontendMaxKeyRate: 0 SslFrontendSessionReuse_pct: 0 SslBackendKeyRate: 0 SslBackendMaxKeyRate: 0 SslCacheLookups: 0 SslCacheMisses: 0 CompressBpsIn: 0 CompressBpsOut: 0 CompressBpsRateLim: 0 ZlibMemUsage: 0 MaxZlibMemUsage: 0 Tasks: 5 Run_queue: 1 Idle_pct: 100 node: 6ebd8af752eb
ここからは、ncコマンドを使って確認してみます。
まず、どんなコマンドがあるか見てみましょう。
※「help」って入力しても、認識してないんですけど…
$ echo 'help' | nc localhost 9999
Unknown command. Please enter one of the following commands only :
help : this message
prompt : toggle interactive mode with prompt
quit : disconnect
show tls-keys [id|*]: show tls keys references or dump tls ticket keys when id specified
set ssl tls-key [id|keyfile] <tlskey>: set the next TLS key for the <id> or <keyfile> listener to <tlskey>
show errors : report last request and response errors for each proxy
disable agent : disable agent checks (use 'set server' instead)
disable health : disable health checks (use 'set server' instead)
disable server : disable a server for maintenance (use 'set server' instead)
enable agent : enable agent checks (use 'set server' instead)
enable health : enable health checks (use 'set server' instead)
enable server : enable a disabled server (use 'set server' instead)
set maxconn server : change a server's maxconn setting
set server : change a server's state, weight or address
get weight : report a server's current weight
set weight : change a server's weight (deprecated)
show sess [id] : report the list of current sessions or dump this session
shutdown session : kill a specific session
shutdown sessions server : kill sessions on a server
clear table : remove an entry from a table
set table [id] : update or create a table entry's data
show table [id]: report table usage stats or dump this table's contents
clear counters : clear max statistics counters (add 'all' for all counters)
show info : report information about the running process
show stat : report counters for each proxy and server
show schema json : report schema used for stats
show startup-logs : report logs emitted during HAProxy startup
show resolvers [id]: dumps counters from all resolvers section and
associated name servers
set maxconn global : change the per-process maxconn setting
set rate-limit : change a rate limiting value
set severity-output [none|number|string] : set presence of severity level in feedback information
set timeout : change a timeout setting
show env [var] : dump environment variables known to the process
show cli sockets : dump list of cli sockets
show fd [num] : dump list of file descriptors in use
show activity : show per-thread activity stats (for support/developers)
disable frontend : temporarily disable specific frontend
enable frontend : re-enable specific frontend
set maxconn frontend : change a frontend's maxconn setting
show servers state [id]: dump volatile server information (for backend <id>)
show backend : list backends in the current running config
shutdown frontend : stop a specific frontend
set dynamic-cookie-key backend : change a backend secret key for dynamic cookies
enable dynamic-cookie backend : enable dynamic cookies on a specific backend
disable dynamic-cookie backend : disable dynamic cookies on a specific backend
show cache : show cache status
add acl : add acl entry
clear acl <id> : clear the content of this acl
del acl : delete acl entry
get acl : report the patterns matching a sample for an ACL
show acl [id] : report available acls or dump an acl's contents
add map : add map entry
clear map <id> : clear the content of this map
del map : delete map entry
get map : report the keys and values matching a sample for a map
set map : modify map entry
show map [id] : report available maps or dump a map's contents
show pools : report information about the memory pools usage
コマンド自体の説明は、ドキュメントに書かれています。
サーバーの統計情報を見てみます。
$ echo 'show stat' | nc localhost 9999 # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime,agent_status,agent_code,agent_duration,check_desc,agent_desc,check_rise,check_fall,check_health,agent_rise,agent_fall,agent_health,addr,cookie,mode,algo,conn_rate,conn_rate_max,conn_tot,intercepted,dcon,dses, http,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,2,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,,0,0,0,0,,,,,,,,,,,,,,,,,,,,,http,,0,0,0,0,0,0, servers,server1,0,0,0,0,,0,0,0,,0,,0,0,0,0,no check,1,1,0,,,1817,,,1,3,1,,0,,2,0,,0,,,,0,0,0,0,0,0,,,,,0,0,,,,,-1,,,0,0,0,0,,,,,,,,,,,,172.17.0.3:80,,http,,,,,,,, servers,server2,0,0,0,0,,0,0,0,,0,,0,0,0,0,no check,1,1,0,,,1817,,,1,3,2,,0,,2,0,,0,,,,0,0,0,0,0,0,,,,,0,0,,,,,-1,,,0,0,0,0,,,,,,,,,,,,172.17.0.4:80,,http,,,,,,,, servers,server3,0,0,0,0,,0,0,0,,0,,0,0,0,0,no check,1,1,0,,,1817,,,1,3,3,,0,,2,0,,0,,,,0,0,0,0,0,0,,,,,0,0,,,,,-1,,,0,0,0,0,,,,,,,,,,,,172.17.0.5:80,,http,,,,,,,, servers,BACKEND,0,0,0,0,200,0,0,0,0,0,,0,0,0,0,UP,3,3,0,,0,1817,0,,1,3,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,0,0,0,0,0,0,0,-1,,,0,0,0,0,,,,,,,,,,,,,,http,roundrobin,,,,,,,
frontend、backendの情報が見れます。ちょっとわかりにくいですが、バックエンドに3つのサーバーがいることもわかります。
「typed」や「json」を指定することで、フォーマットが変わります。
$ echo 'show stat typed' | nc localhost 9999
F.2.0.0.pxname.1:KNS:str:http
F.2.0.1.svname.1:KNS:str:FRONTEND
F.2.0.4.scur.1:MGP:u32:0
F.2.0.5.smax.1:MMP:u32:0
F.2.0.6.slim.1:CLP:u32:2000
F.2.0.7.stot.1:MCP:u64:0
F.2.0.8.bin.1:MCP:u64:0
F.2.0.9.bout.1:MCP:u64:0
F.2.0.10.dreq.1:MCP:u64:0
F.2.0.11.dresp.1:MCP:u64:0
〜省略〜
$ echo 'show stat json' | nc localhost 9999
[[{"objType":"Frontend","proxyId":2,"id":0,"field":{"pos":0,"name":"pxname"},"processNum":1,"tags":{"origin":"Key","nature":"Name","scope":"Service"},"value":{"type":"str","value":"http"}},{"objType":"Frontend","proxyId":2,"id":0,"field":{"pos":1,"name":"svname"},"processNum":1,"tags":{"origin":"Key","nature":"Name","scope":"Service"},"value":{"type":"str","value":"FRONTEND"}},{"objType":"Frontend","proxyId":2,"id":0,"field":{"pos":4,"name":"scur"},"processNum":1,"tags":{"origin":"Metric","nature":"Gauge","scope":"Process"},"value":{"type":"u32","value":0}},{"objType":"Frontend","proxyId":2,"id":0,"field":{"pos":5,"name":"smax"},"processNum":1,"tags":{"origin":"Metric","nature":"Max","scope":"Process"},"value":{"type":"u32","value":0}},{"objType":"Frontend","proxyId":2,"id":0,"field":{"pos":6,"name":"slim"},"processNum":1,"tags":{"origin":"Config","nature":"Limit","scope":"Process"},"value":{"type":"u32","value":2000}},
〜省略〜
また、値を変更することもできます。
例えば、maxconnは現在デフォルトの2000で起動していますが
$ echo 'show info' | nc localhost 9999 | grep -i maxconn Maxconn: 2000 Hard_maxconn: 2000 MaxConnRate: 0
これを、100に変更してみましょう。
$ echo 'set maxconn global 100' | nc localhost 9999
maxconnは、frontend、backend、server、globalと複数の箇所で設定できますが、今回はglobalで変更してみます。
確認。
$ echo 'show info' | nc localhost 9999 | grep -i maxconn Maxconn: 100 Hard_maxconn: 2000 MaxConnRate: 0
maxconnが変更されていますね。
Web UIから統計情報を見る
ここまでコマンドラインでアクセスしてきましたが、ちょっと見づらい感じもします。
Web UIで統計情報を見ることもできるようなので、そちらを試してみましょう。
frontendセクションを追加して、statsを有効にします。
frontend stats
bind *:8404
stats enable
stats uri /stats
stats refresh 10s
stats admin if { src 192.168.0.2 }
まずは、「stats enable」。それから、8404ポートで、パス「/stats」で見られるようにしています。
また、10秒ごとにリフレッシュして、アクセス元は絞る感じで。
HAProxy越しに、nginxに何度かアクセスしてみます。
$ curl 172.17.0.2
この状態で、「http://172.17.0.2:8404/stats」にアクセス。

だいぶわかりやすく、統計情報を見ることができます。
また、ドキュメントに記載のある通り、backendにも設定することができます。
例えば、こんな感じで。
frontend http
bind *:80
default_backend servers
backend servers
balance roundrobin
mode http
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
server server1 172.17.0.3:80
server server2 172.17.0.4:80
server server3 172.17.0.5:80
stats enable
stats uri /stats
stats refresh 10s
stats admin if { src 192.168.0.2 }
この場合、「http://172.17.0.2/stats」のように、バックエンドに対するパスが一部奪われる形でWeb UIが参照できます。

この設定方法だと、指定されたbackendに関する情報(とその前段のfrontendの情報)が表示されるようです。
こういう機能は、アクセスに関する制限をかけたりする必要があると思うので、そのあたりに関する設定は考慮しておきましょう、と。
まとめ
HAProxyの実行時の情報をコマンドラインやWeb UIから見たり、コマンドラインからは操作したりしてみました。
HAProxyの情報はややわかりにくいところもあるので、こうやって確認する方法は把握しておいた方がいいのかなぁと思います。
Web UIは、助かります…。
参考)