Docker Windows 推送到 AWS ECR 失败:没有基本身份验证凭据

Docker push to AWS ECR fails on Windows: no basic auth credentials

我在 windows 上使用 docker(Docker 用于 Windows,而不是 Docker 工具箱)和 cygwin 中的 aws cli("git bash") shell。我正在尝试将 docker 图像推送到 AWS ECR - 私有 ECS 存储库。

无论我做什么 - 当我 运行宁 docker push 我反复得到:

no basic auth credentials

方法一

我一直在遵循说明并运行使用标准命令:

$ $(aws --profile myprofile ecr get-login --region us-east-1)
Login Succeeded
$ docker tag myrepo:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo:latest
$ docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo:latest
The push refers to a repository [232097583865.dkr.ecr.us-east-1.amazonaws.com/potion]
688f61a6956d: Preparing
11908ead416e: Preparing
no basic auth credentials

没有成功。

尝试拉取显示我确实没有访问权限:

$ docker pull 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo
Using default tag: latest
Pulling repository 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo
unauthorized: authentication required

但是 docker 是否认为我已登录:

$ docker logout https://123456789.dkr.ecr.us-east-1.amazonaws.com
Remove login credentials for https://123456789.dkr.ecr.us-east-1.amazonaws.com

# let's run again - should not be logged in now
$ docker logout https://123456789.dkr.ecr.us-east-1.amazonaws.com
Not logged in to https://123456789.dkr.ecr.us-east-1.amazonaws.com

嗯。

方法二

Internet 建议分解命令并使用较旧的过程登录。

基本上可以归结为这样的事情:

docker login -u AWS -p $(aws --profile myprofile ecr get-authorization-token --region us-east-1 --output text --query authorizationData[].authorizationToken | python -c 'import base64, sys; print base64.b64decode(sys.stdin.read())' | cut -d: -f2) https://123456789.dkr.ecr.us-east-1.amazonaws.com

这似乎也成功了,但是 docker pushpull 导致了同样的失败。

其他死胡同

Windows 而且 cygwin 很奇怪。因此,让我们将 docker login 命令放在 shell 脚本文件中,然后将其 运行 或 source 它。没有成功。

正在使用显式访问令牌和新的凭证集生成额外的 AMI 配置文件。没有成功。

将 AWS 凭证导出为环境变量并重复该过程。没有成功。

使用很棒的 aws-temp-token.sh 脚本获取 MFA 代码并生成会话凭据作为环境变量。没有成功(虽然这个工具在其他时候是救命稻草,所以使用它)。

剧透警告

我最终设法解决了这个问题。虽然很令人沮丧,但我发现网上没有提到解决方案,所以写一个答案应该可以减轻一些精神上的痛苦。

我的一个搜索让我 , which while irrelevant to my case, brought to my attention the place where authentication credentials are stored: the docker config.json file. Take a look here 阅读更多关于它和它的授权用法。

但是,在使用上述任何一种方法登录后,我自己的文件中有这些内容:

{
    "auths": {
        "https://123456789.dkr.ecr.us-east-1.amazonaws.com": {}
    },
    "credsStore": "wincred"
}

Windows (wincred) 的明确提及引起了我的注意。阅读更多内容,Windows 上的 docker 使用 helper credential store 可能比将凭据作为纯文本存储在文件系统上更好(它通常存储为 base64,这是希腊语 "plain text").

但是 - 当我手动编辑此文件以直接包含身份验证令牌时,解决方案就出现了。

我使用此命令生成了我的身份验证令牌(为简洁起见缩短了输出):

$ aws --profile myprofile ecr get-authorization-token --region us-east-1 --output text --query authorizationData[].authorizationToken
jFHNnVxZ............Vqc==

编辑 ~/.docker/config.json 后,它看起来像这样:

{
    "auths": {
        "https://123456789.dkr.ecr.us-east-1.amazonaws.com": {
            "auth": "jFHNnVxZ............Vqc=="
        }
    }
}

有了这个,推送终于成功了:

$ docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo:latest
The push refers to a repository [123456789.dkr.ecr.us-east-1.amazonaws.com/myrepo]
61a69688f56d: Pushed
11ad4908e16e: Pushed
myrepo: digest: sha256:20c0f3......82aa19 size: 42162

一切都又好了。

扩展你自己的精彩答案,让我出狱。我发现如果你删除:

,
"credsStore": "wincred"

保存文件,运行 再次使用 docker 登录命令,它会将凭据直接放入 config.json,我发现它可以工作。

留下一点点像

{
    "auths": {
        "https://407163548648.dkr.ecr.eu-west-1.amazonaws.com": {
            "auth": "QV...Nbz0=",
            "email": "AWS"
        }
    }
}

除了上述内容之外,这可能值得 Docker 提出一个关于 AWS 兼容性的问题和一个关于 AWS 文档的问题。在这种情况下,Docker 通过使用 Windows 凭证存储做正确的事情,但是 AWS 正试图使用​​证书身份验证超载基本身份验证。

具体来说,运行 docker login 实际上 确实 将条目添加到您的 Windows 凭据存储中。您可以通过打开凭据管理器看到这一点,select "Windows Credentials" 并且您会看到 <a href="https://12345678.dkr.ecs.region.amazonaws.com" rel="nofollow noreferrer">https://12345678.dkr.ecs.region.amazonaws.com</a> URL 的新条目已进入。

问题是 AWS 使用 public 密钥作为密码,Windows 不会让您输入那么长的密码。 您可以通过从 AWS 复制密码、编辑存储的凭据并尝试将值粘贴进去来尝试此操作。Windows 不会让你这样做。

试试这个:

eval $(aws ecr get-login --no-include-email | sed 's|https://||')

第一步: 获取您的授权令牌:

aws --profile default ecr get-authorization-token --region us-east-1 --output text --query authorizationData[].authorizationToken

(注意:如果您有个人资料,则将默认设置更改为您的个人资料名称)

第 2 步:编辑您的 ~/.docker/config.json

{
"auths": {
    "https://45456644454545.dkr.ecr.us-east-1.amazonaws.com": {
        "auth": "TRdfdhwe53hsdshhSdSHdsdssdsd...GGSDe="
    }
  }

}

第 3 步:现在您可以推送 docker 图片。