監査ログ

このページでは、Google Kubernetes Engine クラスタで監査ロギングを使用する方法について説明します。

概要

Kubernetes 対応のすべてのクラスタでは Kubernetes Audit Logging を使用して、Kubernetes API サーバーに対して行われた呼び出しを時系列でログに記録します。Kubernetes 監査ログのエントリは、怪しい API リクエストの調査、統計情報の収集、不要な API 呼び出しに対するモニタリング アラートの作成に役立ちます。

GKE クラスタは Kubernetes Audit Logging を Cloud Audit Logging および Stackdriver Logging に統合します。Kubernetes 監査ログのエントリは、Google Cloud Platform プロジェクトで表示できます。

プロジェクトの監査ログには、Kubernetes により書き込まれたエントリに加えて、Kubernetes Engine により書き込まれたエントリがあります。

Audit Logging 一般提供は GKE 1.11.4 以降で使用できます。

始める前に

このタスクの準備として、次の手順を行います。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Google Kubernetes Engine API の有効化
  • Cloud SDK がインストール済みであることを確認します。
  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project [PROJECT_ID]
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone [COMPUTE_ZONE]
  • リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud を最新バージョンに更新します。
    gcloud components update

プロジェクトに Kubernetes Engine クラスタが必要です。既存のクラスタを使用することも、このトピックの演習用に新しいクラスタを作成することもできます。既存のクラスタを使用する場合は、クラスタに最近のアクティビティがあることを確認してください。たとえば、Deployment を最近作成していない場合は、次のコマンドを入力して Deployment を作成できます。

kubectl run log-exercise --image nginx

Kubernetes Audit Logging について調べます。

プロジェクトの監査ログ

GCP プロジェクトには、次の監査ログがあります。

  • 管理アクティビティ ログ
  • データアクセス ログ

管理アクティビティのロギングはデフォルトで有効になっており、追加料金は不要です。

データアクセスのロギングはデフォルトでは無効になっており、有効にすると追加料金が発生します。データアクセスのロギングを有効にする方法と関連する費用の詳細については、データアクセス ログの構成をご覧ください。

Kubernetes Engine はアクセスの透明性のロギングをサポートしていません。

さまざまな Google Cloud Platform サービスによって、プロジェクトのログにエントリが書き込まれます。Kubernetes サービスは、プロジェクトの監査ログにもエントリを書き込みます。Kubernetes Engine クラスタの場合、以下のサービスによって書き込まれたログエントリが最も重要です。

サービス 表示名
k8s.io Kubernetes
container.googleapis.com Kubernetes Engine

プロジェクトの管理アクティビティ ログの表示

Console

  1. GCP Console で、[ログ] ページの [ロギング] メニューに移動します。

    [ログ] ページに移動

  2. ページの上部で、リソースタイプを選択するためのプルダウン メニューを見つけます。プルダウン メニューで、[Kubernetes クラスタ] を選択します。

  3. 必要に応じて、[ロケーション] を指定するか、[すべてのロケーション] を選択します。ロケーションを選択すると、そのロケーションにある特定のクラスタを選択できます。

  4. 右側にある次のメニューは、ログを選択するためのメニューです。プルダウン メニューで、[アクティビティ] を選択して [OK] をクリックします。

  5. デフォルトでは、すべてのログレベルが表示されます。ログレベル(警告など)を指定するには、ログレベルのプルダウン メニューで選択します。

  6. 直近 1 時間のログエントリのみが表示されることがあります。1 時間前のログエントリが表示されない場合は、[古いログを読み込む] をクリックします。

  7. 上で説明したプルダウン メニューのすぐ上にある [ラベルまたはテキスト検索でフィルタ] ボックスで、下矢印をクリックしてプルダウン メニューを開きます。メニューで、[高度なフィルタに変換] を選択します。

  8. テキスト ボックスに次のようなフィルタが表示されます。

    resource.type="k8s_cluster"
    logName="projects/my-project/logs/cloudaudit.googleapis.com%2Factivity"
    
  9. 行の先頭にある矢印をクリックして、ログエントリの 1 つを開きます。エントリの logName フィールドの値は projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity です。

gcloud

プロジェクトの管理アクティビティ ログの最初の 2 つのログエントリを一覧表示します。

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"' \
    --limit 2 \
    --freshness 300d

ここで、[PROJECT_ID] はプロジェクト ID です。

出力には 2 つのログエントリが表示されます。各ログエントリの logName フィールドの値が projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity である点に注意してください。

