私たちは最近、Kops を使用して AWS 上で Kubernetes 1.9 をリリースしました。 昨日、新しいトラフィックを最大の Kubernetes クラスターにスムーズにロールアウトしているときに、アプリケーションによってログに記録された異常な DNS 名前解決エラーに気づき始めました。
これについては GitHub にたくさんあります kube-dns
и dnsmasq
。 私にとって最も興味深く、新しいことは、DNS リクエストのトラフィックが大幅に増加したまさにその理由でした。 私の投稿はこれとそれについて何をすべきかについてです。
コンテナ内の DNS 解決は、他の Linux システムと同様に、構成ファイルによって決まります。 /etc/resolv.conf
。 デフォルトのKubernetes dnsPolicy
それ ClusterFirst
これは、DNS リクエストがすべて に転送されることを意味します。 dnsmasq
、ポッド内で実行 kube-dns
クラスター内でリクエストがアプリケーションに転送されます。 kube-dns
、名前がクラスターサフィックスで終わる場合、それ以外の場合は上位レベルの DNS サーバーに送信されます。
ファイル /etc/resolv.conf
各コンテナ内のデフォルトは次のようになります。
nameserver 100.64.0.10
search namespace.svc.cluster.local svc.cluster.local cluster.local
eu-west-1.compute.internal
options ndots:5
ご覧のとおり、次の XNUMX つのディレクティブがあります。
- ネームサーバーはサービスのIPです
kube-dns
- 4 つのローカル検索ドメインが指定されています
search
- オプションがあります
ndots:5
この構成の興味深い点は、ローカル検索のドメインと設定がどのように行われるかです。 ndots:5
一緒に仲良くしましょう。 これを理解するには、非修飾名の DNS 解決がどのように機能するかを理解する必要があります。
フルネームとは何ですか?
完全修飾名は、ローカル検索が実行されない名前であり、名前解決中にその名前は絶対とみなされます。 慣例により、DNS ソフトウェアは名前がドット (.) で終わる場合は完全修飾され、それ以外の場合は完全修飾されないとみなします。 あれは google.com.
完全に定義されており、 google.com
- いいえ。
修飾されていない名前はどのように処理されますか?
アプリケーションが名前で指定されたリモート ホストに接続するとき、DNS 名前解決は通常、システム コールを使用して行われます。 getaddrinfo()
。 しかし、名前が修飾されていない (. で終わっていない) 場合、システム コールは最初に名前を絶対名として解決しようとするのか、それとも最初にローカル検索ドメインを通過しようとするのか疑問に思います。 オプションによります ndots
.
マニュアルより resolv.conf
:
ndots:n
устанавливает порог для количества точек, которые должны появиться в имени, прежде чем будет сделан начальный абсолютный запрос. Значение по умолчанию для n равно 1, что означает, что если в имени есть какие-либо точки, имя будет сначала опробовано как абсолютное имя, прежде чем к нему будут добавлены какие-либо элементы списка поиска.
これは、次のことを意味します。 ndots
値が 5 で、名前に含まれるドットが 5 つ未満の場合、システム コールは、最初にすべてのローカル検索ドメインを走査して、順番に解決を試みます。失敗した場合は、最終的に絶対名として解決します。
なぜ同じ ndots:5
アプリケーションのパフォーマンスに悪影響を与える可能性はありますか?
ご想像のとおり、アプリケーションが大量の外部トラフィックを使用する場合、TCP 接続が確立されるたびに (より正確には、名前が解決されるたびに)、名前が正しく解決されるまでに 5 つの DNS クエリが発行されます。 4 ローカル検索ドメイン、最後に絶対名前解決リクエストを発行します。
次のグラフは、アプリケーションで構成されたいくつかのホスト名を完全修飾ホスト名に切り替える前と後の 3 つの kube-dns モジュールの合計トラフィックを示しています。
次の図は、アプリケーションで構成されているいくつかのホスト名を完全名に切り替える前後のアプリケーションの遅延を示しています (青い垂直線はデプロイメントです)。
解決策 #1 - 完全修飾名を使用する
多数の接続を作成する静的な外部名 (つまり、アプリケーション構成で定義されたもの) がほとんどない場合、おそらく最も簡単な解決策は、それらを追加するだけで完全修飾名に切り替えることです。 最後に。
これは最終的な解決策ではありませんが、きれいにではないにせよ、状況を迅速に改善するのに役立ちます。 この問題を解決するためにこのパッチを適用しました。その結果は上のスクリーンショットに示されています。
解決策 #2 - カスタマイズ ndots
в dnsConfig
Kubernetes 1.9 では、アルファ モード (ベータ バージョン v1.10) で機能が登場しました。これにより、ポッド プロパティを通じて DNS パラメーターをより適切に制御できるようになります。 dnsConfig
。 特に、値を設定できます。 ndots
特定のポッドの場合、つまり
apiVersion: v1
kind: Pod
metadata:
namespace: default
name: dns-example
spec:
containers:
- name: test
image: nginx
dnsConfig:
options:
- name: ndots
value: "1"
ソース
私たちのブログの他の記事もお読みください。
Golang の Context パッケージを理解する Docker イメージを縮小するための XNUMX つの簡単なトリック Kubernetes のステートフル バックアップ 多数の異種 Web プロジェクトのバックアップ Redmineのテレグラムボット。 自分自身と他人の生活を簡素化する方法
出所: habr.com