為什麼我的 Amazon EMR 應用程式失敗,出現 HTTP 403「存取遭拒」AmazonS3Exception?

上次更新日期:2022 年 5 月 3 日

當我將應用程式提交至 Amazon EMR 叢集時,應用程式失敗,出現 HTTP 403「存取遭拒」AmazonS3Exception:

java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 8B28722038047BAA; S3 Extended Request ID: puwS77OKgMrvjd30/EY4CWlC/AuhOOSNsxfI8xQJXMd20c7sCq4ljjVKsX4AwS7iuo92C9m+GWY=), S3 Extended Request ID: puwS77OKgMrvjd30/EY4CWlC/AuhOOSNsxfI8xQJXMd20c7sCq4ljjVKsX4AwS7iuo92C9m+GWY=

解析度

如果未正確設定許可,您可能會在 Amazon EMR 或 Amazon Simple Storage Service (Amazon S3) 上收到 "Access Denied"「存取遭拒」錯誤。

首先,檢查應用程式的程式碼中指定的憑證或角色

在 EMR 叢集的主節點上執行下列命令。將 s3://doc-example-bucket/abc/ 取代為您的 Amazon S3 路徑。

aws s3 ls s3://doc-example-bucket/abc/

如果此命令成功,則表示您應用程式的程式碼中指定的憑證或角色導致「存取遭拒」錯誤。確認您的應用程式使用了預期的憑證或承擔了預期的角色,並確認應用程式能夠存取 Amazon S3 路徑。使用 AWS CLI 承擔 AWS Identity and Access Management (IAM) 角色,以驗證角色具有存取 Amazon S3 路徑的許可。然後,對 S3 路徑執行範例請求。

