You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS ECR镜像拉取凭证过期及CronJob刷新故障求助

解决AWS ECR凭证过期及CronJob中'aws: not found'问题

问题原因分析

  1. AWS ECR凭证过期: 通过docker login生成的ECR凭证有效期为12小时,24小时后必然失效,导致镜像拉取时返回403 Forbidden错误。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:53:10