Browse Source

new doc: using skopeo

pull/1/head
Nicolas Massé 7 years ago
parent
commit
a091c7c9d2
  1. 354
      Using-Skopeo/README.md
  2. 7
      Using-Skopeo/config.json.m4

354
Using-Skopeo/README.md

@ -0,0 +1,354 @@
# Using Skopeo to copy docker images between registries
## Context
When you need to deploy a container in OpenShift, you need an image of
this container. This image can be built from scratch or from another
image or be available "off-the-shelf" in another registry.
To use an image, three options are possible:
1. reference the target image directly in the build / deployment
2. use an image stream that references the target image
3. copy the target image to the OpenShift registry
Each approach as pros and cons.
If you reference the target image directly in the build / deployment,
any change to the reference will be cumbersome to implement. For instance,
if you want to change all `centos:7.4` images by a `centos:7.5`, it will
require a lot of work.
The [Image Stream](https://docs.openshift.com/container-platform/latest/dev_guide/managing_images.html)
is an indirection level that let you manage your images in a more flexible
way. An Image Stream contains tags and each tag can be:
- a reference to an external image such as `docker.io/centos:7` or
`registry.access.redhat.com/rhel7:7.5`.
- a reference to another tag in the same image stream
- a reference to a tag in another image stream
- a container image by itself
A reference can be used to point to an existing image which is fetched
directly by the OpenShift nodes when this image is needed (the pointed
image is not "mirrored" in the OpenShift registry).
Alternatively, it is possible to copy physically the image to the
OpenShift registry. In this way, if the external registry is unavailable,
the image can still be fetched from within the OpenShift cluster.
Also, some OpenShift clusters are completely disconnected from any other
network and copying images in the OpenShift registry is the only way to
use an image.
In this document, we will see how to copy images between registries using
[skopeo](https://github.com/projectatomic/skopeo).
## Installing skopeo
Skopeo is available in RHEL, Fedora and CentOS as an RPM package:
```sh
yum install skopeo
```
## Copying locally an image from DockerHub
Let's say, we need to make a local copy of the `centos:7`, `centos:7.5.1804`,
`centos:7.4.1708` and `rhel7:7.5` images.
First, you can inspect the target images using `skopeo inspect`:
```sh
skopeo inspect docker://docker.io/centos:7
skopeo inspect docker://docker.io/centos:7.5.1804
skopeo inspect docker://docker.io/centos:7.4.1708
```
The RHEL 7.5 image is hosted on a different registry (`registry.access.redhat.com`)
and needs to be fetched from a system registered on RHN/Satellite with the proper subscriptions.
First, make sure you are on a RHEL system:
```raw
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.4 (Maipo)
```
Make sure the system is registered with RHN/Satellite:
```raw
$ sudo subscription-manager status
+-------------------------------------------+
System Status Details
+-------------------------------------------+
Overall Status: Current
```
And then run the `skopeo inspect` as root:
```sh
sudo skopeo inspect docker://registry.access.redhat.com/rhel7:7.5
```
The `skopeo inspect` command queries information about the image
from the remote registry and prints them as JSON. If needed, you can then
extract the relevant fields using [jq](https://stedolan.github.io/jq/).
Now that you inspected the desired images, you can copy them locally:
```sh
skopeo copy docker://docker.io/centos:7 oci:./target:centos:7
skopeo copy docker://docker.io/centos:7.5.1804 oci:./target:centos:7.5.1804
skopeo copy docker://docker.io/centos:7.4.1708 oci:./target:centos:7.4.1708
sudo skopeo copy docker://registry.access.redhat.com/rhel7:7.5 oci:./target:rhel7:7.5
```
**Note:** we used `sudo` for the last command since we need to authenticate
to the Red Hat Registry with the machine credentials (the ones stored in
`/etc/docker/certs.d/registry.access.redhat.com`).
The image have been copied locally, in a directory named `./target`. This
directory is in the OCI format (Open Container Initiative).
You can inspect the local copy of those images with:
```sh
skopeo inspect oci:./target:centos:7
skopeo inspect oci:./target:centos:7.5.1804
skopeo inspect oci:./target:centos:7.4.1708
skopeo inspect oci:./target:rhel7:7.5
```
## Accessing the OpenShift registry with `skopeo`
To access the OpenShift registry, we need to:
- find the URL of the registry
- create a service account
- give the proper privileges to this service account in order to pull or push
to the registry
First, you can find the **public URL** of the registry by login as `cluster-admin`
on your OpenShit cluster and querying:
```sh
oc get route docker-registry -n default -o 'jsonpath={.spec.host}{"\n"}'
```
If you are logged in on a node of your cluster, you can also reach the
OpenShift registry by its **private URL**:
```sh
docker-registry.default.svc.cluster.local:5000
```
In the rest of this guide, the registry URL will be replaced by an environment
variable named `REGISTRY`.
If you are on one of your openshift nodes, you can use the internal URL:
```sh
REGISTRY=docker-registry.default.svc.cluster.local:5000
```
Otherwise, you can use the public URL:
```sh
REGISTRY="$(oc get route docker-registry -n default -o 'jsonpath={.spec.host}')"
```
Then, create a project (or re-use an existing one) to hold the `skopeo`
service account:
```sh
oc new-project admin
```
And create the service account:
```sh
oc create serviceaccount skopeo
```
Extract the token of the `skopeo` service account:
```sh
oc get secrets -o jsonpath='{range .items[?(@.metadata.annotations.kubernetes\.io/service-account\.name=="skopeo")]}{.metadata.annotations.openshift\.io/token-secret\.value}{end}' |tee skopeo-token
```
For the rest of this guide, the token will be replaced by an environment variable named `TOKEN`.
You can set it using:
```sh
TOKEN="$(cat skopeo-token)"
```
You can check that this token is working properly by inspecting an image stream
in the `openshift` namespace:
```sh
skopeo --insecure-policy inspect --creds="skopeo:$TOKEN" docker://$REGISTRY/openshift/nodejs
```
`nodejs` is an image stream that is provisioned by default on every OpenShift
cluster. If it is not there on yours, you can pick any image stream in the
`openshift` namespace:
```sh
oc get is -n openshift
```
## Pushing an image to the OpenShift registry
If you want to push an image in the OpenShift registry, you will have to:
- create a project to hold the pushed images
- grant the right to push images in this project to the `skopeo` service
account
First, create a new project (or re-use an existing one) to hold the images
that you will push:
```sh
oc new-project my-images
```
And then grant the right to push images in the `my-images` project to the
`skopeo` service account (that has been defined in the `admin` project):
```sh
oc adm policy add-role-to-user system:image-builder -n my-images system:serviceaccount:admin:skopeo
```
You can then copy your images to the OpenShift registry, in the `my-images`
project:
```sh
skopeo --insecure-policy copy --dest-creds="skopeo:$TOKEN" oci:./target:rhel7:7.5 docker://$REGISTRY/my-images/rhel7:7.5
```
Did you know that even if you can store the images locally, you can also copy
them "on the fly" without any local storage ?
Try to copy an image from the Docker Hub directly to the OpenShift registry:
```sh
skopeo --insecure-policy copy --dest-creds="skopeo:$TOKEN" docker://docker.io/centos:7 docker://$REGISTRY/my-images/centos:7
```
## Pulling an image to the OpenShift registry
If you want to pull an image from the OpenShift registry, you will have to:
- have access to the project that hold the images
- grant the right to pull images in this project to the `skopeo` service
account
First, make sure you have access to the project that holds the images
(in this example, the project is named `other-images`):
```sh
oc get imagestream -n other-images
```
And then grant the right to pull images from the `other-images` project to the
`skopeo` service account (that has been defined in the `admin` project):
```sh
oc adm policy add-role-to-user system:image-puller -n other-images system:serviceaccount:admin:skopeo
```
You can then copy your images from the OpenShift registry, located in the
`other-images` project:
```sh
skopeo --insecure-policy copy --src-creds="skopeo:$TOKEN" docker://$REGISTRY/other-images/myimage:latest oci:./target:myimage:latest
```
## Persist the registry credentials
Instead of passing the registry credentials on the command line, you can store
them in a configuration file.
Skopeo can re-use out-of-the-box any credential defined in the Docker/CRI-O
configuration.
If you have Docker installed locally, you can login to the registry:
```sh
docker login -u skopeo -p "$TOKEN" "$REGISTRY"
```
**Note:** to use the docker login, you need to be root or member of the
`docker` group.
If you do not have docker installed locally or if you are neither root nor
member of the `docker` group, you can generate a Docker configuration
manually:
```sh
mkdir -p $HOME/.docker
m4 "-D__REGISTRY__=$REGISTRY" "-D__BASE64AUTH__=$(echo -n "skopeo:$TOKEN" |base64 -w0)" < config.json.m4 > $HOME/.docker/config.json
chmod 600 $HOME/.docker/config.json
```
Try to inspect an image from the OpenShift registry without any explicit
credentials:
```sh
skopeo inspect docker://$REGISTRY/openshift/nodejs:latest
```
## SSL/TLS issues
If you are using skopeo from a machine that is not part of the cluster,
you will have to trust the OpenShift CA Certificate on this machine.
Otherwise, you will get an SSL/TLS Certificate Validation error:
```sh
FATA[0000] pinging docker registry returned: Get https://docker-registry-default.app.itix.fr/v2/: x509: certificate signed by unknown authority
```
If you need to trust the OpenShift CA, you will have to:
- fetch it from the master
- store it in your CA Trust Store
- update the CA Trust Store
You can fetch the OpenShift CA certificate by using `openssl s_client` to
connect to the master:
```sh
openssl s_client -host openshift.itix.fr -port 8443 -showcerts > trace < /dev/null
perl -0777 -ne 'while (m|((-----BEGIN CERTIFICATE-----)[-A-Za-z0-9+/=\n]+(-----END CERTIFICATE-----))|igs) { $cert = $1 }; print $cert, "\n";' > openshift-ca.crt
```
You can check that the fetched certificate is correct with:
```sh
cat openshift-ca.crt
openssl x509 -noout -text -in openshift-ca.crt
```
If it is correct, you can copy the CA certificate in the CA Trust Store:
```sh
sudo cp openshift-ca.crt /etc/pki/ca-trust/source/anchors/skopeo-openshift-ca.crt
```
You can now update the CA Trust Store:
```sh
sudo update-ca-trust extract
```
## Conclusion
Skopeo is a powerful tool to copy and archive container images. It is
self-contained and does not depend on the Docker daemon.
You can use it to copy images between registries, including the OpenShift
registry.

7
Using-Skopeo/config.json.m4

@ -0,0 +1,7 @@
{
"auths": {
"https://__REGISTRY__/v2/": {
"auth": "__BASE64AUTH__"
}
}
}
Loading…
Cancel
Save