iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0
Kubernetes

異世界生存戰記:30天煉成GKE大師系列 第 6

Day6 GKE 服務的一張身份證 GKE IAM Workload Identity

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240920/201690170VigDzSSR9.png

前言

在雲端環境中,安全一直是所有 SRE 至關重要的議題,每個雲服務都有不同的最佳權限控管方式,從 AWS 轉移至GCP 後嘗試了在 GKE 中使用各種方式,例如:Instance Service Account, SA credential Json Token 踩了很多坑後,發現Workload Identity 才是 GKE 內權限控管的最佳實踐方式。本文將深入探討 GKE 的 Workload Identity 功能,說明其運作原理以及如何設定。

Workload Identity 簡介

為了解決 GKE 內的服務連接到其他 GCP 服務,Google 為 GKE 用戶推出 Workload Identity 功能,透過建立 GKE Service Account 和 Cloud IAM Service Account 之間的關聯,用戶能夠定義Workload Identity,不需要管理 GKE Secret 機密資訊或是 IAM Service Account Token,GKE 應用程式就能自動地存取其他雲端服務。

GKE Service Account 與 Cloud IAM Service Account 之間的關聯是由 Identity Namespace 定義,當用戶在 GKE 叢集啟用 Workload Identity 之後,專案會便會收到 Identity Namespace,共用 GKE Service Account 名稱、GKE Namespace 以及 Identity Namespace 的應用程式,將獲得存取 Cloud IAM Service Account 的權限。

以下圖為例,左側 GKE Cluster 中有兩個 Namespace,當中各有自己的 Service Account,各自綁定到GKE 外部不同的 GCP IAM 的 Service Account,然後 GCP IAM 中的 Service Account 有各自訪問不同 GCP Pub/Sub 服務的權限,如此一來 GKE 內的 Pod 即可以 Service Account 來訪問 GKE 外的其他服務。

https://ithelp.ithome.com.tw/upload/images/20240920/201690172JbwrjwhtU.png

先到 GKE Custer 設定打開 GKE Workload Identity
https://ithelp.ithome.com.tw/upload/images/20240920/20169017wphS3DbqXS.png

接下來讓我們使用 Terraform 來建立 Workload Identity , GKE Service Account ,IAM Policy Binding,當然也可以使用指令創建,這邊就以 Terraform 來作為示範

# main.tf

module "service_accounts_workload_identity" {
  source = "terraform-google-modules/kubernetes-engine/google//modules/workload-identity"

  project_id                      = var.project
  cluster_name                    = var.k8s_cluster
  location                        = var.k8s_location
  automount_service_account_token = true

  for_each            = var.service_accounts
  name                = each.key
  gcp_sa_name         = each.value.gcp_service_account
  k8s_sa_name         = each.value.k8s_service_account
  namespace           = each.value.k8s_service_account_namespace
  use_existing_gcp_sa = each.value.use_existing_gcp_sa
  use_existing_k8s_sa = each.value.use_existing_k8s_sa
  roles               = each.value.roles
  additional_projects = each.value.additional_projects
}
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.14.0"
    }
  }
  required_version = ">= 0.14"
}
provider "google" {
  project     = var.project
  region      = var.region
  zone        = var.zone
}
provider "google-beta" {
  project     = var.project
}
provider "kubernetes" {
  host  = "https://${data.google_container_cluster.k8s_cluster.endpoint}"
  token = data.google_client_config.default.access_token
  cluster_ca_certificate = base64decode(
    data.google_container_cluster.k8s_cluster.master_auth[0].cluster_ca_certificate,
  )
}
# variable.tf

data "google_container_cluster" "k8s_cluster" {
  name     = var.k8s_cluster
  location = var.k8s_location
}
data "google_client_config" "default" {}

# 填入GKE專案名
variable "project" {
  description = "GCP project ID"
  type        = string
  default     = "ithome-202409-demo-2"
}
# 填入地區
variable "region" {
  description = "Name of the GCP region"
  type        = string
  default     = "us-central1"
}
variable "zone" {
  description = "Name of the GCP region"
  type        = string
  default     = "us-central1-a"
}
# 填入GKE名稱
variable "k8s_cluster" {
  default = "demo2-cluster"
}
# 填入GKE地區
variable "k8s_location" {
  default = "us-central1"
}

## Service Account
variable "service_accounts" {
  default = {
    cert-manager = {
      gcp_service_account           = "cert-manager"
      k8s_service_account           = "cert-manager"
      k8s_service_account_namespace = "cert-manager"
      use_existing_gcp_sa           = false
      use_existing_k8s_sa           = false
      roles = [
      ],
      # 填入管理 Cloud DNS 所在的專案
      additional_projects = {
        "ithome-202409-demo" = [
          "roles/dns.admin"
        ]
      }
    }
  }
}

在 ithome-202409-demo-2 專案下創建 cert-manager@ithome-202409-demo-2.iam.gserviceaccount.com 服務帳戶,此帳戶具有 ithome-202409-demo 專案的 DNS 管理員權限,IAM Policy Binding 到 cert-manager 命名空間下的 cert-manager 服務帳戶

以下表來說明

GCP 服務帳戶 角色 GKE 服務帳戶 GKE Namespace
cert-manager@ithome-202409-demo-2.iam.gserviceaccount.com ithome-202409-demo專案下的 DNS Administrator cert-manager cert-manager

成功後的 GCP IAM

https://ithelp.ithome.com.tw/upload/images/20240920/2016901745n27Ya2l7.png

會發現 GKE 內的 Service Account 會多一個 Annotation

metadata:
  annotations:
    iam.gke.io/gcp-service-account: cert-manager@ithome-202409-demo-2.iam.gserviceaccount.com

https://ithelp.ithome.com.tw/upload/images/20240920/20169017Oq7vwxynDv.png

總結

Workload Identity 是 GCP GKE 中特有的權限管理方式,解決了自己困擾了很久的 GKE Pod IAM 問題,無需在 GKE 內加入敏感資訊,例如:Token, Secret Key等,既可以防止金鑰洩漏,且方便進行服務的權限稽核,再配合上 Terraform 自動化使 SRE 的日常權限控管更加方便。

參考文件


上一篇
Day5 域名解析的利器 GCP Cloud DNS
下一篇
Day7 掌控流量入門 GKE NEG Service and Ingress
系列文
異世界生存戰記:30天煉成GKE大師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言