Chuyển đổi SA key sang Workload Identity

Bài viết được sự cho phép của tác giả Trần Nhật Trường

I. GIỚI THIỆU

Thay vì sử dụng Service Account keysWorkload Identity cho phép các workload xác thực bằng cách sử dụng danh tính của chúng mà không cần lưu trữ các khóa bí mật.

Workload Identity là một tính năng của Google Cloud cho phép bạn quản lý và cấp phát danh tính cho các workload (ứng dụng, dịch vụ) chạy trên Google Cloud hoặc trên các môi trường khác như Kubernetes hay các cloud khác. Workload Identity giúp giảm thiểu việc quản lý và sử dụng các khóa dịch vụ (Service Account keys), thay vào đó, nó sử dụng danh tính liên kết để ủy quyền và truy cập tài nguyên.

Chuyển đổi SA key sang Workload Identity

II. HƯỚNG DẪN

1. Cấu hình trên GCP

Để chuyển đổi Service Account (SA) key sang Workload Identity trên Google Cloud, bạn cần làm theo các bước sau:

Bước 1: Tạo một Workload Identity Pool

– Mở Google Cloud Console.

– Điều hướng tới “IAM & Admin” > “Workload Identity Federation”.

– Nhấp vào “Create Pool” và cung cấp các thông tin cần thiết như tên pool, ID, và mô tả.

gcloud iam workload-identity-pools create my-pool \
  --project="PROJECT_ID" \
  --location="global" \
  --display-name="My Workload Identity Pool"

Bước 2: Thêm một Provider vào Workload Identity Pool

– Sau khi tạo pool, chọn pool đó và nhấp vào “Add Provider”.

– Chọn loại provider phù hợp với dịch vụ của bạn (như OIDC, AWS, v.v.).

– Cung cấp các thông tin cần thiết như URL của nhà cung cấp danh tính, các claim mapping, và các điều kiện lọc.

gcloud iam workload-identity-pools providers create-oidc my-provider \
  --project="PROJECT_ID" \
  --location="global" \
  --workload-identity-pool="my-pool" \
  --display-name="My Provider" \
  --issuer-uri="https://accounts.google.com"

Bước 3: Liên kết Service Account với Workload Identity

Tạo một ràng buộc IAM để liên kết Service Account với Workload Identity. Sử dụng lệnh gcloud để tạo ràng buộc:

gcloud iam service-accounts add-iam-policy-binding [SERVICE_ACCOUNT_EMAIL] \ --role=roles/iam.workloadIdentityUser \ --member="principal://iam.googleapis.com/projects/[PROJECT_NUMBER]/locations/global/workloadIdentityPools/[POOL_ID]/subject/[SUBJECT]"

Bước 4: Cấu hình GKE sử dụng Workload Identity

Tạo Service Account Kubernetes và liên kết với Google Cloud Service Account:

kubectl create serviceaccount KSA_NAME --namespace K8S_NAMESPACE

gcloud iam service-accounts add-iam-policy-binding "SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/iam.workloadIdentityUser" \
  --member="serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/KSA_NAME]"

Gán Service Account cho Pod:

apiVersion: v1
kind: Pod
metadata:
  name: POD_NAME
  namespace: K8S_NAMESPACE
spec:
  serviceAccountName: KSA_NAME
  containers:
  - name: CONTAINER_NAME
    image: IMAGE

  So sánh AWS, Google Cloud và Azure năm 2024

  Google Cloud hướng tới hỗ trợ tất cả dữ liệu phi cấu trúc

2. Cấu hình trên ứng dụng

Cập nhật ứng dụng của bạn để sử dụng chứng chỉ của provider thay vì sử dụng SA key.

Tùy thuộc vào ngôn ngữ lập trình và môi trường, cấu hình có thể khác nhau, ta sẽ cần cung cấp đường dẫn tới file cấu hình hoặc thiết lập các biến môi trường.

Bước 4: Cấu hình ứng dụng để sử dụng Workload Identity

Ví dụ 1: Sử dụng Google Cloud Storage trong Spring Boot:

Thêm thư viện Google Cloud vào dự án Spring Boot:

1
2
3
4
5
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-storage</artifactId>
    <version>2.1.7</version>
</dependency>

