Container Service for Kubernetes (ACK) では、NodeLocal DNSCache をデプロイして、サービスディスカバリの安定性とパフォーマンスを向上させることができます。NodeLocal DNSCache は DaemonSet として実装され、クラスタノード上で DNS キャッシングエージェントを実行して、ACK クラスタの DNS 解決の効率を向上させます。このトピックでは、ACK クラスタ内のアプリケーションに対して NodeLocal DNSCache をデプロイおよび構成する方法について説明します。
前提条件
ACK クラスタが作成されていること。詳細については、「ACK マネージドクラスターを作成する」をご参照ください。
kubectl クライアントがクラスタに接続されていること。詳細については、「クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続する」をご参照ください。
制限事項
NodeLocal DNSCache は、Serverless Kubernetes クラスター 内、または ACK マネージドクラスターや ACK 専用クラスターの Elastic Container Instance 上で実行されているポッドをサポートしていません。
クラスタで Terway ネットワークプラグインを使用している場合、Terway のバージョンは 1.0.10.301 以降である必要があります。 IPvlan ベースの包括的な ENI モードで Terway を実行しているクラスタの場合、Terway の構成を変更する必要があります。詳細については、「Terway の構成を変更する(以前のバージョンの Terway を使用して作成されたクラスター)」をご参照ください。
NodeLocal DNSCache は、CoreDNS の透過的なキャッシングプロキシとして機能し、hosts や rewrite などのプラグインは提供しません。これらのプラグインを有効にする場合は、CoreDNS の構成を変更してください。
NodeLocal DNSCache を使用する前に CoreDNS の構成を変更しないと、CoreDNS が外部ドメイン名を解決できない場合があります。詳細については、「Forward プラグインのデフォルトプロトコルと VPC のアップストリーム DNS サーバーを構成する」をご参照ください。
概要
ACK NodeLocal DNSCache は、オープンソースの NodeLocal DNSCache プロジェクトに基づいて開発されたローカル DNS キャッシングソリューションです。このソリューションは、DaemonSet として実行される DNS キャッシングエージェントと、Deployment として実行されるアドミッションコントローラーで構成され、DNSConfig を動的に挿入します。
アドミッションコントローラーは、アドミッション Webhook に基づいてポッド作成リクエストをインターセプトし、ポッド構成に DNSConfig を動的に挿入します。
説明アドミッションコントローラーで DNSConfig を自動的に挿入しない場合は、ポッド構成に DNS 設定を手動で追加する必要があります。詳細については、「方法 2: DNSConfig を手動で指定する」をご参照ください。
各ノードで DNS キャッシングエージェントを実行する DaemonSet は、仮想ネットワークインターフェースを作成できます。デフォルトでは、仮想ネットワークインターフェースは IP アドレス 169.254.20.10 に送信された DNS クエリをリッスンします。 IP アドレスを変更するには、チケットを送信する。ポッドで生成された DNS クエリは、ポッド DNSConfig とノードネットワーク設定に基づいて DaemonSet によってプロキシされます。
重要DNS キャッシングエージェントを実行する DaemonSet は、CoreDNS に基づいて構築されており、プロキシサービスとキャッシングサービスのみを提供します。 hosts や rewrite などの他のプラグインは有効にしないでください。
NodeLocal DNSCache でサポートされているキャッシングポリシーの詳細については、「DNS 解決ポリシーとキャッシングポリシー」をご参照ください。
図 1. NodeLocal DNSCache のしくみ
番号 | 説明 |
① | デフォルトでは、ローカル DNSConfig が挿入されたポッドは、NodeLocal DNSCache を使用して、ノード上の IP アドレス 169.254.20.10 に送信された DNS クエリをリッスンします。 |
② | NodeLocal DNSCache が DNS クエリに対するキャッシュヒットを見つけられない場合、kube-dns サービスを使用して CoreDNS にクエリ処理をリクエストします。 |
③ | CoreDNS は、VPC(Virtual Private Cloud)にデプロイされた DNS サーバーを使用して、クラスターローカルではないドメイン名を解決します。 |
④ | ローカル DNSConfig が挿入されたポッドが NodeLocal DNSCache に接続できない場合、ポッドは kube-dns サービスを使用して CoreDNS に接続し、DNS 解決を行います。 |
⑤ | ローカル DNSConfig が挿入されていないポッドは、kube-dns サービスを使用して CoreDNS に接続し、DNS 解決を行います。 |
NodeLocal DNSCache のインストール
ACK コンソール にログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターを見つけ、[アクション] 列の を選択します。
[アドオン] ページで、[ネットワーキング] タブをクリックし、[ACK NodeLocal DNSCache] を見つけます。
[インストール] をクリックします。表示されるメッセージで、[OK] をクリックします。
NodeLocal DNSCache の構成
デフォルトでは、NodeLocal DNSCache はマスターノードにインストールされません。マスターノードにビジネスポッドをデプロイする場合、マスターノードに taint が追加されている場合は、kube-system 名前空間の node-local-dns の構成に一致する toleration を追加する必要があります。
CoreDNS 宛ての DNS リクエストを DNS キャッシングエージェントを実行する DaemonSet にリダイレクトするには、ポッド構成の nameservers パラメーターを 169.254.20.10 と kube-dns の IP アドレスに設定する必要があります。これを行うには、次のいずれかの方法を使用します。
方法 1: DNSConfig を自動的に挿入する(推奨):ポッドの作成時にアドミッションコントローラーを使用して DNSConfig を自動的に挿入します。
方法 2: DNSConfig を手動で指定する:ポッドの作成時に DNSConfig を手動で指定します。
方法 3: kubelet 起動パラメーターを構成する(非推奨):kubelet パラメーターを変更し、kubelet を再起動します。この方法では、ビジネスが中断される可能性があります。
方法 1: DNSConfig を自動的に挿入する
アドミッションコントローラーを使用して、新しく作成されたポッドに DNSConfig を自動的に挿入できます。こうすることで、ポッドの YAML ファイルを手動で構成する必要がなくなります。デフォルトでは、アプリケーションは、node-local-dns-injection=enabled
ラベルが付いた名前空間からのポッド作成リクエストをリッスンします。次のコマンドを使用して、このラベルを名前空間に追加できます。
kubectl label namespace default node-local-dns-injection=enabled
上記のコマンドは、default 名前空間に対してのみ DNSConfig の自動挿入を有効にします。他の名前空間に対して DNSConfig の自動挿入を有効にするには、要件に基づいて
default
を置き換えます。名前空間に対して DNSConfig の自動挿入が有効になっているが、一部のポッドに DNSConfig を自動的に挿入したくない場合は、これらのポッドのテンプレートに
node-local-dns-injection=disabled
ラベルを追加できます。Elastic Container Instance は NodeLocal DNSCache をサポートしていません。Deployment が動的にスケールアウトされると、Elastic Container Instance に新しいポッドが作成される場合があります。この場合、Elastic Container Instance 上で実行されている新しいポッドは NodeLocal DNSCache に接続できず、DNS 解決エラーが発生する可能性があります。この問題を解決するには、ポッドテンプレートの labels パラメーターに
node-local-dns-injection=disabled
を追加することで、Deployment にプロビジョニングされたすべてのポッドに対して DNSConfig の自動挿入を無効にする必要があります。
DNSConfig の自動挿入が有効になると、新しく作成されたポッドに次のパラメーターが追加されます。 DNS サービスの高可用性を確保するために、kube-dns のクラスター IP アドレスがバックアップ DNS サーバーとして nameservers パラメーターに追加されます。
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
DNSConfig の自動挿入は、ポッドが次のすべての要件を満たしている場合にのみ有効になります。ポッド内のコンテナーに DNS サーバーの IP アドレスが挿入されていない場合は、ポッドがこれらの要件を満たしているかどうかを確認する必要があります。
新しく作成されたポッドは、kube-system または kube-public 名前空間に属していません。
新しく作成されたポッドが属する名前空間には、
node-local-dns-injection=enabled
ラベルが付いています。新しく作成されたポッドが属する名前空間には、
virtual-node-affinity-injection
、eci
、alibabacloud.com/eci
などの Elastic Container Instance に関連するラベルが付いていません。新しく作成されたポッドには、
eci
やalibabacloud.com/eci
などの Elastic Container Instance に関連するラベル、またはnode-local-dns-injection=disabled
ラベルが付いていません。新しく作成されたポッドは、
hostNetwork
ネットワークとClusterFirstWithHostNet
DNS ポリシーを使用するか、hostNetwork
ネットワークを使用せずにClusterFirst
DNS ポリシーを使用します。
方法 2: DNSConfig を手動で指定する
アドミッション Webhook を使用して DNSConfig を自動的に挿入したくない場合は、ポッド構成を変更して 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
に設定します。nameservers: 値を 169.254.20.10 と kube-dns のクラスター IP アドレスに設定します。
searches: DNS 検索ドメインを設定します。内部ドメイン名が解決できることを確認してください。
ndots: このパラメーターを小さい値に設定することで、解決効率を向上させることができます。デフォルト値:5。詳細については、resolv.conf を参照してください。
方法 3: kubelet 起動パラメーターを構成する
kubelet は、--cluster-dns パラメーターと --cluster-domain パラメーターを使用して、ポッド DNSConfig を制御します。/etc/systemd/system/kubelet.service.d/10-kubeadm.conf ファイルで、--cluster-dns パラメーターを追加し、値をローカル IP アドレス 169.254.20.10 に設定します。次に、変更を有効にするために、sudo systemctl daemon-reload
コマンドと sudo systemctl restart kubelet
コマンドを実行します。
--cluster-dns=169.254.20.10 --cluster-dns=<kube-dns ip> --cluster-domain=<search domain>
cluster-dns: ポッド構成で使用される DNS サーバーを指定します。デフォルトでは、
`kube-dns`
の IP アドレスのみが指定されています。ローカル IP アドレス 169.254.20.10 を追加する必要があります。cluster-domain: ポッド構成で使用される DNS 検索ドメインを指定します。既存の検索ドメインを使用できます。ほとんどの場合、既存の検索ドメインは
`cluster.local`
です。
NodeLocal DNSCache を構成する例
次の例は、default 名前空間で作成された Deployment に対して NodeLocal DNSCache を構成する方法を示しています。
次のコマンドを実行して、Deployment が属する名前空間にラベルを追加します。この例では、Deployment は default 名前空間に作成されます。
kubectl label namespace default node-local-dns-injection=enabled
重要アドミッションコントローラーは、kube-system 名前空間と kube-public 名前空間のアプリケーションを無視します。2 つの名前空間のアプリケーションに dnsConfig を自動的に挿入するように構成しないでください。
default 名前空間にサンプルアプリケーションをデプロイします。
次の YAML テンプレートを使用して、ubuntu-deployment という名前のサンプルアプリケーションを作成します。
apiVersion: apps/v1 # 1.8.0 より前のバージョンでは apps/v1beta1 を使用します 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
次のコマンドを実行して、アプリケーションに関する情報を表示します。
kubectl get deployment ubuntu
予期される出力:
NAME READY UP-TO-DATE AVAILABLE AGE ubuntu 2/2 2 2 7s
dnsConfig が挿入されているかどうかを確認します。
次のコマンドを実行して、アプリケーションを実行しているポッドをクエリします。
kubectl get pods
予期される出力:
NAME READY STATUS RESTARTS AGE ubuntu-766448f68c-m**** 1/1 Running 0 4m39s ubuntu-766448f68c-w**** 1/1 Running 0 4m39s
次のコマンドを実行して、ポッドの dnsConfig で NodeLocal DNSCache が有効になっているかどうかを確認します。
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]]
上記の出力は、アプリケーションに対して NodeLocal DNSCache が有効になっていることを示しています。
アプリケーションに対して NodeLocal DNSCache が有効になると、アプリケーションにプロビジョニングされたポッドに次のパラメーターが追加されます。 DNS サービスの高可用性を確保するために、kube-dns サービスのクラスター IP アドレス 172.21.0.10 が、nameservers パラメーターのバックアップ 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
NodeLocal DNSCache の更新
ACK コンソール にログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターを見つけて名前をクリックします。左側のナビゲーションウィンドウで、[アドオン] をクリックします。
[アドオン] ページで、NodeLocal DNSCache を見つけて [アップグレード] をクリックします。表示されるメッセージで、[OK] をクリックします。
説明node-local-dns DaemonSet の toleration を変更した場合、変更内容は更新プロセス中に上書きされます。更新が完了したら、toleration を再構成する必要があります。
システムが NodeLocal DNSCache を更新できない場合は、返されたエラーコードに基づいて障害のトラブルシューティングを行ってください。詳細については、「コンポーネントのトラブルシューティング」をご参照ください。
NodeLocal DNSCache のアンインストール
ACK コンソール にログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターを見つけて名前をクリックします。左側のナビゲーションウィンドウで、[アドオン] をクリックします。
[アドオン] ページで、NodeLocal DNSCache を見つけて [アンインストール] をクリックします。表示されるメッセージで、[OK] をクリックします。
説明NodeLocal DNSCache をアンインストールすると、すべての DNS クエリが CoreDNS に送信されます。 NodeLocal DNSCache をアンインストールする前に、CoreDNS をスケールアウトすることをお勧めします。
Terway の構成を変更する(以前のバージョンの Terway を使用して作成されたクラスター)
以前のバージョンの Terway で作成されたクラスターでは、デフォルトの Terway 構成が NodeLocal DNSCache をサポートしていない場合があります。以下の手順を参照して、Terway 構成を確認および変更できます。
次のコマンドを実行して、Terway の ConfigMap を表示します。
kubectl -n kube-system edit cm eni-config -o yaml
Terway の ConfigMap を確認します。
eniip_virtual_type
フィールドで IPvlan が有効になっているかどうかを確認します。このフィールドが ConfigMap に存在しない場合、または値が IPvlan に設定されていない場合は、NodeLocal DNSCache をインストールする前に、以下の手順を実行する必要はありません。詳細については、「NodeLocal DNSCache のインストール」をご参照ください。ConfigMap に
host_stack_cidrs
フィールドが指定されているかどうかを確認します。host_stack_cidrs
フィールドが指定されている場合は、NodeLocal DNSCache をインストールする前に、以下の手順を実行する必要はありません。詳細については、「NodeLocal DNSCache のインストール」をご参照ください。
Terway の ConfigMap に
host_stack_cidrs
フィールドを追加し、値を 169.254.20.10/32 に設定します。次に、ConfigMap を保存して終了します。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 ポッドをクエリします。
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
次のコマンドを実行して、Terway ポッドを再作成します。
kubectl -n kube-system delete pod terway-eniip-7**** terway-eniip-s****
クラスターのノードにログインし、次のコマンドを実行して Terway の ConfigMap をクエリします。
ConfigMap に追加した CIDR ブロックが含まれている場合、Terway の ConfigMap は変更されています。
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 ポッドが再作成され、正常に実行されたら、NodeLocal DNSCache をインストールできます。