Commit a469e307 authored by Pierre Smeyers's avatar Pierre Smeyers
Browse files

Merge branch '24-document-issues-related-to-dockerhub-quotas' into 'master'

Resolve "Document issues related to DockerHub quotas"

Closes #24

See merge request to-be-continuous/doc!43
parents 4e3cfb1e 2cb7322a
Loading
Loading
Loading
Loading
Loading
+54 −0
Original line number Diff line number Diff line
@@ -210,3 +210,57 @@ define the `TRACKING_CONFIGURATION` CI/CD project variable as follows:
    ```
4. Manually start a pipeline on the `main` (or `master`) branch: this will (re)generate a new Docker image with your
   configuration that will now be used by every template job.

## Use Docker registry mirrors

### _to be continuous_ uses explicit Docker registries

By default Docker images names that do not specify a registry (e.g. `alpine:latest`) are [fetched from the Docker Hub](https://docs.docker.com/engine/reference/commandline/pull/#pull-from-a-different-registry).

Since Docker Hub has some [quotas](https://docs.docker.com/docker-hub/download-rate-limit/), some companies use Docker registry mirrors.

Some Docker registry mirrors can mirror multiple registries (e.g. [Artifactory](https://www.jfrog.com/confluence/display/JFROG/Virtual+Repositories)).

In that case, when pulling an image without specifying the original registry, the mirror will look for an image with the same name in each of the upstream registries.

It will return the 1st matching image, which is not necessarily from the registry you expected.

Example:

- a developer builds the `superapp/backend:1.0.0` image and pushes it to both Docker Hub and Quay.io
- the developer also tags this image with tag `latest` and pushes the `latest` tag to both Docker Hub and Quay.io
- the developer then builds image `superapp/backend:1.1.0` and pushes it only to Docker Hub (e.g. because of a failure in the build pipeline) without noticing that the image has not been pushed to Quay.io
- if a user pulls `superapp/backend:latest` he would expect to get the `superapp/backend:1.1.0` image from Docker Hub
- but if a mirror has been set up to proxy both Docker Hub and Quay.io with a priority to Quay.io, the returned image would be `superapp/backend:1.0.0` pulled from Quay.io

This behavior can be used by attackers in supply chain attacks: they can push a malicious image in lots of Docker registries with the same name as a trustworthy image which is only published in the Docker Hub. A mirror could return the malicious image just because it found an image with the correct name on a different registry before the Docker Hub.

In order to protect against this kind of attacks, _to-be-continuous_ always use fully qualified image names (i.e. including the registry).

Example:

To refer to `aquasec/trivy:latest`, _to be continuous_ templates will always specify `registry.hub.docker.com/aquasec/trivy:latest`


### Drawbacks

When using [`containerd`](https://containerd.io/) as a container runtime, this should have no impact, containerd will still try to use the configured Docker registry mirrors if any.

On the other hand, when using Docker as a container runtime, specifying the registry name when pulling a Docker image prevents Docker from using a Docker registry mirror. Instead, the Docker daemon will directly pull the image from the specified registry. As a consequence, Docker Hub quotas may be reached sooner.


### Workarounds

You can simply override the image names specifying your own Docker registry mirror.

Example:

If you have a Docker registry mirror for the Docker Hub, you can use something like this:

```yaml
variables:
  DOCKER_TRIVY_IMAGE: "docker-proxy.mycorp.org/aquasec/trivy:latest"
```

In this case, both `containerd` and the Docker daemon will try to pull the `aquasec/trivy:latest` image through your Docker registry mirror.