GKE でのマルチテナント ロギング

このページでは、Google Kubernetes Engine(GKE)クラスタのマルチテナント ロギングを構成する方法について説明します。

一般的に、複数のチームが 1 つの GKE クラスタを共有します。クラスタを共有すると、サービス ディスカバリが容易になり、セキュリティも簡素化されるなどの多くの利点が得られます。つまり、クラスタ管理者が管理するクラスタの数が少なくなります。ただし、個々のアプリケーション チームは、多くの場合それぞれ別々のプロジェクトを持っています。メインの GKE クラスタを持つ一方で Namespace が別々となるこの構造は、マルチテナンシーと呼ばれます。アプリケーション チームのプロジェクトはテナントと呼ばれます。

GKE クラスタ管理者は、Google Cloud を使用することで、クラスタのログがメインの GKE プロジェクト内に残り、テナントログがテナント プロジェクトに配布されるシステムを作成できます。この方法でログを構成するには、Cloud Logging のログルーターを使用します。ログルーターを使用すると、Google Cloud プロジェクト内でのログのフローと、他の Google Cloud プロジェクトへのログのフローを制御できます。

テナント固有のログを作成する場合、クラスタ管理者はシンクを作成し、テナントのプロジェクトで作成されたログバケットにログエントリをルーティングします。オプションで除外ルールを作成して、メインの GKE プロジェクトにテナントのログが保存されないようにすることもできます。

下の図は、ログバケットを使用したマルチテナント ロギング アーキテクチャの概要を示しています。

GKE マルチテナント アーキテクチャ

このアーキテクチャには次のものが含まれます。

  1. 各テナント プロジェクトで作成されたログバケット
  2. テナントの Namespace ごとに作成されたログシンク
  3. ログシンクごとに自動的に作成されたサービス アカウント
  4. オプションでメインの GKE プロジェクトのログの重複を防ぐための除外ルール

この後のセクションで、このアーキテクチャを作成する方法について説明します。

要件

マルチテナント ロギングの構成

マルチテナント ロギングの構成には、gcloud コマンドライン ツールまたは Google Cloud Console を使用できます。

gcloud

GKE クラスタにマルチテナント ロギングを実装する手順は次のとおりです。

  1. 変数を設定します。

    export TENANT_NAMESPACE="TENANT_NAMESPACE"
    export MAIN_PROJECT="MAIN_PROJECT_ID"
    export TENANT_PROJECT="TENANT_PROJECT_ID"
    

    次のように置き換えます。

    • TENANT_NAMESPACE: テナント プロジェクトの名前空間の名前
    • MAIN_PROJECT_ID: メイン プロジェクトのプロジェクト ID
    • TENANT_PROJECT_ID: テナント プロジェクトのプロジェクト ID
  2. マルチテナント クラスタに名前空間を作成します。

    kubectl create namespace $TENANT_NAMESPACE
    
  3. テナント プロジェクトにログバケットを作成します。

    gcloud logging buckets create gke-$TENANT_NAMESPACE-log-bucket \
        --project=$TENANT_PROJECT \
        --location=global \
        --description="Log bucket for $TENANT_NAMESPACE namespace from $MAIN_PROJECT"
    

    これらのフィールドの詳細については、gcloud logging buckets create API ドキュメントをご覧ください。

  4. メインの GKE プロジェクトにログシンクを作成します。

    gcloud logging sinks create gke-$TENANT_NAMESPACE-sink \
    logging.googleapis.com/projects/$TENANT_PROJECT/locations/global/buckets/gke-$TENANT_NAMESPACE-log-bucket \
        --project=$MAIN_PROJECT \
        --log-filter=resource.labels.namespace_name="$TENANT_NAMESPACE" \
        --description="Log sink to $TENANT_PROJECT for $TENANT_NAMESPACE namespace"
    

    このコマンドは、前の手順で作成したログバケットに $TENANT_NAMESPACE 名前空間に関連するすべてのログを送信するログシンクを作成します。

    場合によっては、より制限の厳しい --log-filter を使用する必要があります。たとえば、クラスタとテナントに同じ名前空間がある場合、クラスタ フィルタを追加できます。

    これらのフィールドの詳細については、gcloud logging sinks create API ドキュメントをご覧ください。

  5. メイン プロジェクトのシンクからサービス アカウントを取得して、変数に割り当てます。このサービス アカウントは、次の手順で権限を付与するために必要です。

    export SERVICE_ACCOUNT=$(gcloud logging sinks describe gke-$TENANT_NAMESPACE-sink \
        --project=$MAIN_PROJECT \
        --format='value(writerIdentity)')
    
  6. シンクで使用されるサービス アカウントに logging.bucketWriter ロールを付与します。メイン プロジェクトでは、テナント プロジェクトのバケットへの書き込みにこの権限が必要になります。

     gcloud projects add-iam-policy-binding $TENANT_PROJECT \
         --member=$SERVICE_ACCOUNT --role='roles/logging.bucketWriter' \
         --condition="expression=resource.name.endsWith(\"locations/global/buckets/gke-$TENANT_NAMESPACE-log-bucket\"),title=Log bucket writer for $TENANT_NAMESPACE,description=Grants logging.bucketWriter role to service account $SERVICE_ACCOUNT used by gke-$TENANT_NAMESPACE-sink"
    

    これらのフィールドの詳細については、gcloud projects add-iam-policy-binding API ドキュメントをご覧ください。

  7. オプションで、_Default バケットに除外ルールを作成します。このルールにより、テナントログもメインバケットに書き込まれなくなります。このコマンドを省略すると、メイン プロジェクトの _Default バケットとテナント バケットでログの重複が発生します。

    gcloud logging sinks update _Default --project=$MAIN_PROJECT \
        --add-exclusion="name=gke-$TENANT_NAMESPACE-default-exclusion,description=\"Exclusion rule on the _Default bucket for $TENANT_NAMESPACE\",filter=resource.labels.namespace_name=\"$TENANT_NAMESPACE\""
    

    これらのフィールドの詳細については、gcloud logging sinks update API ドキュメントをご覧ください。

