Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Registry host configuration cleanup #47380

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

dmcgowan
Copy link
Member

First commit copies the resolver code from buildkit with fix for insecure registries and could be backported.
Second commit cleans up the resolve logic using containerd's host config.

closes #47240

@thaJeztah
Copy link
Member

Couple of failures that look related. Could be that the test was written for a specific error output though (these are the integration-cli tests, which use a fixed, old version of the CLI), or perhaps we're missing some conversion for errors returned 🤔

=== Failed
=== FAIL: amd64.integration-cli TestDockerRegistryAuthHtpasswdSuite/TestBuildFromAuthenticatedRegistry (0.34s)
    docker_cli_build_test.go:4988: assertion failed: 
        Command:  /usr/local/cli-integration/docker push 127.0.0.1:5000/baseimage
        ExitCode: 1
        Error:    exit status 1
        Stdout:   The push refers to repository [127.0.0.1:5000/baseimage]
        76df9210b28c: Waiting
        
        Stderr:   unexpected status from HEAD request to http://127.0.0.1:5000/v2/baseimage/blobs/sha256:76df9210b28cbd4bc127844914d0a23937ed213048dc6289b2a2d4f7d675c75e: 401 Unauthorized
        
        
        Failures:
        ExitCode was 1 expected 0
        Expected no error
    check_test.go:532: [da6a45cfad359] daemon is not started
    --- FAIL: TestDockerRegistryAuthHtpasswdSuite/TestBuildFromAuthenticatedRegistry (0.34s)

=== FAIL: amd64.integration-cli TestDockerRegistryAuthHtpasswdSuite/TestBuildWithExternalAuth (0.31s)
    docker_cli_build_test.go:5024: assertion failed: 
        Command:  /usr/local/cli-integration/docker --config /tmp/integration-cli-1513645647 push 127.0.0.1:5000/dockercli/busybox:authtest
        ExitCode: 1
        Error:    exit status 1
        Stdout:   The push refers to repository [127.0.0.1:5000/dockercli/busybox]
        76df9210b28c: Waiting
        
        Stderr:   unexpected status from HEAD request to http://127.0.0.1:5000/v2/dockercli/busybox/blobs/sha256:76df9210b28cbd4bc127844914d0a23937ed213048dc6289b2a2d4f7d675c75e: 401 Unauthorized
        
        
        Failures:
        ExitCode was 1 expected 0
        Expected no error
    check_test.go:532: [d254f721c0d6c] daemon is not started
    --- FAIL: TestDockerRegistryAuthHtpasswdSuite/TestBuildWithExternalAuth (0.31s)

=== FAIL: amd64.integration-cli TestDockerRegistryAuthHtpasswdSuite/TestLogoutWithExternalAuth (0.87s)
    docker_cli_logout_test.go:53: assertion failed: error is not nil: exit status 1
    --- FAIL: TestDockerRegistryAuthHtpasswdSuite/TestLogoutWithExternalAuth (0.87s)

=== FAIL: amd64.integration-cli TestDockerRegistryAuthHtpasswdSuite/TestPullWithExternalAuth (0.29s)
    docker_cli_pull_local_test.go:439: assertion failed: 
        Command:  /usr/local/cli-integration/docker --config /tmp/integration-cli-2597430029 push 127.0.0.1:5000/dockercli/busybox:authtest
        ExitCode: 1
        Error:    exit status 1
        Stdout:   The push refers to repository [127.0.0.1:5000/dockercli/busybox]
        76df9210b28c: Waiting
        
        Stderr:   unexpected status from HEAD request to http://127.0.0.1:5000/v2/dockercli/busybox/blobs/sha256:1c35c441208254cb7c3844ba95a96485388cef9ccc0646d562c7fc026e04c807: 401 Unauthorized
        
        
        Failures:
        ExitCode was 1 expected 0
        Expected no error
    check_test.go:532: [d37782d3d4dbc] daemon is not started
    --- FAIL: TestDockerRegistryAuthHtpasswdSuite/TestPullWithExternalAuth (0.29s)

=== FAIL: amd64.integration-cli TestDockerRegistryAuthHtpasswdSuite/TestPullWithExternalAuthLoginWithScheme (0.29s)
    docker_cli_pull_local_test.go:397: assertion failed: 
        Command:  /usr/local/cli-integration/docker --config /tmp/integration-cli-846080656 push 127.0.0.1:5000/dockercli/busybox:authtest
        ExitCode: 1
        Error:    exit status 1
        Stdout:   The push refers to repository [127.0.0.1:5000/dockercli/busybox]
        76df9210b28c: Waiting
        
        Stderr:   unexpected status from HEAD request to http://127.0.0.1:5000/v2/dockercli/busybox/blobs/sha256:1c35c441208254cb7c3844ba95a96485388cef9ccc0646d562c7fc026e04c807: 401 Unauthorized
        
        
        Failures:
        ExitCode was 1 expected 0
        Expected no error
    check_test.go:532: [df1a930ceacf0] daemon is not started
    --- FAIL: TestDockerRegistryAuthHtpasswdSuite/TestPullWithExternalAuthLoginWithScheme (0.29s)

