通过RRSA配置ServiceAccount的RAM权限实现Pod权限隔离

通过基于服务账户的RAM角色(RAM Roles for Service Accounts,简称RRSA)功能,您可以在集群内实现Pod维度的OpenAPI权限隔离,从而实现云资源访问权限的细粒度隔离,降低安全风险。本文介绍RRSA功能的使用方法。

背景信息

OIDC(OpenID Connect)是建立在OAuth 2.0基础上的一个认证协议,阿里云RAM支持基于OIDC的角色SSO。Kubernetes集群内的应用可以通过实例RAM角色策略生成的STS临时凭证访问云资源OpenAPI。阿里云容器计算服务ACS已经支持了RRSA功能,在多租户场景下,RRSA功能可以实现集群内应用Pod之间的云资源访问权限的细粒度隔离。在ACS场景下,RRSA功能可以满足使用STS临时凭证控制凭证有效期的需求。

image

RRSA功能的工作流程如下。

  1. 提交使用了服务账户令牌卷投影功能的应用Pod。

    说明

    ACS集群默认启用服务账户令牌卷投影功能。

  2. 集群将为该应用Pod创建和挂载相应的服务账户OIDC Token文件。

  3. Pod内程序使用挂载的OIDC Token文件访问STS服务的AssumeRoleWithOIDC接口,获取指定RAM角色的临时凭证。

    说明

    请提前修改RAM角色配置,允许Pod使用的服务账户使用该RAM角色。更多信息,请参见AssumeRoleWithOIDC

  4. Pod内应用程序使用获取到的临时凭证访问云资源OpenAPI。

启用RRSA功能

  1. 登录容器计算服务控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择集群信息

  3. 集群信息页面,单击基本信息页签,然后在安全与审计区域单击RRSA OIDC后的开启

  4. 在弹出的启用 RRSA对话框,单击确定

    说明
    • RRSA功能启用大约需要2-3min的时间,若遇到集群状态一直处于更新中的情况,请手动点击页面右上角的image按钮手动刷新。

    • 当集群状态由更新中变为运行中后,表明该集群的RRSA特性已变更完成。将鼠标移动到RRSA OIDC右侧的已开启上,将显示OIDC提供商的URL链接和ARN信息。

集群开启RRSA功能后,ACS控制台将在后台执行如下操作:

  • 自动创建一个集群专用的OIDC Issuer服务。该服务由ACS托管,无需手动维护。

  • 在您的账号下创建一个使用该OIDC IssuerOIDC身份提供者,名称为ack-rrsa-<cluster_id>,其中 <cluster_id>为您的集群ID。

使用RRSA功能

集群开启RRSA功能后,您可以参考以下内容,赋予集群内应用通过RRSA功能获取访问云资源OpenAPI的临时凭证的能力。

使用新创建的RAM角色并授权

说明

如果您希望使用已存在的RAM角色,不创建新的RAM角色,您可以为已有RAM角色新增相关权限

