インフラ系SEの技術メモ

雑なエンジニアが低信頼性のメモを書いています。参考程度にとどめてください。

(Kubernetes)CoreDNSをサーバから使ってみたり

Kubernetesの世界ではCoreDNSと呼ばれる機構があり、コンテナはこのCoreDNSに名前解決を依頼することでサービスのIPを知らなくても通信が行えます。

そんなCoreDNSですが、実はコンテナの外(Node)からも利用できます。

環境情報

Kubernetes 1.23
Red Hat Enterprise Linux Server 7.9

PodからDNSを引く

こんな感じでNginxのPodに紐づくServiceがある場合

# kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
backend      ClusterIP   10.105.20.83    <none>        80/TCP    31h
frontend     ClusterIP   10.96.228.219   <none>        80/TCP    24h
# kubectl get pod
NAME       READY   STATUS    RESTARTS   AGE
backend    1/1     Running   0          31h
frontend   1/1     Running   0          31h

コンテナの中でcurlコマンドを打つとIPアドレスを入れずとも通信ができます。

# kubectl exec -it backend -- curl frontend.default.svc.cluster.local
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

NodeからDNSを引く

一方でNode上からService名を指定しても接続ができません。

# curl frontend.default.svc.cluster.local
curl: (6) Could not resolve host: frontend.default.svc.cluster.local; Unknown error

というのもそもそもServiceが名前解決できるのは以下のkube-dns(CoreDNS)がServiceを検出してIPを返してくれているから。

# kubectl get service -n kube-system
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   46d

確かにコンテナの中にはCoreDNSのIPがDNSのIPとして記載されています。

# kubectl exec -it backend -- cat /etc/resolv.conf
nameserver 10.96.0.10

というわけでNode上の/etc/resolv.confに同じように上記IPを追記すれば

# curl frontend.default.svc.cluster.local -v
* About to connect() to frontend.default.svc.cluster.local port 80 (#0)
*   Trying 10.96.228.219...
* Connected to frontend.default.svc.cluster.local (10.96.228.219) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: frontend.default.svc.cluster.local
> Accept: */*
>
< HTTP/1.1 200 OK
...

コンテナ同様に名前解決ができます。やったね。