導入
Kubernetes 環境下でシステム連携(Pod 間通信)を行った際に、名前解決で苦労したため、知識の整理をする目的で本記事を執筆します。
Kubernetes 環境下での名前解決
Namespace が異なる場合
Kubernetes では、異なる Namespace 間で通信を行う場合、FQDN を使用する必要があります。
例: service-name.namespace.svc.cluster.local
異なる Namespace の Service にアクセスする場合、以下のように指定することで名前解決が可能です。
curl http://my-service.my-namespace.svc.cluster.local:8080
同じ Namespace に属する場合
同じ Namespace 内であれば、Service 名のみで名前解決が可能です。
例:curl http://my-service:8080
Kubernetes の DNS は、まず同じ Namespace 内の Service を探索するため、短縮形でも解決されます。
Kubernetes の Service Discovery の仕組み
ClusterIP, NodePort, LoadBalancer, Ingress での名前解決の違い
ClusterIP(デフォルト)
クラスタ内でのみアクセス可能。
my-service.default.svc.cluster.local
で名前解決。
NodePort
各ノードの固定ポートで外部からアクセス可能。
http://<NodeIP>:<NodePort>
でアクセス。
LoadBalancer
クラウドプロバイダーのロードバランサを使用し、外部アクセスを提供。
パブリック IP を持ち、直接名前解決が可能。
Ingress
ドメインベースのルーティングを提供。
example.com
などのドメイン名でアクセス可能。
CoreDNS の仕組み
-
Kubernetes では、CoreDNS が DNS 解決を担当しています
- Service や Pod に対して svc.cluster.local 形式の DNS レコードを提供
- kube-dns や coredns の Pod がクラスタ内で稼働し、DNS クエリを処理
-
動いているか確認する
-
kubectl get pods -n kube-system | grep coredns
で CoreDNS の稼働確認が可能
-
nslookup, dig, kubectl exec でのデバッグ方法
名前解決の問題をデバッグする際は、以下の方法を試します。
-
nslookup コマンドで名前解決を確認
kubectl exec -it my-pod -- nslookup my-service.default.svc.cluster.local
-
dig コマンドで詳細な DNS 情報を取得
kubectl exec -it my-pod -- dig my-service.default.svc.cluster.local
-
kubectl exec を使用して Pod 内部から通信テスト
kubectl exec -it my-pod -- bash
curl http://my-service:8080