K8sログ管理の落とし穴:テスト環境でのFluentdログ肥大化とノード障害からの復旧
1. はじめに:なぜテスト環境でもログ管理が重要なのか
Kubernetesにおけるログの重要性、そしてテスト環境での見落としがちな側面を説明する。「テストだから大丈夫」という思い込みが招くリスクにも言及する。
2. 失敗の経緯:ローカルストレージとFluentdログ肥大化の悲劇
2.1. 環境構成の概要
- ログ収集ツール: Fluentd
- ストレージプロビジョナー: local-path-provisioner
- テスト内容: 長時間の負荷テストや特定のアプリケーションの動作確認など。
2.2. 問題発生のメカニズム
- ログローテーションの実装不足: Fluentdで収集したログのローテーション設定が不十分、または全くされていなかった。
-
ローカルストレージへのログ蓄積: Fluentdが収集したログが、
local-path-provisioner
によってプロビジョニングされたPV(ノードのローカルパス)に蓄積され続けた。 -
ノードストレージの満杯化: テストの進行とログの増大により、ノードのルートファイルシステム(
/
)が満杯になった。
2.3. 発現した具体的な症状
-
ImageGCFailed
: ノードのストレージ不足により、Kubernetesが新しいイメージのプルや不要なイメージのガベージコレクションを実行不能になった。 -
EvictionThresholdMet
: ノードのディスク使用率がしきい値を超え、kubeletが新しいPodのスケジューリングを拒否したり、既存のPodをエビクトしたりする状態になった。 - 新規Podデプロイの失敗: 容量不足のため、新しいPodが起動しなくなった。
3. 絶体絶命からの復旧:K8s内からの突破口
3.1. 直面した課題:SSHアクセス不可
テスト環境のため、セキュリティポリシーやネットワーク制限により、ノードに直接SSH接続できない状況だった。通常の復旧手順が使えないという制約があった。
3.2. K8sを駆使した解決策
- 容量不足Podのエビクト回避: 新規Podがエビクトされる状況下で、いかにしてシェルアクセス用のPodを起動するかを検討した。ノード上に既にキャッシュされている、より小さなサイズのコンテナイメージ(例: busybox)を使用してPodのデプロイを試みた。これにより、イメージプルによる容量消費を避け、最低限の容量でPodを起動できる可能性を高めた。
- PVコンテンツへのアクセス: 起動したシェルPodから、問題のローカルストレージPV(例: /opt/local-path-provisioner/pvc-*)をPodにマウントした。kubectl exec -it <pod-name> -- /bin/sh でシェルに入り、マウントされたパスに移動した。
- 原因の特定とログファイルの削除: df -h や du -sh (Pod内でこれらのコマンドが利用可能なイメージであれば)で、具体的にどのディレクトリが容量を圧迫しているかを確認した。大量のログファイルを特定し、rm コマンドで安全に削除した(例: find . -type f -name "*.log" -delete)。容量が確保されたことを確認した。
3.3. 復旧後の状況
ノードのストレージが解放され、EvictionThresholdMet
やImageGCFailed
の状態が解消された。新規Podのデプロイが可能になり、クラスタが正常な状態に復帰した。
4. 今後の対策:再発防止と堅牢なログ管理体制の構築
4.1. 外部ストレージの活用
- クラウドプロバイダー提供のストレージサービス: AWS EBS, Azure Disk, GCP Persistent Diskなど。ストレージの動的プロビジョニング、スナップショット、サイズ変更の容易さが利点となる。ノードのディスク使用率に依存しないため、根本的な解決策となる。
- NFS/Cephなどの共有ストレージ: 自前で構築する場合の選択肢。
4.2. Fluentd/Fluent Bitでのログローテーションの実装
-
Fluentd/Fluent Bitの設定によるローテーション:
file
出力プラグインのpath
、buffer_path
、chunk_limit_size
、rotate_wait
、flush_interval
などの設定を見直す。ログファイルのサイズや時間でローテーションし、古いログを自動削除する設定を導入する。 - 外部ツールとの連携: Fluentdから直接S3などのオブジェクトストレージに転送し、K8sノード上には一時的なログのみを保持する設計にする。
4.3. ログ監視とアラートの設定
ノードのディスク使用率を定期的に監視し、閾値を超えた場合にアラートを発報する仕組みを導入する。Prometheus + Grafanaなどの監視スタックを活用する。ログ基盤自体の健全性(取り込み遅延、エラーなど)も監視対象とする。
まとめ
テスト環境でもログ管理は手を抜かないことの重要性を強調する。ローカルストレージ利用時のリスクと、それを回避するための設計についても言及する。予期せぬ障害発生時でも、Kubernetesの特性を理解していれば復旧の道があることを伝える。恒久的な対策としての外部ストレージ利用と適切なログローテーションの導入を改めて推奨する。