コンテンツにスキップ

Top 10 Real-World Issues Faced in Kubernetes (EKS) — And How to Fix Them

チェック

  • [ ] 本文を確認した
  • [ ] 概要を確認した
  • [ ] タグを確認した
  • [ ] inbox/ 直下へ移行した

概要

EKS/Kubernetes の現場でよく起きる 10 個のトラブルと、その確認・対処方法を整理した記事。 CrashLoopBackOff、OOMKilled、ImagePullBackOff、Pending、DNS、Probe、HPA、PVC Pending、TLS 証明書、Evicted Pod が扱われる。 基本的な kubectl describekubectl logs、イベント確認、リソース制限、StorageClass、metrics-server、CoreDNS などを押さえるためのトラブルシュートメモとして使える。

本文

Kubernetes の本番運用では、Pod が起動しない、再起動する、スケールしない、通信できない、ストレージが割り当たらない、といった問題が頻繁に起きる。 記事は、EKS を前提にしつつ、Kubernetes 全般で使える調査観点を 10 個に分けて紹介している。

1. CrashLoopBackOff

CrashLoopBackOff は、コンテナが起動してすぐ終了し、Kubernetes が再起動を繰り返している状態。 アプリケーションの起動失敗、設定ミス、環境変数不足、依存サービスへの接続失敗、権限不足などが原因になる。

最初に見るコマンドは次の通り。

kubectl describe pod <pod-name>
kubectl logs <pod-name>
kubectl logs <pod-name> --previous

describe では Events、Restart Count、Last State、Exit Code を見る。 logs --previous は前回落ちたコンテナのログを見るために重要。

対処は、ログに出ているアプリケーションエラーを直すことが中心。 ConfigMap/Secret の参照漏れ、DB 接続情報、起動コマンド、イメージ内のファイルパス、マイグレーション失敗などを確認する。

2. OOMKilled

OOMKilled は、コンテナがメモリ制限を超え、カーネルに kill された状態。 kubectl describe podReason: OOMKilled や exit code 137 を確認する。

kubectl describe pod <pod-name>
kubectl top pod <pod-name>

対処としては、メモリリークや大きすぎるバッファなどアプリケーション側の問題を調べる。 同時に、requests/limits が実態に合っているか確認する。

resources:
  requests:
    memory: "512Mi"
    cpu: "250m"
  limits:
    memory: "1Gi"
    cpu: "500m"

Prometheus/Grafana でメモリ使用量の推移を見て、ピーク時の実測から設定する。 単に limit を大きくするだけでは、ノード全体のメモリ圧迫やコスト増につながる。

3. ImagePullBackOff / ErrImagePull

ImagePullBackOffErrImagePull は、Pod がコンテナイメージを取得できない状態。 イメージ名、タグ、レジストリ認証、ネットワーク、ECR 権限などが原因になる。

kubectl describe pod <pod-name>

Events に、image not found、unauthorized、manifest unknown、pull access denied などが出る。

対処は次の観点。

  • image repository と tag が正しいか。
  • private registry の imagePullSecret が設定されているか。
  • ServiceAccount に image pull secret が紐づいているか。
  • EKS で ECR を使う場合、node IAM role や ECR credential provider が正しく動いているか。
  • image が multi-arch で、node architecture と合っているか。

4. Pod が Pending のまま

Pod が Pending から進まない場合、スケジューリングできていない可能性が高い。

kubectl describe pod <pod-name>

Events に Insufficient cpuInsufficient memory、taint/toleration 不一致、node selector 不一致、affinity 条件不一致などが出る。

確認観点は次の通り。

  • Pod の requests が大きすぎないか。
  • ノードに十分な CPU/Memory があるか。
  • nodeSelector、nodeAffinity、podAffinity が厳しすぎないか。
  • taints に対する tolerations があるか。
  • Cluster Autoscaler が動いているか。

EKS では、Managed Node Group や Karpenter/Cluster Autoscaler の設定も確認対象になる。

5. DNS 解決問題

Pod から Service 名や外部ドメインが解決できない場合、CoreDNS、NetworkPolicy、VPC DNS、NodeLocal DNSCache などを確認する。

kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system deployment/coredns

Pod 内から確認する。

