ノードごとの DNS キャッシュをインストールすることで、クエリのレイテンシを低減し、名前解決の信頼性を向上させます。
仕組み
NodeLocal DNSCache は次の 2 つのコンポーネントで構成されます:
DaemonSet (DNS キャッシュエージェント):各ノードで実行され、仮想ネットワークインターフェイスを作成し、デフォルトで
169.254.20.10宛ての DNS クエリをリッスンします。リッスン IP アドレスを変更するには、チケットを送信してください。Deployment (アドミッションコントローラー):アドミッション Webhook を介して Pod の作成リクエストをインターセプトし、Pod の spec に dnsConfig を自動的に注入します。
キャッシュエージェントは CoreDNS をベースとしており、プロキシとキャッシュのみを提供します。hosts や rewrite などのプラグインは有効化しないでください。これらは CoreDNS 側で設定します。
NodeLocal DNSCache のデプロイ後の DNS クエリフロー:
NodeLocal DNSCache のデプロイ後の DNS クエリフロー:
番号 | 説明 |
① | デフォルトでは、ローカル dnsConfig が注入された Pod は NodeLocal DNSCache を使用します。NodeLocal DNSCache は、ノード上の 169.254.20.10 宛てに送信された DNS クエリをリッスンします。 |
② | NodeLocal DNSCache でキャッシュヒットしない場合は、kube-dns Service を使用してクエリを CoreDNS に転送します。 |
③ | CoreDNS は、仮想プライベートクラウド (VPC) にデプロイされた DNS サーバーを使用して、クラスター外のドメイン名を解決します。 |
④ | ローカル dnsConfig が注入された Pod が NodeLocal DNSCache に接続できない場合は、kube-dns Service を使用して CoreDNS に接続し、DNS 解決を行います。 |
⑤ | ローカル dnsConfig が注入されていない Pod は、kube-dns Service を使用して CoreDNS に接続し、DNS 解決を行います。 |
詳細については、「DNS 解決ポリシーとキャッシュポリシー」をご参照ください。
前提条件
開始する前に、次の事項を確認してください:
制限事項
Windows ノードはサポートされていません。仮想ノード (ECI および ACS Pod を含む) 上の Pod では、NodeLocal DNSCache v1.6.0 以降と ack-virtual-node v2.14.0 以降がインストールされている場合にのみ DNS キャッシュがサポートされます。
クラスターで Terway を使用している場合、バージョン 1.0.10.301 以降が必要です。Terway が IPvlan を使用した inclusive ENI モードで実行されている場合は、先に Terway を IPvlan モード向けに設定してください。
NodeLocal DNSCache は CoreDNS の透過的なキャッシュプロキシとしてのみ動作し、プラグイン拡張性は提供しません。
hostsやrewriteなどのプラグインは、代わりに CoreDNS で設定してください。NodeLocal DNSCache を使用する前に、CoreDNS forward プラグインのデフォルトプロトコルを設定してください。そうしないと、CoreDNS が外部ドメインを解決できないことがあります。DNS サービスのベストプラクティスをご参照ください。
デフォルトでは master ノードにインストールされません。Pod が Taint 付きの master ノード上で実行される場合は、
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を対象の名前空間に置き換えてください。
有効化すると、新規 Pod に次の dnsConfig が追加されます。高可用性のフォールバックとして 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を使用しており DNS ポリシーがClusterFirstWithHostNetであるか、またはhostNetworkを使用しておらず DNS ポリシーがClusterFirstであること。
注入に失敗する場合は、上記の条件をすべて満たしていることを確認してください。
特定の 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 の 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"主なフィールド:
フィールド | 値 | 補足 |
|
| カスタム dnsConfig を指定する場合に必須です。 |
|
| 1 つ目は NodeLocal DNSCache にルーティングし、2 つ目は kube-dns のフォールバックです。 |
| クラスター DNS の検索ドメイン | 内部 Service 名が正しく解決されるようにします。 |
|
| 値を小さくすると、検索ドメインを試行してから名前をそのまま解決するまでのルックアップ回数を減らせます。デフォルトは |
方法 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>パラメーター | 説明 |
| Pod の dnsConfig に書き込まれる DNS サーバーです。先に |
| Pod の dnsConfig に書き込まれる DNS 検索ドメインです。多くのクラスターでは |
ファイルを編集した後、変更を適用します:
sudo systemctl daemon-reload
sudo systemctl restart kubeletkubelet の再起動により、実行中のワークロードが短時間中断される可能性があります。
例:Deployment 向けの NodeLocal DNSCache 設定
default 名前空間の Deployment で、方法 1 (自動注入) を使用して 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]] 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 の初期バージョンを使用するクラスターでは、デフォルト設定で 169.254.20.10 宛ての DNS トラフィックが正しくルーティングされない場合があります。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 のインストールに進んでください。