我如何判断我是否';m从脚本登录到私有Docker注册表?
如何判断我是否从脚本登录到私有Docker注册表服务器?换句话说,我如何判断我是否';m从脚本登录到私有Docker注册表?,docker,Docker,如何判断我是否从脚本登录到私有Docker注册表服务器?换句话说,docker login some.registry.com是否已成功运行(并且仍然有效) 注意:我询问的是一个任意的私有注册表,而不是docker.io注册表。如果docker登录成功,您将在主目录(~/.docker/)上找到一个.docker文件夹,其中包含一个带有凭据的config.json文件 否则,您将在登录时出错 注意:docker通过查看注册表名来确定要使用的凭据: 如果你这样做 docker pull myreg
docker login some.registry.com
是否已成功运行(并且仍然有效)
注意:我询问的是一个任意的私有注册表,而不是
docker.io
注册表。如果docker登录成功,您将在主目录(~/.docker/
)上找到一个.docker
文件夹,其中包含一个带有凭据的config.json
文件
否则,您将在登录时出错
注意:docker通过查看注册表名来确定要使用的凭据:
如果你这样做
docker pull myregistry.com/myimage:tag
docker将查看您是否已登录,如果未登录,docker将检查您是否具有注册表myregistry.com
的凭据,并使用这些凭据登录
如果没有,您将得到一个权限错误,这有点不正常,但它在大多数情况下对我有效:
if ! grep -q "my.private.registry.com" ~/.docker/config.json ; then
docker login "my.private.registry.com"
fi
基本上,您可以搜索~/.docker/config.json
中是否有“my.private.registry.com”的记录。但是,如果会话已过期,此检查将无法捕获它。当您执行
Docker login <private registry> -u <user> -p <password>
如果你成功了
在shell脚本中,您可以只查看收到的响应,如果它不等于0,则表示您登录失败
sudo docker login <registry> -u <uname> -p <password>
if [ $? -ne 0 ]; then
echo Login failed!
else
echo Login OK!
fi
sudo docker登录-u-p
如果[$?-ne 0];然后
echo登录失败!
其他的
回音登录好!
fi
这有点不对劲,我认为在docker获得检查登录的命令之前,不会有任何好的解决方案。您可以在bash脚本中尝试以x秒的超时时间登录,如果您未登录,该命令将尝试提示输入用户名,然后将以状态
124
超时。如果您确实已登录,它将使用保存凭据再次登录,并继续执行状态0
#/bin/bash
超时-s SIGKILL 3s docker登录some.registry.com>/dev/null 2>&1
如果[$?-等式0]
然后
echo已登录!
其他的
echo未登录。。。
fi
如果您必须检查本地系统,则不可能知道
。。。确保docker存储的凭据仍然有效的唯一方法是执行一个操作,该操作将使这些凭据呈现给注册表,并查看注册表是否接受它们
如果您想使用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'
对
# 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
(假设您不想拉入
,因为您不想有任何延迟或大数据传输,所以上述方法仍然是“ok”)
过去,当docker总是将凭证存储在~/.docker/config.json
(或您的操作系统的等效文件)中时,您可以解析该文件以获取当前存储的凭证,然后使用curl
或类似工具运行凭证。然而,最近的docker版本将凭证存储在主机操作系统特定的存储中(例如Mac OS X上的钥匙链),因此这不再是一种可移植的方法。如果可移植性不重要,您仍然可以尝试类似的方法-在config.json
中的散列只是base64编码的用户名和密码,用冒号分隔,这是HTTP basic auth的标准,例如在linux上,用jq
解析json,用base64
解码base64:
$ cat ~/.docker/config.json | jq -r '.auths["registry.example.com"].auth' | base64 -d
username:password
因此,使用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"
将返回退出代码零,如果凭据良好,则返回JSON响应;或非零退出代码(如果不是)
{
"repositories": [
"jamesjj/test-image",
"jamesjj/other-image",
...
...
}
注意:解析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)”
您可以解析.docker/config.json
并尝试手动连接到文件中指定的每个注册表。该文件包含注册表地址和编码的用户名和密码,因此您可以编写此过程的脚本。您可以使用类似的库来实现这一点
然后:
import base64
import docker_registry_client
import json
import os.path
def get_authed_registries():
result = []
config_path = os.path.expanduser("~/.docker/config.json")
if not os.path.isfile(config_path):
print("No docker config")
return []
docker_config = json.load(open(config_path))
for registry, auth in docker_config.get("auths", {}).items():
username, password = base64.b64decode(auth["auth"]).decode("utf-8").split(":", 1)
if not registry:
registry = "https://index.docker.io/v1/"
if not registry.startswith("http"):
registry = "https://" + registry
try:
rc = docker_registry_client.DockerRegistryClient(registry, username=username, password=password)
result.append(registry)
except Exception, e:
print(registry, "failed:", e)
return result
get_authed_registries()
有几点需要注意:
- 如果您使用的是一个
- 在Python2.7上测试。可能需要对Python3进行一些小的调整
- 此代码用于身份验证,但对注册表的任何进一步操作都会失败。您需要从主机名中删除API版本(
,/v1
,等等)/v2
- 代码假定所有注册表都是HTTPS(除非在
中另有规定)config.json
- 更正确的版本可能会删除除主机名以外的任何内容,并尝试v1和v2
这就是说,我能够获得登录注册表的列表,它正确地忽略了过期的ECR登录。我相信错误消息会因注册表实现而异。但是,我自己的技术是提取一个不存在的图像并解析任何错误消息:
$!/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
这已经通过docker standalone注册表和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
#/垃圾箱/垃圾箱
回购=1美元
#注意,我不喜欢这里的“.”,最好把它改成一个空目录
#如果您不能在某个地方创建自己的空目录,请参阅“mktemp”以获取选项
docker构建-t“${repo}/empty:test”-f-。可能重复的“否”,仅适用于docker.io注册表。您是绝对的
$!/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
#!/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