

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 设置服务账户的 IAM 角色
<a name="set-up-irsa"></a>

通过服务账户的 IAM 角色，您可以将 IAM 角色与 Kubernetes 服务账户关联。然后，该服务帐号可以为使用该服务帐号的任何 Pod 中的容器提供 AWS 权限。有关更多信息，请参阅[服务账户的 IAM 角色](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)。

服务账户的 IAM 角色也称为*服务角色*。

在 Amazon Managed Service for Prometheus 中，使用服务角色有助于您获取在 Amazon Managed Service for Prometheus、Prometheus 服务器和 Grafana 服务器之间进行授权和身份验证所需的角色。

**先决条件**

本页上的步骤要求您安装 AWS CLI 和 EKSCTL 命令行界面。

## 设置服务角色从 Amazon EKS 集群中摄取指标
<a name="set-up-irsa-ingest"></a>

要设置服务角色以使 Amazon Managed Service for Prometheus 能够从 Amazon EKS 集群中的 Prometheus 服务器摄取指标，您必须登录到具有以下权限的账户：
+ `iam:CreateRole`
+ `iam:CreatePolicy`
+ `iam:GetRole`
+ `iam:AttachRolePolicy`
+ `iam:GetOpenIDConnectProvider`

**设置服务角色以摄取到 Amazon Managed Service for Prometheus**

1. 使用以下内容创建名为 `createIRSA-AMPIngest.sh` 的文件。将 `<my_amazon_eks_clustername>` 替换为您集群的名称，并将 `<my_prometheus_namespace>` 替换为您的 Prometheus 命名空间。

   ```
   #!/bin/bash -e
   CLUSTER_NAME=<my_amazon_eks_clustername>
   SERVICE_ACCOUNT_NAMESPACE=<my_prometheus_namespace>
   AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
   OIDC_PROVIDER=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
   SERVICE_ACCOUNT_AMP_INGEST_NAME=amp-iamproxy-ingest-service-account
   SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE=amp-iamproxy-ingest-role
   SERVICE_ACCOUNT_IAM_AMP_INGEST_POLICY=AMPIngestPolicy
   #
   # Set up a trust policy designed for a specific combination of K8s service account and namespace to sign in from a Kubernetes cluster which hosts the OIDC Idp.
   #
   cat <<EOF > TrustPolicy.json
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
         },
         "Action": "sts:AssumeRoleWithWebIdentity",
         "Condition": {
           "StringEquals": {
             "${OIDC_PROVIDER}:sub": "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_AMP_INGEST_NAME}"
           }
         }
       }
     ]
   }
   EOF
   #
   # Set up the permission policy that grants ingest (remote write) permissions for all AMP workspaces
   #
   cat <<EOF > PermissionPolicyIngest.json
   {
     "Version": "2012-10-17",		 	 	 
      "Statement": [
          {"Effect": "Allow",
           "Action": [
              "aps:RemoteWrite", 
              "aps:GetSeries", 
              "aps:GetLabels",
              "aps:GetMetricMetadata"
           ], 
           "Resource": "*"
         }
      ]
   }
   EOF
   
   function getRoleArn() {
     OUTPUT=$(aws iam get-role --role-name $1 --query 'Role.Arn' --output text 2>&1)
   
     # Check for an expected exception
     if [[ $? -eq 0 ]]; then
       echo $OUTPUT
     elif [[ -n $(grep "NoSuchEntity" <<< $OUTPUT) ]]; then
       echo ""
     else
       >&2 echo $OUTPUT
       return 1
     fi
   }
   
   #
   # Create the IAM Role for ingest with the above trust policy
   #
   SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN=$(getRoleArn $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE)
   if [ "$SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN" = "" ]; 
   then
     #
     # Create the IAM role for service account
     #
     SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN=$(aws iam create-role \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE \
     --assume-role-policy-document file://TrustPolicy.json \
     --query "Role.Arn" --output text)
     #
     # Create an IAM permission policy
     #
     SERVICE_ACCOUNT_IAM_AMP_INGEST_ARN=$(aws iam create-policy --policy-name $SERVICE_ACCOUNT_IAM_AMP_INGEST_POLICY \
     --policy-document file://PermissionPolicyIngest.json \
     --query 'Policy.Arn' --output text)
     #
     # Attach the required IAM policies to the IAM role created above
     #
     aws iam attach-role-policy \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE \
     --policy-arn $SERVICE_ACCOUNT_IAM_AMP_INGEST_ARN  
   else
       echo "$SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN IAM role for ingest already exists"
   fi
   echo $SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN
   #
   # EKS cluster hosts an OIDC provider with a public discovery endpoint.
   # Associate this IdP with AWS IAM so that the latter can validate and accept the OIDC tokens issued by Kubernetes to service accounts.
   # Doing this with eksctl is the easier and best approach.
   #
   eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
   ```

