moby: Buildkit in docker 18.09 won't allow insecure registry with self-signed TLS

Description Docker 18.09 with buildkit activated fails to pull from my private “insecure” registry. When buildkit is deactivated, the same Dockerfile builds fine.

I originally posted this as a comment to https://github.com/moby/buildkit/issues/606 , I did more tests since then : I’ve found that the problem only occurs when activating the experimental syntax (to allow using RUN --mount).

[ EDIT : the above isn’t true : actually both builds fail if I properly delete all images before testing ]

Steps to reproduce the issue:

  1. In daemon.json, declare private mirror + insecure registry and activate buildkit :
{
  "registry-mirrors": ["https://repo.mycompany.com"],
  "insecure-registries" : ["repo.mycompany.com"],
  "features":{
    "buildkit": true
  }
}
  1. Build the following Dockerfile - it works : [ Edit : this was beause I had maven:3.5.3-alpine available locally, if I remove it and retry, it fails ]
FROM maven:3.5.3-alpine
RUN mvn dependency:help
  1. Now modify the Dockerfile to add the experimental syntax and a --mount argument to RUN :
# syntax=docker/dockerfile:experimental
FROM maven:3.5.3-alpine
RUN --mount=target=/root/.m2,type=cache mvn dependency:help

Describe the results you received: This second build fails with :

[+] Building 0.4s (3/3) FINISHED
 => [internal] load build definition from Dockerfile
 => => transferring dockerfile: 169B
 => [internal] load .dockerignore
 => => transferring context: 2B
 => ERROR resolve image config for docker.io/docker/dockerfile:experimental
------
 > resolve image config for docker.io/docker/dockerfile:experimental:
------
failed to do request: Head https://repo.mycompany.com/v2/docker/dockerfile/manifests/experimental: x509: certificate signed by unknown authority

Describe the results you expected: I was expecting the image to build without error.

As a bonus I’m also expecting that if I delete the generated image, and build it again, the maven dependencies will not need to be downloaded again, and fetched from the mounted cache instead, making my build a lot faster (which is the main reason why I want to use this feature).

Additional information you deem important (e.g. issue happens only occasionally):

Note that if I do docker pull docker/dockerfile:experimental (which works) and retry, the error will now be on pulling maven:3.5.3-slim as part of the build. [ Edit : this was because I had done docker images -q | xargs docker rmi between the tests ]

I’ve also tested with dockerfile:1.0-experimental instead of dockerfile:experimental (as found in https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information) - with the same result.

Output of docker version:

Client:
 Version:           18.09.0
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        4d60db4
 Built:             Wed Nov  7 00:49:01 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.0
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       4d60db4
  Built:            Wed Nov  7 00:16:44 2018
  OS/Arch:          linux/amd64
  Experimental:     false

Output of docker info:

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 497
Server Version: 18.09.0
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: c4446665cb9c30056f4998ed953e6d4ff22c7c39
runc version: 4fc53a81fb7c994640722ac585fa9ca548971871
init version: fec3683
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.15.0-38-generic
Operating System: Ubuntu 18.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 9.754GiB
Name: pic
ID: JMTB:MV5N:DFIK:T6VA:BMPB:46DT:R6XZ:CLOJ:7NDD:ZVVP:BYXY:7L2F
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 repo.mycompany.com
 127.0.0.0/8
Registry Mirrors:
 https://repo.mycompany.com/
Live Restore Enabled: false
Product License: Community Engine

WARNING: No swap limit support

Additional environment details (AWS, VirtualBox, physical, etc.):

VM on VMWare ESXi 6.5. The “insecure” registry is our internal instance of Sonatype Nexus OSS 3.11.0 behind a reverse-proxy handling SSL with a letsencrypt-issued certificate. Above, I’ve replaced the real server address by repo.mycompany.com.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 6
  • Comments: 30 (12 by maintainers)

Commits related to this issue

Most upvoted comments

same issue with docker 20.10 if registry work on http://repo.mycompany.com,but buildkit pull https://repo.mycompany.com, notice the insecure-registries

{
  "insecure-registries" : ["http://repo.mycompany.com"],
  "features":{
    "buildkit": true
  }
}

It works for me.

We are using private registries and a registry mirror on private domains with plain http. Will there be a fix for buildkit supporting plain http registries in the future?

Initially the registry was using a self-signed certificate, so I had to declare it as insecure. Then I switched to letsencrypt and it wouldn’t work without that setting. Then I followed the documentation to add letsencrypt certificates in /etc/docker/certs.d/, and I am finally able to remove this setting and use my “secure” registry with the “default” builder. Still, it doesn’t solve the issues with buildkit (see below).