insertId: 18yao5jem14og
labels:
  cluster_version: 1.8.8-gke.0
logName: projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity
...

基本および高度なフィルタ インターフェース

GCP Console では、[ログ] ページに基本と高度という 2 つのフィルタリング インターフェースがあります。2 つのフィルタリング インターフェースについて詳しくは、ログビューアのフィルタ インターフェースをご覧ください。

管理アクティビティ ログに書き込むサービスを表示する

Console

  1. GCP Console で、[ログ] ページの [ロギング] メニューに移動します。

    [ログ] ページに移動

  2. [ログ] ページが高度なモードでない場合は、高度なモードに切り替えます。フィルタ ボックスで、右側の下向き矢印をクリックして、[高度なフィルタに変換] を選択します。

  3. フィルタ ボックスで、既存のテキストを削除して、以下のフィルタを入力します。

    logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
    protoPayload.serviceName="k8s.io"
    

    ここで、[PROJECT_ID] はプロジェクト ID です。

    [フィルタを送信] をクリックします。

    管理アクティビティ ログに k8s.io サービスによって書き込まれたすべてのエントリが一覧表示されます。つまり、これらのエントリは Kubernetes コントロール プレーンによって書き込まれました。

  4. ここで、k8s.io 以外のサービスにより書き込まれたログエントリを探します。フィルタ ボックスで、serviceName="k8s.io"serviceName!="k8s.io" に変更します。[フィルタを送信] をクリックします。

    管理アクティビティ ログに k8s.io サービスによって書き込まれなかったログエントリが一覧表示されます。

  5. ログエントリの 1 つを開いて、protoPayload フィールドを展開します。serviceName の値を確認して、そのログエントリを書き込んだサービスを調べます。

  6. 次に、container.googleapis.com サービスによって書き込まれたログエントリを探します。つまり、これらのエントリは Kubernetes Engine コントロール プレーンによって書き込まれました。フィルタ ボックスで、serviceName!="k8s.io"serviceName="container.googleapis.com" に変更します。[フィルタを送信] をクリックします。

gcloud

プロジェクトの管理アクティビティ ログに k8s.io サービスによって書き込まれた最初の 2 つのログエントリを一覧表示します。つまり、これらのエントリは Kubernetes コントロール プレーンによって書き込まれました。

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
        AND protoPayload.serviceName="k8s.io"' \
    --limit 2 \
    --freshness 300d

ここで、[PROJECT_ID] はプロジェクト ID です。

出力で、protoPayload:serviceName の値が k8s.io であることがわかります。

protoPayload:
  ...
  serviceName: k8s.io

ここで、k8s.io 以外のサービスにより書き込まれたログエントリを探します。

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
        AND protoPayload.serviceName!="k8s.io"' \
    --limit 2 \
    --freshness 300d

出力には、管理アクティビティ ログに k8s.io サービスによって書き込まれなかったログエントリが一覧表示されます。

logName: projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity
...
protoPayload:
  ...
  serviceName: compute.googleapis.com
...

ログエントリの 1 つで、protoPayload.serviceName の値を見て、ログエントリを書き込んだサービスを確認します。

次に、container.googleapis.com サービスによって書き込まれたログエントリを探します。つまり、これらのエントリは Kubernetes Engine コントロール プレーンによって書き込まれました。

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
        AND protoPayload.serviceName="container.googleapis.com"' \
    --limit 2 \
    --freshness 300d

ここで、[PROJECT_ID] はプロジェクト ID です。

管理アクティビティ ログをリソースタイプでフィルタリングする

管理アクティビティ ログ内の各ログエントリは、特定のタイプのリソースに該当します。以下は、Kubernetes クラスタに最も関連するリソースタイプです。

リソースタイプ 表示名
k8s_cluster Kubernetes クラスタ
gke_cluster GKE クラスタ オペレーション

Kubernetes API サーバーによって書き込まれたログエントリは、k8s_cluster リソースタイプに該当します。これらのログエントリは、クラスタ内の Kubernetes リソース(ポッド、Deployment、シークレットなど)のオペレーションを記述します。

Kubernetes Engine API サーバーによって書き込まれたログエントリは、gke_cluster リソースに該当します。これらのログエントリは、クラスタの作成や削除などのオペレーションを記述します。

