Подтвердить что ты не робот

Как я могу узнать, был ли я зарегистрирован в приватном реестре Docker из script?

Как я могу узнать, авторизован ли я на частном сервере реестра Docker из скрипта? Другими словами, успешно docker login some.registry.com был выполнен docker login some.registry.com (и все еще действителен)?

Примечание: я спрашиваю о произвольном частном реестре, а не о реестре docker.io.

4b9b3361

Ответ 1

Если вход в docker работал, вы найдете папку .docker в своем домашнем каталоге (~/.docker/) с файлом config.json с учетными данными в нем.

в противном случае вы получите ошибку входа в систему.

Примечание. Докеры определяют, какие учетные данные следует использовать, просмотрев имя реестра:

если вы делаете

docker pull myregistry.com/myimage:tag

docker будет выглядеть, если вы вошли в систему, а если не проверите, есть ли у вас учетные данные для реестра myregistry.com и войдите в систему с ними.

Если вы не получите ошибку разрешения

Ответ 2

Это немного взломанный, но он работает в большинстве случаев для меня:

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". Однако, если сессия истекла, эта проверка не будет ее улавливать.

Ответ 3

Это немного глупо, я думаю, что до тех пор, пока у докера не появится команда для проверки входа в систему, хорошего решения не будет.
В вашем bash-скрипте вы можете попытаться войти в систему с тайм-аутом x секунд, если вы не вошли в систему, команда попытается запросить имя пользователя, а затем произойдет тайм-аут со статусом 124. Если вы действительно вошли в систему, он просто снова войдет в систему с использованием учетных данных сохранения и продолжит работу со статусом 0

#!/bin/bash
timeout -s SIGKILL 3s docker login some.registry.com >/dev/null 2>&1
if [ $? -eq 0 ]
then
   echo Logged In!
else
   echo Not logged in...
fi

Ответ 4

Если вы ограничены в изучении вашей локальной системы, это невозможно узнать!

... Единственный способ убедиться, что хранитель учетных данных все еще действителен, - это выполнить операцию, которая приведет к их представлению в реестр, и проверить, принимает ли их реестр.

Если вы хотите использовать интерфейс командной строки Docker, чтобы получить ответ, то вы можете использовать @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

(предположим, что вы не хотите pull потому что вам не нужна задержка или передача больших данных, поэтому приведенный выше метод все еще в порядке)

В прошлом, когда Docker всегда сохранял учетные данные в ~/.docker/config.json (или эквивалент для вашей ОС), вы могли анализировать этот файл, чтобы получить сохраненные в данный момент учетные данные, а затем запустить простую операцию со списком, используя curl или подобный. Однако в последних версиях докера учетные данные хранятся в специальных хранилищах хост-ОС (например, в цепочке для ключей в 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

Итак, завершив это с помощью операции списка реестра с помощью 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[\"${REGISTRY}\"].auth" | base64 -d)" cat ~/.docker/config.json | jq -r ".auths[\"${REGISTRY}\"].auth" | base64 -d)"... может потребоваться: cat ~/.docker/config.json | jq -r ".auths[\"https://${REGISTRY}\"].auth" | base64 -d)"

Ответ 5

Когда вы выполните

Docker login <private registry> -u <user> -p <password> 

с вашего терминала, вы получите ответ: (хранится в $?)

0
Login Succeeded

если вы были успешны.

В вашей оболочке script вы можете просто посмотреть ответ, который вы получаете, если он не равен 0, вам не удалось войти в систему.

sudo docker login <registry> -u <uname> -p <password>
if [ $? -ne 0 ]; then
    echo Login failed!
else
    echo Login OK!
fi

Ответ 6

Вы можете проанализировать .docker/config.json и попробовать вручную подключиться к каждому реестру, указанному в файле. Файл содержит адрес реестра и закодированные имя пользователя и пароль, чтобы вы могли написать сценарий этого процесса. Вы можете сделать это, используя такую библиотеку, как docker-registry-client.

pip install docker-registry-client

А потом:

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()

Несколько предостережений:

  • Это может не сработать, если вы используете хранилище учетных данных.
  • Проверено на Python 2.7. Может потребоваться небольшие корректировки для Python 3.
  • Этот код работает для проверки подлинности, но дальнейшие действия в реестре не выполняются. Для этого вам потребуется удалить версию API (/v1, /v2 и т.д.) Из имени хоста.
  • Код предполагает, что все реестры являются HTTPS (если не указано иное в config.json)
  • Еще более правильная версия, вероятно, удалит все, кроме имени хоста, и попробует v1 и v2.

Тем не менее, я смог получить список зарегистрированных реестров, и он правильно проигнорировал истекший логин ECR.

Ответ 7

Я считаю, что сообщение об ошибке будет зависеть от реализации реестра. Тем не менее, моя собственная техника - извлечь изображение, которое не существует, и проанализировать любое сообщение об ошибке:

$!/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 и 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