Kubernetes容器内非root用户如何通过ServiceAccount访问AWS S3
这是EKS IRSA(IAM Roles for Service Accounts)的典型权限问题,和你配置的ServiceAccount绑定的IAM角色、S3访问策略没有关系。root用户能正常执行S3操作,非root用户返回AccessDenied,核心原因是IRSA准入webhook注入到容器内的资源默认仅对root开放:
- 用于换取IAM临时凭证的OIDC身份token,默认挂载路径为
/var/run/secrets/eks.amazonaws.com/serviceaccount/token,默认文件权限为0600,属主是root,其余Linux用户无读权限,拿不到有效token自然无法获取合法访问凭证 - 部分低版本AWS CLI/SDK不会主动读取webhook注入的环境变量,会走默认凭证链检索凭证,非root用户读不到默认路径的配置时,会fallback到无S3权限的身份,最终触发权限报错
以下方案无需调整现有IAM角色、S3策略以及ServiceAccount配置,按实际场景选择即可:
方案1:配置Pod安全上下文(生产环境优先推荐)
无需修改业务镜像,只需要在Pod(或Deployment/StatefulSet的Pod模板)的spec段添加securityContext配置,填入你运行业务的非root用户对应的UID/GID,Kubernetes会自动调整挂载的IRSA token、ServiceAccount密钥的文件权限,让对应GID的用户拥有读权限:
spec: securityContext: runAsUser: 1000 # 替换为你实际使用的非root用户UID runAsGroup: 1000 # 替换为你实际使用的非root用户GID fsGroup: 1000 # 核心配置,所有挂载的Secret/Projected Volume会自动为该GID添加读权限 containers: - name: your-business-container image: your-image:tag
配置更新后重启Pod即可生效。
方案2:构建镜像时提前预置挂载目录权限
如果集群有强制Pod安全策略,不允许自定义fsGroup配置,可以在构建业务镜像时,提前创建IRSA token的挂载目录并设置全局可读权限,后续webhook挂载token文件时会继承父目录权限,所有用户都能读取:
在Dockerfile中添加如下配置即可:
# 提前创建IRSA token挂载目录,分配全局读+执行权限 RUN mkdir -p /var/run/secrets/eks.amazonaws.com/serviceaccount \ && chmod 755 /var/run/secrets/eks.amazonaws.com/serviceaccount
注意不要提前在该目录下创建token文件,否则挂载时会被覆盖,仅需要创建目录并设置权限。
方案3:显式注入AWS凭证环境变量
如果使用的AWS CLI版本低于1.16.232、或AWS SDK版本过旧,存在无法自动识别IRSA注入配置的问题,可以在Pod配置中显式声明IRSA相关环境变量,强制CLI/SDK从指定路径读取token:
containers: - name: your-business-container env: - name: AWS_WEB_IDENTITY_TOKEN_FILE value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token - name: AWS_ROLE_ARN value: arn:aws:iam::替换为你的AWS账号ID:role/替换为ServiceAccount绑定的IAM角色名
注意:该方案仅解决旧版本SDK/CLI的配置识别问题,仍需要配合方案1或方案2保证非root用户对token文件有读权限,单独配置环境变量无法解决文件权限不足的问题。
配置调整并重启Pod后,切到容器内的非root用户,按顺序执行以下操作验证:
- 执行
echo $AWS_WEB_IDENTITY_TOKEN_FILE,确认环境变量正常输出 - 执行
cat $AWS_WEB_IDENTITY_TOKEN_FILE,确认能正常输出长串token内容,无Permission denied报错 - 执行
aws sts get-caller-identity,确认返回的身份ARN是你绑定给ServiceAccount的IAM角色,而非工作节点实例角色 - 执行原
aws s3 cp相关操作,确认权限正常
踩坑提示:如果完成以上配置后非root用户仍报权限错误,先检查容器内的AWS CLI版本,低于1.16.232的版本原生不支持IRSA的WebIdentity凭证方式,升级CLI版本后再排查。
内容的提问来源于stack exchange,提问作者unludo

