Skip to content

Registry host configuration cleanup#47380

Merged
vvoland merged 5 commits intomoby:masterfrom
dmcgowan:registry-http-fallback
Oct 30, 2024
Merged

Registry host configuration cleanup#47380
vvoland merged 5 commits intomoby:masterfrom
dmcgowan:registry-http-fallback

Conversation

@dmcgowan
Copy link
Member

@dmcgowan dmcgowan commented Feb 14, 2024

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.

@dmcgowan dmcgowan force-pushed the registry-http-fallback branch from e99532d to e3fb795 Compare February 14, 2024 05:28
@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)

@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.

@thaJeztah thaJeztah added area/distribution Image Distribution status/2-code-review area/daemon Core Engine kind/refactor PR's that refactor, or clean-up code kind/bugfix PR's that fix bugs labels Mar 16, 2024
@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 dmcgowan force-pushed the registry-http-fallback branch from 28acdd4 to 4e5cf6d Compare April 23, 2024 00:13
@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.

@dmcgowan dmcgowan force-pushed the registry-http-fallback branch 2 times, most recently from 5abfc63 to 8512eb4 Compare April 26, 2024 17:30
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

@dmcgowan dmcgowan force-pushed the registry-http-fallback branch 3 times, most recently from 9d15d56 to a404358 Compare April 28, 2024 03:45
@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
Copy link
Contributor

@vvoland vvoland left a comment

Choose a reason for hiding this comment

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

LGTM; left one small nit in test

@dmcgowan dmcgowan force-pushed the registry-http-fallback branch from a404358 to 336126a Compare May 13, 2024 23:40
@dmcgowan
Copy link
Member Author

Rebased but we don't need to consider this for 27 for the fix. The fix for #47240 was included in the latest buildkit update with moby/buildkit#4975.

We can consider the improved registry configuration for 28 release.

@dmcgowan dmcgowan removed this from the 27.0.0 milestone Jun 12, 2024
@dmcgowan dmcgowan force-pushed the registry-http-fallback branch from 336126a to 07bdfbd Compare June 12, 2024 18:43
@dmcgowan dmcgowan added this to the 28.0.0 milestone Jun 20, 2024
@vvoland vvoland requested a review from thaJeztah July 4, 2024 09:06
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 <[email protected]>
@dmcgowan dmcgowan force-pushed the registry-http-fallback branch 2 times, most recently from fb69fce to 5f7578f Compare October 22, 2024 14:56
Copy link
Contributor

@vvoland vvoland left a comment

Choose a reason for hiding this comment

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

LGTM
@thaJeztah PTAL

@vvoland
Copy link
Contributor

vvoland commented Oct 25, 2024

Rerunning CI

@vvoland
Copy link
Contributor

vvoland commented Oct 25, 2024

Ah, looks like there's a linter error:

 daemon/hosts.go:16: File is not `goimports`-ed (goimports)
	cerrdefs "github.com/containerd/errdefs"

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 <[email protected]>
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 <[email protected]>
Move the conversion to its own function and add unit tests.

Signed-off-by: Derek McGowan <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/daemon Core Engine area/distribution Image 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.

3 participants