Console

  1. GCP Console で、[ログ] ページの [ロギング] メニューに移動します。

    [ログ] ページに移動

  2. [ログ] ページが基本モードでない場合は、基本モードに切り替えます。フィルタ ボックスで、右側の下向き矢印をクリックして、[フィルタを解除して基本モードに戻る] を選択します。

  3. リソースタイプを選択するプルダウン メニューで、[Kubernetes クラスタ] を選択します。これは、k8s_cluster リソースタイプの表示名です。

  4. ログを選択するプルダウン メニューで、[アクティビティ] を選択して [OK] をクリックします。

    管理アクティビティ ログで k8s_cluster リソースタイプに該当するすべてのログエントリが一覧表示されます。

  5. ログエントリの 1 つを開いて、resource フィールドを展開します。type フィールドの値が k8s_cluster であることを確認します。

  6. 次に、プルダウン メニューで [GKE クラスタ オペレーション] を選択します。これは、gke_cluster リソースタイプの表示名です。ログを選択するプルダウン メニューで、[アクティビティ] を選択して [OK] をクリックします。

    管理アクティビティ ログで gke_cluster リソースタイプに該当するすべてのログエントリが一覧表示されます。

gcloud

プロジェクトの管理アクティビティ ログで k8s_cluster リソースタイプに該当するログエントリの最初の 2 つを一覧表示します。

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
        AND resource.type="k8s_cluster"' \
    --limit 2 \
    --freshness 300d

ここで、[PROJECT_ID] はプロジェクト ID です。

出力で、resource:type フィールドの値が k8s_cluster であることがわかります。

resource:
  ...
  type: k8s_cluster

次に、プロジェクトの管理アクティビティ ログで gke_cluster リソースタイプに該当するログエントリの最初の 2 つを一覧表示します。

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
        AND resource.type="gke_cluster"' \
    --limit 2 \
    --freshness 300d

出力で、resource:type フィールドの値が gke_cluster であることがわかります。

resource:
  ...
  type: gke_cluster

管理アクティビティ ログのフィルタの例

GCP Console で試すことができるフィルタの例をいくつか示します。各フィルタで、[PROJECT_ID] を該当するプロジェクト ID で置き換えてください。

自動化されたシステムの変更は除き、役割ベースのアクセス制御への変更を見つけます。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.methodName:"io.k8s.authorization.rbac.v1"
NOT protoPayload.authenticationInfo.principalEmail:"system"
logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.methodName:"io.k8s.authorization.rbac.v1.roles"
NOT protoPayload.authenticationInfo.principalEmail:"system"
logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.methodName:"io.k8s.authorization.rbac.v1.rolebindings"
NOT protoPayload.authenticationInfo.principalEmail:"system"

同様のクエリを使用して、clusterrolesclusterrolebindings への変更を見つけることができます。

証明書署名リクエストを見つけます。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.resourceName:"certificates.k8s.io/v1beta1/certificatesigningrequests"

未認証のウェブ リクエストを見つけます。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.authenticationInfo.principalEmail:"system:anonymous"

kubelet のブートストラップ ID 呼び出しを見つけます。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.authenticationInfo.principalEmail:"kubelet"

ノード認証リクエストを見つけます。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.authenticationInfo.principalEmail:"system:node"

IP 範囲外の呼び出しを見つけます。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.requestMetadata.callerIp!="127.0.0.1"
protoPayload.requestMetadata.callerIp!="::1"
NOT protoPayload.requestMetadata.callerIp:"[IP Prefix]"

管理アクティビティ ログで、k8s_cluster リソースタイプに該当し、Deployment の作成を記述しているエントリを探します。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.methodName:"deployments.create"

管理アクティビティ ログで、k8s_cluster リソースタイプに該当し、principalEmail の値が system:anonymous のエントリを探します。こうしたエントリは、おそらく認証に失敗したことを表しています。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.authenticationInfo.principalEmail="system:anonymous"

管理アクティビティ ログで、gke_cluster リソースタイプに該当し、クラスタの作成を記述しているエントリを探します。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="gke_cluster"
protoPayload.methodName="google.container.v1.ClusterManager.CreateCluster"

管理アクティビティ ログで、gke_cluster リソースタイプに該当し、severity の値が ERROR のエントリを探します。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="gke_cluster"
severity="ERROR"

管理アクティビティ ログで、k8s_cluster リソースタイプに該当し、シークレットへの書き込みリクエストを記述しているエントリを探します。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.methodName:"io.k8s.core.v1.secrets"
NOT protoPayload.methodName:"get"
NOT protoPayload.methodName:"list"
NOT protoPayload.methodName:"watch"