Code ứng dụng Spring Boot:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class StorageController {
    private final Storage storage;
    public StorageController() {
        // Tạo một client mới cho Google Cloud Storage
        this.storage = StorageOptions.getDefaultInstance().getService();
    }
    @GetMapping("/buckets")
    public String listBuckets() {
        StringBuilder bucketNames = new StringBuilder();
        for (Bucket bucket : storage.list().iterateAll()) {
            bucketNames.append(bucket.getName()).append("\n");
        }
        return bucketNames.toString();
    }
}

Cấu hình ứng dụng:

Ta không cần thêm cấu hình đặc biệt nào trong ứng dụng Spring Boot vì thư viện Google Cloud Client Library sẽ tự động phát hiện các chứng chỉ từ môi trường khi chạy trên GKE với Workload Identity.

Lưu ý:

Đảm bảo rằng ta đã cài đặt và cấu hình gcloud, kubectl. Kiểm tra và thay thế tất cả các biến PROJECT_ID, SERVICE_ACCOUNT_NAME, K8S_NAMESPACE, KSA_NAME, POD_NAME, CONTAINER_NAME, IMAGE

Tham khảo việc làm Cloud cao, hấp dẫn trên TopDev!

Ví dụ 2: Đối với GOLANG

Cài đặt thư viện Google Cloud Client cho Golang:

1
go get cloud.google.com/go

Sử dụng thư viện trong ứng dụng Golang: Trong ví dụ này, storage.NewClient(ctx) tự động phát hiện các chứng chỉ từ môi trường của GKE, nhờ cấu hình Workload Identity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main
import (
    "context"
    "log"
    "cloud.google.com/go/storage"
)
func main() {
    ctx := context.Background()
    // Tạo client mới cho Google Cloud Storage
    client, err := storage.NewClient(ctx)
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }
    // Sử dụng client để tương tác với Google Cloud Storage
    buckets, err := client.Buckets(ctx, "YOUR_PROJECT_ID")
    if err != nil {
        log.Fatalf("Failed to list buckets: %v", err)
    }
    for buckets.Next() {
        log.Println(buckets.Attrs().Name)
    }
    if err := buckets.Err(); err != nil {
        log.Fatalf("Bucket iterator error: %v", err)
    }
}
Thay vì sử dụng option.WithCredentialsFile(“path/to/your/credentials/file.json”) (case sử dụng SA key), ta có thể cấu hình ứng dụng sử dụng chứng chỉ được tự động phát hiện từ môi trường khi chạy trên GKE với Workload Identity.

BONUS

Vậy với GCE (Compute engine) a.k.a VM thì có phương pháp nào không phải sử dụng SA key không? Câu trả lời là có.

Để một ứng dụng chạy trên VM của Google Cloud Platform (GCP) sử dụng service account của VM đó mà không cần sử dụng Service Account key (SA key), bạn có thể cấu hình VM để sử dụng Application Default Credentials (ADC). Đây là phương pháp được khuyến nghị vì nó đơn giản hơn và an toàn hơn so với việc quản lý và sử dụng SA key thủ công. Đọc thêm bài viết này để hiểu ADC hoạt động như nào https://cloud.google.com/docs/authentication/application-default-credentials.

Vậy ADC có thể apply cho cả GKE, vậy sao không dùng luôn ADC mà lại dùng Workload Identity? Lý do là:

– ADC thiếu Pod-level Identity: ADC không hỗ trợ việc ánh xạ danh tính tới mức pod. Tất cả các pod trên cùng một node sẽ chia sẻ cùng một service account, dẫn đến quyền truy cập rộng hơn và khó kiểm soát chi tiết.

– ADC không Hỗ trợ Kubernetes RBAC: ADC không tích hợp với hệ thống Role-based Access Control (RBAC) của Kubernetes, dẫn đến khó khăn trong việc quản lý và gán quyền truy cập chi tiết.

– Workload Identity có khả năng liên kết với các nhà cung cấp danh tính bên ngoài như AWS, Azure, hoặc hệ thống OIDC, giúp mở rộng khả năng xác thực và quản lý danh tính cho các workload đa đám mây. ADC không cung cấp khả năng này.

Bài viết gốc được đăng tải tại nhattruong.blog

Xem thêm: