全部產品
Search
文件中心

Container Service for Kubernetes:通過RRSA配置ServiceAccount的RAM許可權實現Pod許可權隔離

更新時間:Dec 17, 2024

基於適用於服務賬戶的RAM角色(RAM Roles for Service Accounts,簡稱RRSA)功能,您可以在叢集內實現Pod維度OpenAPI許可權隔離,從而實現雲資源存取權限的細粒度隔離,降低安全風險。本文介紹如何在叢集中使用RRSA。

背景資訊

ECS執行個體中繼資料套件含ECS執行個體(ECI執行個體基於ECS執行個體實現)在阿里雲系統中的資訊。您可以在運行中的執行個體內查看執行個體中繼資料,並基於執行個體中繼資料配置或管理執行個體。通過執行個體中繼資料,Kubernetes叢集內應用可以擷取執行個體RAM角色策略所產生的STS臨時憑證,然後通過該臨時憑證訪問雲資源OpenAPI。更多資訊,請參見執行個體中繼資料

當您需要限制叢集內不同應用的RAM許可權時,出於安全考慮,您應當禁止這些應用通過ECS或ECI執行個體中繼資料擷取您的執行個體關聯角色對應的臨時憑證或者不為執行個體關聯角色授予任何RAM權限原則。但這些應用仍然會需要一種安全的途徑去擷取訪問雲資源的臨時憑證。因此,阿里雲Container ServiceACK聯合RAM存取控制服務推出了RRSA功能。

基於RRSA功能,您可以在叢集內實現Pod層級隔離的應用關聯RAM角色功能。各個應用可以扮演獨立的RAM角色並使用擷取的臨時憑證訪問雲資源,從而實現應用RAM許可權最小化以及無AccessKey訪問阿里雲OpenAPI避免AccessKey泄露的需求。

從使用者側視角來看,RRSA功能的工作流程如下。

  1. 使用者提交使用了服務賬戶令牌卷投影功能的應用Pod。

  2. 叢集將為該應用Pod建立和掛載相應的服務賬戶OIDC Token檔案。

  3. Pod內程式使用掛載的OIDC Token檔案訪問STS服務的AssumeRoleWithOIDC介面,擷取扮演指定RAM角色的臨時憑證。

    說明
    • 請提前修改RAM角色配置,允許Pod使用的服務賬戶扮演該RAM角色。更多資訊,請參見AssumeRoleWithOIDC

    • 從檔案中讀取的OIDC Token是一個臨時Token,建議應用程式每次在使用時都從檔案中讀取最新的Token,叢集會在Token到期前更新替換檔案內已有的Token。

  4. 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功能。

image

在叢集資訊頁面開啟

  1. 登入Container Service管理主控台,在左側導覽列選擇叢集

  2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇叢集資訊

  3. 基本資料頁簽的安全與審計地區,單擊RRSA OIDC右側的開啟image

  4. 在彈出的啟用RRSA對話方塊,單擊確定

    基本資料地區,當叢集狀態由更新中變為運行中後,表明該叢集的RRSA特性已變更完成。

擷取叢集中OIDC供應商的URL和ARN資訊

叢集中RRSA功能開啟後,在基本資料頁簽的安全與審計地區,將滑鼠懸浮至RRSA OIDC右側已開啟上面,即可查看供應商的URL連結和ARN資訊。image