如果此命令失敗,請確認您使用的是最新版本的 AWS Command Line Interface (AWS CLI)。然後,檢查下列各項以解決「存取遭拒」錯誤:

    檢查 Amazon EC2 執行個體設定檔角色的政策

    如果 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體設定檔 沒有對 S3 儲存貯體的必要讀寫許可,您可能會收到 "Access Denied"「存取遭拒」錯誤。

    注意:依預設,應用程式會從 Amazon EC2 執行個體設定檔的 IAM 角色繼承 Amazon S3 存取權。請確保連接至此角色的 IAM 政策允許對來源和目的地儲存貯體執行所需的 S3 操作。

    若要對此問題進行疑難排解,請透過執行以下命令檢查您是否具有所需的讀取許可:

    $ aws s3 ls s3://doc-example-bucket/myfolder/

    您的輸出可能如下所示:

    An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

    -或-

    執行以下命令:

    $ hdfs dfs -ls s3://doc-example-bucket/myfolder

    您的輸出可能如下所示:

    ls: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: RBT41F8SVAZ9F90B; S3 Extended Request ID: ih/UlagUkUxe/ty7iq508hYVfRVqo+pB6/xEVr5WHuvcIlfQnFf33zGTAaoP2i7cAb1ZPIWQ6Cc=; Proxy: null), S3 Extended Request ID: ih/UlagUkUxe/ty7iq508hYVfRVqo+pB6/xEVr5WHuvcIlfQnFf33zGTAaoP2i7cAb1ZPIWQ6Cc=

    請確保執行個體設定檔角色具有 S3 儲存貯體所需的讀寫許可。例如,以下 IAM 政策中的 S3 動作提供了對 S3 儲存貯體 doc-example-bucket 所需的讀寫存取權:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "ListObjectsInBucket",
          "Effect": "Allow",
          "Action": [
            "s3:ListBucket"
          ],
          "Resource": [
            "arn:aws:s3:::doc-example-bucket"
          ]
        },
        {
          "Sid": "AllObjectActions",
          "Effect": "Allow",
          "Action": "s3:*Object*",
          "Resource": [
            "arn:aws:s3:::doc-example-bucket/*"
          ]
        }
      ]
    }

    檢查 EMRFS 角色映射的 IAM 角色

    如果使用安全組態指定 EMRFS 的 IAM 角色,則您使用的是設定角色映射。您的應用程式會根據角色映射組態從IAM 角色繼承 S3 許可。

    連接至這些角色的 IAM 政策必須對來源和目的地儲存貯體具有所需的 S3 許可。要為 Amazon S3 指定 EMRFS 的 IAM 角色請求,請參閱使用 EMRFS 的 IAM 角色設定安全組態

    檢查 Amazon S3 VPC 端點政策

    如果 EMR 叢集的子網路路由表具有指向 Amazon S3 VPC 端點的路由,則確認端點政策允許所需的 Amazon S3 操作。

    要使用 CLI 來檢查和修改端點政策:

    執行以下命令以檢閱端點政策。將 vpce-xxxxxxxx 取代為 VPC ID。

    aws ec2 describe-vpc-endpoints --vpc-endpoint-ids "vpce-xxxxxxxx"

    如有必要,執行下列命令來上傳修改後的端點政策。取代 VPC ID 和 JSON 檔案路徑。

    aws ec2 modify-vpc-endpoint --vpc-endpoint-id "vpce-xxxxxxxx" --policy-document file://policy.json

    要使用 Amazon VPC 主控台來檢查和修改端點政策:

    1. 開啟 Amazon VPC 主控台
    2. 在導覽窗格中,選擇 Endpoints (端點)。
    3. 選取 Amazon S3 端點 (EMR 叢集的子網路路由表中的端點)。然後,選擇 Policy (政策) 標籤以檢閱端點政策。
    4. 若要新增所需的 Amazon S3 動作,請選擇 Edit Policy (編輯政策)。

    檢查 S3 來源和目的地儲存貯體政策

    儲存貯體政策指定允許或拒絕主體的動作。來源和目的地儲存貯體必須允許 EC2 執行個體設定檔角色或映射的 IAM 角色執行所需的 Amazon S3 操作。

    要使用 CLI 來檢查和修改儲存貯體政策:

    執行下列命令以檢閱儲存貯體政策。將 doc-example-bucket 取代為來源或目的地儲存貯體的名稱。

    aws s3api get-bucket-policy --bucket doc-example-bucket

    如有必要,執行下列命令來上傳修改後的儲存貯體政策。取代儲存貯體名稱和 JSON 檔案路徑。

    aws s3api put-bucket-policy --bucket doc-example-bucket --policy file://policy.json

    要使用 Amazon S3 主控台來檢查和修改儲存貯體政策:

    1. 開啟 Amazon S3 主控台
    2. 選擇儲存貯體。
    3. 選擇 Permissions (許可) 標籤。
    4. 選擇 Bucket Policy (儲存貯體政策) 以檢閱和修改儲存貯體政策。

    存取其他帳戶中的 S3 儲存貯體

    重要提示:如果您的應用程式存取屬於其他 AWS 帳戶的 S3 儲存貯體,則帳戶擁有者必須允許您在儲存貯體政策上的 IAM 角色。

    例如,下列儲存貯體政策將為 emr-account 中的所有 IAM 角色和使用者提供 s3://doc-example-bucket/myfolder/ 的完整存取權。

    {
      "Id": "MyCustomPolicy",
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowRootAndHomeListingOfCompanyBucket",
          "Principal": {
            "AWS": [
              "arn:aws:iam::emr-account:root"
            ]
          },
          "Action": [
            "s3:ListBucket"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::doc-example-bucket"
          ],
          "Condition": {
            "StringEquals": {
              "s3:prefix": [
                "",
                "myfolder/"
              ],
              "s3:delimiter": [
                "/"
              ]
            }
          }
        },
        {
          "Sid": "AllowListingOfUserFolder",
          "Principal": {
            "AWS": [
              "arn:aws:iam::emr-account:root"
            ]
          },
          "Action": [
            "s3:ListBucket"
          ],
          "Effect": "Allow",
          "Resource": [
            "arn:aws:s3:::doc-example-bucket"
          ],
          "Condition": {
            "StringLike": {
              "s3:prefix": [
                "myfolder/*"
              ]
            }
          }
        },
        {
          "Sid": "AllowAllS3ActionsInUserFolder",
          "Principal": {
            "AWS": [
              "arn:aws:iam::emr-account:root"
            ]
          },
          "Effect": "Allow",
          "Action": [
            "s3:*"
          ],
          "Resource": [
            "arn:aws:s3:::doc-example-bucket/myfolder/*",
            "arn:aws:s3:::doc-example-bucket/myfolder*"
          ]
        }
      ]
    }