-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[WIP] Replace ImageStreamMapping by ImageStreamImport #16475
Conversation
Signed-off-by: Oleg Bulatov <obulatov@redhat.com>
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: dmage Assign the PR to them by writing The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
To: &kapi.LocalObjectReference{Name: tag}, | ||
|
||
ImportPolicy: imageapiv1.TagImportPolicy{ | ||
Insecure: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@smarterclayton At the moment the registry does not know the correct value of this flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The registry knows if it's secure or not (for managed images). And source image streams have TagImportPolicy as well - it can be inherited for external images. It's not bulletproof though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does the registry know if it's secure or not? I'm pretty sure it doesn't.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does the registry know if it's secure or not? I'm pretty sure it doesn't.
You're right. I took into consideration just passthrough
tls termination where the certificate paths are passed to registry via environment variables. For edge
tls termination, the registry cannot be sure for sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that's just another reason for me for not replacing imagestreammapping with imagestreamimport.
context.GetLogger(ctx).Errorf("error retrieving ImageStream %s/%s: %v", t.repo.namespace, t.repo.name, err) | ||
return distribution.ErrRepositoryUnknown{Name: t.repo.Named().Name()} | ||
} | ||
dockerImageReference := fmt.Sprintf("%s/%s/%s@%s", t.repo.config.registryAddr, t.repo.namespace, t.repo.name, dgst.Digest.String()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change bypasses the quota check. How would quota be checked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will access control to the image work? Does this require the api server to have full credentials to the registry?
What are the performance implications of this change? You're changing:
- registry POST ImageStreamMapping to server
- server write two objects to etcd
to
- registry POST ImageStreamImport to server
- server GET manifest from registry
- registry GET ImageStream to prove client has access
- server write two objects to etcd
Which seems like you're doing to double latency and number of API calls
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change bypasses the quota check. How would quota be checked?
The imagestreamimport
checks the quota [1]. Also now we have a broken quota check at the time of blobs uploading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're doing to double latency and number of API calls
My change adds one read from the registry (which will induce a get API call) to the write call. But in the whole it won't double number of API calls: manifest uploading is just a part of the image uploading process, and it has other steps too (layers verification, authentication).
Also, in the old code, ImageStreamMapping is created twice (from manifest service and from tag service). If it didn't not exist yet, then it would be created for the 3rd time. In the new code, only 1 API call will be preformed.
The new code gives the registry authority for untagged manifests, and solves #9550. It allows us to upload manifest lists to the integrated registry. The integrated registry becomes just a regular docker registry, and to support new types of manifests changes will be required only on API side (which seems more elegant).
This PR removes from the integrated registry responsibility for filling DockerImageMetadata. It makes the integrated registry a step closer to not using internal pkg/image/apis/image.
And in the end, the best code is no code. We can eventually remove ImageStreamMapping from master API without loosing functionality.
But if you don't like it, you can close the PR, though.
@dmage: The following tests failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
@@ -169,7 +169,7 @@ func (s *SecretCredentialStore) init() credentialprovider.DockerKeyring { | |||
func basicCredentialsFromKeyring(keyring credentialprovider.DockerKeyring, target *url.URL) (string, string) { | |||
// TODO: compare this logic to Docker authConfig in v2 configuration | |||
var value string | |||
if len(target.Scheme) == 0 || target.Scheme == "https" { | |||
if len(target.Scheme) == 0 || target.Scheme == "https" || target.Scheme == "http" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quoting @smarterclayton from (see original comment):
We don't want to send https credentials to http endpoints. You have to explicitly say you want to send credentials to an insecure endpoint.
If this is going to change, the comment below needs to be modified or removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
credentialprovider.DockerKeyring
doesn't know anything about schemas. We are using it wrong, it works with image names, not with URLs.
} | ||
|
||
ism := imageapiv1.ImageStreamMapping{ | ||
isi := imageapiv1.ImageStreamImport{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will the image stream import work if the image isn't tagged in any image stream yet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The image is imported by the digest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The imagestreamimport requires a source repository name. What if there is no corresponding image stream yet?
To: &kapi.LocalObjectReference{Name: tag}, | ||
|
||
ImportPolicy: imageapiv1.TagImportPolicy{ | ||
Insecure: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The registry knows if it's secure or not (for managed images). And source image streams have TagImportPolicy as well - it can be inherited for external images. It's not bulletproof though.
|
||
manifest, err := m.manifests.Get(withRepository(ctx, m.repo), dgst, options...) | ||
switch err.(type) { | ||
case distribution.ErrManifestUnknownRevision: | ||
break | ||
case nil: | ||
m.repo.rememberLayersOfManifest(dgst, manifest, ref.Exact()) | ||
m.migrateManifest(withRepository(ctx, m.repo), image, dgst, manifest, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may still want to remove manifest and config from the image object.
@@ -47,38 +40,29 @@ func (m *manifestService) Exists(ctx context.Context, dgst digest.Digest) (bool, | |||
func (m *manifestService) Get(ctx context.Context, dgst digest.Digest, options ...distribution.ManifestServiceOption) (distribution.Manifest, error) { | |||
context.GetLogger(ctx).Debugf("(*manifestService).Get") | |||
|
|||
image, _, _, err := m.repo.getStoredImageOfImageStream(dgst) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This moves the status of "source of truth" from etcd to registry's storage. Is that intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it fixes #9550.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO etcd should stay as a source of truth. Deleting an image using oc delete
should prevent registry from serving it, which applies to deleting imagestreamtag or whole imagestream. Tagging the image into new image stream using oc tag
should allow registry to serve it from the corresponding repository.
Moving the source of truth from etcd to storage implies a need for one-way synchronization of storage state to etcd. We don't have that in place yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, you are right, this code has a bug. Image streams should be the source of truth for tagged manifests. Though, image streams don't contain information about untagged manifests and can't be used as a source of truth for them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though, image streams don't contain information about untagged manifests and can't be used as a source of truth for them.
Well, we don't keep the history of image presence in image streams (something like untagged images). And I don't think it's desirable since image stream is already too fat.
The rejection to serve a manifest can be determined from the absence of image reference in the image stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to get a rejection, I want to pull it back even if I don't tag it.
@dmage PR needs rebase |
Issues go stale after 90d of inactivity. Mark the issue as fresh by commenting If this issue is safe to close now please do so with /lifecycle stale |
Stale issues rot after 30d of inactivity. Mark the issue as fresh by commenting If this issue is safe to close now please do so with /lifecycle rotten |
Rotten issues close after 30d of inactivity. Reopen the issue by commenting /close |
We can decouple the integrated registry and OpenShift code if we change the process of uploading images. Instead of creating Image objects and pushing them to OpenShift, the integrated registry can ask OpenShift to import just uploaded images.
At the code level, it means using ImageStreamImport instead of ImageStreamMapping.
cc @miminar @legionus @bparees