如何判断我是否从脚本登录到私有Docker注册表?

scj*_*ody 35 docker

如何判断我是否从脚本登录到私有Docker注册表服务器?换句话说,已经docker login some.registry.com成功运行?

注意:我问的是一个任意的私人注册表,而不是docker.io注册表.

MrE*_*MrE 21

如果docker登录有效,您将.docker在主目录(~/.docker/)上找到一个文件夹,其中包含一个config.json包含凭据的文件.

否则你会收到登录错误.

注意:docker通过查看注册表名称来确定要使用的凭据:

如果你这样做

docker pull myregistry.com/myimage:tag

如果您已登录,则docker会查看,如果没有,将检查您是否拥有注册表的凭据myregistry.com并使用这些凭据登录.

如果不是,您将收到权限错误

  • 如果使用(例如)ASW ECR,这会变得更加模糊.您登录的凭据每12小时到期一次,所以如果仅仅查看`config.json`它会看起来一切都好,但它不会.唯一的检查方法是尝试一些操作,但是如上所述,错误代码并没有真正告诉你什么出错(可能是auth,可能不是). (4认同)
  • 不幸的是,在这种情况下,“ docker pull”以状态1存在,因此无法将“未登录”与所有其他“ docker pull”故障模式区分开。因此,看来我只能解析config.json或docker pull输出,并希望格式在将来的Docker版本中不会改变。 (2认同)
  • 我试图避免运行已经成功运行的docker login。同样,上面已经建议您链接的问题,并且正如我所解释的,该答案仅适用于docker.io注册表,不适用于其他注册表。 (2认同)

Vla*_*lov 13

这有点hacky,但它适用于我的大多数情况:

if ! grep -q "my.private.registry.com" ~/.docker/config.json ; then
    docker login "my.private.registry.com"
fi
Run Code Online (Sandbox Code Playgroud)

基本上,你搜索是否有"my.private.registry.com"的记录~/.docker/config.json.但是,如果会话过期,则此检查不会捕获它.


BMi*_*tch 11

我相信错误消息会因注册表实现而异。但是,我自己的技术是提取一个不存在的图像并解析任何错误消息:

$!/bin/sh
repo="$1"
msg=$(docker pull ${repo}/missing:missing 2>&1)
case "$msg" in
  *"requested access to the resource is denied"*|*"pull access denied"*)
    echo "Logged out";;
  *"manifest unknown"*|*"not found"*)
    echo "Logged in, or read access for anonymous allowed";;
  *"Pulling from"*)
    echo "Missing image was not so missing after all?";;
  *) 
    echo "Unknown message: $msg";;
esac
Run Code Online (Sandbox Code Playgroud)

这已经通过 docker 独立注册表和 docker_auth 进行了测试。您需要使用可能遇到的注册表进行测试。

如果您的注册服务器允许匿名拉取,并且您想验证推入是否可行,您可以创建一个虚拟的空映像并用该映像的推取替换拉取。例如

#!/bin/sh
repo=$1
# note, I do not like the "." here, better to change it to an empty directory
# see "mktemp" for an option if you cannot make your own empty directory somewhere
docker build -t "${repo}/empty:test" -f - . <<EODF
FROM scratch
EODF
msg=$(docker push "${repo}/empty:test" 2>&1)
rc=$?
if [ "$rc" = "0" ]; then
  echo "Access granted to push"
else
  case "$msg" in
    *"requested access to the resource is denied"*)
      echo "Access denied";;
    *) 
      echo "Unknown error message: $msg";;
  esac
fi
Run Code Online (Sandbox Code Playgroud)


Jam*_*sJJ 6

如果您不得不检查本地系统,那将是不可能的!

...确保泊坞窗存储的凭据仍然有效的唯一方法是执行一项操作,以将其显示在注册表中,并查看注册表是否接受它们。

如果要使用Docker CLI来获取答案,则可以使用@matanper建议“再次登录”,如果您仍然具有有效的凭据,该建议将自动完成。

另一种方法是尽量拉闻名的图像不存在,登录或没有如时会显示不同的错误信息

# NO VALID LOGIN:

$ docker pull 999999999999.dkr.ecr.us-west-2.amazonaws.com/this/image:does_not_exist
Error response from daemon: pull access denied for 999999999999.dkr.ecr.us-west-2.amazonaws.com/this/image, repository does not exist or may require 'docker login'
Run Code Online (Sandbox Code Playgroud)

# WITH VALID LOGIN:

$ docker pull 999999999999.dkr.ecr.us-west-2.amazonaws.com/this/image:does_not_exist
Error response from daemon: manifest for 999999999999.dkr.ecr.us-west-2.amazonaws.com/this/image:does_not_exist not found
Run Code Online (Sandbox Code Playgroud)

(假设您不想,pull因为您不希望有任何延迟或大数据传输程序,因此上述方法仍然可以)

过去,当Docker始终将凭据存储在~/.docker/config.json(或与您的操作系统等效)时,您可以解析该文件以获取当前存储的凭据,然后使用或类似方法运行简单的列表操作curl。但是,最新的docker版本将凭据存储在特定于主机OS的存储中(例如Mac OS X上的钥匙串),因此不再是可移植的方法。如果可移植性不重要,您仍然可以尝试类似的方法-哈希config.json值只是base64编码的用户名和密码,用冒号分隔,这是HTTP基本身份验证的标准,例如在linux上,jq用于解析JSON和base64进行解码base64:

$  cat ~/.docker/config.json  | jq -r '.auths["registry.example.com"].auth' | base64 -d

username:password
Run Code Online (Sandbox Code Playgroud)

因此,使用以下命令完成注册表列表操作curl

REGISTRY="registry.example.com"

CREDENTIALS="$(cat ~/.docker/config.json | jq -r ".auths[\"${REGISTRY}\"].auth" | base64 -d)"

curl -sSf --max-time 3 --user "${CREDENTIALS}" "https://${REGISTRY}/v2/_catalog"
Run Code Online (Sandbox Code Playgroud)

如果CREDENTIALS正确,将返回退出代码零,并返回JSON响应;或非零退出代码(如果没有)

{
  "repositories": [
    "jamesjj/test-image",
    "jamesjj/other-image",
    ...
    ...
}
Run Code Online (Sandbox Code Playgroud)

注意:解析JSON时,注册表地址键可能包含也可能不包含架构https://,具体取决于原始登录的执行方式,因此cat ~/.docker/config.json | jq -r ".auths[\"${REGISTRY}\"].auth" | base64 -d)" ...可能需要: cat ~/.docker/config.json | jq -r ".auths[\"https://${REGISTRY}\"].auth" | base64 -d)"