基于適用于服務賬戶的RAM角色(RAM Roles for Service Accounts,簡稱RRSA)功能,您可以在集群內實現Pod維度的OpenAPI權限隔離,從而實現云資源訪問權限的細粒度隔離,降低安全風險。本文介紹如何在集群中使用RRSA。
索引
背景信息
ECS實例元數據包含ECS實例(ECI實例基于ECS實例實現)在阿里云系統中的信息。您可以在運行中的實例內查看實例元數據,并基于實例元數據配置或管理實例。通過實例元數據,Kubernetes集群內應用可以獲取實例RAM角色策略所生成的STS臨時憑證,然后通過該臨時憑證訪問云資源OpenAPI。更多信息,請參見ECS實例元數據概述。
當您需要限制集群內不同應用的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版。
啟用RRSA功能
登錄容器服務管理控制臺。
在控制臺左側導航欄,單擊集群。
在集群列表頁面,單擊目標集群名稱或者目標集群右側操作列下的詳情。
在集群詳情頁面,單擊基本信息頁簽,然后在集群信息區域單擊RRSA OIDC對應的啟用RRSA。
在彈出的啟用RRSA對話框,單擊確定。
在基本信息區域,當集群狀態由更新中變為運行中后,表明該集群的RRSA特性已變更完成,RRSA OIDC右側將顯示OIDC提供商的URL鏈接和ARN信息。
集群開啟RRSA功能后,ACK將在后臺執行如下操作。
自動創建一個集群專用的OIDC Issuer服務。該服務由ACK托管,無需您運維。更多信息,請參見OIDC Issuer。
修改當前集群的服務賬戶令牌卷投影功能的配置,使用本次創建的OIDC Issuer配置合并集群已有的service-account-issuer參數的值。更多信息,請參見部署服務賬戶令牌卷投影。
在您的賬號下創建一個使用該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。--- 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
執行以下命令,部署測試應用。
kubectl apply -f demo.yaml
執行以下命令,查看測試應用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的配置。
執行以下命令,查看測試應用日志。
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功能。
應用模板示例代碼如下。
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可在容器服務管理控制臺集群信息頁面的基本信息頁簽獲取。<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>"
]
}
}
您也可以使用命令行工具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 | 使用示例 |
對象存儲 | 更多信息,請參考OIDC訪問憑證。 | |
更多信息,請參考OIDC訪問憑證。 | ||
更多信息,請參考OIDC訪問憑證。 | ||
日志服務 | 更多信息,請參考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,您需要使用命令 |
| |
您可以在配置文件中通過配置 說明
|