本主題說明如何為 GKE on AWS 工作負載啟用 Workload Identity,以控管其 AWS 資源存取權。
如要瞭解如何搭配使用 Workload Identity 與 Google Cloud Identity and Access Management (IAM) 帳戶,控管 GCP 資源的存取權,請參閱「搭配使用 Workload Identity 與 Google Cloud」。
總覽
Workload Identity 會使用 AWS IAM 權限控管雲端資源的存取權。透過工作負載身分,您可以為每個工作負載指派不同的 IAM 角色。您可以透過這項精細的權限控管機制,遵循最低權限原則。如果沒有 Workload Identity,您必須將 AWS IAM 角色指派給 GKE on AWS 節點,讓節點上的所有工作負載都擁有與節點本身相同的權限。
如要為叢集啟用 Workload Identity,請完成下列步驟,這些步驟會依執行步驟的管理員角色分組。
叢集管理員
- 建立 Cloud Storage bucket,以儲存 OIDC 探索資料。
- 建立 Identity and Access Management 角色,從該 bucket 讀取資料。
- 建立啟用 Workload Identity 的使用者叢集。
- 在叢集上建立Webhook,在建立 Pod 時套用 Workload Identity 憑證。如果不想使用 Webhook,可以在 Pod 中手動設定環境變數。
- 設定 AWS OIDC 提供者。
- 建立 AWS IAM 角色和政策。
- 建立 Kubernetes 服務帳戶,並將 AWS 政策繫結至這些帳戶。
必要條件
如要完成本文中的步驟,您必須進行下列設定:
- GKE on AWS 管理服務。
執行 Kubernetes 版本高於 1.17.9 的使用者叢集。
下列權限和工具。
權限
如要建立啟用 Workload Identity 的叢集,您需要下列權限:
Google Cloud
- 建立可公開讀取的 Cloud Storage bucket,並啟用統一 bucket 層級存取權。
- 授予 bucket 讀取/寫入權限。
management-sa@PROJECT_NAME.iam.gserviceaccount.com
AWS
- 建立 AWS OIDC 供應商
- 建立 AWS 身分與存取權管理角色
工具
建議在本機電腦上安裝 jq
工具。
建立 OIDC 探索值區
本節適用於叢集管理員。
使用者叢集必須將 OIDC 探索資料儲存在可公開存取的 Cloud Storage 值區中。這個 bucket 包含 OIDC 探索設定和公開金鑰。AWS 會使用這些內容驗證來自使用者叢集的要求。
值區必須具備下列屬性:
如果沒有具備這些屬性的值區,請使用下列 gcloud storage
指令建立一個:
BUCKET=BUCKET_NAME
gcloud storage buckets create gs://${BUCKET} --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \
--member=allUsers --role=roles/storage.objectViewer
將 BUCKET_NAME
替換為新值區的名稱。
授予管理服務帳戶權限
GKE on AWS 管理服務的身分與存取權管理服務帳戶,需要具備在這個值區中讀取及寫入物件的權限。
使用下列指令授予管理服務帳戶權限。
MANAGEMENT_SA=management-sa@PROJECT_NAME.iam.gserviceaccount.com gcloud storage buckets add-iam-policy-binding gs://${BUCKET} \ --member=serviceAccount:${MANAGEMENT_SA} \ --role=roles/storage.admin
將
PROJECT_NAME
替換為您的 Google Cloud 專案。建立新的 IAM 角色,並授予管理這個值區的權限。 如要建立角色,請先將角色定義儲存至檔案,然後建立角色,並將角色繫結至管理服務帳戶。
如要完成這些步驟,請執行下列指令:
cat << EOF > anthos-oidc-role.yaml title: anthosAwsOidcStorageAdmin description: permissions to manage the OIDC buckets stage: GA includedPermissions: - storage.buckets.get EOF gcloud iam roles create anthosAwsOidcStorageAdmin --project=PROJECT_NAME \ --file=anthos-oidc-role.yaml gcloud projects add-iam-policy-binding \ PROJECT_NAME \ --member=serviceAccount:${MANAGEMENT_SA} \ --role=projects/PROJECT_NAME/roles/anthosAwsOidcStorageAdmin
將
PROJECT_NAME
替換為您的 Google Cloud 專案。Google Cloud CLI 會確認已建立政策繫結。
建立使用者叢集
本節適用於叢集管理員。
建立啟用 Workload Identity 的使用者叢集
建立使用者叢集,其中包含 OIDC 探索 bucket 的詳細資料。您可以在 AWSCluster
的 spec.controlPlane.workloadIdentity.oidcDiscoveryGCSBucket
欄位中設定這項資訊。
在本範例中,您會從 AWSCluster
和 AWSNodePool
CRD 手動建立叢集。
切換至 GKE on AWS 設定所在的目錄。 您在安裝管理服務時建立了這個目錄。
cd anthos-aws
從
anthos-aws
目錄使用anthos-gke
將環境切換至管理服務。cd anthos-aws anthos-gke aws management get-credentials
開啟文字編輯器,然後將下列
AWSCluster
定義複製到名為custom-cluster.yaml
的檔案中。apiVersion: multicloud.cluster.gke.io/v1 kind: AWSCluster metadata: name: CLUSTER_NAME spec: region: AWS_REGION networking: vpcID: VPC_ID podAddressCIDRBlocks: POD_ADDRESS_CIDR_BLOCKS serviceAddressCIDRBlocks: SERVICE_ADDRESS_CIDR_BLOCKS ServiceLoadBalancerSubnetIDs: SERVICE_LOAD_BALANCER_SUBNETS controlPlane: version: CLUSTER_VERSION # Latest version is 1.25.5-gke.2100 instanceType: AWS_INSTANCE_TYPE keyName: SSH_KEY_NAME subnetIDs: - CONTROL_PLANE_SUBNET_IDS securityGroupIDs: - CONTROL_PLANE_SECURITY_GROUPS iamInstanceProfile: CONTROL_PLANE_IAM_ROLE rootVolume: sizeGiB: ROOT_VOLUME_SIZE volumeType: ROOT_VOLUME_TYPE # Optional iops: ROOT_VOLUME_IOPS # Optional kmsKeyARN: ROOT_VOLUME_KEY # Optional etcd: mainVolume: sizeGiB: ETCD_VOLUME_SIZE volumeType: ETCD_VOLUME_TYPE # Optional iops: ETCD_VOLUME_IOPS # Optional kmsKeyARN: ETCD_VOLUME_KEY # Optional databaseEncryption: kmsKeyARN: ARN_OF_KMS_KEY hub: # Optional membershipName: ANTHOS_CONNECT_NAME cloudOperations: # Optional projectID: YOUR_PROJECT location: GCP_REGION enableLogging: ENABLE_LOGGING enableMonitoring: ENABLE_MONITORING workloadIdentity: # Optional oidcDiscoveryGCSBucket: WORKLOAD_IDENTITY_BUCKET
更改下列內容:
- CLUSTER_NAME:叢集名稱。
AWS_REGION:叢集執行的 AWS 區域。
VPC_ID:叢集執行的 VPC ID。
POD_ADDRESS_CIDR_BLOCKS:叢集 Pod 使用的 IPv4 位址範圍。目前僅支援單一範圍。這個範圍不得與可從網路連線的任何子網路重疊。在多個不同的 AWSCluster 物件中使用相同範圍是安全的。例如:
10.2.0.0/16
。SERVICE_ADDRESS_CIDR_BLOCKS:叢集服務使用的 IPv4 位址範圍。目前僅支援單一範圍。這個範圍不得與可從網路連線的任何子網路重疊。 在多個不同的 AWSCluster 物件中使用相同範圍是安全的。例如:
10.1.0.0/16
。SERVICE_LOAD_BALANCER_SUBNETS:GKE on AWS 可在其中建立公開或私有負載平衡器的子網路 ID。
CLUSTER_VERSION:AWS 中的 GKE 支援的 Kubernetes 版本。最新版本為 1.25.5-gke.2100。
AWS_INSTANCE_TYPE:支援的 EC2 執行個體類型。
SSH_KEY_NAME:AWS EC2 金鑰組。
CONTROL_PLANE_SUBNET_IDS:控制層執行個體所在可用區的子網路 ID。
CONTROL_PLANE_SECURITY_GROUPS:在管理服務安裝期間建立的 securityGroupID。您可以新增連線至控制層所需的任何 securityGroupIDs,藉此自訂這項設定。
CONTROL_PLANE_IAM_PROFILE:指派給控制層副本的 AWS EC2 執行個體設定檔名稱。
ROOT_VOLUME_SIZE:控制平面根磁碟區的大小,以 GiB 為單位。
ROOT_VOLUME_TYPE,並使用 EBS 磁碟區類型。 例如:
gp3
。ROOT_VOLUME_IOPS,並根據磁碟區每秒佈建的 IO 作業量 (IOPS) 計算。只有在
volumeType
為GP3
時才有效。詳情請參閱通用 SSD 磁碟區 (gp3)。ROOT_VOLUME_KEY 替換為AWS KMS 金鑰的 Amazon 資源名稱,該金鑰會加密控制層執行個體根磁碟區。
ETCD_VOLUME_SIZE:etcd 使用的磁碟區大小。
ETCD_VOLUME_TYPE,並使用 EBS 磁碟區類型。 例如:
gp3
。ETCD_VOLUME_IOPS,並根據磁碟區每秒佈建的 IO 作業量 (IOPS) 計算。只有在
volumeType
為gp3
時才有效。詳情請參閱通用 SSD 磁碟區 (gp3)。ETCD_VOLUME_KEY,並提供用來加密控制平面 etcd 資料磁碟區的 AWS KMS 金鑰 Amazon Resource Name。
ARN_OF_KMS_KEY:用於加密叢集密鑰的 AWS KMS 金鑰。
ANTHOS_CONNECT_NAME:用於註冊叢集的 Connect 會員名稱。會員方案名稱不得重複。例如:
projects/YOUR_PROJECT/locations/global/memberships/CLUSTER_NAME
, 其中YOUR_PROJECT
是您的 Google Cloud 專案,CLUSTER_NAME
則是專案中的專屬名稱。 這是選填欄位。YOUR_PROJECT:您的專案 ID。
GCP_REGION:您要儲存記錄的 Google Cloud 區域。 選擇鄰近 AWS 區域的區域。詳情請參閱「全球據點 - 區域和可用區」,例如
us-central1
。ENABLE_LOGGING:
true
或false
,指出控制平面節點是否已啟用 Cloud Logging。ENABLE_MONITORING:
true
或false
,控制層節點是否已啟用 Cloud Monitoring。WORKLOAD_IDENTITY_BUCKET:Cloud Storage bucket 名稱,其中包含工作負載身分探索資訊。這是選填欄位。
為叢集建立一或多個 AWSNodePool。開啟文字編輯器,然後將下列 AWSCluster 定義複製到名為
custom-nodepools.yaml
的檔案中。apiVersion: multicloud.cluster.gke.io/v1 kind: AWSNodePool metadata: name: NODE_POOL_NAME spec: clusterName: AWSCLUSTER_NAME version: CLUSTER_VERSION # latest version is 1.25.5-gke.2100 region: AWS_REGION subnetID: AWS_SUBNET_ID minNodeCount: MINIMUM_NODE_COUNT maxNodeCount: MAXIMUM_NODE_COUNT maxPodsPerNode: MAXIMUM_PODS_PER_NODE_COUNT instanceType: AWS_NODE_TYPE keyName: KMS_KEY_PAIR_NAME iamInstanceProfile: NODE_IAM_PROFILE proxySecretName: PROXY_SECRET_NAME rootVolume: sizeGiB: ROOT_VOLUME_SIZE volumeType: VOLUME_TYPE # Optional iops: IOPS # Optional kmsKeyARN: NODE_VOLUME_KEY # Optional
更改下列內容:
- NODE_POOL_NAME:AWSNodePool 的專屬名稱。
- AWSCLUSTER_NAME:AWSCluster 的名稱。例如:
staging-cluster
。 - CLUSTER_VERSION:支援的 GKE on AWS Kubernetes版本。
- AWS_REGION:與 AWSCluster 相同的 AWS 區域。
- AWS_SUBNET_ID:與 AWSCluster 位於相同區域的 AWS 子網路。
- MINIMUM_NODE_COUNT:節點集區中的節點數量下限。詳情請參閱調整使用者叢集大小。
- MAXIMUM_NODE_COUNT:節點集區中的節點數量上限。
- MAXIMUM_PODS_PER_NODE_COUNT:GKE on AWS 可分配給節點的 Pod 數量上限。
- AWS_NODE_TYPE:AWS EC2 執行個體類型。
- KMS_KEY_PAIR_NAME:指派給每個節點集區工作站的 AWS KMS 金鑰組。
- NODE_IAM_PROFILE:指派給集區中節點的 AWS EC2 執行個體設定檔名稱。
- ROOT_VOLUME_SIZE:控制平面根磁碟區的大小,以 GiB 為單位。
- VOLUME_TYPE:節點的 AWS
EBS 磁碟區類型。
例如:
gp3
。 - IOPS:磁碟區每秒佈建的 IO 作業數 (IOPS)。只有在
volumeType
為gp3
時才有效。 - NODE_VOLUME_KEY:用於加密磁碟區的 AWS KMS 金鑰 ARN。詳情請參閱「使用客戶管理的 CMK 加密磁碟區」。
將資訊清單套用至管理服務。
env HTTPS_PROXY=http://localhost:8118 \ kubectl apply -f custom-cluster.yaml env HTTPS_PROXY=http://localhost:8118 \ kubectl apply -f custom-nodepools.yaml
建立 kubeconfig
使用者叢集啟動時,您可以為新的使用者叢集建立 kubeconfig
環境。您可以使用這個內容向使用者或管理叢集進行驗證。
使用
anthos-gke aws clusters get-credentials
在~/.kube/config
中為使用者叢集產生kubeconfig
。env HTTPS_PROXY=http://localhost:8118 \ anthos-gke aws clusters get-credentials CLUSTER_NAME
將 CLUSTER_NAME 替換為叢集名稱。例如:
cluster-0
。使用
kubectl
向新的使用者叢集進行驗證。env HTTPS_PROXY=http://localhost:8118 \ kubectl cluster-info
如果叢集已準備就緒,輸出內容會包含叢集內 Kubernetes 元件的網址。
查看叢集狀態
當您套用 AWSCluster
或 AWSNodePool
時,管理服務會佈建 AWS 資源。
從
anthos-aws
目錄使用anthos-gke
將環境切換至管理服務。cd anthos-aws anthos-gke aws management get-credentials
如要列出叢集,請使用
kubectl get AWSClusters
。env HTTPS_PROXY=http://localhost:8118 \ kubectl get AWSClusters
輸出結果包含每個叢集的名稱、狀態、存在時間、版本和端點。
舉例來說,下列輸出內容只包含一個名為
cluster-0
的AWSCluster
:NAME STATE AGE VERSION ENDPOINT cluster-0 Provisioning 2m41s 1.25.5-gke.2100 gke-xyz.elb.us-east-1.amazonaws.com
查看叢集事件
如要查看使用者叢集的近期 Kubernetes 事件,請使用 kubectl get events
。
從
anthos-aws
目錄使用anthos-gke
將環境切換至管理服務。cd anthos-aws anthos-gke aws management get-credentials
執行
kubectl get events
。env HTTPS_PROXY=http://localhost:8118 \ kubectl get events
輸出內容包括與管理服務相關的資訊、警告和錯誤。
建立 Workload Identity Webhook
本節適用於叢集管理員。
如要為工作負載提供工作負載身分憑證,且不需額外設定,您可以在使用者叢集上建立 Webhook。這個 Webhook 會攔截 Pod 建立要求,然後將下列 AWS IAM 資訊做為 Pod 的環境變數:
AWS_ROLE_ARN
:IAM 角色的 Amazon Resource Name (ARN)aws-iam-token
:用來交換 AWS IAM 憑證的權杖AWS_WEB_IDENTITY_TOKEN_FILE
:權杖的儲存路徑
有了這些變數,工作負載就能呼叫 AWS 指令列工具或 SDK,存取 AWS 角色獲授權的資源。
您可以視需要建立 Webhook。如果您決定不建立 Webhook,則需要在 Pod 中設定先前列出的環境變數。如要瞭解如何不使用 Webhook 申請憑證,請參閱不使用 Webhook 申請憑證。
為 Webhook 建立 YAML 檔案
如要部署 Webhook,請執行下列步驟:
從
anthos-aws
目錄使用anthos-gke
將環境切換至管理服務。cd anthos-aws anthos-gke aws management get-credentials
使用
kubectl
取得使用者叢集名稱:env HTTPS_PROXY=http://localhost:8118 \ kubectl get awscluster
kubectl
會列出所有使用者叢集。選擇您建立的已啟用 Workload Identity 使用者叢集。在環境變數中設定叢集名稱。
CLUSTER_NAME=CLUSTER_NAME
將
CLUSTER_NAME
替換為叢集名稱。例如:cluster-0
。為工作負載身分 Pod 映像檔和命名空間設定環境變數。
IDENTITY_IMAGE=amazon/amazon-eks-pod-identity-webhook:ed8c41f WEBHOOK_NAMESPACE=workload-identity-webhook
執行下列步驟,在名為
aws-webhook.yaml
的檔案中產生 Webhook YAML 資訊清單:env HTTPS_PROXY=http://localhost:8118 \ anthos-gke aws clusters get-credentials ${CLUSTER_NAME} CLUSTER_CA=$(env HTTPS_PROXY=http://localhost:8118 \ kubectl config view --raw -o json | jq -r '.clusters[] | select(.name == "'$(kubectl config current-context)'") | .cluster."certificate-authority-data"') cat << EOF > aws-webhook.yaml apiVersion: v1 kind: Namespace metadata: name: ${WEBHOOK_NAMESPACE} --- apiVersion: v1 kind: ServiceAccount metadata: name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} rules: - apiGroups: [''] resources: ['secrets'] verbs: ['create'] - apiGroups: [''] resources: ['secrets'] verbs: ['get', 'update', 'patch'] resourceNames: - pod-identity-webhook --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: pod-identity-webhook subjects: - kind: ServiceAccount name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: pod-identity-webhook rules: - apiGroups: [''] resources: ['serviceaccounts'] verbs: ['get', 'watch', 'list'] - apiGroups: ['certificates.k8s.io'] resources: ['certificatesigningrequests'] verbs: ['create', 'get', 'list', 'watch'] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: pod-identity-webhook roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: pod-identity-webhook subjects: - kind: ServiceAccount name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} --- apiVersion: apps/v1 kind: Deployment metadata: name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} spec: replicas: 1 selector: matchLabels: app: pod-identity-webhook template: metadata: labels: app: pod-identity-webhook spec: serviceAccountName: pod-identity-webhook containers: - name: pod-identity-webhook image: ${IDENTITY_IMAGE} imagePullPolicy: Always command: - /webhook - --in-cluster - --namespace=${WEBHOOK_NAMESPACE} - --service-name=pod-identity-webhook - --tls-secret=pod-identity-webhook - --annotation-prefix=eks.amazonaws.com - --token-audience=sts.amazonaws.com - --logtostderr volumeMounts: - name: webhook-certs mountPath: /var/run/app/certs readOnly: false volumes: - name: webhook-certs emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} annotations: prometheus.io/port: '443' prometheus.io/scheme: https prometheus.io/scrape: 'true' spec: ports: - port: 443 targetPort: 443 selector: app: pod-identity-webhook --- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} webhooks: - name: pod-identity-webhook.amazonaws.com failurePolicy: Ignore sideEffects: 'None' admissionReviewVersions: ['v1beta1'] clientConfig: service: name: pod-identity-webhook namespace: ${WEBHOOK_NAMESPACE} path: /mutate caBundle: ${CLUSTER_CA} rules: - operations: ['CREATE'] apiGroups: [''] apiVersions: ['v1'] resources: ['pods'] EOF
aws-webhook.yaml
的內容已準備好套用至叢集。
將 Webhook 套用至使用者叢集
如要將 Webhook 套用至使用者叢集,請按照下列步驟操作。
將
aws-webhook.yaml
檔案套用到使用者叢集。env HTTPS_PROXY=http://localhost:8118 \ kubectl apply -f aws-webhook.yaml
套用資訊清單時,Webhook Pod 會產生 Kubernetes 憑證簽署要求 (CSR)。核准來自「
system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook
」的所有要求。kubectl certificate approve
env HTTPS_PROXY=http://localhost:8118 \ kubectl certificate approve $(env HTTPS_PROXY=http://localhost:8118 \ &&\ kubectl get csr -o \ jsonpath="{.items[?(@.spec.username==\"system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook\")].metadata.name}")
確認沒有未核准的 CSR。
使用
kubectl get csr
檢查要求者的所有 CSR 是否已獲核准:system:serviceaccount:${WEBHOOK_NAMESPACE}:pod-identity-webhook
env HTTPS_PROXY=http://localhost:8118 \ kubectl get csr
回應:
NAME AGE REQUESTOR CONDITION csr-mxrt8 10s system:serviceaccount:default:pod-identity-webhook Approved,Issued
設定 AWS OIDC 提供者
本節適用於叢集管理員。
如要在 AWS 建立 OIDC 供應商,AWS 會要求提供中繼憑證授權單位 (CA) 或伺服器憑證指紋。您的 OIDC 探索憑證會儲存在 storage.googleapis.com
,並使用名為 GTS CA 1C3
的中繼 CA 簽署憑證。中繼 CA 的 SHA-1 指紋 GTS CA 1C3
為 08745487E891C19E3078C1F2A07E452950EF36F6
。
如要向 AWS 註冊 OIDC 探索 bucket 做為 OIDC 供應商,請執行下列步驟:
從
anthos-aws
目錄使用anthos-gke
將環境切換至管理服務。cd anthos-aws anthos-gke aws management get-credentials
將 OIDC 簽發者 URL、簽發者主機路徑和 Cloud Storage 指紋儲存在環境變數中。
ISSUER_URL=$(env HTTPS_PROXY=http://localhost:8118 \ kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.workloadIdentityInfo.issuerURL}') ISSUER_HOSTPATH=${ISSUER_URL#"https://"} CA_THUMBPRINT=08745487E891C19E3078C1F2A07E452950EF36F6
使用
aws
指令列工具在 AWS 上建立 OIDC 提供者。aws iam create-open-id-connect-provider \ --url ${ISSUER_URL} \ --thumbprint-list ${CA_THUMBPRINT} \ --client-id-list sts.amazonaws.com
更新指紋
如果 Google 輪替 storage.googleapis.com
的 CA,請執行下列指令:
複製更新後的憑證指紋
08745487E891C19E3078C1F2A07E452950EF36F6
。按照
aws iam update-open-id-connect-provider-thumbprint
指令的操作說明操作。使用storage.googleapis.com
做為目標主機名稱,並使用08745487E891C19E3078C1F2A07E452950EF36F6
做為指紋。
建立 AWS IAM 角色和政策
本節適用於叢集管理員。
建立要繫結至 Kubernetes 服務帳戶的 AWS IAM 角色。IAM 角色具有 sts:AssumeRoleWithWebIdentity
的權限。
如要建立角色,請按照下列步驟操作:
找出或建立 AWS IAM 政策,授予工作負載所需的權限。
您需要政策的 Amazon 資源名稱 (ARN) AWS IAM 政策。例如:
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
。使用驗證資訊設定環境變數。
KSA_NAME=KUBERNETES_SERVICE_ACCOUNT WORKLOAD_NAMESPACE=WORKLOAD_IDENTITY_NAMESPACE AWS_ROLE_NAME=AWS_ROLE_NAME AWS_POLICY=EXISTING_AWS_POLICY
更改下列內容:
- KUBERNETES_SERVICE_ACCOUNT:新的 Kubernetes 服務帳戶名稱
- WORKLOAD_IDENTITY_NAMESPACE:工作負載執行的命名空間名稱
- AWS_ROLE_NAME:工作負載的新 AWS 角色名稱
- EXISTING_AWS_POLICY:現有 AWS IAM 政策的 Amazon 資源名稱 (ARN),例如
arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
。
從
anthos-aws
目錄使用anthos-gke
將環境切換至管理服務。cd anthos-aws anthos-gke aws management get-credentials
建立 AWS IAM 政策,允許使用者叢集透過 AWS Security Token Service 取得臨時安全憑證:
CLUSTER_ID=$(env HTTPS_PROXY=http://localhost:8118 \ kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}') # Get the ID Provider ARN PROVIDER_ARN=$(aws iam list-open-id-connect-providers \ | jq '.OpenIDConnectProviderList' \ | jq ".[] | select(.Arn | contains(\"${CLUSTER_ID}\"))" \ | jq '.Arn' | tr -d '"') # Create AWS role and policy cat > irp-trust-policy.json << EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "${PROVIDER_ARN}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "${ISSUER_HOSTPATH}:sub": "system:serviceaccount:${WORKLOAD_NAMESPACE}:${KSA_NAME}" } } } ] } EOF
如要使用這項政策建立 AWS IAM 角色,並將現有政策附加至該角色,請執行下列指令:
aws iam create-role \ --role-name ${AWS_ROLE_NAME} \ --assume-role-policy-document file://irp-trust-policy.json aws iam update-assume-role-policy \ --role-name ${AWS_ROLE_NAME} \ --policy-document file://irp-trust-policy.json aws iam attach-role-policy \ --role-name ${AWS_ROLE_NAME} \ --policy-arn ${AWS_POLICY}
aws
指令列工具會確認政策已附加至您的角色。
為工作負載建立 Kubernetes 服務帳戶
本節適用於開發人員或叢集管理員。
如要建立繫結至先前指定 AWS IAM 角色的 Kubernetes 服務帳戶,請執行下列步驟:
在
anthos-aws
目錄中,使用anthos-gke
將環境切換至使用者叢集。 將 CLUSTER_NAME 替換為使用者叢集名稱。cd anthos-aws env HTTPS_PROXY=http://localhost:8118 \ anthos-gke aws clusters get-credentials CLUSTER_NAME
執行下列指令,建立 Kubernetes 服務帳戶:
S3_ROLE_ARN=$(aws iam get-role \ --role-name AWS_ROLE_NAME \ --query Role.Arn --output text) cat << EOF > k8s-service-account.yaml apiVersion: v1 kind: ServiceAccount metadata: name: ${KSA_NAME} namespace: WORKLOAD_IDENTITY_NAMESPACE EOF env HTTPS_PROXY=http://localhost:8118 \ kubectl apply -f k8s-service-account.yaml env HTTPS_PROXY=http://localhost:8118 \ kubectl annotate sa --namespace ${WORKLOAD_NAMESPACE} ${KSA_NAME} eks.amazonaws.com/role-arn=${S3_ROLE_ARN}
更改下列內容:
AWS_ROLE_NAME
:要套用至工作負載的 AWS IAM 角色名稱WORKLOAD_IDENTITY_NAMESPACE
:工作負載執行的命名空間名稱
將憑證套用至 Pod
本節內容適用於開發人員。
本節假設您已部署 Workload Identity webhook。如果尚未部署 Webhook,請跳到「不使用 Webhook 套用憑證」。
透過 Webhook 套用憑證
本節說明如何設定 Pod,以便讀取 Webhook 提供的憑證。
將服務帳戶新增至 Pod
如要搭配工作負載使用 Workload Identity,請將 Kubernetes 服務帳戶新增至下列欄位:
- Deployment:
spec.template.spec.serviceAccountName
- Pod:
spec.serviceAccount
下列 Pod 資訊清單會啟動 CentOS 基礎映像檔,並包含 spec.serviceAccount
欄位。
apiVersion: v1
kind: Pod
metadata:
name: sample-centos-pod
namespace: WORKLOAD_IDENTITY_NAMESPACE
spec:
containers:
- command:
- /bin/bash
- -ec
- while :; do echo '.'; sleep 500 ; done
image: amazon/aws-cli
name: centos
serviceAccount: KUBERNETES_SERVICE_ACCOUNT
更改下列內容:
WORKLOAD_IDENTITY_NAMESPACE
:工作負載執行的命名空間名稱KUBERNETES_SERVICE_ACCOUNT
:您先前建立的 Kubernetes 服務帳戶名稱
檢查 Pod 是否已設定環境變數
如要檢查 Pod 是否已設定環境變數,請執行下列指令來取得 Pod 的資訊:
kubectl get pod --namespace WORKLOAD_IDENTITY_NAMESPACE POD_NAME -o yaml
更改下列內容:
WORKLOAD_IDENTITY_NAMESPACE
:工作負載執行的命名空間名稱POD_NAME
:要檢查的 Pod 名稱
輸出內容包含 spec.containers.command.env
中的環境變數值,以及 AWS IAM 權杖的掛接點。以下是 Pod 資訊清單範例。
apiVersion: v1
kind: Pod
metadata:
...
spec:
containers:
- command:
- /bin/bash
- -ec
- while :; do echo '.'; sleep 500 ; done
env:
- name: AWS_ROLE_ARN
value: arn:aws:iam::1234567890:role/my-example-workload-role-1
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
image: amazon/aws-cli
imagePullPolicy: IfNotPresent
name: centos
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: my-k8s-serviceaccount-token-d4nz4
readOnly: true
- mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
name: aws-iam-token
readOnly: true
serviceAccount: my-k8s-serviceaccount
serviceAccountName: my-k8s-serviceaccount
volumes:
- name: aws-iam-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: sts.amazonaws.com
expirationSeconds: 86400
path: token
- name: my-k8s-serviceaccount-token-d4nz4
secret:
defaultMode: 420
secretName: my-k8s-serviceaccount-token-d4nz4
...
status:
...
不使用 Webhook 即可套用憑證
如果沒有部署 workload identity webhook,請執行下列操作:
-
AWS_ROLE_ARN
:IAM 角色的 Amazon Resource Name (ARN)AWS_WEB_IDENTITY_TOKEN_FILE
:權杖的儲存路徑
為 IAM 權杖 (
aws-iam-token
) 和與 AWS IAM 角色相關聯的服務帳戶建立掛接點
建立具有工作負載身分憑證的 Pod
如要建立包含工作負載身分識別必要憑證的 Pod,請按照下列步驟操作:
將下列 Pod 資訊清單複製到名為
sample-pod-no-webhook.yaml
的檔案。設定會啟動具備必要憑證的 CentOS 基本映像檔。apiVersion: v1 kind: Pod metadata: name: sample-centos-pod-no-webhook namespace: WORKLOAD_IDENTITY_NAMESPACE spec: containers: - command: - /bin/bash - -ec - while :; do echo '.'; sleep 500 ; done image: centos:7 name: centos env: - name: AWS_ROLE_ARN value: IAM_ROLE_ARN - name: AWS_WEB_IDENTITY_TOKEN_FILE value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token volumeMounts: - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount name: aws-iam-token readOnly: true volumes: - name: aws-iam-token projected: defaultMode: 420 sources: - serviceAccountToken: audience: sts.amazonaws.com expirationSeconds: 86400 path: token serviceAccount: KUBERNETES_SERVICE_ACCOUNT
更改下列內容:
WORKLOAD_IDENTITY_NAMESPACE
:工作負載執行的命名空間名稱。IAM_ROLE_ARN
:授予 Pod 的 IAM 角色 ARN。例如:arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
。KUBERNETES_SERVICE_ACCOUNT
:您先前建立的 Kubernetes 服務帳戶名稱。
使用
kubectl
將 Pod 資訊清單套用至叢集:env HTTPS_PROXY=http://localhost:8118 \ kubectl apply -f sample-pod-no-webhook.yaml
檢查 Pod 是否可以存取 AWS 資源
以下程序說明如何檢查 Pod 是否已收到工作負載身分識別運作所需的憑證。
如要完成這些步驟,您必須具備下列條件:
bash
容器的殼層存取權;大多數的正式版映像檔都沒有可用的殼層。以下範例說明如何使用前一節中指定的 Pod 存取 AWS S3。Pod 必須能連出網際網路,才能下載 AWS 指令列介面。
如要檢查 Pod 是否可以存取 S3 bucket,請執行下列步驟:
使用
kubectl exec
在 Pod 上啟動互動式 Bash 殼層sample-centos-pod-no-webhook
:env HTTPS_PROXY=http://localhost:8118 \ kubectl exec -it --namespace ${WORKLOAD_NAMESPACE} sample-centos-pod-no-webhook -- bash
終端機會在 Pod 上開啟 bash 殼層。
使用
aws
工具檢查 AWS IAM 權限和憑證:aws sts assume-role-with-web-identity \ --role-arn ${AWS_ROLE_ARN} \ --role-session-name mh9test \ --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token \ --duration-seconds 1000
aws
工具會列印類似下列內容的憑證資訊:{ "AssumedRoleUser": { "AssumedRoleId": "AROAR2ZZZLEXVSDCDJ37N:mh9test", "Arn": "arn:aws:sts::126285863215:assumed-role/my-example-workload-role-1/mh9test" }, "Audience": "sts.amazonaws.com", "Provider": "arn:aws:iam::126285863215:oidc-provider/storage.googleapis.com/gke-issuer-cec6c353", "SubjectFromWebIdentityToken": "system:serviceaccount:default:my-s3-reader-ksa", "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "MY_TOKEN", "Expiration": "2020-08-14T22:46:36Z", "AccessKeyId": "AKIAIOSFODNN7EXAMPLE" } }
如果看到下列訊息,請檢查儲存空間是否可公開存取:
An error occurred (InvalidIdentityToken) when calling the AssumeRoleWithWebIdentity operation: Couldn't retrieve verification key from your identity provider, please reference AssumeRoleWithWebIdentity documentation for requirements
升級 Webhook
如果您建立的 Kubernetes 1.18 以下版本叢集已啟用 Workload Identity,且 Workload Identity Webhook 版本為 release-0.2.2-gke.0
,則必須先升級 Webhook,才能升級至 Kubernetes 1.19。
如要升級 Webhook,請執行下列步驟:
執行下列指令,確認已安裝 Webhook:
env HTTPS_PROXY=http://localhost:8118 \ kubectl get MutatingWebhookConfiguration
如果叢集已部署 Webhook,輸出內容會包含下列項目:
NAME WEBHOOKS AGE pod-identity-webhook 1 11m
如果叢集未部署 Webhook,可以略過下列步驟。
如果已儲存
aws-webhook.yaml
檔案,可以刪除資訊清單。如果沒有這個檔案,可以手動刪除 Webhook 的元件。從下列檔案或元件中選擇。檔案
如果仍有
aws-webhook.yaml
檔案,請執行下列指令來刪除 Webhook:env HTTPS_PROXY=http://localhost:8118 \ kubectl delete -f aws-webhook.yaml
元件
如要手動刪除 Webhook 的元件,請執行下列指令:
env HTTPS_PROXY=http://localhost:8118 \ kubectl delete namespace WEBHOOK_NAMESPACE env HTTPS_PROXY=http://localhost:8118 \ kubectl delete clusterrole pod-identity-webhook env HTTPS_PROXY=http://localhost:8118 \ kubectl delete clusterrolebinding pod-identity-webhook env HTTPS_PROXY=http://localhost:8118 \ kubectl delete mutatingwebhookconfiguration pod-identity-webhook
將 WEBHOOK_NAMESPACE 替換為您安裝 workload identity Webhook 的命名空間。例如:
workload-identity-webhook
。執行下列指令,檢查是否還有任何憑證簽署要求 (CSR):
env HTTPS_PROXY=http://localhost:8118 \ kubectl get csr |grep pod-identity-webhook
如果輸出內容空白,請跳至下一個步驟。如果還有剩餘的 CSR,
kubectl
指令會列出現有的 CSR。如要移除 CSR,請執行下列指令:env HTTPS_PROXY=http://localhost:8118 \ kubectl delete csr $(kubectl get csr -o \ jsonpath="{.items[?(@.spec.username==\"system:serviceaccount:WEBHOOK_NAMESPACE:pod-identity-webhook\")].metadata.name}")
將 WEBHOOK_NAMESPACE 替換為您安裝 workload identity Webhook 的命名空間。例如:
workload-identity-webhook
。按照「建立 Webhook」一文的步驟操作,部署新版 Webhook。
部署新版 Webhook 後,您需要重新啟動使用 Webhook 的 Pod。你可以透過升級使用者叢集的方式重新啟動 Pod。
正在清除所用資源
本節說明如何移除您在本文件稍早建立的資源。
清除服務帳戶及其相關聯的 IAM 角色
如要刪除服務帳戶及其相關聯的 IAM 角色,請按照下列步驟操作:
清除服務帳戶:
env HTTPS_PROXY=http://localhost:8118 \ kubectl delete sa KUBERNETES_SERVICE_ACCOUNT --namespace WORKLOAD_IDENTITY_NAMESPACE
更改下列內容:
KUBERNETES_SERVICE_ACCOUNT
:新的 Kubernetes 服務帳戶名稱WORKLOAD_IDENTITY_NAMESPACE
:工作負載執行的命名空間名稱
清除 AWS IAM 角色。選擇下列其中一個選項:
使用 AWS 主控台刪除 AWS IAM 角色。
使用下列指令,透過 AWS 指令列工具刪除角色:
aws iam detach-role-policy \ --role-name=${AWS_ROLE_NAME} \ --policy-arn=${AWS_POLICY} aws iam delete-role --role-name=${AWS_ROLE_NAME}
刪除使用者叢集
如要刪除使用者叢集,請按照「在 AWS 中解除安裝 GKE」一文中的步驟操作。
清除 AWS OIDC 供應商
刪除使用者叢集後,請使用下列 bash
shell 指令或 AWS 控制台,取消註冊並刪除 AWS 上的 OIDC 提供者。
從
anthos-aws
目錄使用anthos-gke
將環境切換至管理服務。cd anthos-aws anthos-gke aws management get-credentials
使用 AWS 指令列工具,透過下列指令刪除角色:
CLUSTER_ID=$(env HTTPS_PROXY=http://localhost:8118 \ kubectl get awscluster ${CLUSTER_NAME} -o jsonpath='{.status.clusterID}') PROVIDER_ARN=$(aws iam list-open-id-connect-providers \ | jq '.OpenIDConnectProviderList' \ | jq ".[] | select(.Arn | contains(\"${CLUSTER_ID}\"))" \ | jq '.Arn' | tr -d '"') aws iam delete-open-id-connect-provider \ --open-id-connect-provider-arn=${PROVIDER_ARN}
系統會顯示確認訊息,表示已刪除 AWS OIDC 提供者。
後續步驟
- 瞭解 AWS 服務帳戶適用的 IAM 角色 (IRSA),這是 GKE on AWS 用於工作負載身分識別的角色。
- 瞭解如何搭配使用 Workload Identity 與 Google Cloud。