Our “private mirror” is an instance of Sonatype Nexus 3 configured as a proxy repository of docker.io. We also have a hosted private repository and both are in a single group. URL https://repo.mycompany.com/ points to this group. It is used in daemon.json in the registry-mirrors entry.

This morning I’m testing with the following configuration in daemon.json :

{
  "registry-mirrors": ["https://repo.mycompany.com"],
  "features":{
    "buildkit": true
  }
}

This is the output I’m getting for docker build . (same Dockerfile as above):

[+] Building 0.3s (3/3) FINISHED
 => [internal] load build definition from Dockerfile
 => => transferring dockerfile: 238B 
 => [internal] load .dockerignore 
 => => transferring context: 2B 
 => ERROR resolve image config for docker.io/docker/dockerfile:1.0-experimental
------
 > resolve image config for docker.io/docker/dockerfile:1.0-experimental:
------
docker.io/docker/dockerfile:1.0-experimental not found

(I’ve also tried with docker/dockerfile:experimental, same result)

However, docker pull docker/dockerfile:1.0-experimental succeeds… So after pulling the “experimental” image, I retried and the build goes further, but fails with a similar error:

------
 > [internal] load metadata for docker.io/library/maven:3.5.3-alpine:
------
------
 > [1/4] FROM docker.io/library/maven:3.5.3-alpine:
------
rpc error: code = Unknown desc = docker.io/library/maven:3.5.3-alpine not found

If I understand correctly:

  • buildkit has a problem when the insecure-registry setting is used, the workaround is to configure the certificates properly to use the registry as a secure one
  • even with a secure registry, buildkit fails to fetch the images when the registry-mirrors setting is used (in my case, Sonatype Nexus). The strange thing is that a docker pull of these same images succeeds : it seems that buildkit is not pulling images the same way the cli does ??

[EDIT] I also tested removing the registry-mirrors parameter. In this case, building an image referencing images from docker.io only works (ex FROM maven). But if I am referencing my private registry (FROM repo.mycompany.com/whatever/image) I am getting the same rpc error: code = Unknown desc = repo.mycompany.com/whatever/image not found

When using docker buildkit to build images, if you don’t want to configure the CA certificate, you can modify the docker configuration file (/etc/docker/daemon.json) to make it work properly. You can follow these steps: 1):edit /etc/docker/daemon.json (#Add the prefix ‘http://’ in front of ‘myregistry.domain.com’)

{
  "insecure-registries": ["http://myregistry.domain.com"]
}

2): save json file, and restart docker service:

service docker restart 
#or 
systemctl restart docker

Updated workaround: adding the cert used on my Artifactory server to the docker host works with buildkit. That is cp <cert> /usr/local/share/ca-certificates/ update-ca-certificates systemctl restart docker works just fine.

I’ve made progress.

My problem seems to be caused by two simultaneous issues:

  1. Buildkit has issues with insecure registries, as stated above by @tonistiigi . Solution: secure the registry
  2. Buildkit can’t fetch images from private registry hosted on Sonatype Nexus. I’ve eventually found that Buildkit issues a HEAD request to the registry before fetching the images, which a regular “docker pull” doesn’t do. This triggers this Sonatype Nexus bug: https://issues.sonatype.org/browse/NEXUS-12684. Solution : upgrade Nexus to version > 3.15

With these two changes in place, I am now able to use buildkit. 😃

Maybe it’d be worth to mention the Nexus issue somewhere in Docker’s documentation ? (how about here : https://docs.docker.com/develop/develop-images/build_enhancements/ ? I’ll prepare a PR)

Then, if there is another ticket for the issue with insecure registries, I think we could close this issue.

@thaJeztah Nope, it doesn’t work either. The error is slightly different though 😉 - see in the log how it is using https despite the mirror address is configured as HTTP ?

me@pic:~/test$ docker build .
[+] Building 0.1s (3/3) FINISHED
 => [internal] load .dockerignore
 => => transferring context: 2B
 => [internal] load build definition from Dockerfile
 => => transferring dockerfile: 238B
 => ERROR resolve image config for docker.io/docker/dockerfile:1.0-experimental
------
 > resolve image config for docker.io/docker/dockerfile:1.0-experimental:
------
failed to do request: Head https://repo.mycompany.com:80/v2/docker/dockerfile/manifests/1.0-experimental: http: server gave HTTP response to HTTPS client
me@pic:~/test$ sudo cat /etc/docker/daemon.json
{
  "registry-mirrors": ["http://repo.mycompany.com:80"],
  "insecure-registries" : ["repo.mycompany.com"],
  "features":{
    "buildkit": true
  }
} 

(if I remove the “insecure-registries” entry, restart docker, and try again, I’m getting the same error)