ノード単位の DNS キャッシュをインストールして、クエリレイテンシーを削減し、名前解決の信頼性を向上させます。
仕組み
NodeLocal DNSCache は、次の 2 つのコンポーネントで構成されます。
DaemonSet (DNS キャッシュエージェント):各ノードで実行され、仮想ネットワークインターフェイスを作成し、デフォルトで
169.254.20.10で DNS クエリをリッスンします。リッスン IP アドレスを変更するには、チケットを送信してください。Deployment (アドミッションコントローラー):Admission Webhook を介して Pod 作成リクエストをインターセプトし、Pod 仕様に dnsConfig を自動的に注入します。
キャッシュエージェントは CoreDNS をベースに構築されており、プロキシとキャッシュ機能のみを提供します。hosts や rewrite などのプラグインをキャッシュエージェントで有効にしないでください。これらは CoreDNS で設定してください。
NodeLocal DNSCache をデプロイした後の DNS クエリフローは以下の通りです。
番号 | 説明 |
① | デフォルトでは、ローカルの dnsConfig がインジェクトされた Pod は NodeLocal DNSCache を使用します。NodeLocal DNSCache は、ノード上の 169.254.20.10 に送信される DNS クエリをリッスンします。 |
② | NodeLocal DNSCache でキャッシュヒットしない場合、kube-dns Service を使用してクエリを CoreDNS に転送します。 |
③ | CoreDNS は、クラスターローカルではないドメイン名を解決するために、Virtual Private Cloud (VPC) にデプロイされた DNS サーバーを使用します。 |
④ | ローカルの dnsConfig がインジェクトされた Pod が NodeLocal DNSCache への接続に失敗した場合、Pod は kube-dns Service を使用して CoreDNS に接続し、DNS 名前解決を行います。 |
⑤ | ローカルの dnsConfig がインジェクトされていない Pod は、kube-dns Service を使用して CoreDNS に接続し、DNS 名前解決を行います。 |
詳細については、「DNS 名前解決ポリシーとキャッシュポリシー」をご参照ください。
前提条件
作業を開始する前に、以下を確認してください。
制限事項
Windows ノードはサポートされていません。仮想ノード (ECI および ACS Pod を含む) 上の Pod の場合、DNS キャッシュは NodeLocal DNSCache v1.6.0 以降と ack-virtual-node v2.14.0 以降がインストールされている場合にのみサポートされます。
クラスターで Terway を使用している場合、バージョン 1.0.10.301 以降が必要です。Terway が IPvlan を使用する包括的 ENI モードで実行されている場合、まずIPvlan モード用に Terway を設定してください。
NodeLocal DNSCache は CoreDNS の透過的キャッシュプロキシとしてのみ機能し、プラグイン拡張性は公開しません。
hostsやrewriteなどのプラグインは、CoreDNS で設定してください。NodeLocal DNSCache を使用する前に、CoreDNS フォワードプラグインのデフォルトプロトコルを設定してください。設定しないと、CoreDNS が外部ドメインの名前解決に失敗する可能性があります。詳細については、「DNS サービスのベストプラクティス」をご参照ください。
デフォルトでは、マスターノードにはインストールされません。テイント付きのマスターノードで Pod を実行する場合は、
kube-system名前空間のnode-local-dnsDaemonSet に、一致する Toleration を追加してください。
NodeLocal DNSCache のインストール
NodeLocal DNSCache の設定
Pod からの DNS クエリを NodeLocal DNSCache 経由でルーティングするには、Pod の dnsConfig の nameservers を 169.254.20.10 と kube-dns のクラスター IP アドレスに設定します。次のいずれかの方法を使用してください。
方法 | 推奨度 | 説明 |
推奨 | アドミッションコントローラーが Pod 作成時に dnsConfig をインジェクトします。YAML の手動編集は不要です。 | |
中立 | Pod の YAML で dnsConfig を直接指定します。 | |
非推奨 | kubelet を変更し、再起動する必要があります。これによりワークロードが中断される可能性があります。 |
方法1: dnsConfig の自動インジェクト
アドミッションコントローラーは、node-local-dns-injection=enabled ラベルが付いた名前空間内の Pod に dnsConfig をインジェクトします。名前空間にラベルを付けてインジェクションを有効にします。
kubectl label namespace default node-local-dns-injection=enabledこれにより、default名前空間のみでインジェクションが有効になります。必要に応じてdefaultをターゲット名前空間に置き換えてください。
有効にすると、次の dnsConfig が新しい Pod に追加されます。kube-dns のクラスター IP は、高可用性のためのフォールバックとして含まれています。
dnsConfig:
nameservers:
- 169.254.20.10
- 172.21.0.10
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
dnsPolicy: Noneインジェクションの条件
インジェクションは、以下のすべての条件が満たされた場合にのみ適用されます。
Pod が
kube-systemまたはkube-public名前空間にないこと。Pod の名前空間に
node-local-dns-injection=enabledラベルがあること。Pod の名前空間に ECI 関連ラベル (
virtual-node-affinity-injection、eci、またはalibabacloud.com/eci) がないこと。Pod に
eci、alibabacloud.com/eci、またはnode-local-dns-injection=disabledラベルがないこと。Pod が
hostNetworkを使用してClusterFirstWithHostNetDNS ポリシーを使用しているか、またはhostNetworkを使用せずにClusterFirstDNS ポリシーを使用していること。
インジェクションが失敗した場合は、上記のすべての条件を確認してください。
特定の Pod のインジェクションを除外する方法
特定の Pod をインジェクションから除外するには、Pod テンプレートのラベルに node-local-dns-injection=disabled を追加します。
metadata:
labels:
node-local-dns-injection: "disabled"NodeLocal DNSCache v1.6.0 より前のバージョン、または ack-virtual-node v2.14.0 より前のバージョンでは、ECI Pod は NodeLocal DNSCache を使用できず、DNS 障害が発生します。その場合は、Pod テンプレートのラベルに node-local-dns-injection=disabled を追加して、Deployment のインジェクションを無効にしてください。
方法2: dnsConfig の手動設定
Pod 仕様で dnsConfig を直接指定します。
apiVersion: v1
kind: Pod
metadata:
name: alpine
namespace: default
spec:
containers:
- image: alpine
command:
- sleep
- "10000"
imagePullPolicy: Always
name: alpine
dnsPolicy: None
dnsConfig:
nameservers: ["169.254.20.10","172.21.0.10"]
searches:
- default.svc.cluster.local
- svc.cluster.local
- cluster.local
options:
- name: ndots
value: "3"
- name: attempts
value: "2"
- name: timeout
value: "1"主要なフィールド:
フィールド | 値 | 注記 |
|
| カスタム dnsConfig を指定する場合に必須です。 |
|
| 最初のエントリは NodeLocal DNSCache にルーティングされ、2 つ目は kube-dns のフォールバックです。 |
| クラスター DNS 検索ドメイン | 内部サービス名が正しく解決されるようにします。 |
|
| 値を小さくすると、名前をそのまま試す前の検索ドメインルックアップが減少します。デフォルトは |
方法3: kubelet 起動パラメーター
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf で、--cluster-dns に NodeLocal DNSCache の IP と kube-dns の IP を追加します。
--cluster-dns=169.254.20.10 --cluster-dns=<kube-dns-ip> --cluster-domain=<search-domain>パラメーター | 説明 |
| Pod の dnsConfig に書き込まれる DNS サーバー。最初に |
| Pod の dnsConfig に書き込まれる DNS 検索ドメイン。ほとんどのクラスターでは、これは |
ファイルを編集した後、変更を適用します。
sudo systemctl daemon-reload
sudo systemctl restart kubeletkubelet を再起動すると、実行中のワークロードが一時的に中断される可能性があります。
例: Deployment に NodeLocal DNSCache を設定する
方法1 (自動インジェクト) を使用して、default 名前空間の Deployment に NodeLocal DNSCache を有効にします。
名前空間にラベルを付けて、dnsConfig の自動インジェクションを有効にします。
重要アドミッションコントローラーは、
kube-systemおよびkube-public名前空間の Pod をスキップします。これらの名前空間ではインジェクションを有効にしないでください。kubectl label namespace default node-local-dns-injection=enabledサンプルアプリケーションをデプロイします。この YAML を
ubuntu-deployment.yamlとして保存します。apiVersion: apps/v1 kind: Deployment metadata: name: ubuntu labels: app: ubuntu spec: replicas: 2 selector: matchLabels: app: ubuntu template: metadata: labels: app: ubuntu spec: containers: - name: ubuntu image: ubuntu command: ["sh", "-c"] args: ["sleep 100000"]マニフェストを適用します。
kubectl apply -f ubuntu-deployment.yaml想定される出力:
deployment.apps/ubuntu createdDeployment が実行されていることを確認します。
kubectl get deployment ubuntu想定される出力:
NAME READY UP-TO-DATE AVAILABLE AGE ubuntu 2/2 2 2 7sdnsConfig のインジェクションを確認します。Pod 名を取得します。
kubectl get pods想定される出力:
NAME READY STATUS RESTARTS AGE ubuntu-766448f68c-m**** 1/1 Running 0 4m39s ubuntu-766448f68c-w**** 1/1 Running 0 4m39sPod の dnsConfig を確認します。
kubectl get pod ubuntu-766448f68c-m**** -o=jsonpath='{.spec.dnsConfig}'想定される出力:
map[nameservers:[169.254.20.10 172.21.0.10] options:[map[name:ndots value:3] map[name:attempts value:2] map[name:timeout value:1]] searches:[default.svc.cluster.local svc.cluster.local cluster.local]]nameserversに169.254.20.10が含まれていることで、dnsConfig のインジェクションが確認できます。
NodeLocal DNSCache の更新
ACK コンソールにログオンします。左側のナビゲーションペインで、[クラスター]をクリックします。
クラスター名をクリックします。左側のナビゲーションペインで、[操作] > [アドオン] を選択します。
[アドオン] ページで、NodeLocal DNSCache を見つけ、[アップグレード] をクリックします。ダイアログボックスで、[OK] をクリックします。
node-local-dns DaemonSet のカスタムの toleration は、アップグレード中に上書きされます。アップグレード後に再設定してください。アップグレードに失敗した場合は、「コンポーネントのトラブルシューティング」をご参照ください。NodeLocal DNSCache のアンインストール
ACK コンソールにログインします。左側のナビゲーションペインで、[クラスター] をクリックします。
クラスター名をクリックします。 左側のナビゲーションペインで、[運用] > [アドオン] を選択します。
[アドオン] ページで NodeLocal DNSCache を探して [アンインストール] をクリックします。ダイアログボックスで [OK] をクリックします。
アンインストール後、すべての DNS クエリは CoreDNS に直接送信されます。アンインストール前に CoreDNS をスケールアウトして、増加した負荷に対応してください。
IPvlan モード用 Terway の設定
古いバージョンの Terway を使用しているクラスターでは、デフォルト設定では DNS トラフィックが 169.254.20.10 に正しくルーティングされない可能性があります。NodeLocal DNSCache をインストールする前に設定を更新してください。
Terway の ConfigMap を編集用に開きます。
kubectl -n kube-system edit cm eni-config -o yamlConfigMap を確認します。
eniip_virtual_typeがIPVlanでない場合、変更は不要です。「NodeLocal DNSCache のインストール」に進んでください。host_stack_cidrsがすでに存在する場合、変更は不要です。「NodeLocal DNSCache のインストール」に進んでください。
eniip_virtual_typeがIPVlanで、host_stack_cidrsが存在しない場合、host_stack_cidrsを追加して169.254.20.10/32に設定します。保存して終了します。10-terway.conf: | { "cniVersion": "0.3.0", "name": "terway", "eniip_virtual_type": "IPVlan", "host_stack_cidrs": ["169.254.20.10/32"], "type": "terway" }Terway DaemonSet の Pod を一覧表示します。
kubectl -n kube-system get pod | grep terway-eniip想定される出力:
terway-eniip-7**** 2/2 Running 0 30m terway-eniip-s**** 2/2 Running 0 30m更新された設定を適用するために、Pod を削除します。
kubectl -n kube-system delete pod terway-eniip-7**** terway-eniip-s****クラスターノードにログインし、更新を確認します。
cat /etc/cni/net.d/*想定される出力:
{ "cniVersion": "0.3.0", "name": "terway-chainer", "plugins": [ { "eniip_virtual_type": "IPVlan", "host_stack_cidrs": [ "169.254.20.10/32" ], "type": "terway" }, { "type": "cilium-cni" } ] }すべての Terway Pod が実行中になったら、「NodeLocal DNSCache のインストール」に進んでください。