NodeLocal DNSCache は、すべてのクラスターノードで DaemonSet として DNS キャッシュエージェントを実行し、DNS のレイテンシーを削減し、Container Service for Kubernetes (ACK) クラスターの信頼性を向上させます。このトピックでは、NodeLocal DNSCache のインストール、設定、管理方法について説明します。
仕組み
NodeLocal DNSCache は、2 つのコンポーネントで構成されています。
-
DaemonSet (DNS キャッシュエージェント):各ノードで実行され、仮想ネットワークインターフェースを作成し、デフォルトで
169.254.20.10で DNS クエリをリッスンします。リッスンする IP アドレスを変更するには、チケットを送信してください。 -
Deployment (アドミッションコントローラー):アドミッション Webhook を介して Pod の作成リクエストをインターセプトし、Pod の spec に dnsConfig を自動的にインジェクションします。
キャッシュエージェントは CoreDNS 上に構築されており、プロキシおよびキャッシュサービスのみを提供します。hosts や rewrite などの他のプラグインを有効にせず、代わりに CoreDNS でこれらを設定してください。
以下の図は、NodeLocal DNSCache がデプロイされた後の DNS クエリのフローを示しています。
<table> <thead> <tr> <td><p><b>No.</b></p></td> <td><p><b>説明</b></p></td> </tr> </thead> <colgroup></colgroup> <colgroup></colgroup> <tbody> <tr> <td><p>①</p></td> <td><p>デフォルトでは、ローカル dnsConfig が注入された Pod は NodeLocal DNSCache を使用し、ノード上の IP アドレス 169.254.20.10 に送信される DNS クエリをリッスンします。 </p></td> </tr> <tr> <td><p>②</p></td> <td><p>NodeLocal DNSCache が DNS クエリのキャッシュヒットを見つけられない場合、kube-dns サービスを使用して CoreDNS にクエリの処理をリクエストします。 </p></td> </tr> <tr> <td><p>③</p></td> <td><p>CoreDNS は、VPC にデプロイされた DNS サーバーを使用して、クラスターローカルではないドメイン名を解決します。 </p></td> </tr> <tr> <td><p>④</p></td> <td><p>ローカル dnsConfig が注入された Pod が NodeLocal DNSCache への接続に失敗した場合、Pod は kube-dns サービスを使用して CoreDNS に接続し、DNS 名前解決を行います。 </p></td> </tr> <tr> <td><p>⑤</p></td> <td><p>ローカル dnsConfig が注入されていない Pod は、kube-dns サービスを使用して CoreDNS に接続し、DNS 名前解決を行います。 </p></td> </tr> </tbody> </table>
キャッシュポリシーの詳細については、「DNS 名前解決ポリシーとキャッシュポリシー」をご参照ください。
前提条件
開始する前に、以下が準備できていることを確認してください。
-
ACK クラスター。詳細については、「ACK マネージドクラスターを作成する」をご参照ください。
-
kubectl がクラスターに接続されていること。 詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
制限事項
-
NodeLocal DNSCache は、ACK Serverless クラスターまたは ACK マネージドクラスターや専用クラスターの Elastic Container Instance (ECI) で実行されている Pod をサポートしていません。
-
クラスターが Terway ネットワークプラグインを使用している場合、Terway 1.0.10.301 以降が必要です。Terway が IPvlan ベースの包括的な ENI モードで実行されている場合は、追加の設定が必要です。詳細については、「IPvlan モード用の Terway の設定」をご参照ください。
-
NodeLocal DNSCache は CoreDNS の透過的なキャッシングプロキシであり、
hostsやrewriteなどのプラグインは提供しません。これらのプラグインを使用するには、CoreDNS で設定してください。 -
NodeLocal DNSCache を使用する前に、CoreDNS forward プラグインのデフォルトプロトコルを設定してください。そうしないと、CoreDNS が外部ドメイン名を解決できなくなる場合があります。詳細については、「DNS サービスのベストプラクティス」をご参照ください。
-
NodeLocal DNSCache は、デフォルトではマスターノードにインストールされません。ビジネス Pod が Taint の付与されたマスターノードで実行される場合は、
kube-system名前空間のnode-local-dnsDaemonSet に、一致する Toleration を追加してください。
NodeLocal DNSCache のインストール
NodeLocal DNSCache の設定
Pod からの DNS クエリを NodeLocal DNSCache を経由してルーティングするには、Pod の dnsConfig の nameservers を 169.254.20.10 と kube-dns のクラスター IP アドレスに設定します。以下のいずれかの方法を使用してください。
| 方法 | 推奨 | 説明 |
|---|---|---|
| 方法 1:dnsConfig の自動インジェクション | 推奨 | アドミッションコントローラーが Pod 作成時に dnsConfig をインジェクションするため、手動での YAML 編集は不要です。 |
| 方法 2:手動での dnsConfig 設定 | どちらでもない | Pod の YAML で直接 dnsConfig を指定します。 |
| 方法 3:kubelet 起動パラメーター | 非推奨 | kubelet を変更し、再起動が必要なため、ワークロードが中断される可能性があります。 |
方法 1:dnsConfig の自動インジェクション
アドミッションコントローラーは、node-local-dns-injection=enabled のラベルが付いた名前空間での Pod 作成リクエストを監視し、自動的に dnsConfig をインジェクションします。名前空間にラベルを付けてインジェクションを有効にします。
kubectl label namespace default node-local-dns-injection=enabled
上記のコマンドはdefault名前空間に対してのみインジェクションを有効にします。必要に応じてdefaultを他の名前空間に置き換えてください。
自動インジェクションが有効な場合、新しく作成された Pod に以下の dnsConfig が追加されます。kube-dns のクラスター IP アドレスは、高可用性を維持するためのバックアップ DNS サーバーとして含まれます。
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 のコンテナに DNS サーバーの IP アドレスがインジェクションされない場合は、上記のすべての条件が満たされていることを確認してください。
特定の Pod をインジェクションから除外する
名前空間でインジェクションが有効になっている状態で特定の Pod をインジェクションから除外するには、Pod テンプレートのラベルに node-local-dns-injection=disabled を追加します。
metadata:
labels:
node-local-dns-injection: "disabled"
ECI は NodeLocal DNSCache をサポートしていません。Deployment がスケールアウトし、新しい Pod が ECI 上に配置されると、それらの Pod は NodeLocal DNSCache に接続できず、DNS 名前解決の失敗を引き起こします。Pod テンプレートのラベルに node-local-dns-injection=disabled を追加して、Deployment 全体のインジェクションを無効にしてください。
方法 2:手動での dnsConfig 設定
Pod の spec で直接 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"
主要なフィールド:
| フィールド | 値 | 注意 |
|---|---|---|
dnsPolicy |
None |
カスタムの dnsConfig を指定する際に必須です。 |
nameservers |
169.254.20.10、kube-dns クラスター IP |
最初のエントリは NodeLocal DNSCache にルーティングされ、2 番目は kube-dns のフォールバックです。 |
searches |
クラスター DNS 検索ドメイン | 内部サービス名が正しく解決されることを保証します。 |
ndots |
3 |
値を小さくすると、名前をそのまま試す前の検索ドメインのルックアップ回数が減ります。デフォルトは 5 です。詳細については、「resolv.conf」をご参照ください。 |
方法 3:kubelet 起動パラメーター
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf に、NodeLocal DNSCache の IP と kube-dns の IP を持つ --cluster-dns を追加します。
--cluster-dns=169.254.20.10 --cluster-dns=<kube-dns-ip> --cluster-domain=<search-domain>
| パラメーター | 説明 |
|---|---|
--cluster-dns |
Pod の dnsConfig に書き込まれる DNS サーバー。最初に 169.254.20.10 を指定し、次に kube-dns の IP を指定します。 |
--cluster-domain |
Pod の dnsConfig に書き込まれる DNS 検索ドメイン。ほとんどのクラスターでは、これは cluster.local です。 |
ファイルを編集した後、変更を適用します。
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubelet を再起動すると、実行中のワークロードが一時的に中断される可能性があります。
例: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 created -
Deployment が実行中であることを確認します。
kubectl get deployment ubuntu期待される出力:
NAME READY UP-TO-DATE AVAILABLE AGE ubuntu 2/2 2 2 7s -
dnsConfig がインジェクションされたことを確認します。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:5]] 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 を変更した場合、それらの変更はアップグレード中に上書きされます。アップグレードの完了後に Toleration を再設定してください。アップグレードが失敗した場合は、「コンポーネントのトラブルシューティング」をご参照ください。
NodeLocal DNSCache のアンインストール
-
ACK コンソールにログインします。左側のナビゲーションウィンドウで [クラスター] をクリックします。
-
管理したいクラスターを見つけて、その名前をクリックします。左側のナビゲーションウィンドウで、[操作] > [アドオン] を選択します。
-
[アドオン] ページで NodeLocal DNSCache を見つけ、[アンインストール] をクリックします。表示されるダイアログボックスで [OK] をクリックします。
アンインストール後、すべての DNS クエリは直接 CoreDNS に送信されます。増加する負荷に対応するため、アンインストールする前に CoreDNS をスケールアウトしてください。
IPvlan モード用の Terway の設定
古いバージョンの Terway で作成されたクラスターでは、デフォルトの Terway 設定が DNS トラフィックを 169.254.20.10 に正しくルーティングしない場合があります。NodeLocal DNSCache をインストールする前に、設定を確認して更新してください。
-
Terway の ConfigMap を編集用に開きます。
kubectl -n kube-system edit cm eni-config -o yaml -
ConfigMap を確認します。
-
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 のインストール」に進んでください。