Docker Registry v2 api return strange code - docker

The screenshot shows what I get from http api
When I enter:
curl -X GET registry.yiqixie.com:5000/v2/
It returns something that I can't read:

For a remote registry, you should access it through https.
And you can add a -v in order to see the encoding of the answer.
curl -k -v -X GET https://registry.yiqixie.com:5000/v2/_catalog
Make sure your bash supports utf8.

Related

Google cloud run: Can a service know its own url?

I'm wondering if a container deployed on cloud run can somehow obtain its own service url or is it impossible?
I'm wanting to know this because I want a cloud run worker that creates google cloud tasks for itself.
If it is possible, how can it be done?
Use namespaces.services.get to retrieve the cloud run service info, some information required for this api
Service name
Cloud Run has provided default environment variable K_SERVICE
Project ID
Region
Access token
Project ID, region and access token can retrieve from metadata server
PROJECT_ID=$(curl "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google")
REGION=$(curl "http://metadata.google.internal/computeMetadata/v1/instance/region" -H "Metadata-Flavor: Google" | sed "s/.*\///")
TOKEN=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | jq -r '.access_token')
Then you can use namespaces.services.get to retrieve the cloud run service info in json, extract url with jq, export environment variable for application use
export PUCLIC_URL=$(curl -s "https://${REGION}-run.googleapis.com/apis/serving.knative.dev/v1/namespaces/${PROJECT_ID}/services/${K_SERVICE}" -H "Authorization: Bearer ${TOKEN}" | jq -r '.status.url')
curl and jq may required to install, for alpine: apk add --no-cache curl jq
Cloud Run service account requires run.services.get permission to call namespaces.services.get
I wrote an article to self call Cloud Run service to prevent Cold Start. The code that I wrote in Go is in my github
The idea is to call the metadata server to find the project number and the region (like this you don't have this hardcoded or in env var), and then you call the namespace API.
If you need help to write it in another language, let me know.
If you know the service name, you can make a GET HTTP request to https://{endpoint}/apis/serving.knative.dev/v1/{name}
Method: namespaces.services.get
For example :
curl -X GET -H "Authorization: Bearer $(gcloud auth print-access-token)" https://us-central1-run.googleapis.com/apis/serving.knative.dev/v1/namespaces/your-project/services/your-service| grep url
"url": "https://cloud-run-xxxxxxxxxx-uc.a.run.app"

remove docker repository on remote docker registry

Given a docker registry managing multiple docker repositories, how do I delete one of the repositores?
Given docker repositories repo1 and repo2.
$ curl -X GET localhost:5000/v2/_catalog
{"repositories":["repo1", "repo2"]}
I want to remove repository repo1 so _catalog does not list repo1, like
$ curl -X GET localhost:5000/v2/_catalog
{"repositories":["repo2"]}
Currently, repository repo1 only has the default "latest" image tag
$ curl -X GET localhost:5000/v2/repo1/tags/list
{"name":"repo1","tags":["latest"]}
(Maybe that affects being able to delete repo1?)
I have tried...
The following commands returned 404 page not found:
$ curl -X DELETE localhost:5000/v1/repositories/repo1
$ curl -X DELETE localhost:5000/v2/repositories/repo1
$ curl -X DELETE localhost:5000/v2/repo1
And the following returned {"errors":[{"code":"UNSUPPORTED","message":"The operation is unsupported."}]}
$ curl -X DELETE localhost:5000/v2/repo1/manifests/latest
Using versions
The remote docker-registry is registry/2.0
curl -vX GET localhost:5000/v2/
< HTTP/1.1 200 OK
...
< Docker-Distribution-Api-Version: registry/2.0
...
and
$ /bin/registry github.com/docker/distribution v2.4.1
by enabling DELETE API you're only able to delete the TAG not the whole repository from v2/_catalog.
in order to do this, you should:
1. enable DELETE API:
1.1 by config.yml : storage.delete.enabled:true
1.2 by env: -e REGISTRY_STORAGE_DELETE_ENABLED=true
2. get the tag reference via GET /v2/<name>/manifests/<tag>
(don't forget to have Header Accept: application/vnd.docker.distribution.manifest.v2+json).
in response headers, you have docker-content-digest: <sha256:xxx>
3. send DELETE /v2/<name>/manifests/<sha256:xxx>
4. run garbage collector: bin/registry garbage-collect /etc/docker/registry/config.yml
5. remove files: rm -r /var/lib/registry/docker/registry/v2/repositories/<name>/<tag>
finally: now you can see
curl -X GET localhost:5000/v2/_catalog
{"repositories":["repo2", "repo3"]}
ps.
consequences of 5: https://github.com/docker/distribution/issues/2983#issuecomment-530251232
There is no API to delete a repository. You need to delete individual tags or manifests within the repository. And until OCI's distribution-spec, there wasn't even an API to delete tags, you need to delete image manifests by digest, which deletes all tags pointing to that same digest.
To delete manifests, first ensure that you have enabled deletion according to this documentation before attempting anything. In your configuration of the registry, you would add the following section:
delete:
enabled: true
That can also be set by starting your registry container with the REGISTRY_STORAGE_DELETE_ENABLED=true environment variable specified.
Then you can call the manifest delete API:
curl -X DELETE \
-s "https://registry.example.org/v2/${repo}/manifests/${sha}"
If you want a wrapper around this to handle auth, and even support tag deletion, see regclient's regctl CLI that I've written. Google's crane and RedHat's skopeo may also provide this.
Once the manifests are deleted, you still need to clean the other items the manifest pointed to with a garbage collection (this needs to be done when no writes are occurring):
docker exec registry /bin/registry garbage-collect /etc/docker/registry/config.yml --delete-untagged
That said, you'll still reach the point where the repository itself is not removed. You can delete the entire directory from the filesystem of the registry. But I would recommend getting support for this implemented from the project. See this issue for more details on getting the capability added to the official registry image.

docker API v2 - how to tag and push an image

I want to promote image from test to prod environment. How do I use "curl POST" to tag and push an image thru docker registry API v2? (Docker API 1.22)
The equivalent command are:
docker tag my_testrepo:6000/new_test_image:test_tag myprod_repo:5000/new_prod_image:tag
docker push myprod_repo:5000/new_prod_image:tag
How do I use curl command to tag an image into a repo:
POST /images/test/tag?repo=myrepo&force=0&tag=v42 HTTP/1.1
Could not find any instructions. Tried many times, all failed.
While researching this issue I stumbled upon this question. The solution I found resolved around this blog post. Credit to wheleph for the solution.
Essentially there is no method to tag an existing image, you can simply download the manifest of the existing tag, and re-upload the manifest as a new tag:
curl /v2/mybusybox/manifests/latest -H 'accept: application/vnd.docker.distribution.manifest.v2+json' > manifest.json
Then upload that manifest file back up.
curl -XPUT '/v2/mybusybox/manifests/new_tag' -H 'content-type: application/vnd.docker.distribution.manifest.v2+json' -d '#manifest.json'

Can't delete Docker Image from Registry

Hi I want to delete a docker image from my private registry the steps that I did was:
I already did what the solution of How can I use the Docker Registry API V2 to delete an image from a private registry? recommended and it did not work
I did a HEAD request to get the Docker-Content-Digest
curl --cacert ~/Documents/certificates//ca.pem --key ~/Documents/certificates//key.pem --cert ~/Documents/certificates/certificate.p12 --pass certpass -I https://myprivateregistry/v2/imagename/manifests/tag
Then using the Dcker-content-digest from the previous step I did a delete request:
curl --cacert ~/Documents/certificates//ca.pem --key ~/Documents/certificates//key.pem --cert ~/Documents/certificates/certificate.p12 --pass certpass --header "Accept: application/vnd.docker.distribution.manifest.v2+json" -X DELETE https://myprivateregisty/v2/imagename/manifests/dockercontentdigestgotfrompreviousstep
I got this error:
{"errors":[{"code":"MANIFEST_UNKNOWN","message":"manifest unknown"}]}
In all likelihood, it means, that you have deleted the manifest, and this is right first step. To delete actual data from disk, you need to run docker registry garbage collector on registry host machine.
docker exec -it registry bin/registry garbage-collect /etc/docker/registry/config.yml
The info is from that comment
Also, as some adv, I want to propose you to check my docker registry web UI =) There is the possibility to delete an images from registry right with that UI.

Does Google container registry support docker remote API V2

I'm storing my docker images in my private Google Container Registry and I want to interact with the images through registry V2 APIs, such as getting tags of an image (/v2/:imageName/tags/list). I believe that it is supported, according to this link But I cannot found related documentation. Can anyone help me?
Just got answer from google support, hope this helps others:
$ export NAME=project-id/image
$ export BEARER=$(curl -u _token:$(gcloud auth print-access-token) https://gcr.io/v2/token?scope=repository:$NAME:pull | cut -d'"' -f 10)
$ curl -H "Authorization: Bearer $BEARER" https://gcr.io/v2/$NAME/tags/list
Indeed it is (including that endpoint). You should be able to interact with it after authenticating in the standard way outlined here.
Feel free to reach out on gcr-contact#google.com also if you have any troubles.
To add to Quyen Nguyen Tuan's answer, if you don't want to have to use gcloud at all, create a service account, pass the username _json_key and use the service account's json key as the password instead:
$ export NAME=project-id/image
$ export BEARER=$(curl -u "_json_key:$(cat path/to/json/key.json)" "https://gcr.io/v2/token?scope=repository:$NAME:pull" | cut -d'"' -f 10)
$ curl -H "Authorization: Bearer $BEARER" https://gcr.io/v2/$NAME/tags/list
and remember to prefix appropriately (e.g. eu.gcr.io) if that's where your repo is.

Resources