叢集開啟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角色並授權

  1. 安裝ack-pod-identity-webhook組件。

    1. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇營運管理 > 組件管理

    2. 組件管理頁面,單擊安全頁簽,找到ack-pod-identity-webhook組件,單擊組件右下方的安裝

    3. 在提示對話方塊確認組件資訊後,單擊確定

  2. 建立一個名為demo-role-for-rrsa的RAM角色。

    1. 使用阿里雲帳號登入RAM控制台

    2. 在左側導覽列,選擇身份管理 > 角色,然後在角色頁面,單擊建立角色

    3. 建立角色面板,選擇可信實體類型為身份供應商,然後單擊下一步

    4. 配置角色頁面,配置如下角色資訊後,單擊完成

      本樣本配置如下。

      配置項

      描述

      角色名稱

      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

  3. 步驟2建立的角色授予測試應用所需的AliyunCSReadOnlyAccess系統策略許可權。具體操作,請參見為RAM角色授權

  4. 部署測試應用。關於測試應用的參考代碼,請參見阿里雲官方SDK使用RRSA OIDC Token的參考代碼

    1. 使用以下內容,建立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

      展開查看範例程式碼

      ---
      apiVersion: v1
      kind: Namespace
      metadata:
        name: rrsa-demo
        labels:
          pod-identity.alibabacloud.com/injection: 'on'
      
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: demo-sa
        namespace: rrsa-demo
        annotations:
          pod-identity.alibabacloud.com/role-name: demo-role-for-rrsa
      
      ---
      apiVersion: v1
      kind: Pod
      metadata:
        name: demo
        namespace: rrsa-demo
      spec:
        serviceAccountName: demo-sa
        containers:
          - image: registry.cn-hangzhou.aliyuncs.com/acs/ack-ram-tool:1.0.0
            imagePullPolicy: "Always"
            args:
              - rrsa
              - demo
            name: demo
        restartPolicy: OnFailure
    2. 執行以下命令,部署測試應用。

      kubectl apply -f demo.yaml
  5. 執行以下命令,查看測試應用Pod,確認ack-pod-identity-webhook組件已為Pod自動注入所需的配置。

    kubectl -n rrsa-demo get pod demo -o yaml

    展開查看預期輸出

    apiVersion: v1
    kind: Pod
    metadata:
      name: demo
      namespace: rrsa-demo
    spec:
      containers:
      - args:
        - rrsa
        - demo
        env:
        - name: ALIBABA_CLOUD_ROLE_ARN
          value: acs:ram::1***:role/demo-role-for-rrsa
        - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN
          value: acs:ram::1***:oidc-provider/ack-rrsa-c***
        - 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/kubernetes.io/serviceaccount
          name: kube-api-access-4bwdg
          readOnly: true
        - 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: kube-api-access-4bwdg
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              expirationSeconds: 3607
              path: token
          - configMap:
              items:
              - key: ca.crt
                path: ca.crt
              name: kube-root-ca.crt
          - downwardAPI:
              items:
              - fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
                path: namespace
      - name: rrsa-oidc-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: sts.aliyuncs.com
              expirationSeconds: 3600
              path: token

    預期輸出表明,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的配置。

  6. 執行以下命令,查看測試應用日誌。

    kubectl -n rrsa-demo logs demo

    預期輸出叢集列表資訊:

    cluster id: cf***, cluster name: foo*
    cluster id: c8***, cluster name: bar*
    cluster id: c4***, cluster name: foob*
  7. 可選:移除角色被授予的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功能。

應用模板範例程式碼如下。

展開查看應用模板範例程式碼

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
          path: token
重要

請替換應用模板範例程式碼中的如下欄位。

  • <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條目內容樣本中的如下欄位。

您也可以使用命令列工具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

Go SDK使用樣本

Java

Alibaba Cloud Credentials for Java 0.2.10及以上版本。更多資訊,請參考方式六:使用OIDCRoleArn

Java SDK使用樣本

Python 3

Alibaba Cloud Credentials for Python 0.3.1及以上版本。更多資訊,請參考方式六:使用OIDCRoleArn

Python 3 SDK使用樣本

Node.js和TypeScript

Alibaba Cloud Credentials for TypeScript/Node.js 2.2.6及以上版本。更多資訊,請參考方式六:使用OIDCRoleArn

Node.js和TypeScript使用樣本

部分雲產品自研的SDK也可以參考上面的方法實現使用RRSA OIDC Token進行OpenAPI認證的功能。具體實現方式的參考代碼如下。

雲產品

SDK

使用樣本

Object Storage Service

OSS GO SDK

更多資訊,請參考方式五:使用OIDCRoleARN

Go SDK使用樣本

OSS Java SDK

更多資訊,請參考方式六:使用OIDCRoleARN

Java SDK使用樣本

OSS Python SDK

更多資訊,請參考方式六:使用OIDCRoleARN

Python SDK使用樣本

Log Service

Log ServiceJava SDK

更多資訊,請參考Java SDK快速入門

Java SDK使用樣本

SDK報錯資訊解決方案

不同報錯資訊的解決方案如下表所示。

報錯資訊

原因

解決方案

{
 "Code": "AuthenticationFail.OIDCToken.Expired",
 "Message": "This JsonWebToken is expired."
}

您的應用使用的OIDC Token已到期。

您需要每次都從環境變數ALIBABA_CLOUD_OIDC_TOKEN_FILE指向的檔案中讀取最新的OIDC Token。建議您使用阿里雲官方SDK而不是自行實現擷取臨時憑證的邏輯。更多資訊,請參見阿里雲官方SDK使用RRSA OIDC Token的參考代碼

{
 "Code": "Throttling.User",
 "Message": "Request was denied due to user flow control."
}

您的應用擷取臨時憑證的操作太頻繁,導致操作被限流。

請勿過於頻繁調用擷取臨時憑證的介面,在臨時憑證到期前您無需頻繁擷取新的憑證。建議您使用阿里雲官方SDK而不是自行實現擷取臨時憑證的邏輯。更多資訊,請參見阿里雲官方SDK使用RRSA OIDC Token的參考代碼

