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 を確認)