Docker CLI разрешает тег, но Docker Python API вызывает APIError
Я пытаюсь вставить локальный образ Docker в ECR с помощью Docker Python API. В рамках этого процесса мне нужно пометить изображение определенным образом. Когда я делаю это на CLI, это работает:
docker tag foo/bar '{user_id}.dkr.ecr.us-east-1.amazonaws.com/foo/bar'
Однако, когда я пытаюсь сделать то же самое, используя docker.images.Image.tag
Функция в Docker Python SDK не работает:
import docker
(docker.client.from_env().images.get('foo/bar')
.tag('foo/bar',
'{user-id}.dkr.ecr.us-east-1.amazonaws.com/foo/bar'
)
)
(заменить user_id
в приведенных выше примерах кода со значением идентификатора пользователя AWS, например 717171717171
; Я запутал это здесь для целей этого вопроса)
Со следующей ошибкой:
In [10]: docker.client.from_env().images.get('foo/bar').ta
...: g('foo/bar', '{user_id}.dkr.ecr.us-east-1.amaz
...: onaws.com/foo/bar')
---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
~/miniconda3/envs/alekseylearn-dev/lib/python3.6/site-packages/docker/api/client.py in _raise_for_status(self, response)
255 try:
--> 256 response.raise_for_status()
257 except requests.exceptions.HTTPError as e:
~/miniconda3/envs/alekseylearn-dev/lib/python3.6/site-packages/requests/models.py in raise_for_status(self)
939 if http_error_msg:
--> 940 raise HTTPError(http_error_msg, response=self)
941
HTTPError: 500 Server Error: Internal Server Error for url: http+docker://localhost/v1.35/images/sha256:afe07035bce72b6c496878a7e3960bedffd46c1bedc79f1bd2b89619e8457194/tag?tag={user_id}.dkr.ecr.us-east-1.amazonaws.com%2Ffoo%2Fbar&repo=foo%2Fbar&force=0
During handling of the above exception, another exception occurred:
APIError Traceback (most recent call last)
<ipython-input-10-5bb015d17409> in <module>
----> 1 docker.client.from_env().images.get('alekseylearn-example/build').tag('foo/bar', '{user_id}.dkr.ecr.us-east-1.amazonaws.com/foo/bar')
~/miniconda3/envs/alekseylearn-dev/lib/python3.6/site-packages/docker/models/images.py in tag(self, repository, tag, **kwargs)
120 (bool): ``True`` if successful
121 """
--> 122 return self.client.api.tag(self.id, repository, tag=tag, **kwargs)
123
124
~/miniconda3/envs/alekseylearn-dev/lib/python3.6/site-packages/docker/utils/decorators.py in wrapped(self, resource_id, *args, **kwargs)
17 'Resource ID was not provided'
18 )
---> 19 return f(self, resource_id, *args, **kwargs)
20 return wrapped
21 return decorator
~/miniconda3/envs/alekseylearn-dev/lib/python3.6/site-packages/docker/api/image.py in tag(self, image, repository, tag, force)
531 url = self._url("/images/{0}/tag", image)
532 res = self._post(url, params=params)
--> 533 self._raise_for_status(res)
534 return res.status_code == 201
535
~/miniconda3/envs/alekseylearn-dev/lib/python3.6/site-packages/docker/api/client.py in _raise_for_status(self, response)
256 response.raise_for_status()
257 except requests.exceptions.HTTPError as e:
--> 258 raise create_api_error_from_http_exception(e)
259
260 def _result(self, response, json=False, binary=False):
~/miniconda3/envs/alekseylearn-dev/lib/python3.6/site-packages/docker/errors.py in create_api_error_from_http_exception(e)
29 else:
30 cls = NotFound
---> 31 raise cls(e, response=response, explanation=explanation)
32
33
APIError: 500 Server Error: Internal Server Error ("invalid tag format")
Почему команда CLI завершается успешно, а команда Python API терпит неудачу?
1 ответ
В подробном жаргоне Docker API, имя изображения, как 123456789012.dkr.ecr.us-east-1.amazon.aws.com/foo/bar:baz
делится на репозиторий (перед двоеточием) и тег (после двоеточия). Часть имени хоста имени хранилища является реестром. Значение тега по умолчанию, если ничего не указано, является литералом latest
,
В вашем случае у вас уже есть Image
объект, поэтому вам нужно применить две "половинки" второго аргумента:
docker.client.from_env().images.get('foo/bar')
.tag('{user-id}.dkr.ecr.us-east-1.amazonaws.com/foo/bar',
'latest'
)
(Во многих практических случаях использование latest
тег не очень хорошая идея; что-то вроде временной метки или идентификатора коммита контроля источника лучше идентифицирует изображение и помогает указывать таким службам, как ECS или EKS или обычным Kubernetes, что им необходимо сделать обновление. Кроме того, хотя идентификаторы изображений ECR непрактично длинные, в контексте сценариев ничто не мешает вам использовать их напрямую; Вы можете, например, docker build -t 12345...amazonaws.com/foo/bar:abcdef0
и пропустить промежуточный docker tag
шаг, если хотите.)