GKE Workload Identity
Scenario
使用 GKE 中的某個 pod 可連線至 GCS 不用匯入任何 token 資訊,同理,其他 pod 欲使用 service account 授權 GCP 上任何資源,只要透過 Workload Identity 亦可不用匯入 key 資訊至 secret 中。
實做方式
- 分別建立 GKE 與 Workload Identity 自定義 service account
- 使用所上述之 service account 建立 GKE
- 建立 K8S service account 並綁定 GKE service account
- 使用 K8S service account 於 Pod 中
建立 service account
依照最小權限原則,GKE 上的 node 使用的 service account 僅提供以下權限
- logging.logWriter
- monitoring.metricWriter
- monitoring.viewer
- stackdriver.resourceMetadata.writer
1export PROJECT_ID="${DEVSHELL_PROJECT_ID}"2export SA_NAME="gke-sa"3gcloud iam service-accounts create ${SA_NAME} \4 --description="GKE Cluster sa" \5 --display-name="${SA_NAME}"6gcloud projects add-iam-policy-binding ${PROJECT_ID} \7 --member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \8 --role="roles/logging.logWriter" \9 --role="roles/monitoring.metricWriter" \10 --role="roles/monitoring.viewer" \11 --role="roles/stackdriver.resourceMetadata.writer"建立 GKE
建立 GKE 時記得選用 GKE 專用的 service account

同時開啟 Workload Identity

綁定 GKE 內與 GCP 的 service account
- 建立一組 GCP service account 名為 workload 作為 workload identity 使用
1# 先取得 GKE 連線資訊2gcloud container clusters get-credentials ricky-lab --zone us-central1-c --project ${PROJECT_ID}3# 建立 workload GCP service account 並與 GKE 內 service account 綁定4export WK_SA_NAME="workload"5gcloud iam service-accounts create ${WK_SA_NAME} \6 --description="workload sa" \7 --display-name="${WK_SA_NAME}"8gcloud iam service-accounts add-iam-policy-binding \9--role="roles/iam.workloadIdentityUser" \10--member="serviceAccount:${PROJECT_ID}.svc.id.goog[demo/demosa]" \11${WK_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com12# 建立 GKE 內的 namespace 與 service account13kubectl create ns demo14kubectl -n demo create serviceaccount demosa15kubectl -n demo annotate serviceaccount demosa iam.gke.io/gcp-service-account=${WK_SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com驗證方式
使用 cloudsdk image建立測試
1echo 'apiVersion: v12kind: Pod3metadata:4 labels:5 run: gcloud6 name: gcloud7 namespace: demo8spec:9 containers:10 - name: gcloud11 image: gcr.io/google.com/cloudsdktool/cloud-sdk:latest12 command:13 - sleep14 - "86400"15 serviceAccountName: demosa' > gcloud.yaml16kubectl apply -f gcloud.yaml17kubectl -n demo exec -it gcloud -- bash18
19# 確認是否取得 service account 身分,成功則會出現該 workload service account20curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/21# 於 pod 使用 gsutil 指令會無法正常列出檔案,於 GCP service account 中加入 viever 權限後即可看見指定 bucket 檔案22gsutil ls疑難排解
- 使用 workload identity,如果一開始沒開啟 workload identity 事後開啟時
- 用預設 GCP service account 會出現 service account 無法正常切換問題,此時直接建立新 node pool 並使用其他 service account 即可
- 如果使用自訂 GCP service account 一樣要重新建立 node pool,將 workload 移轉過去新的 node pool 才會套用,否則仍會用到 GCE node 上的 service account