Console

GKE にマルチテナント ロギングを実装する手順は次のとおりです。

  1. テナント プロジェクトにログバケットを作成します。

    1. [ログストレージ] メニューに移動します。

      ログストレージに移動

    2. トップページにあるプロジェクト プルダウンをクリックし、テナント プロジェクトを選択します。

    3. [ログバケットの作成] をクリックします。

    4. バケットの [名前] と [説明] を入力します。

    5. [ログのバケットのリージョンを選択] プルダウンからリージョンを選択します。

    6. [バケットを作成] をクリックします。新しいバケットが [ログバケット] のリストに表示されます。

  2. メインの GKE プロジェクトにログシンクを作成します。

    1. トップページにあるプロジェクト プルダウンをクリックし、メインの GKE プロジェクトを選択します。
    2. 左側のメニューで、[ログルーター] を選択します。[ログルーター] ページが表示されます。
    3. [シンクを作成] をクリックします。[シンクを選択] ウィンドウが表示されます。
    4. [シンクを選択] ウィンドウで、[Cloud Logging バケット] を選択します。
    5. シンクの [名前] と [説明] に入力し、[次へ] をクリックします。
    6. [シンクサービスの選択] プルダウンで、[その他のプロジェクト] を選択します。
    7. [シンクのエクスポート先] フィールドに、次の宛先を追加します。 logging.googleapis.com/projects/TENANT_PROJECT_ID/locations/LOG_BUCKET_REGION/buckets/BUCKET_NAME

      次のように置き換えます。

      • TENANT_PROJECT_ID: メイン プロジェクトのプロジェクト ID
      • LOG_BUCKET_REGION: ログバケットを作成したリージョン
      • BUCKET_NAME: 前のセクションで作成したログバケットの名前
    8. [次へ] をクリックします。

    9. [包含フィルタの作成] で、次のフィルタ resource.labels.namespace_name="TENANT_NAMESPACE" を追加します。TENANT_NAMESPACE をテナント プロジェクトの名前空間の名前に置き換えます。

      場合によっては、より制限の厳しい一致フィルタを使用する必要があります。たとえば、クラスタとテナントに同じ名前空間がある場合、クラスタ フィルタを追加できます。

    10. [シンクを作成] をクリックします。新しいシンクが [ログ ルーティング シンク] のリストに表示されます。

  3. メイン プロジェクトのシンクからサービス アカウントを取得します。このサービス アカウントは、次の手順で権限を付与するために必要です。

    1. [ログルーター] ページで、メイン プロジェクトからログシンクを見つけます。
    2. そのシンクの横にある [その他] アイコンをクリックし、[シンクの詳細を表示] を選択します。
    3. [書き込み ID: serviceAccount:] の横の値をコピーします。
  4. テナントのシンクで使用されるサービス アカウントにログバケット書き込みのロールを付与します。メイン プロジェクトでは、テナント プロジェクトのバケットへの書き込みにこの権限が必要になります。

    1. Cloud Console で [IAM] ページに移動します。

      IAM に移動

    2. [追加] をクリックします。

    3. [新しいメンバー] フィールドに、シンクのサービス アカウントを追加します。

    4. [ロールを選択] プルダウンから [Logging] を選択し、[ログバケット書き込み] を選択します。

    5. [保存] をクリックします。

  5. オプションで、_Default バケットに除外ルールを作成します。これにより、テナントログもメインバケットに書き込まれなくなります。このコマンドを省略すると、メイン プロジェクトの _Default バケットとテナント バケットでログの重複が発生します。

    1. Cloud Console で、[ログルーター] ページに移動します。

      [ログルーター] に移動

    2. _Default バケットの隣にある [ その他] をクリックし、[シンクを編集] を選択します。

    3. [シンクに含めないログの選択] セクションで、[除外設定を追加] をクリックします。

    4. フィルタ名を入力します。

    5. [除外フィルタの作成] ボックスに resource.labels.namespace_name="TENANT_NAMESPACE" を追加します。

    6. [シンクを更新] をクリックします。

テナントログの確認

