Chuyển đến nội dung chính

レッスン6: Services、Endpoints & CoreDNS

Serviceタイプの詳細、Endpointsオブジェクト、kube-proxyモード。CoreDNSの 設定とDNSトラブルシューティング。ExternalName、Headless Service。

CoreDNS、kube-proxyとKubernetesサービスディスカバリー

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)ルール
IPVSLinux 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 DNSserviceNameと同名の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を実行。