KubernetesでPodから外部DNSを参照して名前解決する

KubernetesでPodからクラスター外部のサーバーへアクセスしたいことがあると思います。

しかし、初期設定の状態ではPod内から名前解決ができず、外部サーバーへホスト名でアクセスすることができず、困っている方も多いのでは無いでしょうか。私はめちゃくちゃ困りました。そもそもCoreDNSに関する日本語記事がほとんどなく、公式ドキュメントを見てもあまりピンと来ず・・・

散々調べた挙句、ちょっと設定するだけですぐに解決できることが判明したため、記録として残しておきます。

バージョン1.13で動作確認しています。

やりたいこと

Kubernetesの初期設定だと、コンテナ内からnslookupしても外部のホスト名は解決できません。

適当なPodを作って確認してみます。

kubectl create -f https://k8s.io/examples/admin/dns/busybox.yaml
kubectl get po

kubectl exec busybox -- nslookup k8s.io
Server:    10.32.0.10
Address 1: 10.32.0.10

nslookup: can't resolve 'k8s.io'

名前解決できない状態です。

これを解決できるようにするのが本記事の目的です。

Pod内から外部DNSを参照する設定手順

ConfigMapの編集

Kubernetes 1.13のデフォルトでは、DNSとしてCoreDNSが採用されています。設定ファイルであるCorefileを編集します。

kubectl edit configmap coredns -n kube-system

viなどのエディターが開きます。以下のような設定になっているかと思います。

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           upstream
           fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        proxy . /etc/resolv.conf
        cache 30
        loop
        reload
        loadbalance
    }

(snipped)

これを以下のように変更します。とりあえず誰でも使えるDNSということで8.8.8.8を指定しましたが、各自の環境に合わせて読み替えてください。

apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           upstream 8.8.8.8
           fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        proxy . 8.8.8.8
        cache 30
        loop
        reload
        loadbalance
    }

ConfigMapは、設定ファイルのような簡単かつ変更が発生しやすいテキストファイルを管理するためのリソースです。

こういったファイルをコンテナに入れた状態で編集してもPod再起動で跡形もなく消えてしまうため、ConfigMapに外出ししておいてPod作成時にマウントするようにします。

また、ConfigMapの変更は定期的にPod側へ反映されます。

ConfigMapの反映

数分待つと、Pod内のCorefileがConfigMapで先ほど設定した内容に置き換わります。大体2〜3分ぐらいですかね。

反映されているか気になってしょうがない場合は素直にPodを再起動しましょう。

echo $(kubectl get pods -o=name -n -kube-system | grep coredns) | while read line
do
kubectl delete $line -n kube-system
done

動作確認

最初に立てたPodを使って動作確認します。

kubectl exec busybox -- nslookup k8s.io

Server:    10.32.0.10
Address 1: 10.32.0.10 kube-dns.kube-system.svc.cluster.local

Name:      k8s.io
Address 1: 23.236.58.218 218.58.236.23.bc.googleusercontent.com

こんな感じで応答があればOKです。

まとめ

KubernetesでPodからクラスター外部サーバーの名前解決するには、CoreDNSが参照しているCorefileを外部DNSへ転送するように修正すれば良いです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です