EKS クラスターに NodeLocalDNS をインストールして問題をトラブルシューティングする方法を教えてください。
Amazon Elastic Kubernetes Service (Amazon EKS) クラスターに NodeLocalDNS をインストールして、問題をトラブルシューティングしたいと考えています。
解決策
前提条件:
- Amazon EKS クラスターにアクセスするように kubectl を設定したことを確認します。
- CoreDNS がクラスターで実行されていることを確認します。
NodeLocalDNS をインストールする
NodeLocalDNS は、リンクローカル IP アドレスを使用して各ノードで DNS キャッシュを提供します。リンクローカルアドレスは、ネットワークセグメント内でのみ有効な 169.254.0.0/16 範囲の IP アドレスです。
注: NodeLocalDNS の標準リンクローカル IP アドレスは 169.254.20.10 です。環境内で特定の競合が発生していない限り、この値を変更しないでください。
Amazon EKS クラスターに NodeLocalDNS をインストールするには、次の手順を実行します。
-
次の curl コマンドを実行して、Kubernetes リポジトリから NodeLocalDNS マニフェストをダウンロードします。
curl -Lo nodelocaldns.yaml.template https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/dns/nodelocaldns/nodelocaldns.yaml -
クラスターの kube-dns サービス IP アドレスを取得するには、次のコマンドを実行します。
kubectl get svc kube-dns -n kube-system -o jsonpath='{.spec.clusterIP}'注: 出力の IP アドレスを書き留めます。
-
クラスターのドメインを取得するには、次のコマンドを実行します。
kubectl get configmap coredns -n kube-system -o yaml | grep 'kubernetes'出力にはクラスタードメインが表示されます。
-
kube-proxy モードを判断するには、次のコマンドを実行します。
kubectl get configmap kube-proxy-config -n kube-system -o yaml | grep mode出力には、モード値として iptables または ipvs のいずれかが表示されます。
-
kube-proxy モードに基づいて NodeLocalDNS マニフェストを編集します。
iptables モードの場合は、次のコマンドを使用してマニフェストを編集します。
# Set environment variables for node-local-dns kubedns=$(kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}) domain=cluster.local localdns=`169.254.20.10` # Update the manifest with your cluster's specific values: sed "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/__PILLAR__DNS__SERVER__/$kubedns/g" nodelocaldns.yaml.template > nodelocaldns.yaml注: クラスターが別のドメインを使用している場合は、cluster.local を手順 3 のクラスタードメインに置き換えます。クラスターのリンクローカル IP アドレスが異なる場合は、169.254.20.10 を実際のリンクローカル IP に置き換えてください。
IPVS モードの場合は、次のコマンドを使用してマニフェストを編集します。
# Set environment variables for node-local-dns kubedns=$(kubectl get svc kube-dns -n kube-system -o jsonpath={.spec.clusterIP}) domain=cluster.local localdns=169.254.20.10 # Update the manifest with your cluster's specific values: sed "s/__PILLAR__LOCAL__DNS__/$localdns/g; s/__PILLAR__DNS__DOMAIN__/$domain/g; s/,__PILLAR__DNS__SERVER__//g; s/__PILLAR__CLUSTER__DNS__/$kubedns/g" nodelocaldns.yaml.template > nodelocaldns.yaml注: クラスターが別のドメインを使用している場合は、cluster.local を手順 3 のクラスタードメインに置き換えます。クラスターのリンクローカル IP アドレスが異なる場合は、169.254.20.10 を実際のリンクローカル IP に置き換えてください。IPVS モードでは、NodeLocalDNS を使用するようにポッドを設定する必要があります。「NodeLocalDNS を使用するようにポッドを設定する (IPVS モードのみ)」セクションを参照してください。
-
NodeLocalDNS マニフェストを適用するには、次のコマンドを実行します。
kubectl apply -f nodelocaldns.yaml -
NodeLocalDNS ポッドが Running ステータスになっていることを確認するには、次のコマンドを実行します。
kubectl get pods -n kube-system -l k8s-app=node-local-dns
NodeLocalDNS を使用するようにポッドを設定する (IPVS モードのみ)
重要: このセクションは、クラスターが kube-proxy で IPVS モードを使用する場合にのみ適用されます。クラスターが iptables モードを使用している場合、DNS トラフィックは自動的に NodeLocalDNS にリダイレクトされます。
IPVS モードのクラスターでは、NodeLocalDNS を使用するようにポッドを手動で設定する必要があります。ポッドを NodeLocalDNS に転送するには、個々のポッドを設定するか、kubelet を使用してクラスターを設定します。
個々のポッドを設定する
個々のポッドを設定するには、ポッド仕様に次の設定を追加します。
spec: dnsPolicy: "None" dnsConfig: nameservers: - [169.254.20.10] searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: "5"
注: 169.254.20.10 をクラスターのリンクローカル IP アドレスに置き換えてください。クラスターが別のドメインを使用している場合は、cluster.local をクラスターのドメインに置き換えてください。
kubelet を使用してクラスターを設定する
IPVS モードでは、NodeLocalDNS はリンクローカルアドレス 169.254.20.10 でのみリッスンします。このリンクローカルアドレスを指すように kubelet 設定を変更する必要があります。
NodeLocalDNS を使用するようにクラスター内のすべてのポッドを設定し、各ノードの kubelet 設定を変更するには、次の手順を実行します。
-
kubelet 設定ファイルを編集します。次の設定を追加します。
{ "clusterDNS": ["169.254.20.10"], "clusterDomain": "cluster.local" }注: 169.254.20.10 をクラスターのリンクローカル IP アドレスに置き換えてください。クラスターが別のドメインを使用している場合は、cluster.local をクラスターのドメインに置き換えてください。
-
各ノードで kubelet サービスを再起動するには、次の sudo コマンドを実行します。
sudo systemctl restart kubelet -
kubelet の設定を確認するには、以下のコマンドを実行します。
cat /etc/kubernetes/kubelet/config.json | grep clusterDNS注: 出力には、NodeLocalDNS のリンクローカル IP アドレスとして 169.254.20.10 が表示されています。
注: デプロイを自動化するには、起動テンプレートの userdata セクションで kubelet の設定を変更します。詳細については、「AL2023 Amazon EKS ノードでカスタムユーザーデータを使用する方法を教えてください」を参照してください。
NodeLocalDNS が正しくインストールされていることを確認する
NodeLocalDNS が正しく動作していることを確認するには、次の手順を実行します。
-
テストポッドを作成するには、以下のコマンドを実行します。
kubectl run test-dns --image=busybox:1.28 --restart=Never --rm -it -- nslookup kubernetes.default -
NodeLocalDNS ポッドのステータスが CrashLoopBackOff で、ポート 53 がすでに使用されていることを示すエラーが表示されている場合、出力を確認して、DNS クエリが正しく解決されたことを確認します。
-
DNS クエリが NodeLocalDNS を使用していることを確認するには、次のコマンドを実行します。
kubectl logs -n kube-system -l k8s-app=node-local-dns --tail=50ログには、NodeLocalDNS によって処理されている DNS クエリが表示されます。
注: デフォルトでは、NodeLocalDNS のログ記録は有効になっていません。ログを表示するには、node-local-dns ConfigMap でログ記録を有効にしてください。
# kubectl edit configmaps -n kube-system node-local-dns apiVersion: v1 kind: ConfigMap metadata: name: node-local-dns namespace: kube-system data: Corefile: | cluster.local:53 { log # Enable logging errors cache 30 ... }
NodeLocalDNS に関する問題のトラブルシューティング
注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI のエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。
ポートの競合による CrashLoopBackOff エラーを解決する
NodeLocalDNS ポッドがポート 53 のエラーで CrashLoopBackOff になった場合、これは Amazon EKS 自動モードのノードがポート 53 を予約しているために発生します。この問題を解決するには、次のいずれかの手法を選択します。
方法 1: 自動モードのノードを除外するノードアフィニティルールを追加する
次の手順を実行します。
-
NodeLocalDNS DaemonSet を編集します。
kubectl edit daemonset node-local-dns -n kube-system -
spec.template.spec の下に次のアフィニティ設定を追加します。
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: eks.amazonaws.com/compute-type operator: NotIn values: - auto -
変更を保存し、ポッドが正常に再起動したことを確認します。
方法 2: NodeLocalDNS ConfigMap を変更してヘルスチェックポートを変更する
次の手順を実行します。
-
現在の NodeLocalDNS ConfigMap を表示するには、以下のコマンドを実行します。
kubectl get configmap node-local-dns -n kube-system -o yaml -
ConfigMap を編集してヘルスチェックポートを変更するには、次のコマンドを実行します。
kubectl edit configmap node-local-dns -n kube-system -
ConfigMap で、ヘルスプラグインの設定を見つけてポートを変更します。ConfigMap の構造は次のようになっています。
apiVersion: v1 kind: ConfigMap metadata: name: node-local-dns namespace: kube-system data: Corefile: | cluster.local:53 { errors cache { success 9984 30 denial 9984 5 } reload loop bind IP_ADDRESS forward. __PILLAR__CLUSTER__DNS__ { force_tcp } prometheus :9253 health 169.254.20.10:8081 }注: health 行のポートを 8081 から目的のポートに置き換えてください。クラスターのリンクローカル IP アドレスが異なる場合は、169.254.20.10 を実際のリンクローカル IP に置き換えてください。
-
変更を保存します。
-
NodeLocalDNS ポッドを再起動するには、以下のコマンドを実行します。
kubectl rollout restart daemonset node-local-dns -n kube-system -
新しいポートと一致するように DaemonSet のヘルスチェック設定を更新するには、次のコマンドを実行します。
kubectl edit daemonset node-local-dns -n kube-system -
livenessProbe セクションと readinessProbe セクションを見つけて、新しいヘルスチェックポートに一致するようにポートを更新してください。
DNS クエリのタイムアウトエラーを解決する
ポッドで DNS クエリタイムアウトが発生した場合は、セキュリティグループとネットワーク ACL がポート 53 で TCP および UDP トラフィックを許可していることを確認します。このトラフィックは、ポッド間通信に必要です。
次の手順を実行します。
-
ノードにアタッチされているセキュリティグループを特定するには、次の describe-instances AWS CLI コマンドを実行します。
aws ec2 describe-instances --filters "Name=tag:eks:cluster-name,Values=YOUR-CLUSTER-NAME" --query "Reservations[*].Instances[*].SecurityGroups[*].[GroupId,GroupName]" --output table注: YOUR-CLUSTER-NAME を実際の Amazon EKS クラスター名に置き換えてください。
-
Amazon EC2 コンソールを開きます。
-
ナビゲーションペインで [セキュリティグループ] を選択します。
-
このセクションの手順 1 で特定したセキュリティグループを選択します。
-
[インバウンドルール] タブを選択します。
-
ポッド CIDR 範囲からのポート 53 で TCP および UDP トラフィックを許可するルールが存在することを確認します。
注: ルールが存在しない場合は、[インバウンドのルールを編集] を選択します。次に、ソースをポッドの CIDR 範囲に設定して、ポート 53 に TCP と UDP のルールを追加します。
"Connection refused" エラーメッセージを解決する
ポッドが NodeLocalDNS を使用しようとしたときに "Connection refused" というエラーメッセージが表示される場合は、少なくとも 1 つの CoreDNS ポッドが実行中であることを確認してください。
CoreDNS ポッドのステータスを確認するには、次のコマンドを実行します。
kubectl get pods -n kube-system -l k8s-app=kube-dns
CoreDNS ポッドが実行されていない場合、またはポッドが失敗ステータスにある場合は、CoreDNS デプロイを再開します。デプロイを再起動するには、次のコマンドを実行します。
kubectl rollout restart deployment coredns -n kube-system
CoreDNS ポッドが動作していることを確認するには、次のコマンドを実行します。
kubectl get pods -n kube-system -l k8s-app=kube-dns -w
CoreDNS ポッドが実行された後、NodeLocalDNS DaemonSet を再起動するには、次のコマンドを実行します。
kubectl rollout restart daemonset node-local-dns -n kube-system
関連情報
Using CoreDNS for Service Discovery (サービス検出に CoreDNS を使用する)(Kubernetes ウェブサイト)
Run kube-proxy in IPVS Mode (IPVS モードで kube-proxy を実行する)(Kubernetes ウェブサイト)
- トピック
- Containers
- 言語
- 日本語
