gke-security について
gke-securityは、GKEクラスタのセキュリティ設定に関するリファレンスガイドです。クラスタ管理者やプラットフォームチーム向けに、セキュリティ基準、IDとシークレット、RBAC、ネットワークポリシー、ワークロード保護を説明し、MCPツールも記載します。
主な機能
- 01GKEセキュリティ基準の設定説明
- 02Workload IdentityとSecret Managerの手順
- 03RBAC強化のガイダンス
- 04ネットワークポリシーとBinary Authorizationの解説
- 05Pod Security Standardsとサンドボックスの説明
活用シーン
- 01新しいGKEクラスタのセキュリティ設定の計画
- 02クラスタのRBACとIAM権限の確認
- 03ワークロードからSecret Managerへのアクセス設定
- 04本番namespaceでのPod Security Standards適用
MCP 対応
get_cluster、check_k8s_auth、get_k8s_resource、apply_k8s_manifest、update_clusterなどのMCPツールを記載しています。クラスタやKubernetesリソースの確認、マニフェスト適用、クラスタ更新に利用できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ google/ skills --skill gke-securityインストール後、Claude Code で/gke-securityを入力して読み込まれたか確認します。
同梱ファイルassets/default-deny-netpol.yamlassets/workload-identity-pod.yaml
詳細
GKE セキュリティ
このリファレンスでは、GKE クラスターのセキュリティ設定について説明します。ゴールデンパスでは、デフォルトで強化されたセキュリティ体制が適用されます。
MCP ツール:
get_cluster、check_k8s_auth、get_k8s_resource、apply_k8s_manifest、update_cluster
ゴールデンパスのセキュリティデフォルト
| 設定 | ゴールデンパスの値 | Day-0/1 | 備考 |
|---|---|---|---|
workloadIdentityConfig.workloadPool | <PROJECT>.svc.id.goog | Day-0 | Pod 向け Workload Identity Federation |
secretManagerConfig.enabled | true | Day-1 | Google Secret Manager との統合 |
secretManagerConfig.rotationConfig | enabled: true, rotationInterval: 120s | Day-1 | シークレットの自動ローテーション |
rbacBindingConfig.enableInsecureBindingSystemAuthenticated | false | Day-0 | レガシーな system:authenticated バインディングをブロックします |
rbacBindingConfig.enableInsecureBindingSystemUnauthenticated | false | Day-0 | レガシーな system:unauthenticated バインディングをブロックします |
nodeConfig.shieldedInstanceConfig.enableSecureBoot | true | Day-0 | 検証可能なブート整合性 |
nodeConfig.shieldedInstanceConfig.enableIntegrityMonitoring | true | Day-0 | ランタイムの整合性チェック |
nodeConfig.workloadMetadataConfig.mode | GKE_METADATA | Day-0 | レガシーなメタデータ API をブロックし、Workload Identity を適用します |
| プライベートクラスター + Dataplane V2 の設定 | gke-networking スキルを参照してください | Day-0 | プライベートノード、プライベートエンドポイントの適用、ADVANCED_DATAPATH |
Workload Identity Federation
Workload Identity は、Pod が Google Cloud API にアクセスする際に推奨される方法です。 静的なサービスアカウントキーが不要になります。
セットアップ
# 1. Create a Google Service Account (GSA)
gcloud iam service-accounts create <GSA_NAME> \
--project <PROJECT_ID> \
--display-name "Workload Identity SA" \
--quiet
# 2. Grant IAM roles to the GSA
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member "serviceAccount:<GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role "<ROLE>" \
--quiet
# 3. Create Kubernetes Service Account (KSA)
kubectl create namespace <NAMESPACE>
kubectl create serviceaccount <KSA_NAME> --namespace <NAMESPACE>
# 4. Bind KSA to GSA
gcloud iam service-accounts add-iam-policy-binding \
<GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:<PROJECT_ID>.svc.id.goog[<NAMESPACE>/<KSA_NAME>]" \
--quiet
# 5. Annotate KSA
kubectl annotate serviceaccount <KSA_NAME> \
--namespace <NAMESPACE> \
iam.gke.io/gcp-service-account=<GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com
テスト用 Pod については、assets/workload-identity-pod.yaml を参照してください。
検証
kubectl run workload-identity-test \
--image=gcr.io/google.com/cloudsdktool/cloud-sdk:slim \
--serviceaccount=<KSA_NAME> --namespace=<NAMESPACE> \
--rm -it -- gcloud auth list --quiet
Secret Manager との統合
ゴールデンパスでは、自動ローテーションを有効にして Secret Manager を使用します。シークレットは Kubernetes Secret に同期されます。
# Verify Secret Manager is enabled on cluster
gcloud container clusters describe <CLUSTER_NAME> --region <REGION> \
--format="value(secretManagerConfig.enabled)" \
--quiet
# Enable if not already (Day-1 change)
gcloud container clusters update <CLUSTER_NAME> --region <REGION> \
--enable-secret-manager \
--secret-manager-rotation-interval=120s \
--quiet
CSI ボリュームを使用したシークレットのマウント(Deployment の例)
Secret Manager アドオンを有効にすると、Secrets Store CSI ドライバーを使用してワークロードでシークレットを ボリュームとしてマウントできます。これには、次の 2 つの手順が必要です。
SecretProviderClassを定義すると、Secret Manager から取得するシークレットを指定できます。Deploymentにボリュームをマウントすると、そのクラスを参照できます。
重要
本番環境のベストプラクティス:Secret Manager CSI などのワークロード統合は、未加工の
Podマニフェストではなく、本番環境の標準に沿ったDeploymentマニフェストを使用して必ず示してください。
手順 1:SecretProviderClass を作成する
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: app-secrets-provider
namespace: default
spec:
provider: gke # Identifies GKE managed provider
parameters:
secrets: |
- resourceName: "projects/<PROJECT_ID>/secrets/db-password/versions/latest"
fileName: "db-password.txt"
手順 2:Deployment にシークレットをマウントする
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: secure-app
template:
metadata:
labels:
app: secure-app
spec:
serviceAccountName: secure-ksa # Must be bound to GSA with Secret Manager Secret Accessor role
containers:
- name: app
image: <IMAGE>
volumeMounts:
- name: secrets-volume
mountPath: "/var/secrets"
readOnly: true
volumes:
- name: secrets-volume
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "app-secrets-provider"
RBAC の強化
ゴールデンパスでは、system:authenticated グループと system:unauthenticated グループに広範なアクセス権を付与する
安全でないレガシー RBAC バインディングを無効にします。
# Verify insecure bindings are disabled
gcloud container clusters describe <CLUSTER_NAME> --region <REGION> \
--format="yaml(rbacBindingConfig)" \
--quiet
RBAC のベストプラクティス:
- クラスター全体に適用される ClusterRole よりも、名前空間スコープの Role を使用します
- 特定の Group または ServiceAccount にバインドし、
system:authenticatedには決してバインドしません - MCP を使用して権限を監査します:
check_k8s_auth(parent="...", verb="list", resourceType="pods", namespace="...")(またはkubectl auth can-i --list --as=<user>) - MCP を使用してバインディングを確認します:
get_k8s_resource(parent="...", resourceType="clusterrolebinding")(またはkubectl get clusterrolebindings,rolebindings --all-namespaces)
エンタープライズ RBAC の計画については、
gke-multitenancyスキルと https://docs.cloud.google.com/kubernetes-engine/docs/best-practices/rbac.md.txt を参照してください。
Binary Authorization
ゴールデンパスではデフォルトで有効になっていませんが、本番環境のイメージの プロビナンスには推奨されます。
# Enable Binary Authorization
gcloud container clusters update <CLUSTER_NAME> --region <REGION> \
--binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE \
--quiet
Network Policies
Dataplane V2(ゴールデンパス)には、Network Policy の適用機能が組み込まれています。各名前空間にデフォルト拒否を適用します。
# MCP (preferred)
apply_k8s_manifest(parent="...", yamlManifest="<contents of default-deny-netpol.yaml>")
# kubectl fallback
kubectl apply -f ./assets/default-deny-netpol.yaml -n <NAMESPACE>
GKE Sandbox(gVisor)
信頼できないワークロードを隔離されたサンドボックスで実行する場合:
# Enable on cluster (Standard clusters)
gcloud container clusters update <CLUSTER_NAME> --region <REGION> --enable-gke-sandbox --quiet
# Use in pod spec
# Add: runtimeClassName: gvisor
Pod Security Standards(ゴールデンパス)
Pod Security Standards では、ポッドで実行できる操作を制限する3つのプロファイルを定義しています。
本番環境の名前空間では、restricted プロファイルがゴールデンパスのデフォルトです。
| プロファイル | レベル | 用途 |
|---|---|---|
privileged | 制限なし | システム名前空間(kube-system)、 |
| : : : インフラストラクチャコントローラー : | ||
baseline | 最小限の制限 | 共有/開発用名前空間、移行中のレガシーアプリ |
| : : : : | ||
restricted | ゴールデンパス | 本番環境のワークロード -- 権限昇格、ホストアクセス、 |
| : : : ルートユーザーをブロック : |
名前空間ラベルで適用します(Pod Security Admission):
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/audit: restricted
段階的なロールアウト戦略:
- 既存の名前空間で
warn+auditから始め、違反を特定します - 準拠していないワークロードを修正します(
privileged、hostNetwork、ルートユーザーなどを削除します) - すべてのワークロードが準拠したら
enforceを有効にします
restricted は、ルートユーザーとしての実行、権限昇格、ホストの
ネットワーク/PID/IPC、ホストパスボリューム、ほとんどのケーパビリティをブロックします。ゴールデンパスの
workload-identity-pod.yaml はすでに準拠しています。
Network Policy ロギング(推奨)
Dataplane V2(ゴールデンパス)では、Network Policy の判定に関するロギングを有効にできます。ゴールデンパスのデフォルトではありません -- セキュリティ監査のために推奨されます。
gcloud container clusters update <CLUSTER_NAME> --region <REGION> \
--enable-network-policy-logging \
--quiet
許可および拒否された接続が記録されるため、Network Policy ルールのトラブルシューティングや トラフィックフローの監査に役立ちます。
一般的な IAM ロール
GKE で最もよく使われる5つの定義済み IAM ロール:
| ロール | 目的 | 使用する場面 |
|---|---|---|
roles/container.admin | クラスターと Kubernetes リソースを完全に制御 | クラスターのライフサイクルを管理するプラットフォームチームの管理者 |
| : : : : | ||
| : : : : | ||
roles/container.clusterAdmin | クラスターを管理しますが、プロジェクトレベルの IAM は管理しません | クラスターを作成/削除するクラスターオペレーター |
| : : : : | ||
roles/container.developer | ワークロードをデプロイします(ポッド、サービス、デプロイメント) | 既存のクラスターにデプロイするアプリケーション開発者 |
| : : : : | ||
roles/container.viewer | クラスターと Kubernetes リソースへの読み取り専用アクセス | モニタリング、監査、または読み取り専用ダッシュボード |
| : : : : | ||
| : : : : | ||
roles/container.clusterViewer | クラスターの詳細を一覧表示および取得します | クラスターのメタデータのみを必要とする CI/CD パイプライン |
| : : : : | ||
| : : : : |
最小権限の原則:
roles/container.viewerまたはroles/container.developerから始め、必要な場合にのみ権限を引き上げます。roles/container.adminを広範囲に付与しないでください。
サービスアカウントとエージェント
- GKE サービスエージェント
(
service-<PROJECT_NUMBER>@container-engine-robot.iam.gserviceaccount.com): 自動的に作成されます。ユーザーに代わってノード、ネットワーク、クラスターの操作を管理します。権限を削除または変更しないでください。 - ノードサービスアカウント:デフォルトでは、ノードは Compute Engine のデフォルトのサービスアカウントを使用します。本番環境では、最小限の権限を持つ専用の SA を作成し、ノードプールの構成で割り当ててください。
- Workload Identity:ポッドから Google Cloud API にアクセスするための推奨方法です。Kubernetes ServiceAccount を Google IAM ServiceAccount にマッピングします。詳細は上記のWorkload Identity の設定をご覧ください。
サービス間認証のパターン
GKE ワークロードに他の Google Cloud サービスへのアクセスを許可する一般的なパターンです。
# Grant a GKE workload access to Cloud Storage
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member "serviceAccount:<GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role "roles/storage.objectViewer" \
--quiet
# Grant a GKE workload access to Cloud SQL
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member "serviceAccount:<GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role "roles/cloudsql.client" \
--quiet
# Grant a GKE workload access to Pub/Sub
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member "serviceAccount:<GSA_NAME>@<PROJECT_ID>.iam.gserviceaccount.com" \
--role "roles/pubsub.subscriber" \
--quiet
いずれの場合も、Workload Identity を介して GSA を KSA にバインドする必要があります(上記の設定をご覧ください)。その後、ポッドは KSA を使用して GSA として認証します。