1. Services & Endpoints
Serviceを作成すると、KubernetesはselectorにマッチするPodのIPリストを含むEndpointsオブジェクトを自動的に作成します。
# Service → Endpoints → Pods
kubectl get service my-app # 仮想IP (ClusterIP)
kubectl get endpoints my-app # リスト: 10.244.1.2:80, 10.244.1.3:80
kubectl describe endpoints my-app # 詳細
# Endpointsが空の場合 → selectorがPodラベルと一致しない
# デバッグ: selectorとPodラベルを比較
kubectl get svc my-app -o jsonpath='{.spec.selector}'
kubectl get pods --show-labels | grep app=my-app
2. CoreDNS設定
# CoreDNSはkube-systemでDeploymentとして実行
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get configmap coredns -n kube-system -o yaml
# デフォルトCorefile:
.:53 {
errors
health { lameduck 5s }
ready
kubernetes cluster.local in-addr.arpa ip6.arpa { # クラスタドメイン
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf # クラスタ外クエリをアップストリームに転送
cache 30
loop
reload
loadbalance
}
試験のポイント:CoreDNSトラブルシューティング手順:1) CoreDNS Podが実行中か確認、2) kube-system内のkube-dns Serviceを確認、3)
kubectl exec -it pod -- nslookup kubernetesでPod内からDNSテスト、4) Podの/etc/resolv.confがkube-dns ClusterIPを指しているか確認。
3. kube-proxyモード
| モード | メカニズム | パフォーマンス |
|---|---|---|
| iptables(デフォルト) | Linux iptablesルール、ランダムなPod選択 | 良好、O(n)ルール |
| IPVS | Linux IPVS(カーネル、ハッシュベース) | 大規模クラスタに最適 |
| userspace(非推奨) | ユーザースペースプロキシ | 低速、レガシー |
4. Headless Service
# Headless: clusterIP: None
# DNSはPod IPを直接返す(仮想IPなし)
apiVersion: v1
kind: Service
metadata:
name: mysql-headless
spec:
clusterIP: None
selector:
app: mysql
ports:
- port: 3306
# DNS動作:
# mysql-headless → 複数のAレコード(各Pod IPに1つ)
# mysql-0.mysql-headless → 特定のPod IP(StatefulSet)
5. DNSトラブルシューティングコマンド
# Pod内からDNSテスト
kubectl run dns-test --image=busybox --rm -it -- nslookup kubernetes
kubectl run dns-test --image=busybox --rm -it -- nslookup my-service.namespace
# Pod内のresolv.confを確認
kubectl exec -it my-pod -- cat /etc/resolv.conf
# 表示されるべき: nameserver 10.96.0.10 (kube-dns service IP)
# CoreDNSログの確認
kubectl logs -n kube-system -l k8s-app=kube-dns
# kube-dns Serviceの確認
kubectl get svc -n kube-system kube-dns
6. チートシート
| 問題 | 確認方法 |
|---|---|
| ServiceがPodに到達できない | kubectl get endpoints NAME |
| Endpointsが空 | ServiceセレクタとPodラベルの不一致 |
| PodがDNSを解決できない | /etc/resolv.conf + CoreDNS Pod状態 |
| StatefulSet Pod DNS | serviceNameと同名のHeadless Serviceが必要 |
7. 練習問題
Q1:Serviceを作成しましたがトラフィックがPodに到達しません。ServiceのEndpointsオブジェクトが「no endpoints」を表示しています。最も可能性の高い原因は?
- A) Serviceポートがコンテナポートと一致していない
- B) Serviceセレクタのラベルがpodラベルと一致していない ✓
- C) NetworkPolicyがトラフィックをブロックしている
- D) Podが別のクラスタにある
解説:Endpointsが空はServiceがマッチするPodを見つけられないことを意味します。ラベルセレクタの不一致が原因です。確認方法: kubectl get svc myapp -o jsonpath='{.spec.selector}'とkubectl get pods --show-labelsを比較。
Q2:「frontend」Namespaceで実行中のPodが「backend」Namespaceの「payments」Serviceに到達する必要があります。正しいDNS名は?
- A) payments
- B) payments.backend
- C) payments.backend.svc.cluster.local ✓
- D) backend.payments.cluster.local
解説:異なるNamespace間のDNSは完全なNamespaceの指定が必要です: {service}.{namespace}.svc.cluster.local。短縮名は同じNamespace内でのみ有効です。BとCの両方が機能しますが、Cが最も明示的で信頼性の高い形式です。
Q3:CoreDNSが応答していません。診断手順として適切なのは?
- A) クラスタ全体を再起動する
- B) CoreDNS Podの実行確認、kube-dns ServiceのClusterIP確認、Pod内からnslookupでテスト ✓
- C) kube-proxyを再インストールする
- D) kube-system Namespaceを再作成する
解説:体系的なDNSデバッグ:(1) kubectl get pods -n kube-system -l k8s-app=kube-dns、(2) kube-dns ServiceにClusterIPがあるか確認、(3) Podの/etc/resolv.confがそのIPを指しているか確認、(4) テストPodからnslookupを実行。