このトピックでは、Container Service for Kubernetes (ACK) クラスターにおけるDNS解決ワークフロー、クライアント側の動作、およびサーバー側キャッシュポリシーについて説明します。
DNS解決アーキテクチャ
ACKにおけるDNS解決の動作は、アプリケーションが実行される場所と、NodeLocal DNSCacheアドオンがアクティブであるかどうかによって異なります。
図で参照されているtimeoutやattemptsなどのパラメーターの詳細については、解決ポリシーおよびキャッシュポリシーをご参照ください。
シナリオ1: ホストベースのアプリケーション (非コンテナ化)
Elastic Compute Service (ECS) インスタンス上で直接実行されるアプリケーションは、ホストの /etc/resolv.conf を使用します。これは VPC DNS サーバを指しています。

シナリオ2: 標準コンテナ化Pod (`dnsPolicy: ClusterFirst`)
デフォルトでは、Pod は ClusterFirst ポリシーを使用します。すべての DNS クエリは、クラスター内の CoreDNS サービスに送信されます。

シナリオ3: NodeLocal DNSCacheが有効なPod
NodeLocal DNSCacheがアクティブな場合、Podは同じノード上のローカルキャッシュエージェントにクエリを送信します。これにより、次の2つの利点が得られます。
レイテンシーの削減: DNSクエリはローカルで解決され、CoreDNSへのネットワークホップをスキップします。
Conntrackテーブル保護: クエリは新しいConntrackテーブルエントリを作成せずにローカルエージェントに送信されるため、Conntrack競合が減少し、UDP DNSエントリによるConntrackテーブルの枯渇を防ぎます。