管理アクティビティ ログで、k8s_cluster リソースタイプに該当し、特定のユーザーからのポッド リクエストを記述しているエントリを探します。

logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Factivity"
resource.type="k8s_cluster"
protoPayload.methodName:"io.k8s.core.v1.pods"
protoPayload.authenticationInfo.principalEmail="dev@example.com"

フィルタを構成する方法について詳しくは、高度なログフィルタをご覧ください。

ログエントリの構造

すべてのログエントリは、LogEntry 型のオブジェクトです。詳しくは、監査ログのデータ型をご覧ください。

データアクセス ログの有効化

プロジェクトの Identity and Access Management(IAM)ポリシーを取得します。

gcloud projects get-iam-policy [PROJECT_ID] > my-policy.yaml

ここで、[PROJECT_ID] はプロジェクト ID です。

my-policy.yaml を開いて IAM ポリシーを表示します。ポリシーには、以下のような bindings オブジェクトがおそらく含まれています。

bindings:
- members:
  - serviceAccount:xxx.gserviceaccount.com
  - serviceAccount:yyy.gserviceaccount.com
  role: roles/container.clusterAdmin
- members:
  ...

my-policy.yaml に、auditConfigs オブジェクトを作成するか、既存の auditConfigs オブジェクトに追記して、ADMIN_READDATA_WRITEDATA_READauditLogConfigs の下にリストされるようにします。

auditConfigs:
- auditLogConfigs:
  - logType: ADMIN_READ
  - logType: DATA_WRITE
  - logType: DATA_READ
  service: allServices

etag の値を変更しないでください。

更新されたファイルを my-policy-2.yaml として保存します。

プロジェクトの IAM ポリシーを設定します。

gcloud projects set-iam-policy [PROJECT_ID] my-policy-2.yaml

ここで、[PROJECT_ID] はプロジェクト ID です。

プロジェクトのデータアクセス ログの表示

Console

  1. GCP Console で、[ログ] ページの [ロギング] メニューに移動します。

    [ログ] ページに移動

  2. [ログ] ページが基本モードでない場合は、基本モードに切り替えます。フィルタ ボックスで、右側の下向き矢印をクリックして、[フィルタを解除して基本モードに戻る] を選択します。

  3. ページの上部で、リソースタイプを選択するためのプルダウン メニューを見つけます。プルダウン メニューで、[Kubernetes クラスタ] を選択します。

  4. ログを選択するメニューで、data_access を選択して [OK] をクリックします。

  5. [ラベルまたはテキスト検索でフィルタ] ボックスの右側で、下矢印をクリックしてプルダウン メニューを開きます。メニューで、[高度なフィルタに変換] を選択します。

  6. テキスト ボックスに次のようなフィルタが表示されます。

    resource.type="k8s_cluster"
    logName="projects/my-project/logs/cloudaudit.googleapis.com%2Fdata_access"
  7. ログエントリの 1 つを開き、エントリの logName フィールドの値が projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Fdata_access であることに注意します。

gcloud

プロジェクトのデータアクセス ログのうち、最初の 2 つのログエントリを一覧表示します。

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Fdata_access"' \
    --limit 2 \
    --freshness 30d

ここで、[PROJECT_ID] はプロジェクト ID です。

出力には 2 つのログエントリが表示されます。各ログエントリの logName フィールドの値が projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Fdata_access である点に注意してください。

insertId:  "x0vy9eej0j54"
labels: {…}
logName:  "projects/[PROJECT_ID]/logs/cloudaudit.googleapis.com%2Fdata_access"
...

ログエントリのエクスポートと保存

ログエントリは、一定の時間 Stackdriver Logging で保持されます。この期間を保持期間といいます。この期間が経過すると、エントリは削除されます。

ログエントリの保持時間を長くするには、ログを Cloud Storage、BigQuery、Cloud Pub/Sub などの Google サービスにエクスポートします。

指標とアラートの設定

Stackdriver Monitoring を使用して、ログエントリに基づいて指標を設定できます。また、ログベースの指標を使用してグラフやアラートを設定できます。

監査ポリシー

Kubernetes 監査ポリシーにより、Kubernetes API サーバーによってエクスポートされるログエントリが決まります。Kubernetes Engine 監査ポリシーにより、管理アクティビティ ログに入るエントリと、データアクセス ログに入るエントリが決まります。

Kubernetes Engine の監査ポリシーについて詳しくは、Kubernetes Engine の監査ポリシーをご覧ください。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Kubernetes Engine のドキュメント