Amazon DNSはレートリミットを超えるとNXDOMAINを返すこともある
ども、大瀧です。
Amazon VPCには、同ネットワーク内から名前解決のためのDNSキャッシュサーバー(Amazon DNS)が提供されます。AWSのドキュメントに以下の記述を見つけたので、レートリミットに引っかかるときにどのような挙動になるのか検証してみたのが本ブログです。結果としては、タイトルの通りNXDOMAIN(該当レコードなし)とタイムアウトが観測されました。
DNS の制限 各 Amazon EC2 インスタンスは Amazon が提供する DNS サーバーへ送信できるパケット数をネットワークインターフェイスあたり最大 1024 パケット/秒に制限しています。この制限を増やすことはできません。Amazon が提供する DNS サーバーでサポートされる 1 秒あたりの DNS クエリの数は、クエリのタイプ、レスポンスのサイズ、および使用中のプロトコルにより異なります。スケーラブルな DNS アーキテクチャの詳細および推奨については、「Amazon VPC のハイブリッドクラウド DNS ソリューション」ホワイトペーパーを参照してください。
おことわり : 本検証は独自に行ったものであり、AWSの仕様を説明するものではありません。予告なく挙動が変わる可能性がある点をご注意ください。
検証環境
- OS : Amazon Linux 2 RC
- インスタンスタイプ : c5.9xlarge
同一ENIからのアクセスとするために、Dockerでコンテナを1000個実行しコンテナでdig
を無限ループさせる作戦でやってみました。
- hostloop.bash : コンテナの中で実行するシェルスクリプト
- Dockerfile : Dockerイメージの作成で使用
- docker-run.bash : 作成したDockerイメージで1000個コンテナを実行するシェルスクリプト
1 2 3 4 5 6 | #!/bin/bash while [ 1 ] do host example.com done |
1 2 3 4 5 6 | FROM amazonlinux:2 RUN yum install -y bind-utils COPY hostloop. bash /hostloop . bash CMD bash /hostloop . bash |
1 2 3 4 5 | #!/bin/bash for i in {0..1000}; do sudo docker run -d hostloop:latest done |
それぞれのファイルを作成し、以下のコマンドで動かしてみます。
実行するとDNSサーバーへの問い合わせがまともに動かなくなる&キャッシュサーバーに多大な負荷をかけるので、検証用EC2を用意して試すことを強くお奨めします。PCやMacで実行すると、Dockerの後始末含め多分大変です。
$ sudo yum install -y docker $ sudo service docker start $ docker build -t hostloop . :(略) $ chmod +x docker-run. bash $ . /docker-run . bash 597735e291bf :(略) $ |
実行したコンテナのログを見てみると。。。。
$ sudo docker logs -f 597735e291bf example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 ;; connection timed out; trying next origin Host example.com not found: 3(NXDOMAIN) ;; connection timed out; trying next origin ;; connection timed out; no servers could be reached socket.c:1937: internal_send: 172.31.0.2 #53: Invalid argument socket.c:1937: internal_send: 172.31.0.2 #53: Invalid argument ;; connection timed out; trying next origin ;; connection timed out; no servers could be reached ;; connection timed out; trying next origin ;; connection timed out; no servers could be reached socket.c:1937: internal_send: 172.31.0.2 #53: Invalid argument socket.c:1937: internal_send: 172.31.0.2 #53: Invalid argument ;; connection timed out; trying next origin socket.c:1937: internal_send: 172.31.0.2 #53: Invalid argument ;; connection timed out; no servers could be reached example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 example.com has address 93.184.216.34 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 |
正常な結果が返ってくる中に、タイムアウトとNXDOMAIN(該当レコードなし)の結果が混じっていました。以下の結果はクライアント(Linux)の制約によるもののようなので、今回の制限とは直接の関連は無さそうです。
socket.c:1937: internal_send: 172.31.0.2#53: Invalid argument |
考察とまとめ
Amazon DNSがレートリミットを超えるときの挙動を検証してみました。一般的なDNSクライアントはタイムアウトに対して再問い合わせをする機能があると思いますが、「該当レコードなし」では再問い合わせにはならずネットワークエラーとしてアプリケーション例外に繋がることが多いと思うので注意が必要です。とはいえ、まずはENIあたり秒間1024パケットのラインを越えないように設計するのが最も効果的な対策になるでしょう。
ちなみに、今回検証することになったきっかけは、Amazon ECS環境で同様のエラーになるという相談が社内からあったためです。最近ECSにはコンテナごとにENIを割り当てる構成がサポートされたので、そちらを利用することで回避できるのではと考えます。