在2021年,亞馬遜網路服務 (Amazon Web Services, AWS) 推出了適用於Kubernetes Secrets Store Container Storage Interface (CSI) 驅動的AWS Secrets and Configuration Provider (ASCP),為管理Amazon Elastic Kubernetes Service (Amazon EKS)中的機密提供了一種可靠的方法。今天,我們很高興地宣布ASCP與Pod Identity的整合,這是AWS Identity and Access Management (IAM) 與Amazon EKS整合的新標準。這項整合為需要存取AWS Secrets Manager和AWS Systems Manager Parameter Store中儲存的機密的應用程式提供了增強的安全性、簡化的配置和改進的Day-2操作。在這篇文章中,我們將介紹使用Pod Identity與ASCP整合的單一和跨帳戶機密的使用案例。
Amazon EKS在2023年推出了Pod Identity,這是一項簡化Kubernetes應用程式配置IAM權限的功能。Pod Identity透過允許您直接透過EKS介面設置權限,簡化了在Amazon EKS上運行的應用程式的身份管理,減少了所需的步驟,並減輕了在EKS和IAM服務之間切換的需求。Pod Identity允許在多個叢集中使用單一IAM角色,而無需更新信任政策,並支持角色會話標籤以實現更細緻的存取控制。這種方法不僅通過允許在角色之間重複使用權限政策來簡化政策管理,還通過根據匹配標籤來啟用對AWS資源的存取來增強安全性。
背景
當您在Amazon EKS上運行的應用程式需要敏感信息,如存取資料庫的憑證或通過API進行身份驗證的金鑰時,我們稱這類信息為機密。您可以在AWS Secrets Manager中保護、儲存和管理機密。ASCP允許Kubernetes應用程式安全地檢索儲存在Secrets Manager和Systems Manager Parameter Store中的機密。以前,ASCP依賴於服務帳戶的IAM角色 (IRSA) 進行身份驗證。雖然IRSA比以前的方法有所改進,但Pod Identity提供了更高的安全性和簡單性。
Pod Identity提供了一種更安全和高效的方法來將IAM角色與在EKS上運行的應用程式整合,為單個Pod提供更細緻的AWS權限,因此您不需要實例級憑證或IRSA。
與使用IRSA相比,這項整合提供了以下主要優勢:
增強的安全性:Pod Identity在Pod級別提供了一種更細緻和安全的權限管理方式,減輕了在Kubernetes ServiceAccount對象上暴露IAM角色註釋的需求。
簡化的配置:Pod Identity簡化了設置過程,減少了配置錯誤的可能性,尤其是在大規模環境中。
改進的操作:Pod Identity減少了與以前方法相比的操作負擔,通過AWS API集中管理。
原生EKS整合:Pod Identity是EKS上運行的應用程式的IAM整合的新標準,提供了更一致的體驗。
解決方案概述
通過這項整合,ASCP使用Pod Identity來驗證和授權存取AWS服務。當Pod需要存取機密時,工作流程如圖1所示。
圖1:Pod Identity和ASCP整合的工作流程,為在Amazon EKS上運行的Pod提供存取AWS Secrets Manager中儲存的機密
工作流程如下:
使用者創建一個IAM角色和Pod Identity關聯,將IAM角色與分配給Pod的Kubernetes ServiceAccount關聯。
EKS API驗證Pod Identity關聯,允許ASCP使用此角色與AWS服務進行身份驗證。
如果授權,Pod Identity代理允許ASCP通過使用ServiceAccount令牌假設分配給Pod的IAM角色。
Pod檢索請求的機密值,並通過掛載卷將其提供給Pod。
先決條件
要實施此解決方案,您需要具備以下先決條件:
實施解決方案
本指南介紹了兩種情境:單一帳戶設置和跨帳戶設置。在進行跨帳戶配置之前,請先在帳戶A中完成單一帳戶步驟。跨帳戶設置基於單一帳戶的基礎,展示跨AWS帳戶的安全機密管理。
Amazon EKS叢集設置
在開始之前,您需要在單一帳戶(帳戶A)中設置具有所需附加組件的Amazon EKS叢集。
(可選)使用以下命令設置環境變數並創建Amazon EKS叢集:
export CLUSTER_NAME=<YOUR_CLUSTER_NAME>
export AWS_REGION=<YOUR_AWS_REGION>
export NAMESPACE=<YOUR_NAMESPACE>
export ACCOUNT_A=<ACCOUNT_ID_1>
export ACCOUNT_B=<ACCOUNT_ID_2>
export SECRET_NAME=<NAME_OF_YOUR_SECRET>
export SECRET_NAME_CROSS=<NAME_OF_YOUR_CROSS_SECRET>
以下是此演示的環境變數:
export CLUSTER_NAME=ascp-podidentity
export SECRET_NAME=secret-a
export AWS_REGION=$(aws configure get region)
export NAMESPACE=default
export SECRET_NAME=secret-a
export SECRET_NAME_CROSS=secret-b
創建EKS叢集:
eksctl create cluster —name $CLUSTER_NAME —version=1.31
更新您的kubeconfig文件以在EKS叢集上啟用Pod Identity(如果尚未啟用):
eksctl create addon –cluster $CLUSTER_NAME –name eks-pod-identity-agent
安裝Secrets Store CSI驅動:
aws eks –region $AWS_REGION update-kubeconfig –name $CLUSTER_NAME
helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm install -n kube-system csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver
驗證Secrets Store CSI驅動安裝:
kubectl –namespace=kube-system get pods -l “app=secrets-store-csi-driver”
您應該看到以下預期輸出:
NAME READY STATUS RESTARTS AGE
csi-secrets-store-secrets-store-csi-driver-fcxf6 3/3 Running 0 41s
csi-secrets-store-secrets-store-csi-driver-j9wqh 3/3 Running 0 41s
安裝ASCP插件:
kubectl apply -f https://raw.githubusercontent.com/aws/secrets-store-csi-driver-provider-aws/main/deployment/aws-provider-installer.yaml
在單一帳戶中使用機密
現在您已設置Amazon EKS叢集,在此使用案例中,您將在叢集和應用程式所在的相同帳戶(帳戶A)中創建AWS Secrets Manager機密。
在與EKS叢集相同的AWS帳戶中,使用標籤kubernetes-namespace和eks-cluster-name在AWS Secrets Manager中創建一個機密:
aws secretsmanager create-secret –region $AWS_REGION \
–name $SECRET_NAME \
–tags Key=kubernetes-namespace,Value=$NAMESPACE Key=eks-cluster-name,Value=$CLUSTER_NAME \
–secret-string “”user”:”user1″,”password”:”passwd1″”
您應該看到以下預期輸出:
“ARN”: “arn:aws:secretsmanager:$AWS_REGION:$ACCOUNT_A:secret:dummy-secret-q1w2e3”,
“Name”: “secret-a”,
“VersionId”: “abcdefgh-1234-5678-ijklmnopqrst”
記下新機密的Amazon資源名稱(ARN)。您將在下一步中使用它。
創建一個IAM角色和信任政策,具有在同一AWS帳戶中檢索新創建的機密所需的權限:
SECRET_ARN=
< NOTED_SECRET_ARN_FROM_PREVIOUS_STEP>
cat << EOF > policy.json
{
“Version”: “2012-10-17”,
“Statement”: [
“Effect”: “Allow”,
“Action”: [“secretsmanager:GetSecretValue”, “secretsmanager:DescribeSecret”],
“Resource”: [“$SECRET_ARN”],
“Condition”:
“StringEquals”:
“secretsmanager:ResourceTag/kubernetes-namespace”: “\$aws:PrincipalTag/kubernetes-namespace”,
“secretsmanager:ResourceTag/eks-cluster-name”: “\$aws:PrincipalTag/eks-cluster-name”
]
}
EOF
在前面的IAM角色權限政策示例中,使用條件與kubernetes-namespace和eks-cluster-name標籤有助於通過指定機密只能由特定命名空間和叢集的Pod存取來強制執行細粒度存取控制。這允許secretsmanager操作僅在機密標記有匹配的kubernetes-namespace和eks-cluster-name值時進行。
cat << EOF > trust.json
“Version”: “2012-10-17”,
“Statement”: [
“Effect”: “Allow”,
“Principal”:
“Service”: “pods.eks.amazonaws.com”
,
“Action”: [
“sts:AssumeRole”,
“sts:TagSession”
]
]
EOF
請注意,前面的IAM角色信任政策允許Amazon EKS Pod Identity服務(pods.eks.amazonaws.com)假設角色並標記會話。這些操作對於Pod Identity正確運作是必要的,使Pod能夠安全地存取AWS資源。
最後,應用角色和信任政策:
aws iam create-role –role-name ascp-podidentity –assume-role-policy-document file://trust.json
aws iam put-role-policy –role-name ascp-podidentity –policy-name ascp-podidentity –policy-document file://policy.json
記下新角色的ARN。您將在下一步中使用它。
創建一個Kubernetes ServiceAccount並添加ServiceAccount與IAM角色之間的Pod Identity關聯:
ROLE_ARN=
<NOTED_ROLE_ARN_FROM_PREVIOUS_STEP>
kubectl create serviceaccount serviceaccount-a
aws eks create-pod-identity-association \
–cluster-name “$CLUSTER_NAME” \
–namespace “default” \
–service-account serviceaccount-a \
–role-arn $ROLE_ARN
創建一個SecretProviderClass以在您的Amazon EKS叢集中使用新創建的機密。
cat << EOF | kubectl apply -f –
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: aws-secrets-manager
spec:
provider: aws
parameters:
objects: |
– objectName: “secret-a” # Secret name or ARN to be mounted to the Pod
objectType: “secretsmanager”
usePodIdentity: “true” # Indicator to use Pod Identity instead of IRSA
EOF
創建一個新部署,以使用Pod Identity作為掛載卷來使用您新創建的機密。
cat << EOF | kubectl apply -f –
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: application-a
name: application-a
spec:
replicas: 1
selector:
matchLabels:
app: application-a
template:
metadata:
labels:
app: application-a
spec:
containers:
– image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
name: amazonlinux
args:
– infinity
command:
– sleep
volumeMounts:
– name: secrets-store-inline
mountPath: “/mnt/secret” # Directory where secret will be mounted to
readOnly: true
volumes:
– name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: “aws-secrets-manager” # Match SecretProviderClass name created
serviceAccountName: serviceaccount-a # Specify service account created
EOF
驗證部署是否成功創建並確認機密已正確掛載。
kubectl get pods -l app=application-a
kubectl exec -it $(kubectl get pods -l app=application-a -o name) — cat /mnt/secret/secret-a
您應該看到以下預期輸出:
NAME READY STATUS RESTARTS AGE
application-a-b98d44bb8-bzvn4 1/1 Running 0 3s
“user”:”user1″,”password”:”passwd1″%
通過資源政策處理跨帳戶機密
在第二個使用案例中,您還將使用帳戶A上的Amazon EKS叢集,並在不同的帳戶(帳戶B)中創建一個新的Secrets Manager機密。
為了存取不同帳戶中的機密,您不能使用預設的AWS Key Management Service (AWS KMS) 金鑰,而是將使用aws/secretsmanager來加密此機密。因此,您需要首先創建一個允許跨帳戶存取的AWS KMS金鑰。
在帳戶B上
在AWS KMS上創建具有跨帳戶權限的客戶管理金鑰:
cat < key-policy.json
{
“Version”: “2012-10-17”,
“Id”: “cross-account-access”,
“Statement”: [
“Sid”: “Enable IAM User Permissions”,
“Effect”: “Allow”,
“Principal”:
“AWS”: “arn:aws:iam::$ACCOUNT_B:root”
,
“Action”: “kms:*”,
“Resource”: “arn:aws:kms:$AWS_REGION:$ACCOUNT_B:key/*”
,
“Sid”: “Allow access for Key Administrators”,
“Effect”: “Allow”,
“Principal”:
“AWS”: “arn:aws:iam::$ACCOUNT_B:role/Admin”
,
“Action”: [
“kms:Create”,
“kms:Describe”,
“kms:Enable”,
“kms:List”,
“kms:Put”,
“kms:Update”,
“kms:Revoke”,
“kms:Disable”,
“kms:Get”,
“kms:Delete”,
“kms:TagResource”,
“kms:UntagResource”,
“kms:ScheduleKeyDeletion”,
“kms:CancelKeyDeletion”,
“kms:RotateKeyOnDemand”
],
“Resource”: “arn:aws:kms:$AWS_REGION:$ACCOUNT_B:key/*”
,
“Sid”: “Allow access through AWS Secrets Manager”,
“Effect”: “Allow”,
“Principal”:
“AWS”: “*”
,
“Action”: [
“kms:Encrypt”,
“kms:Decrypt”,
“kms:ReEncrypt”,
“kms:CreateGrant”,
“kms:DescribeKey”
],
“Resource”: “arn:aws:kms:$AWS_REGION:$ACCOUNT_B:key/*”,
“Condition”:
“StringEquals”:
“kms:ViaService”: “secretsmanager.$AWS_REGION.amazonaws.com”,
“kms:CallerAccount”: [
“$ACCOUNT_A”,
“$ACCOUNT_B”
]
,
“Sid”: “Allow access through AWS Secrets Manager for Generate Data Key”,
“Effect”: “Allow”,
“Principal”:
“AWS”: “*”
,
“Action”: “kms:GenerateDataKey”,
“Resource”: “arn:aws:kms:$AWS_REGION:$ACCOUNT_B:key/*”,
“Condition”:
“StringEquals”:
“kms:CallerAccount”: [
“$ACCOUNT_A”,
“$ACCOUNT_B”
]
,
“StringLike”:
“kms:ViaService”: “secretsmanager.$AWS_REGION.amazonaws.com”
,
“Sid”: “Allow direct access to key metadata to the account”,
“Effect”: “Allow”,
“Principal”:
“AWS”: [
“arn:aws:iam::$ACCOUNT_A:root”,
“arn:aws:iam::$ACCOUNT_B:root”
]
,
“Action”: [
“kms:Describe”,
“kms:Get”,
“kms:List”,
“kms:RevokeGrant”
],
“Resource”: “arn:aws:kms:$AWS_REGION:$ACCOUNT_B:key/*”
]
}
EOF
然後創建KMS金鑰:
$ aws kms create key –region $AWS_REGION –policy file://key-policy.json
您應該看到以下預期輸出:
“KeyMetadata”:
“AWSAccountId”: “$ACCOUNT_B”,
“KeyId”: “abcdefgh-1234-5678-90ij-klmnopqrstuv”,
“Arn”: “arn:aws:kms:$AWS_REGION:$ACCOUNT_B:key/abcdefgh-1234-5678-90ij-klmnopqrstuv”,
“CreationDate”: “2025-01-23T18:00:00.756000-05:00”,
“Enabled”: true,
“Description”: “”,
“KeyUsage”: “ENCRYPT_DECRYPT”,
“KeyState”: “Enabled”,
“Origin”: “AWS_KMS”,
“KeyManager”: “CUSTOMER”,
“CustomerMasterKeySpec”: “SYMMETRIC_DEFAULT”,
“KeySpec”: “SYMMETRIC_DEFAULT”,
“EncryptionAlgorithms”: [
“SYMMETRIC_DEFAULT”
],
“MultiRegion”: false
記下金鑰的KeyID和ARN。您可以使用它為新創建的金鑰創建別名:
KEY_ID=<NOTED_KEY_ID_FROM_PREVIOUS_STEP>
aws kms create-alias –region $AWS_REGION —-alias-name alias/secretsmanager-cross —-target-key-id $KEY_ID
在Secrets Manager中創建一個新機密,使用新KMS金鑰加密它:
aws secretsmanager create-secret –region $AWS_REGION \
–name $SECRET_NAME_CROSS \
–tags Key=kubernetes-namespace,Value=$NAMESPACE Key=eks-cluster-name,Value=$CLUSTER_NAME \
–secret-string “This is a Cross Account Secret” \
–kms-key-id $KEY_ID
您應該看到以下預期輸出:
“ARN”: “arn:aws:secretsmanager:$AWS_REGION:$ACCOUNT_B:secret:secret-b-12345”,
“Name”: “secret-b”,
“VersionId”: “abcdefgh-1234-5678-ijklmnopqrst”
記下新機密的ARN。您將在下一步中使用它。
添加資源政策,允許帳戶A上的IAM角色存取新創建的機密:
SECRET_CROSS_ARN=
< NOTED_SECRET_CROSS_ARN_FROM_PREVIOUS_STEP>
cat << EOF > resource-policy.json
“Version” : “2012-10-17”,
“Statement” : [
“Effect” : “Allow”,
“Principal” :
“AWS” : “arn:aws:iam::$ACCOUNT_A:root”
,
“Action” : [ “secretsmanager:GetSecretValue”, “secretsmanager:DescribeSecret” ],
“Resource” : “$SECRET_CROSS_ARN”
]
EOF
aws secretsmanager put-resource-policy –secret-id $SECRET_NAME_CROSS –resource-policy file://resource-policy.json
現在讓我們回到帳戶A。
在帳戶A上
創建一個新IAM角色和信任政策,具有在帳戶B中檢索新創建的機密所需的權限:
KEY_ARN=
< NOTED_KEY_ARN_FROM_PREVIOUS_STEP>
cat << EOF > cross-policy.json
{
“Version”: “2012-10-17”,
“Statement”: [
“Effect”: “Allow”,
“Action”: [“secretsmanager:GetSecretValue”, “secretsmanager:DescribeSecret”],
“Resource”: [“$SECRET_CROSS_ARN”],
“Condition”:
“StringEquals”:
“secretsmanager:ResourceTag/kubernetes-namespace”: “\$aws:PrincipalTag/kubernetes-namespace”,
“secretsmanager:ResourceTag/eks-cluster-name”: “\$aws:PrincipalTag/eks-cluster-name”
,
“Effect”: “Allow”,
“Action”: [
“kms:Decrypt”,
“kms:DescribeKey”
],
“Resource”: “$KEY_ARN”
]
}
EOF
在前面的IAM角色權限政策示例中,請注意資源ARN指向帳戶B中創建的機密。
cat << EOF > trust.json
“Version”: “2012-10-17”,
“Statement”: [
“Effect”: “Allow”,
“Principal”:
“Service”: “pods.eks.amazonaws.com”
,
“Action”: [
“sts:AssumeRole”,
“sts:TagSession”
]
]
EOF
IAM角色信任政策需要將pods.eks.amazonaws.com作為受信實體來執行sts:AssumeRole和sts:TagSession操作。
接下來,創建角色並應用政策:
aws iam create-role –role-name ascp-podidentity-cross –assume-role-policy-document file://trust.json
aws iam put-role-policy –role-name ascp-podidentity-cross –policy-name ascp-podidentity-cross –policy-document file://cross-policy.json
記下新角色的ARN。您將在下一步中使用它。
創建第二個Kubernetes ServiceAccount並添加跨帳戶Pod Identity關聯:
kubectl create serviceaccount serviceaccount-b
ROLE_CROSS_ARN=<NOTED_ROLE_CROSS_ARN_FROM_PREVIOUS_STEP>
aws eks create-pod-identity-association \
–cluster-name “$CLUSTER_NAME” \
–namespace “default” \
–service-account serviceaccount-b \
–role-arn $ROLE_CROSS_ARN
創建一個SecretProviderClass,以在您的Amazon EKS叢集中使用在帳戶B中創建的跨帳戶機密:
cat << EOF | kubectl apply -f –
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: aws-secrets-manager-cross
spec:
provider: aws
parameters:
objects: |
– objectName: “$SECRET_CROSS_ARN” # Full ARN of the Secret in the ACCOUNT B to be mounted on Pod
objectType: “secretsmanager”
usePodIdentity: “true” # Indicator to use Pod Identity instead of IRSA
EOF
創建一個新部署,以使用Pod Identity作為掛載卷來使用您新創建的機密:
cat << EOF | kubectl apply -f –
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: application-b
name: application-b
spec:
replicas: 1
selector:
matchLabels:
app: application-b
template:
metadata:
labels:
app: application-b
spec:
containers:
– image: public.ecr.aws/amazonlinux/amazonlinux:2023-minimal
name: amazonlinux
args:
– infinity
command:
– sleep
volumeMounts:
– name: secrets-store-cross
mountPath: “/mnt/secret” # Directory where secret will be mounted to readOnly: true
volumes:
– name: secrets-store-cross
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: “aws-secrets-manager-cross” # Match SecretProviderClass name created for cross-account access serviceAccountName: serviceaccount-b # Specify service account created for cross-account access
EOF
驗證部署是否成功創建並確認掛載的機密:
kubectl get pods -l app=application-b
kubectl exec -it $(kubectl get pods -l app=application-b -o name) — cat /mnt/secret/$SECRET_CROSS_ARN
請注意,卷名是機密ARN,因為它是跨帳戶機密。
您應該看到以下預期輸出:
NAME READY STATUS RESTARTS AGE
application-b-67b755444f-ngrhv 1/1 Running 0 8s
“This is a Cross Account Secret”%
結論
ASCP與Pod Identity的整合標誌著Amazon EKS機密管理的一個重要進步。它提供了增強的安全性、簡化的配置和改進的操作。我們鼓勵所有EKS用戶探索這項新整合並利用其優勢。
ASCP與Pod Identity的整合提供了這些優勢,相較於IRSA:
簡化的設置:使用Pod Identity,您不需要為每個應用程式創建和管理服務帳戶。
增強的安全性:Pod Identity在Pod級別提供了更細緻的權限控制。
改進的可擴展性:Pod Identity在大規模環境中更容易實施。
一致的AWS體驗:Pod Identity更符合AWS的IAM管理最佳實踐。
欲了解更多信息,請參閱我們的文檔:AWS Secrets Manager、AWS Secrets CSI Store Provider (ASCP) 和Amazon EKS Pod Identity。
如果您對本文有反饋,請在下面的評論部分提交評論。如果您對本文有疑問,請聯繫AWS支持。
Rodrigo Bersa
Rodrigo是一位專注於安全性和基礎設施即代碼自動化的容器和AppMod高級專家解決方案架構師。在這個角色中,Rodrigo旨在幫助客戶通過利用AWS容器服務的最佳實踐來實現其業務目標,無論是在構建新環境還是遷移現有技術時。
Akshay Aggarwal
Akshay是AWS Secrets Manager團隊的高級技術產品經理。作為AWS加密技術團隊的一員,Akshay推動技術發展並定義最佳實踐,以幫助改善客戶在AWS雲中構建安全、可靠工作負載的體驗。Akshay熱衷於構建易於使用、安全且可擴展的技術。
Stephanie Shen
Stephanie Shen是Amazon Web Services (AWS) 的軟體開發工程師,隸屬於AWS安全服務團隊。她擁有超過8年的經驗,曾擔任產品經理。Stephanie旨在通過增強AWS安全服務的功能來幫助客戶提高其安全姿態。