解決ポリシー
クライアント側
以下のパラメーターは、/etc/resolv.conf から取得され、glibc リゾルバーによって解釈されます。以下は、ClusterFirst を使用する標準 Pod の代表的な構成です。
nameserver 10.x.x.x # CoreDNS ClusterIP
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5 timeout:5 attempts:2次の表に、すべてのデプロイメント環境におけるデフォルト値を示します。
パラメーター | 説明 | glibcのデフォルト値 | ECS | `DNSPolicy` が `ClusterFirst` に設定されたPod | `DNSPolicy` が `Default` に設定されたPod | NodeLocal DNSCacheを使用するPod | `DNSPolicy` が `Default` に設定され、ホストネットワークを使用するPod |
| ドメイン名の解決に使用されるDNSサーバー。 | なし | VPC DNSサーバー② | CoreDNS ClusterIP③ | VPC DNSサーバー |
| VPC DNSサーバー |
| リクエストに完全修飾ドメイン名 (FQDN) ではないドメイン名が含まれている場合、リクエストを送信する前に、そのドメイン名に | なし | なし |
| なし |
| なし |
| ドメイン名文字列内のドットの数が `ndots` 値よりも大きい場合、ドメイン名はFQDNとして扱われ、直接解決されます。それ以外の場合、クエリの前にドメイン名に検索サフィックスが付加されます。 | 1 | 1 | 5 | 1 | 3 | 1 |
| 単一のDNS解決リクエストのタイムアウト。単位: 秒。 | 5 | 2 | 5 | 5 | 1 | 2 |
| DNS解決が失敗した場合の最大再試行回数。 | 2 | 3 | 2 | 2 | 2 | 3 |
| DNSサーバーをラウンドロビン方式でクエリします。 | 無効 | 有効 | 無効 | 無効 | 無効 | 有効 |
| 有効で、同じソケットを使用して2つのリクエストが送信される場合、リゾルバは最初のリクエスト後にソケットを閉じ、2番目のリクエストの前に新しいソケットを開きます。 | 無効 | 有効 | 無効 | 無効 | 無効 | 有効 |
^①^ attempts パラメーターは、特定のシナリオでのみ有効になります:サーバーが SERVFAIL、NOTIMP、または REFUSED を返す場合、またはサーバーが NOERROR を返すが解決結果がない場合です。詳細については、「attempts パラメーターのリクエスト詳細」をご参照ください。
^②^ VPC DNS サーバは、ECS インスタンスに設定されているデフォルトの DNS サーバです。その IP アドレスは 100.100.2.136 と 100.100.2.138 です。PrivateZone 内のドメイン名と権限のあるドメイン名を解決します。
^③^ CoreDNS ClusterIP は、kube-system 名前空間にある kube-dns サービスの IP アドレスです。これは、内部サービスドメイン名を解決し、PrivateZone および権限のあるドメイン名の解決リクエストを転送します。
^④^ NodeLocal DNSCache の IP アドレスは 169.254.20.10 です。NodeLocal DNSCache アドオンがデプロイされると、各ノードでこの IP アドレスをリッスンします。
追加の /etc/resolv.conf オプションについては、「resolv.conf」をご参照ください。非標準リゾルバ
上記のglibcのデフォルトは、コンテナがglibcを使用している場合にのみ適用されます。一般的な例外は次の2つです。
Alpine (musl libc): Alpine に組み込まれている
muslライブラリは glibc を置き換え、いくつかの点で動作が異なります。musl の解決動作の詳細については、「musl libc」をご参照ください。/etc/resolv.conf内のsingle-requestおよびsingle-request-reopenオプションは無視されます。Alpine 3.3 以前では、
searchパラメーターおよび検索ドメインがサポートされておらず、これによりサービス検出が機能しなくなります。複数のDNSサーバーへの同時リクエストにより、NodeLocal DNSCacheの最適化が無効になります。
同じソケットを使用してAレコードとAAAAレコードを同時にリクエストすると、古いカーネルバージョンでConntrack競合がトリガーされ、断続的なパケット損失が発生します。
組み込みリゾルバーを持つ言語(Go、Node.js):これらのランタイムは、
/etc/resolv.confを完全にバイパスすることが多く、システムリゾルバーとは異なる解決動作を示します。
クラスター内DNSサーバー
デフォルトでは、CoreDNS は ECS の /etc/resolv.conf から上流サーバーを読み取り、組み込みの forward プラグインを使用して DNS リクエストを転送します。NodeLocal DNSCache は組み込みの CoreDNS インスタンスを実行し、同じ転送構成を使用します。
次の表に、forward プラグインの解決ポリシーを制御するパラメーターを示します。完全なリファレンスについては、「Forward」をご参照ください。
パラメーター | 説明 | CoreDNSのデフォルト値 | NodeLocal DNSCacheのデフォルト値 |
| 可能な場合、アップストリームサーバーとの通信にUDPを使用します。 | 有効 | 無効 |
| すべてのアップストリーム通信にTCPを強制します。 | 無効 | 有効 |
| アップストリームサーバーが異常とマークされるまでの連続したヘルスチェック失敗回数。 | 2 | 2 |
| アップストリームサーバーへの接続を維持する期間。 | 10秒 | 10秒 |
| アップストリームサーバーを選択するためのポリシー。 |
|
|
| ヘルスチェック間隔。 | 0.5秒 | 0.5秒 |
| 同時アップストリーム接続の最大数。 | なし | なし |
| アップストリームサーバーへの接続タイムアウト。値は実際の接続時間に基づいて動的に減少します。 | 30秒 | 30秒 |
| アップストリームサーバーからのデータ待機タイムアウト。 | 2秒 | 2秒 |
キャッシュポリシー
クライアント側
クライアント側キャッシュは、コンテナイメージとアプリケーションによって異なります。有効なポリシーは、特定の構成によって決まります。
クラスター内DNSサーバー
次の表に、ACKにおけるCoreDNSとNodeLocal DNSCacheのキャッシュパラメーターを示します。
パラメーター | 説明 | CoreDNSコミュニティのデフォルト | NodeLocal DNSCache ACKのデフォルト | CoreDNS ACKのデフォルト |
成功時の最大TTL | キャッシュされた成功したDNS解決結果の最大生存時間 (TTL)。 | 3600秒 | 30秒 | 30秒 |
成功時の最小TTL | キャッシュされた成功したDNS解決結果の最小TTL。 | 5秒 | 5秒 | 5秒 |
成功時のキャッシュ容量 | キャッシュする成功したDNS解決結果の数。 | 9984 | 9984 | 9984 |
拒否時の最大TTL | キャッシュされた失敗したDNS解決結果の最大TTL。 | 1800年代 | 5秒 | 30秒 |
拒否時の最小TTL | キャッシュされた失敗したDNS解決結果の最小TTL。 | 5秒 | 5秒 | 5秒 |
拒否容量 | キャッシュする失敗したDNS解決結果の数。 | 9984 | 9984 | 9984 |
ServerError TTL | アップストリームDNSサーバーが利用できない場合に適用されるTTL。 | 5秒 | 0秒 (NodeLocal DNSCache Helm Chartバージョン1.5.0以前のデフォルトは5秒) | 0秒 (CoreDNSバージョン1.8.4.2以前のデフォルトは5秒) |
`serve_stale` | アップストリームDNSサーバーに到達できない場合、CoreDNSが期限切れのキャッシュエントリを提供できるようにします。 | 無効 | 有効 (NodeLocal DNSCache Helm Chartバージョン1.5.0以前のデフォルトは無効) | 有効 (CoreDNSバージョン1.12.1以前のデフォルトは無効) |
有効なTTLは、解決結果TTL、最大TTL、および最小TTLによって次のように決定されます。
結果TTL > 最大TTL の場合、有効なTTLは最大TTLです。
結果TTL < 最小TTL の場合、有効なTTLは最小TTLです。
最小TTL ≤ 結果TTL ≤ 最大TTL の場合、有効なTTLは結果TTLです。
最適化の提案
Pod YAML、CoreDNS ConfigMap、またはNodeLocal DNSCache ConfigMapを編集して、DNS動作を調整します。
フォールトトレランスの強化
Pod で dnsPolicy: Default が設定されている場合、コンテナは ECS インスタンスの /etc/resolv.conf から VPC の DNS サーバの設定を継承します。ただし、rotate、single-request-reopen、timeout:2、および attempts:3 のオプションは継承されません。これらのオプションがない場合、ネットワークジッターにより、DNS 解決失敗が断続的に発生する可能性があります。
以下に、継承された構成を示します。
apiVersion: v1
kind: Pod
metadata:
name: example
namespace: default
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/example-ns/example:v1
name: example
# The dnsPolicy value in the Pod YAML is Default.
dnsPolicy: Default
# The /etc/resolv.conf file in the container at this time.
# cat /etc/resolv.conf
nameserver 100.100.2.136
nameserver 100.100.2.138dnsConfig を追加して、欠落している耐障害性オプションを復元します:
apiVersion: v1
kind: Pod
metadata:
name: example
namespace: default
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/example-ns/example:v1
name: example
# The dnsPolicy value in the pod YAML is Default.
dnsPolicy: Default
# Add the following fault tolerance configuration.
dnsConfig:
options:
- name: timeout
value: "2"
- name: attempts
value: "3"
- name: rotate
- name: single-request-reopen
# After modification, redeploy the pod. The options parameter is added to /etc/resolv.conf in the container.
# cat /etc/resolv.conf
nameserver 100.100.2.136
nameserver 100.100.2.138
options rotate single-request-reopen timeout:2 attempts:3`serve_stale`による高可用性
serve_stale 機能を使用すると、上流 DNS サーバが到達不能な場合に、CoreDNS は期限切れのキャッシュエントリを返すことができます。これにより、一時的な上流の障害によって引き起こされる名前解決の失敗を防ぐことができます。
serve_stale はデフォルトで有効になっています。RFC 仕様については、「RFC-8767」をご参照ください。構成形式
serve_stale [DURATION] [REFRESH_MODE]DURATION: 期限切れのエントリが、期限切れ後も提供対象となる期間です。デフォルトは1hです。正常にリフレッシュされることなく、エントリの期限切れからの経過時間がこの持続時間を超えた場合、CoreDNS はその提供を停止します。REFRESH_MODE: CoreDNS が期限切れのエントリをどのように処理するかを制御します:verify:まず上流 DNS サービスが到達可能であることを確認してから、クライアントに結果を返します。上流が応答した場合は新しいエントリを使用し、応答しなかった場合は期限切れのエントリにフォールバックします。これにより、古いデータに対する応答のレイテンシーは増加しますが、新しいエントリが利用可能な場合に古いエントリが提供されるのを防ぎます。immediate: 期限切れのエントリをクライアントにすぐに返し、バックグラウンドでアップストリームを確認します。これにより応答は高速になりますが、アップストリームが更新されている場合は古いデータを提供する可能性があります。
例
以下の構成は、CoreDNSアンマネージド版v1.12.1.2以降のデフォルトです。
cache 30 {
...
serve_stale 30s verify
}CoreDNSアンマネージド版v1.12.1.1-4035d7a99-aliyunのデフォルト構成は次のとおりです。
cache 30 {
...
serve_stale 1h immediate
}「serve_stale 1h immediate」を設定すると、クライアントがヘッドレスサービスの反復更新中に DNS 解決を実行するなどの極端なシナリオにおいて、CoreDNS が期限切れのエントリを返す場合があります。この現象が頻繁に発生する場合は、ポリシーを「verify」に変更してください。