Open ojundt opened 6 years ago
This hit me, too. It's a big bummer. I was looking forward to shortening the <horrendous ID>.dkr.ecr.<region name>.amazonaws.com
URIs. I, apparently, successfully got a proxy in front of it, and then had to throw it all away when I had no way to authenticate (neither ecr-login
nor aws ecr get-login
returns an auth that Docker can use with my custom URL). Would really love to see this fixed. In my opinion (which, of course, is just that—an opinion), this is a defect, not a feature. The internet is simply full of people trying to shorten these ridiculous URIs with one proxy or another, usually with success, but it's all moot if the login tools intentionally prevent us from doing so. :-(
I'm surprised there isn't an easier way to front ECR behind a CNAME, it's definitely a usability failure in my opinion. Nevertheless I was able to cobble together workaround which others hitting this might be interested in.
First you need to setup some kind of proxy that can rewrite both request and response headers. I used haproxy. The relevant part of the config that reqwrites both the Host(request) and Location(Response) headers looks like this:
frontend fe_router
bind 0.0.0.0:9550 ssl crt /tmp/cert.pem
option forwardfor
use_backend be_external_host
backend be_external_host
http-request set-header Host 1234567890.dkr.ecr.us-east-1.amazonaws.com
http-response replace-value Location ^(https://1234567890.dkr.ecr.us-east-1.amazonaws.com)(.*)$ https://example.com\2
server server_external 1234567890.dkr.ecr.us-east-1.amazonaws.com:443 check ssl
Then I implemented my own dumb credential helper (with caching of the token)
#!/bin/bash
LOCAL_DOCKER_DIR=~/.docker
DOCKER_CONFIG="${LOCAL_DOCKER_DIR}/config.json"
ECR_CREDENTIAL="${LOCAL_DOCKER_DIR}/example_ecr_credential.json"
ECR_ENDPOINT=1234567890.dkr.ecr.us-east-1.amazonaws.com
mkdir -p "${LOCAL_DOCKER_DIR}"
install_config="false"
while [[ $# -gt 0 ]]
do
key="$1"
case $key in
install)
install_config="true"
shift
;;
*)
shift
;;
esac
done
if [[ "${install_config}" == "true" ]]; then
original_config=$(cat ${DOCKER_CONFIG} 2>/dev/null)
if [ -z "${original_config}" ];
then
original_config="{}"
fi
cred_helpers="{\"credHelpers\": {\"${ECR_ENDPOINT}\": \"ecr-login\",\"example.com\": \"cname-ecr-login\"}}"
echo "${original_config} ${cred_helpers}" | \
jq -Scs '.[0] * .[1]' > "${DOCKER_CONFIG}"
echo "Config installed in ${DOCKER_CONFIG}"
exit 0
fi
# Docker provides the server url on stdin, but we don't use it
read line
# AWS docs claim the token lasts 12h, I cache it for 11
recent_credential=$(find "${ECR_CREDENTIAL}" -mmin -660 2>/dev/null)
if [ -z "${recent_credential}" ]
then
credential=$( \
aws ecr get-authorization-token \
| jq -r '.authorizationData[0].authorizationToken' \
| base64 -d \
| sed -e 's/^[^:]*://' \
)
echo "{\"ServerURL\":\"${ECR_ENDPOINT}\",\"Username\":\"AWS\",\"Secret\":\"${credential}\"}" | jq -Sc > "${ECR_CREDENTIAL}"
fi
cat "${ECR_CREDENTIAL}"
In this case if the script was named "docker-credential-cname-ecr-login" and somewhere on your path it would be used (I've redacted the above scripts a bit and might have typoed things, but you get the idea)
https://github.com/aws/containers-roadmap/issues/299 is the issue in the roadmap tracking general support for custom domains in ECR.
One fun way to fix this would be to use the distribution protocol itself -- https://distribution.github.io/distribution/spec/auth/token/#how-to-authenticate
If the URL doesn't match the expected pattern, we could send a HEAD to registry.foobar.com/v2/ and grab the ECR authentication URL off the Www-Authenticate response headers, then infer account id and region from that.
Hi there,
We are using ECR in combination with a proxy with a custom domain (e.g.
registry.foobar.com
). We use the custom domain to make migration from and to ECR easier.However, the custom domain currently prevents us from using the ECR credential helper. It requires the ECR domain format for extracting the registry id and region: https://github.com/awslabs/amazon-ecr-credential-helper/blob/3eac0af2021820739ca704166494c1f45a4e8f72/ecr-login/api/client.go#L33-L55
It would be nice if there are alternative means to provide the region and account id information, maybe with environment variables or config files for the helper with a simple mapping such as: