HAProxy 1.6.5での動的名前解決における不具合と対処法
本日時点でのHAProxyの安定最新版である1.6.5で一つ不具合があったので、その解決方法をご紹介します。
3行まとめ
- HAProxy 1.6.5の動的DNS解決の仕組みの部分にバグ
- 1.6.5にパッチを当てるか
- 1.6.4を使うことで修正される
HAProxyとは
HAProxyは高機能なプロキシ・ロードバランサとして開発されているOSSです。HAProxyを利用することで、WEBアプリケーションやDBサーバの負荷分散に利用することが可能です。AWSにもロードバランササービスとしてELBがありますが、ELBはRDSインスタンスを登録できないなどの成約があります。一方でHAProxyではRDSやElastiCacheなど、AWSのマネージドサービスも登録することが可能です。
ただ、HAProxy 1.5以前ではHAProxyの起動時にのみDNSの名前解決が行われていました。ですが、AWSの各種マネージドサービスはフェイルオーバー等でFQDNの指すIPアドレスが変わる可能性があるため、HAProxyをAWSサービスと組み合わせて利用する際にはIPアドレスが変更するたびにreloadやHAProxyの再起動が必要でした。
2015/10にリリースされたHAProxy1.6で、動的DNS解決の機能が追加され、定期的にDNSの名前解決を行うことでIPアドレスの変更に追従することが可能になりました。ですがこの仕組が1.6.5では機能していないようです。
原因
DNS問い合わせのヘッダ定義に問題があり、DNSリクエストが全てDNSレスポンス形式として解釈されてしまっているようです。以下の画像はHAProxy1.6.5を稼働させているAmazon Linux上でtcpdumpしたものをWiresharkで可視化したものになります。
対応策
以下ページでやりとりがされています。
- Dynamic DNS resolution does not work for me after 1.6.4 to 1.6.5 upgrade - Help! - HAProxy community
途中のコメントにある通り、このパッチを適用するか、このバグの出ない1.6.4を使ってほしい、とのことです。1.6.5での修正分が必要ないようであれば1.6.4を利用したほうがよさそうです。
[ec2-user@ip-172-31-12-20 ~]$ cd haproxy-1.6.5/ [ec2-user@ip-172-31-12-20 haproxy-1.6.5]$ cat patch --- a/include/types/dns.h +++ b/include/types/dns.h @@ -63,16 +63,16 @@ /* DNS request or response header structure */ struct dns_header { unsigned short id:16; /* identifier */ - unsigned char qr :1; /* query/response 0: query, 1: response */ - unsigned char opcode :4; /* operation code */ - unsigned char aa :1; /* authoritative answer 0: no, 1: yes */ - unsigned char tc :1; /* truncation 0:no, 1: yes */ unsigned char rd :1; /* recursion desired 0: no, 1: yes */ - unsigned char ra :1; /* recursion available 0: no, 1: yes */ - unsigned char z :1; /* not used */ - unsigned char ad :1; /* authentic data */ - unsigned char cd :1; /* checking disabled */ + unsigned char tc :1; /* truncation 0:no, 1: yes */ + unsigned char aa :1; /* authoritative answer 0: no, 1: yes */ + unsigned char opcode :4; /* operation code */ + unsigned char qr :1; /* query/response 0: query, 1: response */ unsigned char rcode :4; /* response code */ + unsigned char cd :1; /* checking disabled */ + unsigned char ad :1; /* authentic data */ + unsigned char z :1; /* not used */ + unsigned char ra :1; /* recursion available 0: no, 1: yes */ unsigned short qdcount :16; /* question count */ unsigned short ancount :16; /* answer count */ unsigned short nscount :16; /* authority count */ [ec2-user@ip-172-31-12-20 haproxy-1.6.5]$ patch -u include/types/dns.h < patch [ec2-user@ip-172-31-12-20 haproxy-1.6.5]$ make [ec2-user@ip-172-31-12-20 haproxy-1.6.5]$ sudo make install
一応、1.6.5に上記パッチを当てたものを再インストールして試してみました。以下がtcpdumpの結果です。
正常にDNSリクエストとレスポンスが返ってきたのが確認できました:)
HAProxyを新規導入される際やバージョンアップの際にはこの不具合にご注意ください。