docker icon indicating copy to clipboard operation
docker copied to clipboard

docker_registry needs support for Amazon ECR and Google GCR

Open someara opened this issue 8 years ago • 10 comments

Right now docker_registry only supports "vanilla" docker registries. The "big two" cloud providers have unique quirks that need support.

Collapsing these two tickets into one https://github.com/chef-cookbooks/docker/issues/806 https://github.com/chef-cookbooks/docker/issues/814

someara avatar Feb 15 '17 15:02 someara

Here is a workaround for this issue.

  1. Setup your access keys to your node.
  2. Add this to your recipe. It will simply login to ECR.
    cmd = "aws ecr get-login --region us-east-1" value = #{cmd} list = value.split(" ")

docker_registry 'AWS ECR registry' do serveraddress 'https://xyz.ecr.us-east-1.amazonaws.com' username 'AWS' password "#{list[5]}" email 'none' end

rashidmahmood avatar Mar 16 '17 14:03 rashidmahmood

@rashidmahmood it's not a permissions issue. It's an issue with the actual request headers. This is what anyone is already doing to login to ecr using the docker_registry resource.

et304383 avatar Mar 16 '17 14:03 et304383

Any progress @someara ? We're still having to resort to bash resource calls rather than properly using the resources available in this cookbook in order to login to ECR, pull containers down, and run them.

et304383 avatar May 08 '17 13:05 et304383

any chances of this getting fixed any time soon ? just like @et304383 we are forced to use bash calls or find other tools....

dannygu avatar Oct 25 '17 12:10 dannygu

Docker has credential helpers that should help in this situation. Has anyone tried https://github.com/awslabs/amazon-ecr-credential-helper ? I haven't used it in this context with Chef, but theoretically should allow skipping docker_registry with ECR as docker pull just works.

bflad avatar Oct 25 '17 12:10 bflad

I'm sorry but credentials helpers only works if you use the docker client. This cookbooks uses the chef gem, and if I'm not mistaken, it uses the Docker API instead.

davidcaste avatar Oct 25 '17 12:10 davidcaste

@davidcaste you are indeed correct, the problem isn't the login part

dannygu avatar Oct 25 '17 12:10 dannygu

+1

thebrianlopez avatar Feb 27 '18 22:02 thebrianlopez

Another workaround that has the advantage of being 'pure ruby', instead of resorting to shell / aws cli, it uses the aws-sdk gem (which I believe is now standard in the ChefDK) to make the AWS API call directly.

Assuming you keep your AWS access keys in a chef data bag:

chef_gem 'aws-sdk'

ruby_block 'grab_ecr_login_password' do
  block do
    require 'aws-sdk'
    require 'base64'
    aws_creds = data_bag_item('aws','creds')
    client = Aws::ECR::Client.new(access_key_id: aws_creds[:aws_access_key],
                                  secret_access_key: aws_creds[:aws_secret_access_key],
                                  region: 'us-east-1')
    resp = client.get_authorization_token
    token = resp.authorization_data.first.authorization_token
    user, pass = Base64.decode64(token).split(':')
    node.run_state['aws_ecr_user'] = user
    node.run_state['aws_ecr_pass'] = pass
  end
end

docker_registry 'AWS ECR' do
  serveraddress 'https://0123456789.dkr.ecr.region.amazonaws.com' # your AWS ECR URL
  username lazy { node.run_state['aws_ecr_user'] }
  password lazy { node.run_state['aws_ecr_pass'] }
end

In the case of running on an EC2 instance, I believe one can instantiate Aws::ECR::Client directly (without parameters) and it will use instance metadata / IAM role to authenticate.

It uses node.run_state to temporarily store ECR login credentials between the ruby_block and docker_registry resources, which is automatically cleared at the end of a Chef run.

Note that the use of lazy {}is necessary on the docker_registry properties, as the values in node.run_state['...'] will not be populated until the convergence phase.

ziprick avatar Jul 29 '18 13:07 ziprick

I initially had some issues with GCR login / pull as well, but it does indeed work

# login to gcr
credentials = data_bag_item('credentials' ,'gcr')
docker_registry 'https://gcr.io/' do
  username '_json_key'
  password credentials['service_account'].to_json
  action :login
end

# Pull tagged image
docker_image 'something' do
  repo 'gcr.io/your-repo'
  tag 'latest'
  action :pull
end

note: I had some issues with storing the json key inside of json databags, so I chose to nest the plain json under a keyspace 'service_account' and then turn use #to_json for the password. Alternatively, you can stringify the json key in your databag directly.

Another issue I ran into was a weird docker state after several failed attempts at getting the login and pull to work. When running docker login gcr.io and docker pull <my_image> from the terminal, I started receiving the following error:

docker: open /var/lib/docker/tmp/GetImageBlob549217035: no such file or directory.

After restarting the docker daemon, I was again able to pull my images correctly with both the CLI and this cookbook.

When in doubt, start from scratch in test-kitchen.

ls-brentsmith avatar Sep 11 '18 22:09 ls-brentsmith