本主题介绍如何在 AKS 和 EKS 平台上为 Apigee Hybrid 安装启用 Workload Identity 联合。
对于在 GKE 上进行的安装,请按照在 GKE 上启用 Workload Identity 中的说明操作。
概览
借助工作负载身份联合,在 Google Cloud 外部运行的应用可以使用来自外部身份提供方的凭据来模拟 Google Cloud Platform 服务账号。
通过使用工作负载身份联合,您可以让应用使用外部环境提供的身份验证机制并替换服务账号密钥,从而提高安全性。
如需了解概览,请参阅使用工作负载身份联合的最佳实践。
设置工作负载身份联合
如需将工作负载身份联合与 Apigee Hybrid 搭配使用,请先配置集群,然后将该功能应用于 Apigee Hybrid 安装。
准备工作
以下说明假定您已设置 Apigee Hybrid 安装。IAM 服务账号和 Kubernetes 服务账号会在初始安装期间创建。如需大致了解如何安装 Apigee Hybrid,请参阅概览。
对于在 AKS 上进行的安装,请确保您已启用 OpenID Connect (OIDC) 颁发者。您必须启用此功能,以便工作负载身份联合可以访问集群的 OpenID Connect 元数据和 JSON Web 密钥集 (JWKS)。
配置集群以使用工作负载身份联合。
-
使用以下命令检查
gcloud
配置设置为您的 Google Cloud 项目 ID:gcloud config get project
-
启用 Security Token Service API:
使用以下命令检查 Security Token Service API 是否已启用:
gcloud services list --enabled --project PROJECT_ID | grep sts.googleapis.com
如果未启用该 API,请执行以下操作:
控制台
Enable the Security Token Service API.
命令行
使用以下命令启用该 API:
gcloud services enable sts.googleapis.com --project PROJECT_ID
-
创建工作负载身份池和提供方。
所需的角色
如需获得配置工作负载身份联合所需的权限,请让您的管理员为您授予项目的以下 IAM 角色:
-
Workload Identity Pool Admin (
roles/iam.workloadIdentityPoolAdmin
) -
Service Account Admin (
roles/iam.serviceAccountAdmin
)
如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
此外,IAM Owner (roles/owner
) 基本角色还具有配置身份联合的权限。您不应在生产环境中授予基本角色,但可以在开发或测试环境中授予这些角色。如需创建工作负载身份池和提供方,请执行以下操作:
-
确定 AKS 集群的颁发者网址:
AKS
az aks show -n NAME -g RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -otsv
请替换以下内容:
NAME
:集群的名称。RESOURCE_GROUP
:集群的资源组。
该命令会输出颁发者网址。您将在后续的一个步骤中用到颁发者网址。
如果该命令未返回颁发者网址,请验证您是否已启用 OIDC 颁发者功能。
EKS
aws eks describe-cluster --name NAME --query "cluster.identity.oidc.issuer" --output text
将
NAME
替换为集群的名称。该命令会输出颁发者网址。您将在后续的一个步骤中用到颁发者网址。
其他 Kubernetes
-
连接到您的 Kubernetes 集群,并使用 `kubectl` 确定集群的颁发者网址:
kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
您将在后续的一个步骤中用到颁发者网址。
-
可选:如果您的 OIDC 颁发者不可公开访问,请下载集群的 JSON Web 密钥集 (JWKS):
kubectl get --raw /openid/v1/jwks > cluster-jwks.json
如需检查您的 OIDC 提供方是否公开可用,您应该能够使用 C网址 命令访问您的提供方网址,并收到 200 响应。
-
创建新的 Workload Identity 池:
gcloud iam workload-identity-pools create POOL_ID \ --location="global" \ --description="DESCRIPTION" \ --display-name="DISPLAY_NAME"
请替换以下内容:
POOL_ID
:池的唯一 ID。DISPLAY_NAME
:(可选)池的名称。DESCRIPTION
:(可选)您选择的池的说明。当您授予对池身份的访问权限时,系统会显示此说明。
例如:
gcloud iam workload-identity-pools create my-wi-pool --display-name="My workload pool" --description="My workload pool description"
-
将集群添加为工作负载身份池提供方。根据您的 OIDC 颁发者是可公开访问还是不可公开访问,选择用于创建提供方的命令:
可公开访问
如果您的 OIDC 颁发者可供公开访问,请使用以下命令创建提供方:
gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="ISSUER" \ --attribute-mapping="google.subject=assertion.sub"
不可供公开访问
如果您的 OIDC 颁发者无法公开访问,请使用以下命令创建提供方:
gcloud iam workload-identity-pools providers create-oidc WORKLOAD_PROVIDER_ID \ --location="global" \ --workload-identity-pool="POOL_ID" \ --issuer-uri="ISSUER" \ --jwks-file="cluster-jwks.json" \ --attribute-mapping="google.subject=assertion.sub"
请替换以下内容:
WORKLOAD_PROVIDER_ID
:您选择的唯一工作负载身份池提供方 ID。POOL_ID
:您之前创建的工作负载身份池 ID。-
ISSUER
:将您之前确定的颁发者网址用作颁发者 URI。
attribute-mapping="google.subject=assertion.sub"
会将 Kubernetes 正文映射到 IAM 正文。
-
Workload Identity Pool Admin (
如果需要,请设置当前 gcloud
配置:
gcloud config set project PROJECT_ID
创建凭据配置文件
如需部署可访问 Google Cloud 资源的 Kubernetes 工作负载,您首先需要为每个 IAM 服务账号创建一个凭据配置文件:
-
使用以下命令列出 IAM 服务账号(也称为“Google 服务账号”):
gcloud iam service-accounts list --project PROJECT_ID
您需要为以下 IAM 服务账号创建凭据配置文件:
Prod
对于生产环境:
DISPLAY NAME EMAIL DISABLED apigee-cassandra apigee-cassandra@my_project_id.iam.gserviceaccount.com False apigee-mart apigee-mart@my_project_id.iam.gserviceaccount.com False apigee-metrics apigee-metrics@my_project_id.iam.gserviceaccount.com False apigee-runtime apigee-runtime@my_project_id.iam.gserviceaccount.com False apigee-synchronizer apigee-synchronizer@my_project_id.iam.gserviceaccount.com False apigee-udca apigee-udca@my_project_id.iam.gserviceaccount.com False apigee-watcher apigee-watcher@my_project_id.iam.gserviceaccount.com False
非生产
对于非生产环境:
DISPLAY NAME EMAIL DISABLED apigee-non-prod apigee-non-prod@my_project_id.iam.gserviceaccount.com False
-
为上方列表中的每个 IAM 服务账号创建一个凭据配置文件。您需要以下凭据配置文件,才能将 Apigee Hybrid 配置为使用工作负载身份联合:
代码
gcloud iam workload-identity-pools create-cred-config \ projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/WORKLOAD_PROVIDER_ID \ --service-account=SERVICE_ACCOUNT_EMAIL \ --credential-source-file=/var/ --credential-source-type=text \ --output-file=SERVICE_ACCOUNT_NAME-credential-configuration.json
示例
gcloud iam workload-identity-pools create-cred-config \ projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider \ --service-account=apigee-cassandra@myhybridporg.iam.gserviceaccount.com \ --credential-source-file=/var/ --credential-source-type=text \ --output-file=apigee-cassandra-credential-configuration.json
其中:
-
PROJECT_NUMBER
:包含工作负载身份池的项目的项目编号。此字段必须是项目编号,而不是项目 ID。 -
POOL_ID
:工作负载身份池的 ID -
WORKLOAD_PROVIDER_ID
:工作负载身份池提供方的 ID -
SERVICE_ACCOUNT_EMAIL
:服务账号的电子邮件地址(如果您将 Kubernetes 服务账号配置为使用 IAM 服务账号模拟)。
凭据配置文件可让 [Cloud 客户端库](/apis/docs/cloud-client-libraries)、gcloud CLI 和 Terraform 确定以下内容:
- 从何处获取外部凭据
- 要使用的工作负载身份池和提供商
- 需要模拟的服务账号
将 Apigee Hybrid 配置为使用工作负载身份联合
-
将每个输出文件 (
SERVICE_ACCOUNT_NAME-credential-configuration.json
) 复制或移动到以下图表目录(或其子目录)中。这些是您在创建凭据配置文件步骤中创建的文件。生产
服务账号 Apigee Helm 图表目录 apigee-cassandra
apigee-datastore/
apigee-mart
apigee-org/
apigee-metrics
apigee-telemetry/
apigee-runtime
apigee-env/
apigee-synchronizer
apigee-env/
apigee-udca
apigee-org/
apigee-env/
apigee-watcher
apigee-org/
非生产
服务账号 Apigee Helm 图表 apigee-non-prod
apigee-datastore/
apigee-telemetry/
apigee-org/
apigee-env/
-
对集群的替换文件进行以下全局更改:
代码
gcp: workloadIdentity: enabled: false # must be set to false to use Workload Identity Federation federatedWorkloadIdentity: enabled: true audience: "AUDIENCE" credentialSourceFile: "/var/run/service-account/token"
示例
gcp: workloadIdentity: enabled: false federatedWorkloadIdentity: enabled: true audience: "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider" credentialSourceFile: "/var/run/service-account/token"
其中:AUDIENCE 是工作负载身份提供方允许的目标对象。您可以通过在任何凭据配置文件中搜索字词
audience:
来找到该值。每个凭据配置文件中的受众群体值相同。例如,在以下示例
apigee-udca-credential-configuration.json
文件中:{ "universe_domain": "googleapis.com", "type": "external_account:," "audience": "//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider", "subject_token_type": "urn:ietf:params:oauth: token-type:jwt", "token_url": "https://sts.googleapis.com/v1/token", "service "impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/apigee-udca@myhybridproject.iam.gserviceaccount.com:generateAccessToken", "credential_source": { "file": "/var/run/service-account/token", "format": { "type": "text" } } }
受众群体值为
//iam.googleapis.com/projects/123123123123/locations/global/workloadIdentityPools/my-wi-pool/providers/my-wi-provider
。 -
使用工作负载身份联合为每个组件配置替换项。根据需要选择证书文件、Kubernetes Secret 或保险柜的说明。
证书文件
将
serviceAccountPath
的值替换为相应 IAM 服务账号的凭据源文件。此路径必须相对于图表目录。例如:envs: - name: ENVIRONMENT_NAME serviceAccountPaths: synchronizer: apigee-synchronizer-credential-configuration.json runtime: apigee-runtime-credential-configuration.json udca: udca-credential-configuration.json mart: serviceAccountPath: mart-credential-configuration.json connectAgent: serviceAccountPath: mart-credential-configuration.json metrics: serviceAccountPath: metrics-credential-configuration.json udca: serviceAccountPath: UDCA_SERVICE_ACCOUNT_FILEPATH watcher: serviceAccountPath: WATCHER_SERVICE_ACCOUNT_FILEPATH
K8s Secret
-
使用每个凭据配置文件的凭据来源文件创建一个新的 Kubernetes Secret。
kubectl create secret -n APIGEE_NAMESPACE generic SECRET_NAME --from-file="client_secret.json=CREDENTIAL_CONFIGURATION_FILE"
例如:
kubectl create secret -n apigee generic udca-workoad-identity-secret --from-file="client_secret.json=./apigee-udca-credential-configuration.json"
-
将
serviceAccountRef
的值替换为新 Secret。例如:udca: serviceAccountRef: udca-workoad-identity-secret
保险柜
使用相应的凭据源文件更新保险柜中每个服务账号的服务账号密钥
SAKEY
。此过程在所有组件中都类似。例如,对于 UDCA:SAKEY=$(cat .apigee-udca-credential-configuration.json); kubectl -n APIGEE_NAMESPACE exec vault-0 -- vault kv patch secret/apigee/orgsakeys udca="$SAKEY"
如需了解详情,请参阅
Storing service account keys in Hashicorp Vault
。 -
使用每个凭据配置文件的凭据来源文件创建一个新的 Kubernetes Secret。
-
使用
helm upgrade
命令将更改应用于每个受影响的组件:如果您更新了保险柜服务账号密钥,请更新
apigee-operator
图表。helm upgrade operator apigee-operator/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
按以下顺序更新其余受影响的图表:
helm upgrade datastore apigee-datastore/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
helm upgrade telemetry apigee-telemetry/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
helm upgrade $ORG_NAME apigee-org/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
更新每个环境的
apigee-env
图表,每次替换 $ENV_RELEASE_NAME 和 ENV_NAME:helm upgrade $ENV_RELEASE_NAME apigee-env/ \ --namespace APIGEE_NAMESPACE \ --atomic \ --set env=$ENV_NAME \ -f overrides.yaml
如需查看组件及其对应图表的列表,请参阅 Apigee Hybrid Helm 参考文档。
授予对 Kubernetes 服务账号的访问权限
-
使用以下命令列出 Kubernetes 服务账号:
kubectl get sa -n APIGEE_NAMESPACE
-
向 Kubernetes 服务账号授予模拟关联的 IAM 服务账号的访问权限,如下表所示。下表显示了默认的 Apigee IAM 服务账号名称。如果您使用自定义服务账号名称,请使用相应的 IAM 服务账号:
Kubernetes 服务账号 IAM 服务账号 组织级 Kubernetes 服务账号 apigee-connect-agent-ORG_NAME-ORG_HASH_ID
apigee-mart
apigee-mart-ORG_NAME-ORG_HASH_ID
apigee-mart
apigee-metrics-apigee-telemetry
apigee-metrics
apigee-open-telemetry-collector-apigee-telemetry
apigee-metrics
apigee-udca-ORG_NAME-ORG_HASH_ID
apigee-udca
apigee-watcher-ORG_NAME-ORG_HASH_ID
apigee-watcher
环境级 Kubernetes 服务账号 apigee-runtime-ORG_NAME-ENV_NAME-ENV_HASH_ID
apigee-runtime
apigee-synchronizer-ORG_NAME-ENV_NAME-ENV_HASH_ID
apigee-synchronizer
Cassandra 备份和恢复(如果已启用) apigee-cassandra-backup-sa
apigee-cassandra
apigee-cassandra-restore-sa
apigee-cassandra
其中:
ORG_NAME
:组织名称的前 15 个字符。ORG_HASH_ID
:您的完整组织名称的唯一哈希 ID。ENV_NAME
:环境名称的前 15 个字符。ENV_HASH_ID
:组织和环境名称的唯一哈希 ID。
例如:
apigee-connect-agent-myhybridorg-123abcd
apigee-runtime-myhybridorg-prodenv-234bcde
使用以下命令向每个 Kubernetes 服务账号授予模拟相应 IAM 服务账号的访问权限:
gcloud iam service-accounts add-iam-policy-binding \ IAM_SA_NAME@PROJECT_ID.iam.gserviceaccount.com \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/MAPPED_SUBJECT" \ --role=roles/iam.workloadIdentityUser
其中:
- 将
IAM_SA_NAME
替换为服务账号的名称。 PROJECT_ID
:与 Apigee 组织关联的项目的 ID。PROJECT_NUMBER
:您创建工作负载身份池的项目的项目编号。POOL_ID
:工作负载身份池 ID。MAPPED_SUBJECT
:来自您已映射到google.subject
的 ID 令牌中的声明的 Kubernetes ServiceAccount。例如,如果您映射了google.subject=assertions.sub
,并且您的 ID 令牌包含"sub": "system:serviceaccount:default:my-kubernetes-serviceaccount"
,则MAPPED_SUBJECT
为system:serviceaccount:default:my-kubernetes-serviceaccount
。
如需详细了解工作负载身份联合和最佳实践,请参阅使用工作负载身份联合的最佳实践。
-