Kubernetesの監査ログがどこに保存されるかは、制御プレーンを運用するのが誰であるかによって異なります。自己管理型クラスターでは、それらは制御プレーンノードのJSONラインファイルとして–audit-log-pathが指すパスに保存されます。EKSでは、CloudWatch Logsに保存され、AKSではLog Analyticsワークスペースやストレージアカウントに保存され、GKEではCloud Audit Logsに保存されます。どこでも共通しているのは:監査ログを有効にする必要があるということです。自己管理型クラスターやEKSでは、誰かが有効化するまでオフになっています。
監査ログは、Kubernetes APIへのすべてのリクエストを記録します:どのポッドでkubectl execを実行したか、どの秘密を読んだか、自分をどのクラスター管理者にバインドしたか。Prime Coreには、220のMITRE ATT&CKテクニックに対応する93のKubernetes監査データ用検出ルールがあります。その中には、実行中のコンテナへのexec(T1609)、不正コンテナのデプロイ(T1610)、コンテナAPIを介した資格情報の読み取り(T1552.007)があります。
始める前に
有効になっているか?
| プラットフォーム | 確認場所 |
|---|---|
| 自己管理 (kubeadmおよび類似のもの) | APIサーバー上の–audit-policy-fileと–audit-log-path;kubeadmの場合、/etc/kubernetes/manifests/kube-apiserver.yaml |
| EKS | クラスター → 観測性 → 制御プレーンのロギング、「監査」ログタイプ |
| AKS | クラスターの診断設定、カテゴリーkube-auditまたはkube-audit-admin |
| GKE | 管理者アクティビティにはデフォルトでオン;Kubernetesのデータアクセスログはオプトイン |
オンになっていなかった場合、過去のデータをエクスポートできず、このガイドの残りは次回のためのものです。
詳細はポリシーによります。 メタデータレベルでは誰がどのオブジェクトに何をしたかがわかります。リクエストまたはリクエストレスポンスレベルでは、例えば特権:trueを要求するポッドスペックのようなボディも見えます。確認を始める前にどちらかを知っておく必要があります。
ボリュームを想定してください。 コントローラやサービスアカウントはAPIを常に操作します。AKSでは、kube-audit-adminはリードオンリーのgetとlistの呼び出しを除外し、サイズを適切に保ちながら、秘密の読み取りも隠します。
エクスポートする
自己管理クラスタ, 制御プレーンノードで:
# まずパスを確認する
sudo grep -- '--audit-log-path' /etc/kubernetes/manifests/kube-apiserver.yaml
sudo cat /var/log/kubernetes/audit/audit.log > k8s_audit.jsonl
回転ファイル(–audit-log-maxbackupから)は、タイムスタンプの付いた名前で隣に配置されます。ウィンドウが及ぶ場合、それらも含めてください。
EKS, CloudWatch Logsから:
aws logs filter-log-events --log-group-name /aws/eks/my-cluster/cluster
--log-stream-name-prefix kube-apiserver-audit
--start-time $(date -d '2026-10-19T00:00:00Z' +%s000) --end-time $(date -d '2026-10-20T00:00:00Z' +%s000)
--output json | jq -c '.events[].message | fromjson' > eks_audit_1019.jsonl
各CloudWatchイベントは監査エントリを文字列としてラップしています;fromjsonでアンラップします。date -dの構文はGNUです;macOSでは、他の方法でミリ秒タイムスタンプを計算します。
AKS, Log Analyticsから(リソース固有のテーブル):
az monitor log-analytics query -w
--analytics-query "AKSAuditAdmin | where TimeGenerated between (datetime(2026-10-19) .. datetime(2026-10-20))"
--output json > aks_audit_1019.json
GKE, Cloud Audit Logsから:
gcloud logging read 'resource.type="k8s_cluster" AND logName:"cloudaudit.googleapis.com" AND timestamp>="2026-10-19T00:00:00Z" AND timestamp<"2026-10-20T00:00:00Z"'
--project=my-project --format=json | jq -c '.[]' > gke_audit_1019.jsonl
何を探すべきか
| リクエスト | なぜそれが重要なのか |
|---|---|
| pods/execへのcreate(objectRef.subresource: exec) | 誰かが動作中のコンテナ内でシェルを開いた |
| ClusterRoleBindingをcluster-adminに対するcreate | 完全な制御に対する権限昇格 |
| 不審なIDによるsecretsに対するgetまたはlist | 資格情報の収集 |
| privileged、hostPathまたはhostNetworkを指定して作成されたポッド | ノード上での脱出を目指すステップ |
| 2xx応答を受けたsystem:anonymousのuser.username | 機能すべきでない匿名アクセス |
| 一つのサービスアカウントからの403の急増 | 権限を確認している盗まれたトークン |
LogTotalにアップロードし、サニタイズし、レビューする
- アップロード。 開く logtotal.com そして.jsonlファイルをドロップしてください。
- サニタイズ。 [what gets masked: usernames, service account names, source IPs, namespaces, object names]. Look it over before you continue.
- レビュー。
問題が起きたとき
| 症状 | 考えられる原因 | Fix |
|---|---|---|
| 制御プレーンに監査ファイルなし | APIサーバーの監査ポリシーが未設定 | 期待通り;未来のために設定する |
| EKSのロググループや監査ストリームが欠如している | 「監査」制御プレーンのログタイプが有効になっていない | 未来のために有効にする |
| 各行は一つの長いエスケープされた文字列 | CloudWatchのラッピング | 上記のようにfromjsonでアンラップする |
| ポッドを誰が変更したかは見えるが、どのようにかは不明 | ポリシーはメタデータレベル | 機微なリソースに対してレベルを上げる |
| AKSデータに秘密の読み取りはなし | kube-audit-adminがgetとlistを除外している | 必要ならkube-auditを収集する |
FAQ
コンテナログだけでは十分ではないのか?
いいえ。コンテナログはアプリケーションが出力したものを示します。監査ログは、人やサービスアカウントがクラスターに行ったことを示します。異なる質問、異なるログ。
管理クラスタで監査ファイルを読むことはできるのか?
いいえ。EKS、AKS、GKEでは、制御プレーンノードへのアクセスは得られません。プロバイダーのログサービスが唯一のルートです。