Google Cloud での Workload Identity の使用

このガイドでは、GKE on AWS で Workload Identity を構成して GCP リソースへのワークロードのアクセスを制御する方法について説明します。これには、ID を使用してクラスタから Google Cloud リソースにアクセスする方法の例が含まれます。

AWS IAM アカウントで Workload Identity を使用して AWS リソースへのアクセスを制御する方法については、AWS での Workload Identity の使用をご覧ください。

概要

Workload Identity は、Google Cloud IAM 権限を使用して、Google Cloud リソースへのアクセスを制御します。Workload Identity を使用すると、各ワークロードに異なる IAM のロールを割り当てることができます。権限をきめ細かく制御することで、最小権限の原則に準拠できます。Workload Identity を使用しない場合は、GKE on AWS ノードに Google Cloud IAM のロールを割り当て、これらのノード上のすべてのワークロードにノード自体と同じ権限を付与する必要があります。

前提条件

  • Kubernetes バージョン v1.20 以降を使用して、ユーザー クラスタを作成する

  • AWS VPC でプロキシやファイアウォールを使用する場合は、次の URL を許可リストに登録する。

    • securetoken.googleapis.com
    • iamcredentials.googleapis.com
    • sts.googleapis.com
  • anthos-aws ディレクトリから anthos-gke を使用して、コンテキストをユーザー クラスタに切り替えます。

    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    CLUSTER_NAME は、ユーザー クラスタ名に置き換えます。

  • 次のコマンドを実行して、この機能に必要な 4 つの新しいサービスを有効にする。

    gcloud services enable securetoken.googleapis.com
    gcloud services enable iam.googleapis.com
    gcloud services enable iamcredentials.googleapis.com
    gcloud services enable sts.googleapis.com
    

WI プールとプロバイダ名を作成する

各 Google Cloud プロジェクトには、PROJECT_ID.svc.id.goog という形式の名前を持つマネージド Workload Identity プールが自動的に作成されます。同様に、Google Cloud は、https://gkehub.googleapis.com/projects/PROJECT_ID/locations/global/memberships/MEMBERSHIP_ID というパターンの名前で ID プロバイダを作成します。Workload Identity プールの詳細については、フリート対応コンポーネントをご覧ください。プロジェクト ID とメンバーシップ ID から、次の例のように名前を作成します。

export PROJECT_ID=USER_PROJECT_NAME
export CLUSTER_MEMBERSHIP_ID=PROJECT_MEMBERSHIP_NAME
export IDP="https://gkehub.googleapis.com/projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_MEMBERSHIP_ID}"
export WI_POOL="${PROJECT_ID}.svc.id.goog"

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

  • USER_PROJECT_NAME: ユーザーが選択したユーザー プロジェクト名
  • PROJECT_MEMBERSHIP_NAME: クラスタのメンバーシップ名

IAM ポリシー バインディングを作成する

Kubernetes サービス アカウント(KSA)に Google Cloud サービス アカウント(GSA)の権限借用を許可するポリシー バインディングを作成します。

export K8S_NAMESPACE=KUBERNETES_NAMESPACE
export KSA_NAME=KUBERNETES_SA_NAME
export GCP_SA_EMAIL="WORKLOAD_IDENTITY_TEST@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts add-iam-policy-binding \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:$WI_POOL[$K8S_NAMESPACE/$KSA_NAME]" $GCP_SA_EMAIL

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

  • KUBERNETES_NAMESPACE: Kubernetes サービス アカウントが定義されている Kubernetes Namespace
  • WORKLOAD_IDENTITY_TEST: 任意のワークロード名
  • KUBERNETES_SA_NAME: アプリケーションに関連付けられている Kubernetes サービス アカウントの名前

SDK ConfigMap を作成する

下のシェル スクリプトを実行して、Workload Identity の詳細を ConfigMap に保存します。Pod が ConfigMap をマウントすると、Google Cloud CLI は Workload Identity の詳細を読み取ることができます。

cat << EOF > cfmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
  namespace: ${K8S_NAMESPACE}
  name: my-cloudsdk-config
data:
  config: |
    {
      "type": "external_account",
      "audience": "identitynamespace:${WI_POOL}:${IDP}",
      "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${GCP_SA_EMAIL}:generateAccessToken",
      "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
      "token_url": "https://sts.googleapis.com/v1/token",
      "credential_source": {
        "file": "/var/run/secrets/tokens/gcp-ksa/token"
      }
    }
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f cfmap.yaml

Kubernetes サービス アカウントを作成する

IAM バインディングで使用したものと同じ名前と Namespace で KSA を作成します。

cat << EOF > k8s-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ${KSA_NAME}
  namespace: ${K8S_NAMESPACE}
EOF

env HTTPS_PROXY=http://localhost:8118 \
  kubectl apply -f k8s-service-account.yaml

Pod を作成する

次に、上で作成したサービス アカウント トークンのプロジェクションと ConfigMap を含む Pod を作成します。

  1. Pod のサンプル YAML ファイルを作成します。

    cat << EOF > sample-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      namespace: ${K8S_NAMESPACE}
    spec:
      serviceAccountName: ${KSA_NAME}
      containers:
      - command:
        - /bin/bash
        - -c
        - while :; do echo '.'; sleep 500 ; done
        image: google/cloud-sdk
        name: cloud-sdk
        env:
          - name: GOOGLE_APPLICATION_CREDENTIALS
            value: /var/run/secrets/tokens/gcp-ksa/google-application-credentials.json
        volumeMounts:
        - name: gcp-ksa
          mountPath: /var/run/secrets/tokens/gcp-ksa
          readOnly: true
      volumes:
      - name: gcp-ksa
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              path: token
              audience: ${WI_POOL}
              expirationSeconds: 172800
          - configMap:
              name: my-cloudsdk-config
              optional: false
              items:
               - key: "config"
                 path: "google-application-credentials.json"
    EOF
    
  2. Pod の YAML をクラスタに適用します。

    env HTTPS_PROXY=http://localhost:8118 \
     kubectl apply -f sample-pod.yaml
    

Google Cloud Workload Identity の使用

サポートされている SDK バージョン

Google Cloud Workload Identity 機能を使用するには、サポートされている SDK を使用してコードをビルドする必要があります。Google Cloud Workload Identity をサポートする SDK バージョンのリストについては、フリートの Workload Identity をご覧ください。

Workload Identity を使用するサンプルコード

このセクションでは、Google Cloud Workload Identity を使用する Python コードのサンプルを示します。このサンプルのサービス アカウントは、Cloud Storage 管理者権限を持つ ID を使用して、すべての Google Cloud プロジェクトの Cloud Storage バケットのリストを取得します。

  1. Pod 内でシェルを実行します。

    env HTTPS_PROXY=http://localhost:8118 \
    kubectl exec -it sample-pod -- bash
    
  2. スクリプトを実行して、プロジェクトのストレージ バケットのリストを取得します。

    # execute these commands inside the Pod
    pip install --upgrade google-cloud-storage
    
    cat << EOF > sample-list-bucket.py
    from google.cloud import storage
    storage_client = storage.Client()
    buckets = storage_client.list_buckets()
    
    for bucket in buckets:
      print(bucket.name)
    EOF
    
    env GOOGLE_CLOUD_PROJECT=USER_PROJECT_NAME \
     python3 sample-list-bucket.py
    

    USER_PROJECT_NAME は、Google Cloud プロジェクトに置き換えます。

さらに詳しい情報