TENANT_NAMESPACE を使用するワークロードの使用を開始すると、テナント プロジェクトがテナント固有のログを受信していることを確認できます。

  1. テナント プロジェクトから、Cloud Console の [ログビューア] ページに移動します。

    ログビューアに移動する

  2. [範囲を絞り込む] をクリックします。

  3. [ストレージによるスコープ] を選択し、テナントのバケットを選択します。

    gke-TENANT_NAMESPACE-log-bucket
    

クリーンアップ

マルチテナント ロギング用に作成したオブジェクトは、gcloud または Cloud Console を使用して削除できます。

gcloud

マルチテナント ロギング用に作成したオブジェクトを削除するには、次の手順を行います。

  1. 次のコマンドを簡略化する変数を設定します。

    export TENANT_NAMESPACE="TENANT_NAMESPACE"
    export MAIN_PROJECT="MAIN_PROJECT_ID"
    export TENANT_PROJECT="TENANT_PROJECT_ID"
    

    次のように置き換えます。

    • TENANT_NAMESPACE: テナント プロジェクトの名前空間の名前
    • MAIN-PROJECT-ID: メイン プロジェクトのプロジェクト ID
    • TENANT-PROJECT-ID: テナント プロジェクトのプロジェクト ID
  2. メイン プロジェクトで除外ルールを作成した場合は、そのルールを削除します。

    gcloud logging sinks update _Default \
       --project=$MAIN_PROJECT \
       --remove-exclusions=gke-$TENANT_NAMESPACE-default-exclusion
    
  3. サービス アカウントから bucketWriter ロールを削除します。

    export SERVICE_ACCOUNT=$(gcloud logging sinks describe gke-$TENANT_NAMESPACE-sink \
        --project=$MAIN_PROJECT | \
        --format='value(writerIdentity)'
    
    gcloud projects remove-iam-policy-binding $TENANT_PROJECT \
        --member=$SERVICE_ACCOUNT \
        --role='roles/logging.bucketWriter' \
        --all
    
  4. ログシンクを削除します。

    gcloud logging sinks delete gke-$TENANT_NAMESPACE-sink \
        --project=$MAIN_PROJECT
    
  5. ログバケットを削除します。

    gcloud logging buckets delete gke-$TENANT_NAMESPACE-log-bucket \
        --project=$TENANT_PROJECT \
        --location=global
    
  6. 名前空間を削除します。

    kubectl delete namespace $TENANT_NAMESPACE
    

Console

  1. メイン プロジェクトで除外ルールを作成した場合は、そのルールを削除します。

    1. Cloud Console で、[ログルーター] ページに移動します。

      [ログルーター] に移動

    2. _Default バケットの横にあるその他 アイコンをクリックします。

    3. [シンクを編集] を選択します。

    4. 作成した除外ルールの横にある [削除] をクリックします。

    5. [シンクを更新] をクリックします。

  2. メイン プロジェクトでサービス アカウントを削除します。

    1. Cloud Console で [IAM] ページに移動します。

      IAM に移動

    2. シンクのサービス アカウントを選択します。

    3. [削除] をクリックします。

    4. 確認ウィンドウで、[確認] をクリックします。

  3. テナント プロジェクトで、ログシンクを削除します。

    1. トップページにあるプロジェクト プルダウンをクリックし、テナント GKE プロジェクトを選択します。
    2. Logging メニューから [ログルーター] を選択します。

      [ログルーター] に移動

    3. 削除するシンクのその他 アイコンをクリックします。

    4. [シンクを削除] を選択します。

    5. 確認パネルで [削除] をクリックします。

  4. メイン プロジェクトでログバケット(ベータ版)を削除します。

    1. トップページにあるプロジェクト プルダウンをクリックし、メインの GKE プロジェクトを選択します。
    2. Logging メニューから [ログストレージ] を選択します。

      ログストレージに移動

    3. 削除するバケットで、[その他] をクリックします。

    4. [バケットの削除] を選択します。

    5. 確認パネルで [削除] をクリックします。

制限事項

マルチテナント ロギングには次の制限事項があります。

  • プロジェクトあたりのログシンクの数は 200 です。200 を超えるテナントが必要な場合は、サポートケースを作成して、割り当ての増加をリクエストしてください。
  • ログバケットごとに、最大 50 個の除外ルールを設定できます。50 個を超えるテナントを設定する必要がある場合は、_Default バケットの除外ルールのアプローチを変更する必要があります。代わりの方法として、次の方法があります。

    • 下のコマンドを使用して、システム以外の Namespace またはデフォルト以外の Namespace をすべて除外する単一の除外ルールを作成する。

      gcloud logging sinks update _Default \
      --project=$MAIN_PROJECT \
      --add-exclusion="name=gke-all-tenant-default-exclusion,description=\"Exclusion rule on the _Default bucket for all tenants\",filter=resource.labels.namespace_name !~ \"kube\" AND resource.labels.namespace_name !~ \"system\ AND resource.labels.namespace_name != \"Default\""
      
    • 除外ルールを作成しないで、テナント プロジェクトとメイン プロジェクトの間でログを複製する。

次のステップ