docker
docker copied to clipboard
docker_registry needs support for Amazon ECR and Google GCR
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
Here is a workaround for this issue.
- Setup your access keys to your node.
- 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 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.
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.
any chances of this getting fixed any time soon ? just like @et304383 we are forced to use bash calls or find other tools....
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.
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 you are indeed correct, the problem isn't the login part
+1
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.
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.