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

V2 mirror support #13374

Merged
merged 4 commits into from
May 28, 2015
Merged

V2 mirror support #13374

merged 4 commits into from
May 28, 2015

Conversation

RichardScothern
Copy link
Contributor

The v2 registry will act as a pull-through cache, and needs to be
handled differently by the client to the v1 registry mirror.

See distribution/distribution#459 for details

Configuration

Only one v2 registry can be configured as a mirror. Acceptable configurations
in this chanage are: 0...n v1 mirrors or 1 v2 mirror. A mixture of v1 and v2
mirrors is considered an error.

Pull

If a v2 mirror is configured, all pulls are redirected to that mirror. The
mirror will serve the content locally or attempt a pull from the upstream mirror,
cache it locally, and then serve to the client.

Push

If an image is tagged to a mirror, it will be pushed to the mirror and be
stored locally there. Otherwise, images are pushed to the hub. This is
unchanged behavior.

This change should not affect the v1 codepath.

closes distribution/distribution#84
Connects to distribution/distribution#19, distribution/distribution#459

@stevenschlansker
Copy link

I strongly disagree with "Only one v2 registry can be configured as a mirror."
Having multiple fallback mirrors is incredibly useful, as it allows much easier HA without complicated server configuration. It also allows multi-datacenter availability of registries which is even harder to configure on the server side.

Compare configuring your daemon as --add-mirror mycorp-mirror-uswest.mycorp.com --add-mirror mycorp-mirror-useast.mycorp.com versus attempting to create a highly available server side mirror spanning the US west and east coasts.

This was originally filed in #9161

@RichardScothern
Copy link
Contributor Author

@stevenschlansker . I appreciate your point, but you can get the same effect with a load balancer pointing to your two mirror instances without too much complication.

Putting load balancing code in the client which deals with all edge cases would complicate this feature and is outside the scope of this change.

@dmp42
Copy link
Contributor

dmp42 commented May 21, 2015

@RichardScothern agreed.

Thanks @stevenschlansker
Like I said in the other ticket, it's certainly a great idea for the future, and I think it can be implemented as a compatible extension later on, on top of this.

It's still going to make the code more complex, and needs to be thought through (specifically with regard to delegated delivery of layers and failure handling at that level).

@jessfraz
Copy link
Contributor

is this dependent on #13375

@stevvooe
Copy link
Contributor

This is looking good. We may need a few tests.

return v2MirrorEndpoint, v2MirrorRepoInfo, nil
}
if v2MirrorEndpoint != nil && v1MirrorCount > 0 {
lastErr = fmt.Errorf("v1 and v2 mirrors configured")
Copy link
Member

Choose a reason for hiding this comment

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

Why is this an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the behavior's are so different, I don't see how mixing v1 and v2 mirrors would work well. We can avoid this by having backwards compatibility (just v1 mirrors) or new behavior (a v2 mirror)

@dmcgowan
Copy link
Member

I have some concerns about the change of behavior from v1 mirrors. The v1 mirrors were only intended to be used for mirroring the official index. While this is an absolutely horrendous feature and requirement, it does have some relevance here. Without sending the hostname as part of the repo name, the mirror will not know which registry to fetch the content from. The assumption based on the current flag is that the content would come from the official index. If you try and send the hostname as part of the reponame, I believe the current path regexs will choke.

How would the mirror behave between these two requestss

docker pull myregistry.com/dmcgowan/myapp
docker pull dmcgowan/myapp

Are there any instructions on how to test this feature?

registry.DockerHeaders(imagePullConfig.MetaHeaders)...,
)
client := registry.HTTPClient(tr)
mirrorSession, err := registry.NewSession(client, imagePullConfig.AuthConfig, mirrorEndpoint)
Copy link
Contributor

Choose a reason for hiding this comment

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

@RichardScothern did you verify whether this will send credentials to the mirror?

Copy link
Member

Choose a reason for hiding this comment

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

This will send credentials, this needs to clear out the AuthConfig

@RichardScothern
Copy link
Contributor Author

@dmcgowan : the behavior does change between registry versions. Hence the fallback to v1 behavior with v1 mirrors and the inability to mix v1 and v2. In your scenario the registry would have to deal with a hostname and implement behavior on checking upstream for myregistry.com