本示例部署的应用将使用RRSA功能扮演指定角色,获取当前账号下集群列表信息,使用的主要资源如下。

  • 命名空间:rrsa-demo。

  • 服务账户:demo-sa。

  • RAM角色:demo-role-for-rrsa。

  1. 创建一个名为demo-role-for-rrsaRAM角色。

    1. 使用阿里云账号登录RAM控制台

    2. 在左侧导航栏,选择身份管理 > 角色,然后在角色页面,单击创建角色

    3. 创建角色面板,单击切换编辑器来创建角色。

    4. 可视化编辑为例,参考如下角色信息进行配置,然后单击确定

      配置项

      描述

      效果

      默认为允许

      主体

      选择身份提供者后,点击编辑

      选择身份提供者类型为OIDC,然后选择对应集群的身份提供者,如ack-rrsa-<cluster_id>。其中<cluster_id>为您的集群ID。

      操作

      默认勾选sts:AssumeRole

      条件

      • oidc:iss:选择身份提供者后自动添加,保持默认。

      • oidc:aud:选择身份提供者后自动添加,保持默认。

      • oidc:sub:需要手动添加条件

        • 条件键oidc:sub

        • 运算符StringEquals

        • 条件值:格式为system:serviceaccount:<namespace>:<serviceAccountName>。

          • <namespace>:应用所在的命名空间。

          • <serviceAccountName>:服务账户名称。

          根据测试应用的信息,此处需要填入system:serviceaccount:rrsa-demo:demo-sa

      image

    5. 在弹窗页面中,输入角色名称demo-role-for-rrsa,单击确定

  2. 为创建的角色授予测试应用所需的AliyunCSReadOnlyAccess系统策略权限。具体操作,请参见RAM角色授权

    image

  3. 部署测试应用。

    1. 使用以下内容,创建demo.yaml文件。

      说明

      请替换应用模板示例代码中的如下字段。

      • <role_arn>需要替换为当前应用使用的RAM角色ARN。该ARN可在RAM控制台角色基本信息页面的ARN获取。

      • <oid_provider_arn>:替换为当前集群的OIDC提供商ARN。该ARN可在集群信息页面的基本信息页签,将鼠标移动到RRSA OIDC右侧的已开启上获取。

      展开查看示例代码

      ---
      apiVersion: v1
      kind: Namespace
      metadata:
        name: rrsa-demo
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: demo-sa
        namespace: rrsa-demo
      ---
      apiVersion: v1
      kind: Pod
      metadata:
        name: demo
        namespace: rrsa-demo
      spec:
        containers:
        - args:
          - rrsa
          - demo
          env:
          - name: ALIBABA_CLOUD_ROLE_ARN
            value: <role_arn>
          - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN
            value: <oid_provider_arn>
          - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE
            value: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens/token
          image: registry.cn-hangzhou.aliyuncs.com/acs/ack-ram-tool:1.0.0
          imagePullPolicy: Always
          name: demo
          volumeMounts:
          - mountPath: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens
            name: rrsa-oidc-token
            readOnly: true
        restartPolicy: OnFailure
        serviceAccount: demo-sa
        serviceAccountName: demo-sa
        volumes:
        - name: rrsa-oidc-token
          projected:
            defaultMode: 420
            sources:
            - serviceAccountToken:
                audience: sts.aliyuncs.com
                expirationSeconds: 3600  # 单位为秒,取值范围为[600, 43200],即10分钟~12小时。
                path: token
    2. 执行以下命令,部署测试应用。

      kubectl apply -f demo.yaml

      部署应用后,应用内程序可以通过挂载的OIDC Token、RAM角色的ARN以及OIDC身份提供商的ARN,调用STSAssumeRoleWithOIDC接口,以获取指定RAM角色的临时凭证。然后使用该临时凭证访问云资源OpenAPI。更多信息,请参见AssumeRoleWithOIDC

  4. 执行以下命令,查看测试应用日志。

    kubectl -n rrsa-demo logs demo

    预期输出ACK集群列表信息:

    20**/**/** 08:35:23 ======= [begin] list ACK clusters with RRSA =======
    clusters:
    cluster id: cf***, cluster name: foo*
    cluster id: c8***, cluster name: bar*
    cluster id: c4***, cluster name: foob*
    20**/**/** 08:35:24 ======= [end]   list ACK clusters with RRSA =======
  5. 可选:移除角色被授予的AliyunCSReadOnlyAccess系统策略权限。具体操作,请参见RAM角色移除权限

    等待30秒左右,执行以下命令,再次查看测试应用日志。

    kubectl -n rrsa-demo logs demo

    预期输出无权限的错误日志:

    20**/**/** 10:09:33 ======= [begin] list ACK clusters with RRSA =======
    20**/**/** 10:09:33 SDKError:
       StatusCode: 403
       Code: StatusForbidden
       Message: code: 403, STSToken policy Forbidden for action cs:DescribeClusters request id: XXXX
       Data: {"accessDeniedDetail":{"AuthAction":"cs:DescribeClusters","AuthPrincipalDisplayName":"demo-role-for-rrsa:ack-ram-tool","AuthPrincipalOwnerId":"XXXX","AuthPrincipalType":"AssumedRoleUser","EncodedDiagnosticMessage":"XXXX","NoPermissionType":"ImplicitDeny","PolicyType":"ResourceGroupLevelIdentityBasedPolicy"},"code":"StatusForbidden","message":"STSToken policy Forbidden for action cs:DescribeClusters","requestId":"XXXX","status":403,"statusCode":403}

使用已存在的RAM角色并授权

如果您的应用需要使用已存在的RAM角色,而非创建新的单独RAM角色,您可以修改RAM角色的信任策略,新增一条允许使用指定的服务账户的应用有权限通过扮演此RAM角色获取临时凭证的信任策略。更多信息,请参见修改RAM角色的信任策略

RAM角色信任策略中新增的Statement条目内容示例如下。

说明

请替换Statement条目内容示例中的如下字段。

  • <oidc_issuer_url>:替换为当前集群的OIDC提供商URL。在集群信息页面的基本信息页签,将鼠标移动到RRSA OIDC右侧的已开启上获取。

  • <oidc_provider_arn>:替换为当前集群的OIDC提供商ARN。在集群信息页面的基本信息页签,将鼠标移动到RRSA OIDC右侧的已开启上获取。

  • <namespace>:替换为应用所在的命名空间。

  • <service_account>:替换为应用使用的服务账户。

{
  "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>"
    ]
  }
}

相关文档