このページでは、Google Kubernetes Engine(GKE)クラスタで監査ロギングを使用する方法について説明します。
Kubernetes 対応のすべてのクラスタでは Kubernetes Audit Logging を使用して、Kubernetes API サーバーに対して行われた呼び出しを時系列でログに記録します。Kubernetes 監査ログのエントリは、不審な API リクエストの調査、統計情報の収集、不要な API 呼び出しに対するモニタリング アラートの作成に役立ちます。
GKE クラスタは Kubernetes Audit Logging を Cloud Audit Logs と Cloud Logging に統合します。Kubernetes 監査ログのエントリは、Google Cloud プロジェクトで表示できます。
プロジェクトの監査ログには、Kubernetes によって作成されたエントリだけでなく、GKE によって書き込まれたエントリもあります。
Audit Logging の一般提供は GKE 1.11.4 以降で使用できます。
始める前に
作業を始める前に、次のことを確認してください。
- Google Kubernetes Engine API が有効になっていることを確認します。 Google Kubernetes Engine API を有効にする
- Cloud SDK がインストール済みであることを確認します。
次のいずれかの方法で gcloud
のデフォルトの設定を指定します。
gcloud init
。デフォルトの設定全般を確認する場合に使用します。gcloud config
。プロジェクト ID、ゾーン、リージョンを個別に設定する場合に使用します。
gcloud init の使用
エラー One of [--zone, --region] must be supplied: Please specify
location
を受信した場合は、このセクションの内容を実施します。
-
gcloud init
を実行して、次の操作を行います。gcloud init
リモート サーバーで SSH を使用している場合は、
--console-only
フラグを指定して、コマンドがブラウザを起動しないようにします。gcloud init --console-only
- 手順に従って
gcloud
を承認し、Google Cloud アカウントを使用します。 - 新しい構成を作成するか、既存の構成を選択します。
- Google Cloud プロジェクトを選択します。
- ゾーンクラスタの場合はデフォルトの Compute Engine ゾーン、リージョン クラスタまたは Autopilot クラスタの場合はデフォルトの Compute Engine リージョンを選択します。
gcloud config の使用
- デフォルトのプロジェクト ID を設定します。
gcloud config set project PROJECT_ID
- ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
gcloud config set compute/zone COMPUTE_ZONE
- Autopilot クラスタまたはリージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
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
Cloud Console で、[ロギング] メニューの [ログ] ページに移動します。
ページの上部で、リソースタイプを選択するためのプルダウン メニューを見つけます。プルダウン メニューで、[Kubernetes クラスタ] を選択します。
必要に応じて、[ロケーション] を指定するか、[すべてのロケーション] を選択します。ロケーションを選択すると、そのロケーションにある特定のクラスタを選択できます。
右側にある次のメニューは、ログを選択するためのメニューです。プルダウン メニューで、[アクティビティ] を選択して [OK] をクリックします。
デフォルトでは、すべてのログレベルが表示されます。ログレベル(警告など)を指定するには、ログレベルのプルダウン メニューで選択します。
直近 1 時間のログエントリのみが表示されることがあります。1 時間前のログエントリが表示されない場合は、[古いログを読み込む] をクリックします。
上記の手順で説明したプルダウン メニューの上にある [ラベルまたはテキスト検索でフィルタ] ボックスで、下矢印をクリックしてプルダウン メニューを開きます。メニューで、[高度なフィルタに変換] を選択します。
テキスト ボックスに次のようなフィルタが表示されます。
resource.type="k8s_cluster" logName="projects/my-project/logs/cloudaudit.googleapis.com%2Factivity"
行の先頭にある矢印をクリックして、ログエントリの 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
Cloud Console で、[ロギング] メニューの [ログ] ページに移動します。
[ログ] ページが高度なモードでない場合は、高度なモードに切り替えます。フィルタ ボックスで、右側の下向き矢印をクリックして、[高度なフィルタに変換] を選択します。
フィルタ ボックスで、既存のテキストを削除して、以下のフィルタを入力します。
logName="projects/project-id/logs/cloudaudit.googleapis.com%2Factivity" protoPayload.serviceName="k8s.io"
ここで、project-id はプロジェクト ID です。
[フィルタを送信] をクリックします。
管理アクティビティ ログに
k8s.io
サービスによって書き込まれたすべてのエントリが一覧表示されます。つまり、Kubernetes コントロール プレーンによって書き込まれたエントリです。k8s.io
以外のサービスにより書き込まれたログエントリを探します。フィルタ ボックスで、serviceName="k8s.io"
をserviceName!="k8s.io"
に変更します。[フィルタを送信] をクリックします。管理アクティビティ ログに
k8s.io
サービスによって書き込まれなかったログエントリが一覧表示されます。ログエントリの 1 つを開いて、
protoPayload
フィールドを展開します。serviceName
の値を確認して、そのログエントリを書き込んだサービスを調べます。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
サービスによって書き込まれたログエントリ、つまり 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
Cloud Console で、[ロギング] メニューの [ログ] ページに移動します。
[ログ] ページが基本モードでない場合は、基本モードに切り替えます。フィルタ ボックスで、右側の下向き矢印をクリックして、[フィルタを解除して基本モードに戻る] を選択します。
リソースタイプを選択するプルダウン メニューで、[Kubernetes クラスタ] を選択します。これは、
k8s_cluster
リソースタイプの表示名です。ログを選択するプルダウン メニューで、[アクティビティ] を選択して [OK] をクリックします。
管理アクティビティ ログで
k8s_cluster
リソースタイプに該当するすべてのログエントリが一覧表示されます。ログエントリの 1 つを開いて、
resource
フィールドを展開します。type
フィールドの値がk8s_cluster
であることを確認します。プルダウン メニューで [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
管理アクティビティ ログのフィルタの例
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"
同様のクエリを使用して、clusterroles
と clusterrolebindings
への変更を見つけることができます。
証明書署名リクエストを見つけます。
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
リソースタイプに該当し、特定のユーザーからの 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 型のオブジェクトです。詳細については、監査ログについてをご覧ください。
データアクセス ログの有効化
プロジェクトの 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_READ
、DATA_WRITE
、DATA_READ
がauditLogConfigs
の下に列挙されるようにします。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
Cloud Console で、[ロギング] メニューの [ログ] ページに移動します。
[ログ] ページが基本モードでない場合は、基本モードに切り替えます。フィルタ ボックスで、右側の下向き矢印をクリックして、[フィルタを解除して基本モードに戻る] を選択します。
ページの上部で、リソースタイプを選択するためのプルダウン メニューを見つけます。プルダウン メニューで、[Kubernetes クラスタ] を選択します。
ログを選択するメニューで、data_access を選択して [OK] をクリックします。
[ラベルまたはテキスト検索でフィルタ] ボックスの右側で、下矢印をクリックしてプルダウン メニューを開きます。メニューで、[高度なフィルタに変換] を選択します。
テキスト ボックスに次のようなフィルタが表示されます。
resource.type="k8s_cluster" logName="projects/my-project/logs/cloudaudit.googleapis.com%2Fdata_access"
ログエントリの 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 の監査ポリシーをご覧ください。