kubectl exec -it <pod-name> -- nslookup kubernetes.default
kubectl exec -it <pod-name> -- nslookup example.com

CoreDNS が落ちている、メモリ不足、設定ミス、NetworkPolicy で kube-dns への通信が遮断されている、といった原因がある。 EKS では VPC の DNS hostnames / DNS resolution 設定も確認する。

6. Liveness / Readiness Probe 失敗

Probe が失敗すると、liveness ではコンテナ再起動、readiness では Service の endpoint から外れる。 設定が厳しすぎると、アプリケーション自体は動いているのに再起動や切り離しが起きる。

確認する項目は次の通り。

  • path や port が正しいか。
  • アプリケーションが起動する前に probe が始まっていないか。
  • initialDelaySecondsperiodSecondstimeoutSecondsfailureThreshold が妥当か。
  • health endpoint が DB など外部依存に引きずられすぎていないか。

Pod 内または同一 namespace から curl して確認する。

kubectl exec -it <pod-name> -- curl -v http://localhost:8080/healthz

起動に時間がかかるアプリには startupProbe を使うと、liveness が早すぎて kill する問題を避けやすい。

7. HPA / Autoscaling が効かない

Horizontal Pod Autoscaler が期待どおり動かない場合、metrics-server、対象 Deployment、resource requests、メトリクス取得を確認する。

kubectl get hpa
kubectl describe hpa <hpa-name>
kubectl top pods
kubectl top nodes

HPA は CPU 使用率の percentage を計算するために、container の CPU requests が必要。 requests がないと、CPU 使用率ベースの HPA が計算できない。

EKS では metrics-server が入っているか、IAM や API aggregation 周りで問題がないかも確認する。 カスタムメトリクスや外部メトリクスを使う場合は、Prometheus Adapter や KEDA の設定も見る。

8. PVC Pending

PVC が Pending のままになる場合、StorageClass、provisioner、容量、AZ、権限を確認する。

kubectl get pvc
kubectl describe pvc <pvc-name>
kubectl get storageclass

EKS では EBS CSI Driver が必要になる。 StorageClass の provisioner が正しいか、IRSA/IAM 権限があるか、対象 AZ に volume を作れるかを見る。

StatefulSet と EBS の場合、Pod がスケジュールされる AZ と volume の AZ が合わないと attach できない。 volumeBindingMode: WaitForFirstConsumer を使うと、Pod のスケジューリングに合わせて volume を作りやすい。

9. TLS 証明書の期限切れ

EKS の control plane 証明書は AWS が管理するが、Ingress、アプリケーション、独自 webhook、service mesh、外部公開 endpoint の証明書は利用者側の管理になる。

期限確認には openssl が使える。

openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -dates

対処としては、cert-manager、ACM、ExternalDNS、Ingress Controller の連携を整える。 証明書更新が自動化されているか、更新失敗時に通知されるかを確認する。

10. Node pressure による Evicted Pod

Pod が Evicted になる場合、ノードの memory pressure、disk pressure、PID pressure などが原因。

kubectl describe pod <pod-name>
kubectl describe node <node-name>
kubectl get events --sort-by=.lastTimestamp

対処は、不要 image や log の削除、resource requests/limits の調整、ノードサイズの見直し、Cluster Autoscaler/Karpenter の設定、Pod の分散配置。

ephemeral storage の requests/limits を設定していないと、ログや一時ファイルが node disk を圧迫することがある。

resources:
  requests:
    ephemeral-storage: "1Gi"
  limits:
    ephemeral-storage: "2Gi"

要点

  • Kubernetes トラブルの初動は kubectl describekubectl logs、Events、Exit Code。
  • CrashLoopBackOff は起動失敗、設定ミス、依存サービス、コマンド不備を疑う。
  • OOMKilled は memory limit 超過。アプリ調査と requests/limits の見直しが必要。
  • Pending は scheduler が置けない状態。resources、taints、affinity、autoscaler を見る。
  • DNS は CoreDNS、NetworkPolicy、VPC DNS を確認する。
  • HPA には metrics-server と resource requests が必要。
  • PVC Pending は StorageClass、CSI driver、AZ、IAM を見る。
  • Evicted Pod は node pressure と ephemeral storage を疑う。

タグ

kubernetes #eks #troubleshooting #sre #operations