4 min read

GCP GKE 掛載 cloud storage

以下操作將會使用到 GCP IAM 服務帳戶, Cloud Stroage 這兩個服務

大致上分為以下幾個步驟

  1. 創建IAM 服務帳戶
  2. 創建 cloud storage bucket 及給予權限
  3. 返回第一步驟,並配置關鍵的GKE SA帳號(請注意格式!)


1.創建服務帳戶

IAM -> 服務帳戶 -> +建立服務帳戶 創建一組給 cloud storage專用的帳號 ,名稱可以自定義,主要是服務帳戶ID(右圖)稍後會用到,權限具備存取權的主體預設配置即可。

2.創建 cloud storage bucket

選擇授予存取權 -> 新增主體

  1. 主體 -> 上方創建的IAM服務帳戶email。
  2. 角色 -> 儲存空間物件管理員。

3.返回IAM服務帳戶

接下來要到最關鍵的環節,配置具備存取權的主體要填入給GKE使用的SA帳號。

格式為 {project_id}.svc.id.goog[{gke_namespace}/{sa_name}]

example:

  1. GCP 帳號ID為 wooo1314
  2. GKE namespace prod
  3. GKE service Account php

則填入 woo1314.svc.id.goog[prod/php]


最後

以下是使用的範例

apiVersion: v1
kind: ServiceAccount
metadata:
  name: storage-sa
  namespace: prod
  annotations:
    iam.gke.io/gcp-service-account: [email protected]
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php
  namespace: prod
spec:
  selector:
    matchLabels:
      app: php
  template:
    metadata:
      labels:
        app: php
      annotations:
        gke-gcsfuse/volumes: "true"
        # gke-gcsfuse/ephemeral-storage-limit: "5Gi"
    spec:
      serviceAccountName: storage-sa
      containers:
      - name: php
        image: asia-east1-docker.pkg.dev/1234/5678/php
        ports:
        - containerPort: 80
          name: http
        readinessProbe:
          httpGet:
            path: /api/app/version
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 15
        imagePullPolicy: Always
        workingDir: /app
        resources:
          limits:
            cpu: "1000m"
            memory: "2096Mi"
          requests:
            cpu: "500m"
            memory: "200Mi"
        volumeMounts:
        - name: gcs-fuse
          mountPath: /app/http/static
      volumes:
      - name: gcs-fuse
        csi:
          driver: gcsfuse.csi.storage.gke.io
          volumeAttributes:
            bucketName: test-1230-v2 # 輸入創建的bucketName
            mountOptions: "implicit-dirs,http-client-timeout=10s,stat-cache-ttl=1m"

透過glcoud 一鍵快捷

#!/bin/bash
set -e # 遇到錯誤立即停止

# ==========================================
# 1. 設定您的變數 (請修改這裡)
# ==========================================
PROJECT_ID="xxx-xxx"      # 您的 GCP Project ID
CLUSTER_NAME="test-1"               # GKE 集群名稱
REGION="asia-east1"                 # GKE 集群區域
NAMESPACE="prod"                    # K8s Namespace
BUCKET_NAME="test-bucket"           # 要創建/使用的 Bucket 名稱
GSA_NAME="test-storage"        # GCP Service Account 名稱
KSA_NAME="test-storage"        # K8s Service Account 名稱

# ==========================================
# 2. 開始執行 GCP 設定
# ==========================================
echo "=== 正在切換專案到 $PROJECT_ID ==="
gcloud config set project $PROJECT_ID

echo "=== 正在啟用必要的 API ==="
gcloud services enable container.googleapis.com storage.googleapis.com iam.googleapis.com

echo "=== 正在檢查/創建 Bucket: gs://$BUCKET_NAME ==="
if ! gcloud storage buckets describe gs://$BUCKET_NAME > /dev/null 2>&1; then
    gcloud storage buckets create gs://$BUCKET_NAME --location=$REGION
    echo "Bucket 已創建。"
else
    echo "Bucket 已存在,跳過創建。"
fi

echo "=== 正在創建 GCP Service Account: $GSA_NAME ==="
if ! gcloud iam service-accounts describe $GSA_NAME@$PROJECT_ID.iam.gserviceaccount.com > /dev/null 2>&1; then
    gcloud iam service-accounts create $GSA_NAME --display-name="GCS FUSE Access for GKE"
    echo "SA 創建請求已發送,正在等待權限傳播 (30秒)..."
    sleep 30  # <--- 加入這行等待
else
    echo "SA 已存在,跳過創建。"
fi

echo "=== 正在賦予 Bucket 權限 (Storage Object Admin) ==="
gcloud storage buckets add-iam-policy-binding gs://$BUCKET_NAME \
    --member "serviceAccount:$GSA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
    --role "roles/storage.objectAdmin"

echo "=== 正在綁定 Workload Identity (允許 K8s SA 扮演 GCP SA) ==="
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]"