Todd M
Todd M

Reputation: 372

Accessing private Google Container Registry from docker/compose container running on COS

I'm running a Container-Optimized OS VM on GCE (with Docker 17.03.2) and would like to use docker-compose to manage the containers. docker-compose isn't installed on COS, but it can be run from a container using the image docker/compose, as described in this tutorial:

docker run \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v "$PWD:/rootfs/$PWD" \
    -w="/rootfs/$PWD" \
    docker/compose:1.14.0 up

The images I want to access are in a private Google Container Registry, which requires a docker login for pull access. How can I run the docker/compose image to access the private registry?

The COS VM is already authorized to access the registry, and I have a service account JSON file on the VM, but can that be passed to the compose image to login before running the up command?

Upvotes: 0

Views: 1518

Answers (4)

MrAlias
MrAlias

Reputation: 1346

An alternative to directly using the service account JSON credentials, given the COS VM is already authorized to access the registry (e.g. the attached service account has GCS view access to the project hosting the image), is to run the /usr/share/google/dockercfg_update.sh script shipped with COS:

#!/bin/sh
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

set -eu

AUTH_DATA="$(curl -s -f -m 10 "http://metadata/computeMetadata/v1/instance/service-accounts/default/token" \
  -H "Metadata-Flavor: Google")"
R=$?
if [ ${R} -ne 0 ]; then
  echo "curl for auth token exited with status ${R}" >&2
  exit ${R}
fi

AUTH="$(echo "${AUTH_DATA}" \
| tr -d '{}' \
| sed 's/,/\n/g' \
| awk -F ':' '/access_token/ { print "_token:" $2 }' \
| tr -d '"\n' \
| base64 -w 0)"

if [ -z "${AUTH}" ]; then
  echo "Auth token not found in AUTH_DATA ${AUTH_DATA}" >&2
  exit 1
fi

D="${HOME}/.docker"
mkdir -p "${D}"
cat > "${D}/config.json" <<EOF
{
 "auths":{
  "https://container.cloud.google.com":{"auth": "${AUTH}"},
  "https://gcr.io":{"auth": "${AUTH}"},
  "https://b.gcr.io":{"auth": "${AUTH}"},
  "https://us.gcr.io":{"auth": "${AUTH}"},
  "https://eu.gcr.io":{"auth": "${AUTH}"},
  "https://asia.gcr.io":{"auth": "${AUTH}"},
  "https://beta.gcr.io":{"auth": "${AUTH}"}
 }
}
EOF

This has the benefits of being maintained by Google and avoids having to manage service account credentials.

Upvotes: 0

Todd M
Todd M

Reputation: 372

The best solution I found was to authenticate on the Docker host and then mount the docker config into the docker-compose container:

docker login -u _json_key -p "$(cat keyfile.json)" https://gcr.io
docker run \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /root/.docker:/root/.docker \
    -v "$PWD:$PWD" \
    -w="$PWD" \
    docker/compose:1.14.0 \
    up

Upvotes: 0

jsand
jsand

Reputation: 595

Using the _json_key anthentication from GCR's advanced authentication docs, does the following script work?

docker run \ -v /var/run/docker.sock:/var/run/docker.sock \ -v "$PWD:/rootfs/$PWD" \ -w="/rootfs/$PWD" \ docker/compose:1.14.0 \ /bin/bash -c "docker login -u _json_key -p $(cat keyfile.json) https://gcr.io; up"

Upvotes: 0

mattmoor
mattmoor

Reputation: 1707

You want to use this method to authenticate.

Upvotes: 0

Related Questions