AWS ECR镜像拉取凭证过期及CronJob刷新故障求助
解决AWS ECR凭证过期及CronJob中'aws: not found'问题
问题原因分析
- AWS ECR凭证过期: 通过
docker login生成的ECR凭证有效期为12小时,24小时后必然失效,导致镜像拉取时返回403 Forbidden错误。 - CronJob报错'aws: not found': 你使用的
bitnami/kubectl镜像未预装AWS CLI,因此无法执行aws ecr get-login-password命令。此外,即使安装了AWS CLI,容器也缺少调用ECR API的权限。
解决方案步骤
1. 修正CronJob镜像与命令
使用同时包含kubectl和AWS CLI的镜像,避免每次运行时临时安装工具。推荐使用lwolf/kubectl-awscli镜像,它已预装两者。
更新后的CronJob YAML(/opt/aws.yml):
apiVersion: batch/v1 kind: CronJob metadata: name: refresh-aws-secret namespace: default spec: schedule: "0 */6 * * *" # 每6小时执行一次(短于凭证有效期,确保不会过期) jobTemplate: spec: template: spec: restartPolicy: OnFailure serviceAccountName: secrets-manager containers: - name: refresh-aws-secret image: lwolf/kubectl-awscli:latest imagePullPolicy: IfNotPresent env: - name: SECRET_NAME value: regcred - name: AWS_REGION value: us-east-1 command: - /bin/sh - -c - |- kubectl delete secret --ignore-not-found ${SECRET_NAME} kubectl create secret docker-registry ${SECRET_NAME} \ --docker-server=123456789.dkr.ecr.us-east-1.amazonaws.com \ --docker-username=AWS \ --docker-password=$(aws ecr get-login-password)
2. 配置IAM角色绑定(IRSA)
为CronJob使用的ServiceAccount赋予调用ECR API的权限,通过IAM Roles for Service Accounts(IRSA)实现:
步骤2.1 创建IAM策略
创建允许获取ECR登录凭证的策略文件ecr-login-policy.json:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ecr:GetLoginPassword", "Resource": "*" } ] }
执行命令创建策略:
aws iam create-policy --policy-name ECRLoginPasswordPolicy --policy-document file://ecr-login-policy.json
步骤2.2 创建IAM角色并关联ServiceAccount
替换<cluster-name>和<account-id>为你的实际值:
# 获取集群OIDC提供者URL OIDC_PROVIDER=$(aws eks describe-cluster --name <cluster-name> --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///") # 创建IAM角色 aws iam create-role --role-name secrets-manager-role --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<account-id>:oidc-provider/'$OIDC_PROVIDER'" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "'$OIDC_PROVIDER':sub": "system:serviceaccount:default:secrets-manager" } } } ] }' # 为角色附加策略 aws iam attach-role-policy --role-name secrets-manager-role --policy-arn arn:aws:iam::<account-id>:policy/ECRLoginPasswordPolicy
步骤2.3 为ServiceAccount添加IAM角色注解
kubectl annotate serviceaccount secrets-manager -n default eks.amazonaws.com/role-arn=arn:aws:iam::<account-id>:role/secrets-manager-role
3. 重新部署并测试CronJob
kubectl apply -f /opt/aws.yml # 手动触发一次测试 kubectl create job --from=cronjob/refresh-aws-secret manual-test -n default # 查看日志验证是否成功 kubectl logs manual-test-<pod-suffix>
替代方案:使用节点级ECR凭证助手
如果你不想使用CronJob,可以在每个Kubernetes节点上安装AWS ECR凭证助手,自动处理凭证刷新。但这种方法需要在所有节点上配置,不如CronJob的集群级方案简洁。
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

