※当ブログではアフィリエイト広告を利用しています
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へ転送するように修正すれば良いです。
typo?
NG) kubectl get pods -o=name -n -kube-system | grep coredns
OK) kubectl get pods -o=name -n kube-system | grep coredns
thanks I fixed