Google Kubernetes Engine(GKE)ではインスタンス メタデータを使用してノード仮想マシン(VM)を構成しますが、このメタデータの一部は潜在的に機密性が高く、クラスタで実行中のワークロードから保護する必要があります。
始める前に
始める前に、次の作業が完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
ノードのサービス アカウントの構成
各ノードのサービス アカウントの認証情報は引き続きワークロードに公開されます。デフォルトでは、ノードは Compute Engine のデフォルトのサービス アカウントを使用します。Compute Engine のデフォルトのサービス アカウントの代わりに、ノードに対して最小限の権限のサービス アカウントを構成する必要があります。次に、このサービス アカウントをノードに接続して、攻撃者が Compute Engine API を使用して、基盤となる VM インスタンスに直接アクセスすることで GKE メタデータ保護を回避することができないようにします。
詳しくは、最小権限のサービス アカウントを使用するをご覧ください。
最小限の権限のノード サービス アカウントを作成するには、次の操作を行います。
新しい Identity and Access Management(IAM)サービス アカウントを作成し、そのメールアドレスを環境変数に保存します。
gcloud iam service-accounts create NODE_SA_NAME \ --display-name="DISPLAY_NAME" export NODE_SA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \ --filter='displayName:DISPLAY_NAME')
次のように置き換えます。
NODE_SA_NAME
: 新しいノード サービス アカウントの名前。DISPLAY_NAME
: 新しいサービス アカウントの表示名。
ノード サービス アカウントのメールアドレスの形式は
NODE_SA_NAME@PROJECT_ID.iam.gserviceaccount.com
です。GKE ノードを実行するための最小限のロールと権限でサービス アカウントを構成します。
gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:$NODE_SA_EMAIL \ --role=roles/monitoring.metricWriter gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:$NODE_SA_EMAIL \ --role=roles/monitoring.viewer gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:$NODE_SA_EMAIL \ --role=roles/logging.logWriter
PROJECT_ID
は、Google Cloud プロジェクト ID に置き換えます。さらに、クラスタが Artifact Registry から非公開イメージを pull する場合は、
roles/artifactregistry.reader
ロールを追加します。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:$NODE_SA_EMAIL \ --role=roles/artifactregistry.reader
メタデータ隠蔽
GKE のメタデータ隠蔽は、一部の潜在的なシステムの機密メタデータを、クラスタ上で実行中のユーザーのワークロードから保護できます。
メタデータ隠蔽を有効にして、ユーザーの Pod がクラスタのノードの特定の VM メタデータ(Kubelet 認証情報や VM インスタンス情報など)にアクセスすることを防止できます。具体的には、メタデータ隠蔽は、kube-env
(Kubelet 認証情報を含む)と VM のインスタンス ID トークンへのアクセスを保護します。
メタデータ隠蔽は、ユーザーポッド(HostNetwork
上で実行されていないポッド)からクラスタ メタデータ サーバーへのトラフィックをファイアウォール制御し、安全なクエリのみを許可します。ファイアウォールは、ユーザーの Pod により、権限昇格攻撃に kubelet 認証情報が使用されるのを防ぎます。また、インスタンス エスカレーション攻撃に VM ID が使用されるのも防ぎます。
メタデータ隠蔽を有効にできるのは、新しいクラスタを作成するときと、既存のクラスタに新しいノードプールを追加するときのみです。
制限事項
- メタデータ隠蔽は、
kube-env
とノードのインスタンス ID トークンへのアクセスのみを保護します。 - メタデータ隠蔽は、ノードのサービス アカウントへのアクセスを制限しません。
- メタデータ隠蔽は、他の関連するインスタンス メタデータへのアクセスを制限しません。
- メタデータ隠蔽は、その他の以前のメタデータ API へのアクセスを制限しません。
- メタデータ隠蔽では、ホスト ネットワーク(Pod 仕様の
hostNetwork: true
)で実行されている Pod からのトラフィックは制限されません。
メタデータ隠蔽を使用した新しいクラスタまたはノードプールの作成
サービス アカウントの作成後、Google Cloud CLI を使用して新しいクラスタまたはノードプールを作成し、メタデータ隠蔽を有効にできます。
新しいクラスタの作成
メタデータ隠蔽が有効になっているクラスタを作成するには、次のコマンドを実行します。
gcloud beta container clusters create CLUSTER_NAME \
--workload-metadata-from-node=SECURE \
--service-account=$NODE_SA_EMAIL
CLUSTER_NAME
は、使用するクラスタの名前に置き換えます。
--workload-metadata-from-node
フラグは次の値を取ります。
SECURE
: メタデータ隠蔽を有効にします。EXPOSED
またはUNSPECIFIED
: メタデータ隠蔽を無効にします。
新しいノードプールを作成する
メタデータ隠蔽が有効になっているノードプールを作成するには、次のコマンドを実行します。
gcloud beta container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--workload-metadata-from-node=SECURE \
--service-account=$NODE_SA_EMAIL
NODE_POOL_NAME
は、新しいノードプールの名前に置き換えます。
ID トークン メタデータがクラスタのワークロードから隠蔽されていることを確認する
メタデータを隠蔽するときは、ノードのインスタンス ID トークンを介して署名をリクエストできないようにする必要があります。リクエストが隠蔽されているメタデータをユーザーに明示的に通知することを確認するには、次の手順で操作します。
新しい Pod でシェル セッションを開きます。
kubectl run metadata-concealment -it --image=google/cloud-sdk:slim -- /bin/bash
Pod で、隠しエンドポイントを取得してみます。
curl -H "Metadata-Flavor: Google" \ 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://www.example.com'
出力は次のようになります。
This metadata endpoint is concealed.
以前のメタデータ API の無効化と移行
Compute Engine メタデータ サーバー エンドポイント v0.1
と v1beta1
は、2020 年 9 月 30 日にサポート終了となり、停止されました。
停止スケジュールについては、v0.1
と v1beta1
メタデータ サーバー エンドポイントのサポート終了をご覧ください。