Testing this feature is a bit tricky since we don't have the implementation in the v2 registry yet. I was testing with a pre-loaded v2 registry as a mirror.

@dmcgowan
Copy link
Member

@RichardScothern Created a PR against your fork to make it official only. If you don't have time to merge it I will carry the PR. I cannot sign off on this PR without either limiting it to official only (ugly but current behavior) or making this is a much larger change to support a the full namespace format in the URL generation and support sending the canonical name as the remote name. The first is less controversial and more likely to get merged. The latter we WILL do, but will require more discussion and sign off for the namespace proposals.

RichardScothern and others added 2 commits May 26, 2015 11:08
The v2 registry will act as a pull-through cache, and needs to be
handled differently by the client to the v1 registry mirror.

See distribution/distribution#459 for details

Configuration

Only one v2 registry can be configured as a mirror. Acceptable configurations
in this chanage are: 0...n v1 mirrors or 1 v2 mirror. A mixture of v1 and v2
mirrors is considered an error.

Pull

If a v2 mirror is configured, all pulls are redirected to that mirror. The
mirror will serve the content locally or attempt a pull from the upstream mirror,
cache it locally, and then serve to the client.

Push

If an image is tagged to a mirror, it will be pushed to the mirror and be
stored locally there. Otherwise, images are pushed to the hub. This is
unchanged behavior.

Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
Strip authconfig from session to keep credentials from being sent to the mirror.

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
@RichardScothern
Copy link
Contributor Author

Closing - this won't make 1.7.0.

This feature will be far more useful with full namespace support.

@RichardScothern
Copy link
Contributor Author

Re-opened. We would like to have feature parity with the v1 registry in 1.7

@tiborvass
Copy link
Contributor

design +1, this is only for the official index, and does not send hub creds to the mirror.
It is incompatible with v1 mirrors, and there can only be one v2 mirror set, at least for now in this PR. Rationale: if people want to do some fancy things, they can set up load balancers and set the v2 mirror to that, basically eliminating the need to complexify the client.

@tiborvass
Copy link
Contributor

Code LGTM

v1MirrorCount := 0
var v2MirrorEndpoint *registry.Endpoint
var v2MirrorRepoInfo *registry.RepositoryInfo
var lastErr error
Copy link
Contributor

Choose a reason for hiding this comment

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

but why?

Copy link
Contributor

Choose a reason for hiding this comment

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

why what

Copy link
Contributor

Choose a reason for hiding this comment

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

i just dont really like it... but i guess i see the point

@calavera
Copy link
Contributor

it would be cool to have some tests around mirror configuration, because looking at the code I don't really know if it works 😄

if repoInfo.Index.Official {
v2mirrorEndpoint, v2mirrorRepoInfo, err := configureV2Mirror(repoInfo, s.registryService)
if err != nil {
logrus.Errorf("Error configuring mirrors: %s", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

this log might not be necessary if we're returning the error.

Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
}

if v2mirrorEndpoint != nil {
logrus.Debugf("Attempting pull from v2 mirror: %s", v2mirrorEndpoint.URL)
Copy link
Contributor

Choose a reason for hiding this comment

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

Attempting to pull

@dmcgowan
Copy link
Member

LGTM

@calavera
Copy link
Contributor

@RichardScothern no signature in that latest commit :godmode:

Please, add some tests 🙏


if v1MirrorCount == len(mirrors) {
// OK, but mirrors are v1
return nil, nil, nil
Copy link
Contributor

Choose a reason for hiding this comment

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

@RichardScothern this is the exit when there are no mirrors at all, we should probably just have a very early return if len(mirrors) == 0 at the beginning of this function, otherwise this is confusing because it just so happens that v1MirrorCount would also be 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep

    - Match verbiage with other output
    - Remove dead code and clearer flow

Signed-off-by: Richard Scothern <richard.scothern@gmail.com>
@tiborvass
Copy link
Contributor

RE LGTM

@jessfraz
Copy link
Contributor

LGtM

tiborvass added a commit that referenced this pull request May 28, 2015
@tiborvass tiborvass merged commit 2daede5 into moby:master May 28, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add mirror support to engine
10 participants