Назад | Перейти на главную страницу

Как подключиться к AWS ECR с помощью python docker-py

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

dockerCommand=$("aws ecr get-login --profile profileName --region us-west-2")
$dockerCommand  (which looks like docker login -u AWS -p ..longPassword.. -e none https://ACCTID.dkr.ecr.us-west-2.amazonaws.com
docker pull ACCTID.dkr.ecr.us-west-2.amazonaws.com/REPO/NAME:TAGNAME

Если мне нужен другой реестр, я меняю регион или имя профиля

Пробуя это с помощью docker-py, у меня есть

import boto3
import docker
dockerClient = docker.from_env()

session = boto3.setup_default_session(profile_name='vzw')
client = session.client('ecr', region_name='us-west-2')

token = client.get_authorization_token(registryIds=[registryId])

username = 'AWS'
password = token['authorizationData'][0]['authorizationToken']
registry = token['authorizationData'][0]['proxyEndpoint']
regClient = dockerClient.login(username, password, registry)

но dockerClient отказывается от связи с:

неверное имя пользователя или пароль

Оттуда, когда это сработает, я захочу использовать вытягивание / нажатие докер-клиента для перемещения изображений между реестрами.

Это правильное направление, или мне следует попытаться реализовать это полностью с помощью сценариев оболочки? (Python был особенно ценен для вызовов boto для описания того, что находится в каждом реестре)

Полный пример кода, который работает:

#!/usr/bin/env python3
import base64, docker, boto3

docker_client = docker.from_env(version='1.24')
ecr_client = boto3.client('ecr', region_name='eu-west-1')

token = ecr_client.get_authorization_token()
username, password = base64.b64decode(token['authorizationData'][0]['authorizationToken']).decode().split(':')
registry = token['authorizationData'][0]['proxyEndpoint']

docker_client.login(username, password, registry=registry)

И, конечно же, сначала необходимо настроить учетные данные AWS, например:

export AWS_ACCESS_KEY_ID=youraccesskey
export AWS_SECRET_ACCESS_KEY=yoursecretaccesskey

Я столкнулся с той же проблемой, вам необходимо:

  1. декодировать из base64
  2. преобразовать из байта в строку
  3. разделите логин 'AWS'

    password = (base64.b64decode(response['authorizationData'[0]authorizationToken'])).decode("utf-8").split(":")[-1]
    

Неверный логин

dockerClient отказывается от соединения с "неверным логином или паролем"

Подпись функции, которую вы вызываете для входа в систему:

def login(self, username, password=None, email=None, registry=None,
          reauth=False, insecure_registry=False, dockercfg_path=None):

Обратите внимание на положение registry параметр. Он четвертый в списке. Итак, ваш призыв:

regClient = dockerClient.login(username, password, registry)

Проходит ваш registry как email поскольку email - третий параметр. Предлагаю вам изменить что-то вроде:

regClient = dockerClient.login(username, password, registry=registry)

Python или оболочка?

Это правильное направление, или мне следует попытаться реализовать это полностью с помощью сценариев оболочки? (Python был особенно ценен для вызовов boto для описания того, что находится в каждом реестре)

Выбирайте Python.

Я обнаружил, что проще всего пройти auth_config с именем пользователя / паролем при отправке изображения в ECR.

import boto3
import base64
import docker

sess = boto3.Session()
resp = sess.client('ecr').get_authorization_token()
token = resp['authorizationData'][0]['authorizationToken']
token = base64.b64decode(token).decode()
username, password = token.split(':')
auth_config = {'username': username, 'password': password}

# get local docker client
client = docker.from_env()
# build/tag image here....
# then override the docker client config by passing auth_config
client.image.push(<image name>, auth_config=auth_config)

Надеюсь, это кому-то поможет!

Есть открытый вопрос в docker-py проект об этом, и один из их обходных путей сработал для меня - удаление ведущего https:// из реестра при выполнении входа в Docker:

registry_url = token['authorizationData'][0]['proxyEndpoint'].replace("https://", "")