基于适用于服务账户的RAM角色(RAM Roles for Service Accounts,简称RRSA)功能,您可以在集群内实现Pod维度的OpenAPI权限隔离,从而实现云资源访问权限的细粒度隔离,降低安全风险。本文介绍如何在集群中使用RRSA。
背景信息
ECS实例元数据包含ECS实例(ECI实例基于ECS实例实现)在阿里云系统中的信息。您可以在运行中的实例内查看实例元数据,并基于实例元数据配置或管理实例。通过实例元数据,Kubernetes集群内应用可以获取实例RAM角色策略所生成的STS临时凭证,然后通过该临时凭证访问云资源OpenAPI。更多信息,请参见实例元数据。
当您需要限制集群内不同应用的RAM权限时,出于安全考虑,您应当禁止这些应用通过ECS或ECI实例元数据获取您的实例关联角色对应的临时凭证或者不为实例关联角色授予任何RAM权限策略。但这些应用仍然会需要一种安全的途径去获取访问云资源的临时凭证。因此,阿里云容器服务ACK联合RAM访问控制服务推出了RRSA功能。
基于RRSA功能,您可以在集群内实现Pod级别隔离的应用关联RAM角色功能。各个应用可以扮演独立的RAM角色并使用获取的临时凭证访问云资源,从而实现应用RAM权限最小化以及无AccessKey访问阿里云OpenAPI避免AccessKey泄露的需求。
从用户侧视角来看,RRSA功能的工作流程如下。
用户提交使用了服务账户令牌卷投影功能的应用Pod。
集群将为该应用Pod创建和挂载相应的服务账户OIDC Token文件。
Pod内程序使用挂载的OIDC Token文件访问STS服务的AssumeRoleWithOIDC接口,获取扮演指定RAM角色的临时凭证。
说明请提前修改RAM角色配置,允许Pod使用的服务账户扮演该RAM角色。更多信息,请参见AssumeRoleWithOIDC。
从文件中读取的OIDC Token是一个临时Token,建议应用程序每次在使用时都从文件中读取最新的Token,集群会在Token过期前更新替换文件内已有的Token。
Pod内程序使用获取到的临时凭证访问云资源OpenAPI。
使用限制
RRSA功能目前仅支持1.22及以上版本的集群,即ACK集群基础版、ACK集群Pro版、ACK Serverless集群基础版、ACK Serverless集群Pro版和ACK Edge集群Pro版。
启用RRSA功能
若未创建集群,您可以在创建ACK托管集群和ACK Edge集群时开启,若已创建集群,可在集群信息页面的安全与审计页签下开启。
ACK Serverless集群仅支持集群创建后在集群信息页面的安全与审计页签下开启。
创建集群时开启
创建ACK托管集群和ACK Edge集群时,您可以在集群配置的高级选项(选填)区域,选中开启RRSA功能。
在集群信息页面开启
登录容器服务管理控制台,在左侧导航栏选择集群。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息。
在基本信息页签的安全与审计区域,单击RRSA OIDC右侧的开启。
在弹出的启用RRSA对话框,单击确定。
在基本信息区域,当集群状态由更新中变为运行中后,表明该集群的RRSA特性已变更完成。
获取集群中OIDC提供商的URL和ARN信息
集群中RRSA功能开启后,在基本信息页签的安全与审计区域,将鼠标悬浮至RRSA OIDC右侧已开启上面,即可查看提供商的URL链接和ARN信息。
集群开启RRSA功能后,ACK将在后台执行如下操作。
自动创建一个集群专用的OIDC Issuer服务。该服务由ACK托管,无需您运维。更多信息,请参见OIDC Issuer。
修改当前集群的服务账户令牌卷投影功能的配置,使用本次创建的OIDC Issuer配置合并集群已有的service-account-issuer参数的值。更多信息,请参见使用ServiceAccount Token卷投影。
在您的账号下创建一个使用该OIDC Issuer的OIDC身份提供商,名称为ack-rrsa-<cluster_id>,其中 <cluster_id>为您的集群ID。更多信息,请参见管理OIDC身份提供商。
使用RRSA功能
集群开启RRSA功能后,您可以参考以下内容,赋予集群内应用通过RRSA功能获取访问云资源OpenAPI的临时凭证的能力。
使用示例
本示例部署的应用将使用RRSA功能扮演指定角色,获取当前账号下集群列表信息。
示例配置
命名空间:rrsa-demo
ServiceAccount:demo-sa
RAM角色:demo-role-for-rrsa
示例流程
如果您希望通过不安装ack-pod-identity-webhook组件的方式使用RRSA功能,您可以手动修改应用模板挂载应用所需的OIDC Token文件并配置相关环境变量。具体操作,请参见手动修改应用模板使用RRSA功能。
如果您希望使用已存在的RAM角色,不创建新的RAM角色,您可以为已有RAM角色新增相关权限。具体操作,请参见使用已存在的RAM角色并授权。
安装ack-pod-identity-webhook组件。
在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择运维管理 > 组件管理。
在组件管理页面,单击安全页签,找到ack-pod-identity-webhook组件,单击组件右下方的安装。
在提示对话框确认组件信息后,单击确定。
创建一个名为demo-role-for-rrsa的RAM角色。
使用阿里云账号登录RAM控制台。
在左侧导航栏,选择 ,然后在角色页面,单击创建角色。
在创建角色面板,选择可信实体类型为身份提供商,然后单击下一步。
在配置角色页面,配置如下角色信息后,单击完成。
本示例配置如下。
配置项
描述
角色名称
demo-role-for-rrsa。
备注
选填有关该角色的备注信息。
身份提供商类型
OIDC。
选择身份提供商
ack-rrsa-<cluster_id>。其中,<cluster_id>为您的集群ID。
限制条件
oidc:iss:保持默认。
oidc:aud:选择sts.aliyuncs.com。
oidc:sub:条件判定方式选择StringEquals,值的格式为system:serviceaccount:<namespace>:<serviceAccountName>。
<namespace>:应用所在的命名空间。
<serviceAccountName>:服务账户名称。
根据测试应用的信息,此处需要填入system:serviceaccount:rrsa-demo:demo-sa。
为步骤2创建的角色授予测试应用所需的AliyunCSReadOnlyAccess系统策略权限。具体操作,请参见为RAM角色授权。
部署测试应用。关于测试应用的参考代码,请参见阿里云官方SDK使用RRSA OIDC Token的参考代码。
使用以下内容,创建demo.yaml文件。
如下YAML示例中,为命名空间增加标签
pod-identity.alibabacloud.com/injection: 'on'
,并为服务账户增加注解pod-identity.alibabacloud.com/role-name: demo-role-for-rrsa
,启用ack-pod-identity-webhook组件的配置自动注入功能。关于ack-pod-identity-webhook组件配置的更多说明,请参见ack-pod-identity-webhook。执行以下命令,部署测试应用。
kubectl apply -f demo.yaml
执行以下命令,查看测试应用Pod,确认ack-pod-identity-webhook组件已为Pod自动注入所需的配置。
kubectl -n rrsa-demo get pod demo -o yaml
预期输出表明,ack-pod-identity-webhook组件已为Pod自动注入了如下配置。
类别
配置项名称
配置项说明
环境变量
ALIBABA_CLOUD_ROLE_ARN
需要扮演的RAM角色ARN。
ALIBABA_CLOUD_OIDC_PROVIDER_ARN
OIDC身份提供商的ARN。
ALIBABA_CLOUD_OIDC_TOKEN_FILE
包含OIDC Token的文件路径。
VolumeMount
rrsa-oidc-token
挂载OIDC Token的配置。
Volume
rrsa-oidc-token
挂载OIDC Token的配置。
执行以下命令,查看测试应用日志。
kubectl -n rrsa-demo logs demo
预期输出集群列表信息:
cluster id: cf***, cluster name: foo* cluster id: c8***, cluster name: bar* cluster id: c4***, cluster name: foob*
可选:移除角色被授予的AliyunCSReadOnlyAccess系统策略权限。具体操作,请参见为RAM角色移除权限。
等待30秒左右,执行以下命令,再次查看测试应用日志。
kubectl -n rrsa-demo logs demo
预期输出无权限的错误日志:
StatusCode: 403 Code: StatusForbidden Message: code: 403, STSToken policy Forbidden for action cs:DescribeClusters request id: E78A2E2D-*** Data: {"accessDeniedDetail":{"AuthAction":"cs:DescribeClusters","AuthPrincipalDisplayName":"demo-role-for-rrsa:ack-ram-tool","AuthPrincipalOwnerId":"11***","AuthPrincipalType":"AssumedRoleUser","NoPermissionType":"ImplicitDeny","PolicyType":"ResourceGroupLevelIdentityBasedPolicy"},"code":"StatusForbidden","message":"STSToken policy Forbidden for action cs:DescribeClusters","requestId":"E78A2E2D-***","status":403,"statusCode":403}
手动修改应用模板使用RRSA功能
您可以通过手动修改应用模板挂载应用所需的OIDC Token文件以及配置相关环境变量,在不安装ack-pod-identity-webhook组件的情况下使用RRSA功能。
应用模板示例代码如下。
请替换应用模板示例代码中的如下字段。
<oid_provider_arn>
:替换为当前集群的OIDC提供商ARN。该ARN获取请参见获取集群中OIDC提供商的URL和ARN信息。<role_arn>
需要替换为当前应用使用的RAM角色ARN。该ARN可在RAM控制台角色页面的角色详情页面获取。audience
:字段值必须为sts.aliyuncs.com
。该字段值对应的是开启RRSA功能时自动创建的OIDC身份提供商中配置的客户端ID,与SDK访问STS的AssumeRoleWithOIDC接口时使用的域名无关,您可以在使用SDK时指定使用合适的STS域名。expirationSeconds
:单位为秒,取值范围为[600, 43200],即10分钟~12小时。如果设置的值大于43200
(12小时),实际的OIDC Token的过期时间仍为12小时。
部署修改后的应用模板后,应用内程序可以使用容器内挂载的OIDC Token(环境变量ALIBABA_CLOUD_OIDC_TOKEN_FILE指向的文件内容,每次使用时都需要从文件中读取最新的Token)、角色的ARN(环境变量ALIBABA_CLOUD_ROLE_ARN配置的值)以及OIDC身份提供商的ARN(环境变量ALIBABA_CLOUD_OIDC_PROVIDER_ARN配置的值),调用STS的AssumeRoleWithOIDC接口,获取一个扮演指定RAM角色的临时凭证,然后使用该临时凭证访问云资源OpenAPI。应用参考代码,请参见阿里云官方SDK使用RRSA OIDC Token的参考代码。更多信息,请参见AssumeRoleWithOIDC。
使用已存在的RAM角色并授权
如果您的应用需要使用已存在的RAM角色,而非创建新的单独RAM角色,您可以修改RAM角色的信任策略,新增一条允许使用指定的服务账户的应用有权限通过扮演此RAM角色获取临时凭证的信任策略。更多信息,请参见修改RAM角色的信任策略。
RAM角色信任策略中新增的Statement
条目内容示例如下。
{
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"oidc:aud": "sts.aliyuncs.com",
"oidc:iss": "<oidc_issuer_url>",
"oidc:sub": "system:serviceaccount:<namespace>:<service_account>"
}
},
"Effect": "Allow",
"Principal": {
"Federated": [
"<oidc_provider_arn>"
]
}
}
请替换Statement
条目内容示例中的如下字段。
<oidc_issuer_url>
:替换为当前集群的OIDC提供商URL。该URL获取请参见获取集群中OIDC提供商的URL和ARN信息。<oidc_provider_arn>
:替换为当前集群的OIDC提供商ARN。该ARN获取请参见获取集群中OIDC提供商的URL和ARN信息。<namespace>
:替换为应用所在的命名空间。<service_account>
:替换为应用使用的服务账户。
您也可以使用命令行工具ack-ram-tool通过自动化的方式配置该策略。对应的命令行示例如下。
ack-ram-tool rrsa associate-role --cluster-id <cluster_id> \
--namespace <namespace> --service-account <service_account> \
--role-name <role_name> --create-role-if-not-exist
阿里云官方SDK使用RRSA OIDC Token的参考代码
SDK参考代码
目前,阿里云V2.0 SDK已经内置了支持使用RRSA OIDC Token进行OpenAPI认证的功能,所有基于V2.0 SDK生成并且支持STS Token认证的云产品SDK都将默认支持RRSA OIDC Token认证。支持此功能的SDK版本信息和参考代码如下。
编程语言 | 支持认证的SDK版本 | 使用示例 |
Go | Alibaba Cloud Credentials for Go 1.2.6及以上版本。更多信息,请参考方式六:使用OIDCRoleArn。 | |
Java | Alibaba Cloud Credentials for Java 0.2.10及以上版本。更多信息,请参考方式六:使用OIDCRoleArn。 | |
Python 3 | Alibaba Cloud Credentials for Python 0.3.1及以上版本。更多信息,请参考方式六:使用OIDCRoleArn。 | |
Node.js和TypeScript | Alibaba Cloud Credentials for TypeScript/Node.js 2.2.6及以上版本。更多信息,请参考方式六:使用OIDCRoleArn。 |
部分云产品自研的SDK也可以参考上面的方法实现使用RRSA OIDC Token进行OpenAPI认证的功能。具体实现方式的参考代码如下。
云产品 | SDK | 使用示例 |
对象存储 | 更多信息,请参考方式五:使用OIDCRoleARN。 | |
更多信息,请参考方式六:使用OIDCRoleARN。 | ||
更多信息,请参考方式六:使用OIDCRoleARN。 | ||
日志服务 | 更多信息,请参考Java SDK快速入门。 |
SDK报错信息解决方法
不同报错信息的解决方法如下表所示。
报错信息 | 原因 | 解决方法 |
| 您的应用使用的OIDC Token已过期。 | 您需要每次都从环境变量 |
| 您的应用获取临时凭证的操作太频繁,导致操作被限流。 | 请勿过于频繁调用获取临时凭证的接口,在临时凭证过期前您无需频繁获取新的凭证。建议您使用阿里云官方SDK而不是自行实现获取临时凭证的逻辑。更多信息,请参见阿里云官方SDK使用RRSA OIDC Token的参考代码。 |
| 您的应用模板中 | 您需要修改应用模板,确保配置项 |
| 您的集群未启用RRSA功能。 | 您需要为应用所在集群启用RRSA功能。操作方法,请参见启用RRSA功能。完成启用RRSA功能操作后,您还需要重建使用RRSA功能的应用Pod。 |
| 您的应用所使用的RAM角色不存在。 | 您需要创建对应的RAM角色。操作方法,请参见创建OIDC身份提供商的RAM角色以及使用示例。 |
| 您的应用所使用的RAM角色未完成所需的信任策略配置。 | 您需要修改RAM角色的信任策略,允许您的应用扮演该角色。操作方法,请参见使用已存在的RAM角色并授权。 |
常用命令行工具使用RRSA OIDC Token
借助ack-ram-tool,可以赋予部分常用命令行工具在容器内使用RRSA OIDC Token的能力。具体配置和使用示例详见下表。
命令行工具 | 配置方法 | 使用示例 |
您可以在配置文件 说明
|
| |
您也可以不创建配置文件,直接执行阿里云CLI相关命令。 说明 仅v3.0.206及以上版本的阿里云CLI支持该特性。 |
| |
暂不支持在日志服务CLI的配置文件中指定使用RRSA OIDC Token,您需要使用命令 |
| |
您可以在配置文件中通过配置 说明
|