# DNS解決のデバッグ

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->
このページでは、DNSの問題を診断するためのヒントを提供します。

## 始める前に

<p>Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。
このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。
まだクラスターがない場合、<a href="https://minikube.sigs.k8s.io/docs/tutorials/multi_node/">minikube</a>を使って作成するか、
以下のいずれかのKubernetesプレイグラウンドも使用できます:</p>
<ul>
<li><a href="https://labs.iximiuz.com/playgrounds?category=kubernetes&filter=all">iximiuz Labs</a></li>
<li><a href="https://killercoda.com/playgrounds/scenario/kubernetes">Killercoda</a></li>
<li><a href="https://kodekloud.com/public-playgrounds">KodeKloud</a></li>
</ul>
  
クラスターは、CoreDNS<a class='glossary-tooltip' title='Kubernetesの機能を拡張するリソース。' data-bs-toggle='tooltip' data-bs-placement='top' href='/ja/docs/concepts/cluster-administration/addons/' target='_blank' aria-label='アドオン'>アドオン</a>またはその前身であるkube-dnsを使用するように設定されている必要があります。



作業するKubernetesサーバーは次のバージョン以降のものである必要があります: v1.6.
 <p>バージョンを確認するには次のコマンドを実行してください:  <code>kubectl version</code>.</p>


<!-- steps -->

### テスト環境として使用するシンプルなPodを作成する {#create-a-simple-pod-to-use-as-a-test-environment}























<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/admin/dns/dnsutils.yaml" download="admin/dns/dnsutils.yaml"><code>admin/dns/dnsutils.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('admin-dns-dnsutils-yaml')" title="admin/dns/dnsutils.yamlをクリップボードにコピー"></img></div>
    <div class="includecode" id="admin-dns-dnsutils-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Pod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">dnsutils</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l">default</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">dnsutils</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">registry.k8s.io/e2e-test-images/agnhost:2.39</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">imagePullPolicy</span><span class="p">:</span><span class="w"> </span><span class="l">IfNotPresent</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">restartPolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Always</span><span class="w">
</span></span></span></code></pre></div></div>
</div>


<div class="alert alert-info" role="note"><h4 class="alert-heading">備考:</h4>この例では、<code>default</code>名前空間内にPodを作成します。
Serviceに対するDNS名前解決は、Podの名前空間に依存します。
詳細については、<a href="/ja/docs/concepts/services-networking/dns-pod-service/#what-things-get-dns-names">ServiceとPodに対するDNS</a>を参照してください。</div>


このマニフェストを使用してPodを作成します:

```shell
kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
```
```
pod/dnsutils created
```
そして、ステータスを確認します:
```shell
kubectl get pods dnsutils
```
```
NAME       READY     STATUS    RESTARTS   AGE
dnsutils   1/1       Running   0          <some-time>
```

このPodが実行されたら、その環境で`nslookup`を実行できます。
以下のような結果が表示された場合、DNSは正常に動作しています。

```shell
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
```
```
Server:    10.0.0.10
Address 1: 10.0.0.10

Name:      kubernetes.default
Address 1: 10.0.0.1
```

`nslookup`コマンドが失敗した場合は、以下を確認してください:

### まずはローカルのDNS設定を確認する {#check-the-local-dns-configuration-first}