{
 "Code": "AuthenticationFail.OIDCToken.AudienceNotMatch",
 "Message": "Invalid audience."
}

您的應用模板中audience配置項的值不是sts.aliyuncs.com

您需要修改應用模板,確保配置項audience的值是預期的sts.aliyuncs.com

{
 "Code": "AuthenticationFail.OIDCToken.IssuerConfigurationBroken",
 "Message": "Get public keys from OIDC Provider failed, the issuer is https://kubernetes.default.svc."
}
{
 "Code": "AuthenticationFail.OIDCToken.IssuerNotMatch",
 "Message": "The issuer in the OIDC Token doesn't match the OIDC Provider registered."
}
{
 "Code": "AuthenticationFail.NoPermission",
 "Message": "No such OIDC Provider registered."
}

您的叢集未啟用RRSA功能。

您需要為應用所在叢集啟用RRSA功能。操作方法,請參見啟用RRSA功能。完成啟用RRSA功能操作後,您還需要重建使用RRSA功能的應用Pod。

{
 "Code": "EntityNotExist.Role",
 "Message": "The role not exists: acs:ram::19981***:role/***. "
}

您的應用所使用的RAM角色不存在。

您需要建立對應的RAM角色。操作方法,請參見建立OIDC身份供應商的RAM角色以及使用樣本

{
  "Code": "AuthenticationFail.NoPermission",
  "Message": "There is no permission"
}

您的應用所使用的RAM角色未完成所需的信任策略配置。

您需要修改RAM角色的信任策略,允許您的應用扮演該角色。操作方法,請參見使用已存在的RAM角色並授權

常用命令列工具使用RRSA OIDC Token

藉助ack-ram-tool,可以賦予部分常用命令列工具在容器內使用RRSA OIDC Token的能力。具體配置和使用樣本詳見下表。

命令列工具

配置方法

使用樣本

阿里雲CLI

您可以在設定檔~/.aliyun/config.json中將mode配置項的值設定為OIDC的方式使用RRSA OIDC Token。

說明
  • 僅v3.0.206及以上版本的阿里雲CLI支援該特性。

  • 需要將設定檔中region_id的值替換為您期望的地區。

{
  "current": "rrsa",
  "profiles": [
    {
      "name": "rrsa",
      "mode": "OIDC",
      "region_id": "cn-hangzhou",
      "ram_session_name": "test-rrsa"
    }
  ],
  "meta_path": ""
}
$ aliyun sts GetCallerIdentity
{
    "AccountId": "11380***",
    "Arn": "acs:ram::1138***:assumed-role/test-rrsa-***/test-rrsa",
    "IdentityType": "AssumedRoleUser",
    "PrincipalId": "33300***:test-rrsa",
    "RequestId": "20F78881-F47E-5771-90D6-***",
    "RoleId": "33300***"
}

您也可以不建立設定檔,直接執行阿里雲CLI相關命令。

說明

僅v3.0.206及以上版本的阿里雲CLI支援該特性。

$ aliyun sts GetCallerIdentity --region cn-hangzhou --role-session-name=test-rrsa
{
	"AccountId": "11380***",
	"Arn": "acs:ram::1138***:assumed-role/test-rrsa-***/test-rrsa",
	"IdentityType": "AssumedRoleUser",
	"PrincipalId": "33300***:test-rrsa",
	"RequestId": "20F78881-F47E-5771-90D6-***",
	"RoleId": "33300***"
}

Log ServiceCLI

暫不支援在Log ServiceCLI的設定檔中指定使用RRSA OIDC Token,您需要使用命令ack-ram-tool export-credentials -f environment-variables -- aliyunlog執行Log ServiceCLI相關命令。

$ ack-ram-tool export-credentials -f environment-variables -- aliyunlog log list_project --region-endpoint=cn-hangzhou.log.aliyuncs.com

{"count": 1, "projects": [
{"createTime": "1676282996", "description": "k8s log project, ***",
 "lastModifyTime": "1676282996", "owner": "", "projectName": "k8s-log-c0edc***", 
 "region": "cn-hangzhou", "resourceGroupId": "rg-***", "status": "Normal"}],
  "total": 24}

Terraform

您可以在設定檔中通過配置assume_role_with_oidc配置項的方式使用RRSA OIDC Token。

說明
  • 僅v1.222.0及以上版本的阿里雲Provider支援該配置項。

  • 需要將設定檔中region的值替換為您期望的地區。

provider "alicloud" {
  assume_role_with_oidc {
    role_session_name = "terraform-with-rrsa-auth-example"
  }
  region = "cn-hangzhou"
}

Terraform使用樣本

相關文檔