=== FAIL: amd64.integration-cli TestDockerRegistryAuthHtpasswdSuite/TestPushNoCredentialsNoRetry (0.17s)
    docker_cli_push_test.go:225: assertion failed: expression is false: strings.Contains(out, "no basic auth credentials")
    check_test.go:532: [da543621fde40] daemon is not started
    --- FAIL: TestDockerRegistryAuthHtpasswdSuite/TestPushNoCredentialsNoRetry (0.17s)

=== FAIL: amd64.integration-cli TestDockerRegistryAuthHtpasswdSuite (2.88s)

daemon/hosts.go Outdated Show resolved Hide resolved
@dmcgowan dmcgowan force-pushed the registry-http-fallback branch 3 times, most recently from 11ed7f8 to 28acdd4 Compare February 29, 2024 16:44
@dmcgowan dmcgowan marked this pull request as ready for review February 29, 2024 17:59
@dmcgowan
Copy link
Member Author

Marked this as ready to go. I fixed the authorizer with the containerd image service resolver. The other failures now don't seem related, look like flakes.

daemon/hosts.go Outdated
Comment on lines 99 to 103
isLocalhost, err := docker.MatchLocalhost(hosts[i].Host)
if err != nil {
continue
}
if isLocalhost {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this make only the localhost insecure registries use the http fallback?
Also, shouldn't localhost registries should always use the http fallback by default, even if they're not explicitly an insecure registry?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't look at this PR in-depth, but I think we have some code somewhere that automatically adds localhost (more factually; the loopback range) as insecure), so it's possible that it's already automatically configured as insecure before we hit this code (????);

Insecure Registries:
  127.0.0.0/8

(Now wondering if that should also include the IPv6 loopback address ::1 , but I guess that's a separate topic).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmcgowan could you have a look?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this make only the localhost insecure registries use the http fallback?

It was intentional here to only use this for localhost since stepping down from insecure TLS to HTTP on localhost does not have the same implications as non-localhost. Although to keep the functionality the same in regards to the existing ambiguity over the meaning of "insecure" this could be applied to all hosts. In that case an empty TLS config would need to be generated if not set still to match existing logic I think.

I need to find a better approach for skipping over the legacy config, currently it checks for a nil configuration but I don't believe that is ever nil. Ideally the new (and less ambiguous) configuration files can be used without hitting the legacy merge logic when no legacy configuration is provided.

Also, shouldn't localhost registries should always use the http fallback by default, even if they're not explicitly an insecure registry?

I think that is up to the default configuration, as @thaJeztah mentioned, localhost is added by default. (see https://github.com/moby/moby/blob/master/registry/config.go#L187).

Now wondering if that should also include the IPv6 loopback address ::1 , but I guess that's a separate topic

Probably wouldn't hurt to add as a default, we should just make sure the behavior is the same with the new configuration and deprecate the old one.

@dmcgowan
Copy link
Member Author

dmcgowan commented Apr 22, 2024

There is a pending fix for the http handler on the containerd side that we can wait for in 1.7 before updating this one.

Also on another look I'm not sure checking for the service config being nil as the switch to merge in the legacy config is sufficient, especially if the legacy config is allowing for a more loose definition of "insecure" for non-localhost registries.

@dmcgowan
Copy link
Member Author

Pushed an update the fixes I mentioned.

As for the containerd fix, we need to handle TLS handshake timeouts (see containerd/containerd#10014). Although the current version we have also has this issue, so it might not be a blocker for taking this change in. There will be a followup regardless.

This logic is going to be updated to use the new containerd resolver and
needs all the logic handling resolution in the package where it is used.

Signed-off-by: Derek McGowan <derek@mcg.dev>
daemon/hosts.go Outdated Show resolved Hide resolved
daemon/hosts.go Outdated
}
if err == nil && u.Host != "" {
h.Host = u.Host
h.Path = strings.TrimRight(u.Path, "/")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would u.Path ever have multiple trailing slashes (after parsing?) if not, and it will always be one, then perhaps this should be TrimSuffix https://pkg.go.dev/strings#TrimSuffix

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is needed to trim but updated to TrimSuffix

daemon/hosts.go Outdated Show resolved Hide resolved
daemon/hosts.go Outdated Show resolved Hide resolved
daemon/hosts.go Show resolved Hide resolved
Signed-off-by: Derek McGowan <derek@mcg.dev>
Use the daemon's configuration to check whether the legacy registry
configuration is used. Only attempt to merge with the legacy
configuration if it has been provided. This avoids merging in based on
a defaulted legacy config.

Signed-off-by: Derek McGowan <derek@mcg.dev>
Note that while it is not safe to use http fallback on non-localhost
registries, this can be avoided using the new host directories. The
previous legacy insecure configuration is ambiguous and less secure.

Signed-off-by: Derek McGowan <derek@mcg.dev>
@dmcgowan dmcgowan force-pushed the registry-http-fallback branch 2 times, most recently from 1939df7 to 9d15d56 Compare April 27, 2024 14:28
Move the conversion to its own function and add unit tests.

Signed-off-by: Derek McGowan <derek@mcg.dev>
@dmcgowan dmcgowan added the kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny label May 2, 2024
@dmcgowan dmcgowan added this to the 27.0.0 milestone May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/daemon area/distribution kind/bugfix PR's that fix bugs kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny kind/refactor PR's that refactor, or clean-up code status/2-code-review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Docker 25 cannot use unsecured private s3 registry
3 participants