如何配置CloudWatch Agent使用IAM角色ARN替代访问密钥?
问题描述
我在Kubernetes中部署了CloudWatch Agent并测试通过,现在想使用IAM角色ARN替代硬编码的AWS访问密钥和秘密密钥。尝试在aws-credentials文件中仅配置role_arn:
[AmazonCloudWatchAgent] role_arn = $ROLE_ARN
但Agent报错提示未找到aws_access_key_id。当前Deployment配置如下:
--- # Deployment apiVersion: apps/v1 kind: Deployment metadata: name: cwagent-prometheus namespace: amazon-cloudwatch spec: replicas: 1 selector: matchLabels: app: cwagent-prometheus template: metadata: labels: app: cwagent-prometheus spec: containers: - name: cloudwatch-agent image: amazon/cloudwatch-agent:1.247348.0b251302 imagePullPolicy: Always env: - name: CI_VERSION value: "k8s/1.3.8" volumeMounts: - name: prometheus-cwagentconfig mountPath: /etc/cwagentconfig - name: prometheus-config mountPath: /etc/prometheusconfig - name: aws-credentials mountPath: /root/.aws volumes: - name: prometheus-cwagentconfig configMap: name: prometheus-cwagentconfig - name: prometheus-config configMap: name: prometheus-config - name: aws-credentials secret: secretName: aws-credentials serviceAccountName: cwagent-prometheus
常规可用的aws-credentials格式为:
[AmazonCloudWatchAgent] aws_access_key_id = $AWS_ID aws_secret_access_key = $AWS_KEY
解决方案
核心说明
CloudWatch Agent在Kubernetes环境中,不支持直接通过aws-credentials文件仅配置role_arn来获取权限。该文件中的role_arn参数用于角色切换场景,需要搭配基础的访问密钥使用(用密钥发起AssumeRole请求),单独配置会因缺少基础凭证报错。
推荐使用**IAM角色绑定ServiceAccount(IRSA)**的方式实现无密钥认证,这是AWS官方推荐的Kubernetes服务权限管理方案。
具体操作步骤
确认集群已配置IRSA
确保你的EKS集群已经启用了OIDC提供商,这是IRSA的前提条件。如果未配置,需要先完成OIDC提供商的创建。创建具备CloudWatch权限的IAM角色
创建一个IAM角色,为其附加CloudWatch Agent所需的权限策略(例如CloudWatchAgentServerPolicy),并设置信任策略允许你的K8s ServiceAccount进行角色假设。信任策略示例:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<AWS_ACCOUNT_ID>:oidc-provider/oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:sub": "system:serviceaccount:amazon-cloudwatch:cwagent-prometheus" } } } ] }关联IAM角色到ServiceAccount
使用AWS CLI或eksctl将创建的IAM角色ARN关联到Deployment中指定的ServiceAccount:eksctl create iamserviceaccount \ --cluster <CLUSTER_NAME> \ --namespace amazon-cloudwatch \ --name cwagent-prometheus \ --attach-policy-arn <IAM_ROLE_POLICY_ARN> \ --approve \ --override-existing-serviceaccounts或者通过AWS CLI更新ServiceAccount的注释:
kubectl annotate serviceaccount cwagent-prometheus \ -n amazon-cloudwatch \ eks.amazonaws.com/role-arn=<IAM_ROLE_ARN>修改Deployment配置
移除Deployment中与aws-credentials相关的卷和挂载配置,因为IRSA会自动将临时凭证注入到Pod中,无需手动挂载凭证文件。修改后的Deployment片段:spec: containers: - name: cloudwatch-agent image: amazon/cloudwatch-agent:1.247348.0b251302 imagePullPolicy: Always env: - name: CI_VERSION value: "k8s/1.3.8" volumeMounts: - name: prometheus-cwagentconfig mountPath: /etc/cwagentconfig - name: prometheus-config mountPath: /etc/prometheusconfig volumes: - name: prometheus-cwagentconfig configMap: name: prometheus-cwagentconfig - name: prometheus-config configMap: name: prometheus-config serviceAccountName: cwagent-prometheus验证部署
重新部署CloudWatch Agent后,Pod会自动通过IRSA获取临时凭证,无需配置访问密钥即可向CloudWatch发送数据。
内容的提问来源于stack exchange,提问作者Billy Billy

