監査ログ

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

概要

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

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

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

Audit Logging GA は GKE 1.11.4 以降で使用できます。

始める前に

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

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

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

gcloud init の使用

  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

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

    kubectl run log-exercise --image nginx
    

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

プロジェクトの監査ログ

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

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

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

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

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

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

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

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

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 サービスによって書き込まれたログエントリ、つまり 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 リソース(Pod、Deployment、Secret など)のオペレーションを記述します。

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

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 リソースタイプに該当し、Secret への書き込みリクエストを記述しているエントリを探します。

    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 リソースタイプに該当し、特定のユーザーからの Pod リクエストを記述しているエントリを探します。

    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. プロジェクトの Cloud Identity and Access Management(Cloud IAM)ポリシーを取得します。

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

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

  2. my-policy.yaml を開き、Cloud 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. プロジェクトの Cloud 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"
    ...
    

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

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

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

指標とアラートの設定

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

監査ポリシー

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

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

次のステップ