resolv.confファイルの内容を確認します。
(詳細については、[DNSサービスのカスタマイズ](/docs/tasks/administer-cluster/dns-custom-nameservers)および後述の[既知の問題](#known-issues)を参照してください)

```shell
kubectl exec -ti dnsutils -- cat /etc/resolv.conf
```

検索パスとネームサーバーが以下のように設定されていることを確認します。
(検索パスはクラウドプロバイダーによって異なる場合があることに注意してください):

```
search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
nameserver 10.0.0.10
options ndots:5
```

以下のようなエラーは、CoreDNS(またはkube-dns)アドオンまたは関連するServiceに問題があることを示しています:

```shell
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
```
```
Server:    10.0.0.10
Address 1: 10.0.0.10

nslookup: can't resolve 'kubernetes.default'
```

または、

```shell
kubectl exec -i -t dnsutils -- nslookup kubernetes.default
```
```
Server:    10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local

nslookup: can't resolve 'kubernetes.default'
```

### DNSのPodが実行されているか確認する {#check-if-the-dns-pod-is-running}

`kubectl get pods`コマンドを使用して、DNSのPodが実行されていることを確認します。

```shell
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
```
```
NAME                       READY     STATUS    RESTARTS   AGE
...
coredns-7b96bf9f76-5hsxb   1/1       Running   0           1h
coredns-7b96bf9f76-mvmmt   1/1       Running   0           1h
...
```


<div class="alert alert-info" role="note"><h4 class="alert-heading">備考:</h4>ラベル<code>k8s-app</code>の値は、CoreDNSとkube-dnsの両方のデプロイメントで<code>kube-dns</code>です。</div>


CoreDNSのPodが実行されていない、またはPodが失敗/完了している場合、現在の環境ではDNSアドオンがデフォルトでデプロイされていない可能性があり、手動でデプロイする必要があります。

### DNSのPodのエラーを確認する {#check-for-errors-in-the-dns-pod}

`kubectl logs`コマンドを使用して、DNSコンテナのログを確認します。

CoreDNSの場合:
```shell
kubectl logs --namespace=kube-system -l k8s-app=kube-dns
```

以下は正常なCoreDNSログの例です:
```
.:53
2018/08/15 14:37:17 [INFO] CoreDNS-1.2.2
2018/08/15 14:37:17 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.2
linux/amd64, go1.10.3, 2e322f6
2018/08/15 14:37:17 [INFO] plugin/reload: Running configuration MD5 = 24e6c59e83ce706f07bcc82c31b1ea1c
```

ログに疑わしいメッセージや予期しないメッセージがないか確認してください。

### DNSサービスは起動しているか {#is-dns-service-up}

`kubectl get service`コマンドを使用して、DNSサービスが起動していることを確認します。

```shell
kubectl get svc --namespace=kube-system
```
```
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
...
kube-dns     ClusterIP   10.0.0.10      <none>        53/UDP,53/TCP        1h
...
```


<div class="alert alert-info" role="note"><h4 class="alert-heading">備考:</h4>サービス名は、CoreDNSとkube-dnsの両方のデプロイメントで<code>kube-dns</code>です。</div>




Serviceを作成した場合、またはデフォルトで作成されるはずなのに表示されない場合、詳細については、[Serviceのデバッグ](/docs/tasks/debug/debug-application/debug-service/)を参照してください。

### DNSエンドポイントは公開されているか {#are-dns-endpoints-exposed}

`kubectl get endpointslice`コマンドを使用して、DNSエンドポイントが公開されていることを確認できます。

```shell
kubectl get endpointslice -l k8s.io/service-name=kube-dns --namespace=kube-system
```
```
NAME             ADDRESSTYPE   PORTS   ENDPOINTS                  AGE
kube-dns-zxoja   IPv4          53      10.180.3.17,10.180.3.17    1h
```

エンドポイントが表示されない場合は、[Serviceのデバッグ](/docs/tasks/debug/debug-application/debug-service/)ドキュメントのエンドポイントセクションを参照してください。

### DNSクエリは受信/処理されているか {#are-dns-queries-being-received-processed}

CoreDNS設定(別名: Corefile)に`log`プラグインを追加することで、クエリが受信されているかどうかを確認できます。
CoreDNSのCorefileは、`coredns`という名前の<a class='glossary-tooltip' title='機密性のないデータをキーと値のペアで保存するために使用されるAPIオブジェクトです。環境変数、コマンドライン引数、またはボリューム内の設定ファイルとして使用できます。' data-bs-toggle='tooltip' data-bs-placement='top' href='/ja/docs/concepts/configuration/configmap/' target='_blank' aria-label='ConfigMap'>ConfigMap</a>に保持されています。
編集するには、次のコマンドを使用します:

```
kubectl -n kube-system edit configmap coredns
```

次に、以下の例に従ってCorefileセクションに`log`を追加します:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        log
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          upstream
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }
```

変更を保存した後、Kubernetesがこれらの変更をCoreDNSのPodに伝播するまでに最大1〜2分かかる場合があります。

次に、いくつかのクエリを実行し、このドキュメントの上記のセクションに従ってログを確認します。
CoreDNSのPodがクエリを受信している場合、ログにそれらが表示されるはずです。

以下はログ内のクエリの例です:

```
.:53
2018/08/15 14:37:15 [INFO] CoreDNS-1.2.0
2018/08/15 14:37:15 [INFO] linux/amd64, go1.10.3, 2e322f6
CoreDNS-1.2.0
linux/amd64, go1.10.3, 2e322f6
2018/09/07 15:29:04 [INFO] plugin/reload: Running configuration MD5 = 162475cdf272d8aa601e6fe67a6ad42f
2018/09/07 15:29:04 [INFO] Reloading complete
172.17.0.18:41675 - [07/Sep/2018:15:29:11 +0000] 59925 "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd,ra 106 0.000066649s
```

### CoreDNSに十分な権限があるか {#does-coredns-have-sufficient-permissions}

CoreDNSは、サービス名を適切に解決するために、<a class='glossary-tooltip' title='Podの集合で実行されているアプリケーションをネットワークサービスとして公開する方法。' data-bs-toggle='tooltip' data-bs-placement='top' href='/ja/docs/concepts/services-networking/service/' target='_blank' aria-label='Service'>Service</a>および<a class='glossary-tooltip' title='EndpointSliceはServiceに対応するPodのIPアドレスを追跡します。' data-bs-toggle='tooltip' data-bs-placement='top' href='/ja/docs/concepts/services-networking/endpoint-slices/' target='_blank' aria-label='EndpointSlice'>EndpointSlice</a>関連のリソースをリストできる必要があります。

エラーメッセージの例:
```
2022-03-18T07:12:15.699431183Z [INFO] 10.96.144.227:52299 - 3686 "A IN serverproxy.contoso.net.cluster.local. udp 52 false 512" SERVFAIL qr,aa,rd 145 0.000091221s
```

まず、`system:coredns`の現在のClusterRoleを取得します:

```shell
kubectl describe clusterrole system:coredns -n kube-system
```

期待される出力:
```
PolicyRule:
  Resources                        Non-Resource URLs  Resource Names  Verbs
  ---------                        -----------------  --------------  -----
  endpoints                        []                 []              [list watch]
  namespaces                       []                 []              [list watch]
  pods                             []                 []              [list watch]
  services                         []                 []              [list watch]
  endpointslices.discovery.k8s.io  []                 []              [list watch]
```

権限が不足している場合は、ClusterRoleを編集して追加します:

```shell
kubectl edit clusterrole system:coredns -n kube-system
```

EndpointSlices権限の追加例:
```
...
- apiGroups:
  - discovery.k8s.io
  resources:
  - endpointslices
  verbs:
  - list
  - watch
...
```

### 正しい名前空間のServiceを指定しているか {#are-you-in-the-right-namespace-for-the-service}

名前空間を指定しないDNSクエリは、Podの名前空間に制限されます。

Podの名前空間とServiceの名前空間が異なる場合、DNSクエリにはServiceの名前空間を含める必要があります。

このクエリはPodの名前空間に制限されます:
```shell
kubectl exec -i -t dnsutils -- nslookup <service-name>
```

このクエリは名前空間を指定します:
```shell
kubectl exec -i -t dnsutils -- nslookup <service-name>.<namespace>
```

名前解決の詳細については、[ServiceとPodに対するDNS](/docs/concepts/services-networking/dns-pod-service/#what-things-get-dns-names)を参照してください。

## 既知の問題 {#known-issues}

一部のLinuxディストリビューション(Ubuntuなど)は、デフォルトでローカルDNSリゾルバー(systemd-resolved)を使用します。
systemd-resolvedは`/etc/resolv.conf`を移動してスタブファイルに置き換えるため、アップストリームサーバーで名前を解決する際に致命的な転送ループが発生する可能性があります。
これは、kubeletの`--resolv-conf`フラグを使用して正しい`resolv.conf`を指定することで手動で修正できます(`systemd-resolved`の場合、これは`/run/systemd/resolve/resolv.conf`です)。
kubeadmは`systemd-resolved`を自動的に検出し、それに応じてkubeletフラグを調整します。

Kubernetesのインストールにおいて、デフォルトではノードの`resolv.conf`ファイルはクラスターDNSを使用するようには設定されません。
このプロセスは本質的にディストリビューション固有であるためです。
これは最終的には実装される必要があるでしょう。

Linuxのlibc(別名: glibc)には、DNSの`nameserver`レコードに対してデフォルトで3つという制限があり、Kubernetesは1つの`nameserver`レコードを消費する必要があります。
つまり、ローカルインストールがすでに3つの`nameserver`を使用している場合、それらのエントリの一部が失われます。
この制限を回避するには、ノードで`dnsmasq`を実行することで、より多くの`nameserver`エントリを提供できます。
kubeletの`--resolv-conf`フラグを使用することもできます。

ベースイメージとして、バージョン3.17以前のAlpineを使用している場合、Alpineの設計上の問題によりDNSが正しく動作しない可能性があります。
muslバージョン1.24まで、DNSスタブリゾルバーへのTCPフォールバックが含まれていなかったため、512バイトを超えるDNS呼び出しは失敗していました。
バージョン3.18以降のAlpineイメージにアップグレードしてください。

## 次の項目

- [クラスター内のDNSサービスのオートスケール](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/)を参照してください。
- [ServiceとPodに対するDNS](/docs/concepts/services-networking/dns-pod-service/)を読んでください。
