コンテンツにスキップ

Kubernetesで頻出するバグ3パターン:OOMKilled・DNS解決失敗・RBAC

概要

Kubernetes のデバッグで「この3パターンを先に疑え」というノウハウ。最初にこれを学ぶだけで何時間もの調査時間を節約できる。

詳細

1. OOMKilled:リソースリミットが低すぎる

# 症状
kubectl get pods
# NAME       READY   STATUS      RESTARTS
# my-app-x   0/1     OOMKilled   5

# 調査
kubectl describe pod my-app-x
# → "Reason: OOMKilled" を確認
# → "Last State: Terminated" の exitCode が 137

# 解決: limits を現実的な値に上げる
resources:
  requests:
    memory: "256Mi"
  limits:
    memory: "512Mi"   # ← 実際の使用量 + バッファ

落とし穴: requests を下げすぎると他の Pod と競合する。kubectl top pod で実際のメモリ使用量を確認してから設定する。

2. DNS 解決失敗:サービス間通信が切れる

# 症状: service A → service B の通信が失敗
# エラー: "dial tcp: lookup my-service on 10.96.0.10:53: no such host"

# 調査
kubectl exec -it debug-pod -- nslookup my-service
kubectl exec -it debug-pod -- nslookup my-service.my-namespace.svc.cluster.local

# CoreDNS のログ確認
kubectl logs -n kube-system -l k8s-app=kube-dns

# よくある原因と解決
# 1. 別 Namespace なのに FQDN を使っていない
#    → my-service.other-namespace.svc.cluster.local と記述
# 2. Service 名のタイポ
#    → kubectl get svc -A でサービス名を確認
# 3. CoreDNS Pod 自体が不健全
#    → kubectl rollout restart deployment coredns -n kube-system

3. RBAC:Service Account に権限がない

# 症状: Pod のログに "forbidden" エラー
# "User "system:serviceaccount:default:my-app" cannot list resource "pods""

# 調査: 実際に権限があるかテスト
kubectl auth can-i list pods --as=system:serviceaccount:default:my-app

# 解決: 必要な権限を持つ Role と RoleBinding を作成
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: default
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-binding
subjects:
- kind: ServiceAccount
  name: my-app
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

なぜ重要か / いつ使うか

  • K8s 環境で Pod が突然再起動するとき(まず OOMKilled を疑う)
  • マイクロサービス間の通信が突然切れたとき(DNS を疑う)
  • Pod が外部リソース(Secrets, ConfigMaps 等)にアクセスできないとき(RBAC を確認)