1. 要赋予脚本必要的权限，请输入以下命令。

   ```
   chmod +x createIRSA-AMPIngest.sh
   ```

1. 运行 脚本。

## 设置服务账户的 IAM 角色以查询指标
<a name="set-up-irsa-query"></a>

要为服务账户设置 IAM 角色（服务角色）以便从 Amazon Managed Service for Prometheus 工作区查询指标，您必须登录到具有以下权限的账户：
+ `iam:CreateRole`
+ `iam:CreatePolicy`
+ `iam:GetRole`
+ `iam:AttachRolePolicy`
+ `iam:GetOpenIDConnectProvider`

**设置服务角色以查询 Amazon Managed Service for Prometheus 指标：**

1. 使用以下内容创建名为 `createIRSA-AMPQuery.sh` 的文件。将 `<my_amazon_eks_clustername>` 替换为集群的名称，并将 <my\$1prometheus\$1namespace> 替换为您的 Prometheus 命名空间。

   ```
   #!/bin/bash -e
   CLUSTER_NAME=<my_amazon_eks_clustername>
   SERVICE_ACCOUNT_NAMESPACE=<my_prometheus_namespace>
   AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
   OIDC_PROVIDER=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
   SERVICE_ACCOUNT_AMP_QUERY_NAME=amp-iamproxy-query-service-account
   SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE=amp-iamproxy-query-role
   SERVICE_ACCOUNT_IAM_AMP_QUERY_POLICY=AMPQueryPolicy
   #
   # Setup a trust policy designed for a specific combination of K8s service account and namespace to sign in from a Kubernetes cluster which hosts the OIDC Idp.
   #
   cat <<EOF > TrustPolicy.json
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
         },
         "Action": "sts:AssumeRoleWithWebIdentity",
         "Condition": {
           "StringEquals": {
             "${OIDC_PROVIDER}:sub": "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_AMP_QUERY_NAME}"
           }
         }
       }
     ]
   }
   EOF
   #
   # Set up the permission policy that grants query permissions for all AMP workspaces
   #
   cat <<EOF > PermissionPolicyQuery.json
   {
     "Version": "2012-10-17",		 	 	 
      "Statement": [
          {"Effect": "Allow",
           "Action": [
              "aps:QueryMetrics",
              "aps:GetSeries", 
              "aps:GetLabels",
              "aps:GetMetricMetadata"
           ], 
           "Resource": "*"
         }
      ]
   }
   EOF
   
   function getRoleArn() {
     OUTPUT=$(aws iam get-role --role-name $1 --query 'Role.Arn' --output text 2>&1)
   
     # Check for an expected exception
     if [[ $? -eq 0 ]]; then
       echo $OUTPUT
     elif [[ -n $(grep "NoSuchEntity" <<< $OUTPUT) ]]; then
       echo ""
     else
       >&2 echo $OUTPUT
       return 1
     fi
   }
   
   #
   # Create the IAM Role for query with the above trust policy
   #
   SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN=$(getRoleArn $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE)
   if [ "$SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN" = "" ]; 
   then
     #
     # Create the IAM role for service account
     #
     SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN=$(aws iam create-role \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE \
     --assume-role-policy-document file://TrustPolicy.json \
     --query "Role.Arn" --output text)
     #
     # Create an IAM permission policy
     #
     SERVICE_ACCOUNT_IAM_AMP_QUERY_ARN=$(aws iam create-policy --policy-name $SERVICE_ACCOUNT_IAM_AMP_QUERY_POLICY \
     --policy-document file://PermissionPolicyQuery.json \
     --query 'Policy.Arn' --output text)
     #
     # Attach the required IAM policies to the IAM role create above
     #
     aws iam attach-role-policy \
     --role-name $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE \
     --policy-arn $SERVICE_ACCOUNT_IAM_AMP_QUERY_ARN  
   else
       echo "$SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN IAM role for query already exists"
   fi
   echo $SERVICE_ACCOUNT_IAM_AMP_QUERY_ROLE_ARN
   #
   # EKS cluster hosts an OIDC provider with a public discovery endpoint.
   # Associate this IdP with AWS IAM so that the latter can validate and accept the OIDC tokens issued by Kubernetes to service accounts.
   # Doing this with eksctl is the easier and best approach.
   #
   eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve
   ```

1. 要赋予脚本必要的权限，请输入以下命令。

   ```
   chmod +x createIRSA-AMPQuery.sh
   ```

1. 运行 脚本。