監査ログへのアクセス

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

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

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

プロジェクトの監査ログには、Kubernetes によって作成されたエントリだけでなく、GKE によって書き込まれたエントリもあります。

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

始める前に

作業を始める前に、次のことを確認してください。

次のいずれかの方法で gcloud のデフォルトの設定を指定します。

  • gcloud init。デフォルトの設定全般を確認する場合に使用します。
  • gcloud config。プロジェクト ID、ゾーン、リージョンを個別に設定する場合に使用します。

gcloud init の使用

エラー One of [--zone, --region] must be supplied: Please specify location を受信した場合は、このセクションの内容を実施します。

  1. gcloud init を実行して、次の操作を行います。

    gcloud init

    リモート サーバーで SSH を使用している場合は、--console-only フラグを指定して、コマンドがブラウザを起動しないようにします。

    gcloud init --console-only
  2. 手順に従って gcloud を承認し、Google Cloud アカウントを使用します。
  3. 新しい構成を作成するか、既存の構成を選択します。
  4. Google Cloud プロジェクトを選択します。
  5. デフォルトの Compute Engine ゾーンを選択します。

gcloud config の使用

  • デフォルトのプロジェクト 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

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

kubectl run log-exercise --image nginx

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

プロジェクトの監査ログ

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

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

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

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

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

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

サービス 表示名 説明
k8s.io Kubernetes k8s.io サービスは、Kubernetes 監査ログに使用されます。これらのログは、Kubernetes API Server コンポーネントによって生成され、Kubernetes API を使用して実行されたアクションに関する情報が記録されます。たとえば、kubectl コマンドを使用して Kubernetes リソースに行った変更は k8s.io サービスによって記録されます。詳細については、Kubernetes ドキュメントの監査をご覧ください。
container.googleapis.com Kubernetes Engine container.googleapis.com サービスは、GKE コントロール プレーンの監査ログに使用されます。これらのログは GKE 内部コンポーネントによって生成され、GKE API を使用して実行されたアクションに関する情報が記録されます。たとえば、gcloud コマンドを使用して GKE クラスタ構成に行った変更は container.googleapis.com サービスによって記録されます。

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

Console

  1. Cloud 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
...

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

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

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

Console

  1. Cloud 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

  1. プロジェクトの管理アクティビティ ログに 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
    
  2. 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
    ...
    
  3. ログエントリの 1 つで、protoPayload.serviceName の値を見て、ログエントリを書き込んだサービスを確認します。

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

    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 クラスタ Kubernetes API サーバーによって書き込まれたログエントリは、k8s_cluster リソースタイプに該当します。これらのログエントリは、クラスタ内の Kubernetes リソース(Pod、Deployment、Secret など)のオペレーションを記述します。
gke_cluster GKE クラスタ オペレーション Kubernetes Engine API サーバーによって書き込まれたログエントリは、gke_cluster リソースに該当します。これらのログエントリは、クラスタの作成や削除などのオペレーションを記述します。

これらのフィルタは、Cloud Console または gcloud コマンドライン ツールで使用できます。

Console

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

    [ログ] ページに移動

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

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

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

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

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

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

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

gcloud

  1. プロジェクトの管理アクティビティ ログで 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
    
  2. プロジェクトの管理アクティビティ ログで 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
    

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

Cloud 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 型のオブジェクトです。詳細については、監査ログについてをご覧ください。

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

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

    gcloud projects get-iam-policy project-id > my-policy.yaml
    

    ここで、project-id はプロジェクト ID です。

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

    bindings:
    - members:
      - serviceAccount:xxx.gserviceaccount.com
      - serviceAccount:yyy.gserviceaccount.com
      role: roles/container.clusterAdmin
    - members:
      ...
    
  3. my-policy.yaml に、auditConfigs オブジェクトを作成するか、既存の auditConfigs オブジェクトに追加して、ADMIN_READDATA_WRITEDATA_READauditLogConfigs の下に列挙されるようにします。

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

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

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

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

    gcloud projects set-iam-policy project-id my-policy-2.yaml
    

    ここで、project-id はプロジェクト ID です。

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

Console

  1. Cloud 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"
...

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

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

ログエントリをより長期間保持する場合は、Cloud Storage、BigQuery、Pub/Sub などの Google サービスにログエントリをエクスポートできます。

指標とアラートの設定

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

監査ポリシー

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

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

次のステップ