Docker Python库无法正确登录AWS ECR

3
我编写了一个Python脚本,用于从AWS ECR拉取图像到Ubuntu实例。在该实例上,我使用sudo运行Docker命令,因为Docker未设置为非root用户。
在调用脚本时,我确实使用sudo。我发现,如果我当前已经登录到AWS ECR,然后运行脚本,它按预期工作。但是,如果我没有登录,并且认证令牌已过期,则似乎docker login可以正常工作,但是当我尝试拉取时,会出现一个指示“存储库不存在或者需要‘docker login’”的消息。
检查日志,它用如下方式验证了这一点

Feb 15 06:00:38 ubuntu-xenial dockerd[1388]: time="2019-02-15T06:00:38.832827449Z" level=error msg="Not continuing with pull after error: denied: Your Authorization Token has expired. Please run 'aws ecr get-login --no-include-email' to fetch a new one."

def log_into_aws_ecr(docker_client, region):
    # To do, set region
    ecr_client = boto3.client('ecr', region_name=region)

    # Get all repos
    response = ecr_client.describe_repositories()
    repo_names = []
    repositories = response.get('repositories', [])
    for repo in repositories:
        name = repo.get('repositoryName', '')
        if len(name):
            repo_names.append(name)
    token = ecr_client.get_authorization_token()
    username, password = base64.b64decode(token['authorizationData'][0]['authorizationToken']).decode('utf-8').split(":")
    registry_url = token['authorizationData'][0]['proxyEndpoint']
    login_results = docker_client.login(username, password, email='', registry=registry_url)

    prefix='https://'
    if registry_url.startswith(prefix):
        registry = registry_url[len(prefix):]
    else:
        registry = registry_url
    auth_config_payload = {'username': username, 'password': password }
    return ecr_client, repo_names, registry

请注意,此代码正在进行重构,因此有一些变量被定义但目前未使用。
提供的 docker_client 是通过以下行获得的。
    docker_client = docker.from_env()

我尝试以以下方式运行:

sudo -E ./myscript.py image

但是这种方法也不起作用。我使用bash脚本的变体,那个可以正常工作。

docker_client.login 的输出如下所示:

正在查找“ABCXYZ.dkr.ecr.us-west-2.amazonaws.com”的授权条目 找到了“ABCXYZ.dkr.ecr.us-west-2.amazonaws.com”

如果我转储响应,它看起来像这样。

{'password': 'PASSWORD HERE', 'email': None, 'username': 'AWS', 'serveraddress': 'ABCXYZ.dkr.ecr.us-west-2.amazonaws.com'}

2个回答

5

好的,我不确定这是否完全正确,但是基于最近几天的一些实验,它确实有效。我还在docker-py GitHub仓库中开了一个问题,但至少现在为止,没有人参与。

https://github.com/docker/docker-py/issues/2256

简而言之,如链接中所列举的:

我进行了一些实验,过去几天一直在处理 AWS ECR 12小时的票据,所以花了一点时间。

看起来 docker-py 存在问题。

根据我的研究,我可以使用 boto3 或运行一个子进程来调用命令行 aws ecr。然而,下列步骤似乎是唯一有效的:

  1. 使用子进程执行 docker login 。这将导致更新 config.json 文件(不确定这是否有任何相关性)。
  2. 通过 docker.from_env() 创建 docker 客户端。我发现在子进程之前这样做会导致其无法正常工作(除非您已经拥有有效的config.json
  3. 然后调用 docker_client.login(username=username, password=password, registry=registry_url)

无论这是否符合预期或者我做错了什么,我都不知道。但这是我得出的有效步骤。


0

谢谢您的回复。当我调用命令行时,确实包括 --no-include-email 标志以获取 get-login。但是,我找不到 boto3 的等效标志。顺便说一下,如果您查看代码,我会对响应进行 base64 解码。您所说的复制这两行,是指复制到 aws cli 包中吗? - Mobile Ben
你能附上 aws ecr get-loginget_authorization_token 的输出吗? - deosha
我认为比较这两个输出并不重要。我的代码进行了修改,以便我可以通过运行aws ecr get-login作为子进程或调用get_authorization_token来获取授权令牌。我也可以通过子进程或调用docker python的login来进入docker。到目前为止,我已经发现问题似乎不是AWS而是docker-py。现在看来,任何获取授权令牌的组合都有效。但总体成功与否取决于是否使用子进程。 - Mobile Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接