AWS EKS Pod Identity 認證機制

AWS EKS Pod Identity Authentication Mechanism

Pod Identity 概述

AWS EKS Pod Identity 是 AWS 在 2023 年推出的全新認證機制,用於簡化 Kubernetes Pod 存取 AWS 服務的身份驗證流程。相較於傳統的 IAM Roles for Service Accounts (IRSA),Pod Identity 提供了更簡潔的設定方式,無需手動管理 OIDC Provider。

Pod Identity 的核心概念是透過 EKS Pod Identity Agent(以 DaemonSet 形式運行)攔截 Pod 對 AWS 憑證的請求,並自動提供對應的 IAM 角色憑證。

主要優勢

  • 簡化設定流程:無需設定 OIDC Provider
  • 集中管理:透過 Pod Identity Association 統一管理權限對應
  • 跨帳戶存取:原生支援跨 AWS 帳戶的資源存取
  • 減少錯誤:避免 IRSA 中常見的 Trust Policy 設定錯誤

與 IRSA 比較

特性Pod IdentityIRSA
OIDC Provider不需要需要
設定複雜度中等
Trust Policy自動管理手動設定
跨帳戶支援原生支援需額外設定
Agent 需求需要安裝不需要
AWS SDK 版本需求較新版本大多數版本支援

安裝 Pod Identity Agent

Pod Identity Agent 是 EKS Add-on,可透過 AWS CLI 或 Terraform 安裝。

使用 AWS CLI 安裝

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 確認 EKS 叢集名稱
export CLUSTER_NAME="my-eks-cluster"
export AWS_REGION="ap-northeast-1"

# 安裝 Pod Identity Agent Add-on
aws eks create-addon \
    --cluster-name ${CLUSTER_NAME} \
    --addon-name eks-pod-identity-agent \
    --region ${AWS_REGION}

# 確認安裝狀態
aws eks describe-addon \
    --cluster-name ${CLUSTER_NAME} \
    --addon-name eks-pod-identity-agent \
    --region ${AWS_REGION} \
    --query 'addon.status'

驗證 Agent 運行狀態

1
2
3
4
5
# 檢查 DaemonSet 狀態
kubectl get daemonset eks-pod-identity-agent -n kube-system

# 檢查所有節點是否都有運行 Agent Pod
kubectl get pods -n kube-system -l app.kubernetes.io/name=eks-pod-identity-agent

建立 Pod Identity Association

Pod Identity Association 是連結 Kubernetes Service Account 與 IAM Role 的關鍵設定。

建立 Service Account

1
2
3
4
5
# 建立 Namespace(如果尚未存在)
kubectl create namespace my-application

# 建立 Service Account
kubectl create serviceaccount my-app-sa -n my-application

建立 Pod Identity Association

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 設定變數
export CLUSTER_NAME="my-eks-cluster"
export NAMESPACE="my-application"
export SERVICE_ACCOUNT="my-app-sa"
export IAM_ROLE_ARN="arn:aws:iam::123456789012:role/my-app-role"

# 建立 Association
aws eks create-pod-identity-association \
    --cluster-name ${CLUSTER_NAME} \
    --namespace ${NAMESPACE} \
    --service-account ${SERVICE_ACCOUNT} \
    --role-arn ${IAM_ROLE_ARN} \
    --region ${AWS_REGION}

# 列出所有 Association
aws eks list-pod-identity-associations \
    --cluster-name ${CLUSTER_NAME} \
    --region ${AWS_REGION}

設定 IAM Role

建立 Trust Policy

Pod Identity 使用特定的 Trust Policy 格式,與 IRSA 不同。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 建立 Trust Policy 文件
cat > trust-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "pods.eks.amazonaws.com"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ]
        }
    ]
}
EOF

# 建立 IAM Role
aws iam create-role \
    --role-name my-app-role \
    --assume-role-policy-document file://trust-policy.json

附加權限 Policy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 建立權限 Policy(以 S3 存取為例)
cat > permissions-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        }
    ]
}
EOF

# 建立並附加 Policy
aws iam put-role-policy \
    --role-name my-app-role \
    --policy-name my-app-s3-access \
    --policy-document file://permissions-policy.json

應用程式設定

Deployment 範例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-application
  namespace: my-application
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-application
  template:
    metadata:
      labels:
        app: my-application
    spec:
      serviceAccountName: my-app-sa
      containers:
      - name: app
        image: amazon/aws-cli:latest
        command: ["sleep", "infinity"]
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

部署應用程式

1
2
3
4
5
# 套用 Deployment
kubectl apply -f deployment.yaml

# 確認 Pod 運行狀態
kubectl get pods -n my-application

驗證設定

驗證憑證取得

1
2
3
4
5
6
7
# 進入 Pod 執行驗證
kubectl exec -it deployment/my-application -n my-application -- /bin/bash

# 在 Pod 內執行以下命令
aws sts get-caller-identity

# 預期輸出應顯示對應的 IAM Role ARN

驗證 AWS 服務存取

1
2
3
# 測試 S3 存取權限
kubectl exec -it deployment/my-application -n my-application -- \
    aws s3 ls s3://my-bucket/

故障排除

常見問題與解決方案

1. Pod 無法取得憑證

1
2
3
4
5
# 檢查 Pod Identity Agent 是否正常運行
kubectl get pods -n kube-system -l app.kubernetes.io/name=eks-pod-identity-agent

# 檢查 Agent 日誌
kubectl logs -n kube-system -l app.kubernetes.io/name=eks-pod-identity-agent

2. Association 設定錯誤

1
2
3
4
5
# 確認 Association 狀態
aws eks describe-pod-identity-association \
    --cluster-name ${CLUSTER_NAME} \
    --association-id <association-id> \
    --region ${AWS_REGION}

3. IAM Role Trust Policy 問題

確認 Trust Policy 包含正確的 Principal 和 Action:

1
2
3
# 檢查 Role 的 Trust Policy
aws iam get-role --role-name my-app-role \
    --query 'Role.AssumeRolePolicyDocument'

4. SDK 版本不相容

Pod Identity 需要較新版本的 AWS SDK。請確認您的應用程式使用以下最低版本:

  • AWS SDK for Python (Boto3): 1.28.57+
  • AWS SDK for Java: 2.21.0+
  • AWS SDK for Go: 1.47.0+

最佳實踐

安全性建議

  1. 最小權限原則:僅授予 Pod 所需的最小 IAM 權限
  2. 定期審查:定期檢視 Pod Identity Association 設定
  3. 使用 Namespace 隔離:為不同應用程式使用獨立的 Namespace
  4. 監控與日誌:啟用 CloudTrail 記錄 API 呼叫

維運建議

  1. 版本更新:定期更新 Pod Identity Agent Add-on
  2. 備份設定:將 Association 設定納入 Infrastructure as Code
  3. 測試環境驗證:在正式環境部署前先於測試環境驗證

移轉建議

從 IRSA 遷移至 Pod Identity 時:

  1. 在測試環境建立 Pod Identity 設定
  2. 驗證應用程式正常運作
  3. 逐步將正式環境工作負載遷移
  4. 確認無問題後移除 IRSA 設定

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy