がじぇ

お金と家電とプログラミングのブログ

クラスタ起動時に立ち上がるkube-dnsは何をしているか?

こんにちわ

がじぇったー (@hackmylife7) | Twitter


です。

順番めちゃくちゃなんですが勉強する必要がでてきた
Kubernetesクラスタ内のDNSについてまとめていきます。




f:id:gadgeterkun:20190629150041p:plain

TL;DR(要約)

  • kube-dnsクラスタ内に内蔵されているDNSサーバ
  • Master NodeのネームスペースKube-system上にPodとして立ち上がる
  • 各コンテナの名前解決の設定はkubeletによりresolve.confに設定される

kube-dnsとは?

  • kube-dnsクラスタ内に内蔵されているDNSサーバ
    • クラスタ内の個々のコンテナが名前解決できるようkubelet経由でDNSの設定を行う
  • kube-dnsはデフォルトで立ち上がるネームスペース(Default、Kube-system、Kube-public※1)のKube-systemにPodとして立ち上がる
  • kube-dnsのPodは以下の3つのコンテナを含む
    • kube-dns
    • Dnsmasq-nanny
    • sidecar container: podへのhealth checkで使われる
  • 名前解決される側の各PodのDNS設定はkubeletによって行われる
  • そのDNSサーバのIPアドレスはkube-dnsが持つCluster IPが割り当てられる

※注1:
Kube-system: Namespace for objects/resources created by Kubernetes systems
The Why and How of Kubernetes Namespaces - DZone Cloud

クラスタ起動時のDNSまわりの動き

  • 全てのNode上で動いているkubeletが各コンテナのresolve.confにkube-dnsのアドレスとドメインを登録する
    • default: "10.96.0.10"
    • default: "cluster.local"
  • Master Node上で動くkube-apiserverのresolve.confにはdefault "10.96.0.0/12"が割り当てられる
  • kubeadmのoptionを変えればIPレンジ、ドメインの変更を行うことができる

dnsPolicy: ClusterFirst

  • defaultの設定
  • Masterノードで動いているDNSのServiceを使う
    • クライアントPodのresolv.confには、Podの名前空間クラスタのデフォルトドメインが記載される
    • 例えば他のネームスペースで実行されているPodは、ネームスペース "development"で動いているService "test"を"test.development"のqueryを発行することにより見つけることができる

Podが立ち上がる名前空間が"default"だった場合、resolve.confには以下がkubeletにより書き込まれる


$ kubectl exec test-pod-- cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local ap-northeast-1.compute.internal
options ndots:5
$

dnsPolicy: Default Pod Configuration

  • 設定名は"Default"がついているが、デフォルトの設定は上述した"ClusterFirst"である
  • 稼働しているNode自体のDNS設定を継承する
  • 各Nodeに設定されているPrimaryのネームサーバに名前解決しにいく

Serviceが作られた際のDNS周りのの挙動

Service: hogeが作られるケースを例に考える

  1. kubectlコマンドでService "Name: hoge"を作成
  2. kube-apiserver経由で"Service: hoge"が作成され、情報がetcdに書き込まれる(ここで"Service: hoge"にクラスタ内で使われるVIPが割り当てられる)
  3. kube-dnsは"Service: hoge"が作成されたことを検知し、"hoge"への問い合わせにIPアドレスを返せるよう準備する
    1. "hoge.default.svc.cluster.local. IN A 192.168.104.10"
  4. kube-proxyは"Service:hoge"に割り当てたIP: Port番号への通信をPodに転送するよ う、iptablesに設定を加える

最終的にクラスタ内のPodは"Name: hoge"に以下のように問い合わせることができる

f:id:gadgeterkun:20190629200903j:plain

外部のネームサーバへアクセス(名前解決)をしにいく場合

  • クラスタ内に加え、外部のサーバにも追加で名前解決の設定をする場合、ConfigMapを使って設定情報を追加する

apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-dns
  namespace: kube-system
data:
  upstreamNameservers: |
    ["8.8.8.8", "8.8.4.4"]

挙動としてはまずlocalの名前解決をしにいき、それがマッチしなかったら upstreamNameserversに設定したDNS Serverへ名前解決をしにいく
("8.8.8.8", "8.8.4.4"はGoogleのPublic DNSである)


f:id:gadgeterkun:20190629195041j:plain



参考(Kubernetesの最強参考書)

Kubernetes完全ガイド (impress top gear)

Kubernetes完全ガイド (impress top gear)


Kubernetesの他の記事へは下記の一覧から飛べるようにしているので参照ください。

gadgeterkun.hatenablog.com