-
Notifications
You must be signed in to change notification settings - Fork 533
Add repositoryMirrors spec to ImageContentSourcePolicy #690
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
Add repositoryMirrors spec to ImageContentSourcePolicy #690
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
@umohnani8 PTAL |
|
@QiWang19 Another impactful use case outside of disconnected environments is the use of registries that act as transparent pull-through proxy cache for upstream registries. Especially in light of some public registries introducing severe pull rate limits. |
Add MirrorByDigestOnly to RepositoryDigestMirrors. Add the mirror-by-digest-only to the ImageContentSourcePolicy, so that users can pull image from mirror with specifiy the digest if the digest is not application to their use case. API enhancement: openshift/enhancements#690 REF: https://issues.redhat.com/browse/OCPNODE-521, openshift#636 Signed-off-by: Qi Wang <[email protected]>
|
|
||
| ### Upgrade / Downgrade Strategy | ||
|
|
||
| Not applicable. Upgrades and Downgrades should not be affected. The `mirror-by-digest-only` field already exists in the `/etc/containers/registries.conf` file. We will not change current default behavior. We are just exposing this option to the user so that they can configure it through the ImageContentSourcePolicy. |
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.
Users with the new configuration who downgrade to a version that lacks support for the new feature will presumably have their CRI-O configurations clobbered and break their tag-mirroring-dependent workflows.
| - During an upgrade, we will always have skew among components, how will this impact your work? | ||
| - Does this enhancement involve coordinating behavior in the control plane and | ||
| in the kubelet? How does an n-2 kubelet without this feature available behave | ||
| when this feature is used? |
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.
Probably worth saying something about the age and stability of the mirror-by-digest-only CRI-O configuration property, to demonstrate CRI-O with n-2 OpenShift skew will still be able to handle the new property. Or maybe it's just the existing property being removed, in which case it should be even easier to make that case.
| #### Removing a deprecated feature | ||
|
|
||
| - Announce deprecation and support policy of the existing feature | ||
| - Deprecate the feature |
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.
Seems like the body of this section should be replaced with "Not applicable, because we are not deprecating any features." or similar
|
|
||
| ### Graduation Criteria | ||
|
|
||
| **Note:** *Section not required until targeted at a release.* |
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.
Looks like you have a lot of boilerplate template content in this section. If you're going to be born GA, probably just say that?
|
|
||
| Update the tests that are currently in the MCO to verify that `mirror-by-digest-only` not have been set when the ImageContentSourcePolicy is created to drop it. | ||
|
|
||
| **Note:** *Section not required until targeted at a release.* |
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 and later in this section look like template boilerplate that can be dropped.
c9d1608 to
bdff65a
Compare
|
/assign @adambkaplan |
|
@wking PTAL |
75787ea to
1dabb9d
Compare
|
@mrunalp PTAL |
| // If true, mirrors will only be used for digest pulls. Pulling images by | ||
| // tag can potentially yield different images, depending on which endpoint | ||
| // we pull from. Forcing digest-pulls for mirrors avoids that issue. | ||
| MirrorByDigestOnly bool `toml:"mirror-by-digest-only,omitempty"` |
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.
Defaulting to the unsafe false is riskier than I'd like. If this is a true boolean in registries.conf (I don't know), I'd prefer AllowTags or some such here to default safe.
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.
Isn't mirror by digest the default behavior today? If that is the case then then new API needs to be opt-in, as suggested with AllowMirrorByTags
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.
These lines of API definition is current registries.conf. Not the ImageCententSourcePolicy that this enhancement try to implement.
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.
Isn't mirror by digest the default behavior today? If that is the case then then new API needs to be opt-in, as suggested with
AllowMirrorByTags
I have updated this enhancement to add a new spec of repositoryMirrros per comment #690 (comment)
| insecure = false | ||
| ``` | ||
|
|
||
| If both `repositoryMirrors` and `repositoryDigestMirrors` are configured for same “source” repository, the ImageContentSourcePolicy will be rejected. |
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.
With a property for digest-ness under repositoryMirrors, maybe time to go v1alpha2 and drop repositoryDigestMirrors?
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.
If the repositoryDigestMirrors dropped, the digest requirement will not exist. Is it possible the customer still wants to limit the use of mirrors? This looks like a very rare case, I am not 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.
mirror-by-digest-only: true is sane, and protects you from malicious/compromised registries by forcing you to use by-digest pullspecs. But you can ask for one if those with:
apiVersion: operator.openshift.io/v1alpha2
kind: ImageContentSourcePolicy
metadata:
name: ubi8repo
spec:
repositoryMirrors:
- mirrors:
- example.io/example/ubi-minimal
source: registry.access.redhat.com/ubi8/ubi-minimal
allowMirrorByTags: false # or equivalently, by leaving allowMirrorByTags unsetwithout needing a repositoryDigestMirrors entry.
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.
With a property for digest-ness under
repositoryMirrors, maybe time to go v1alpha2 and droprepositoryDigestMirrors?
@wking How we do the API version change and the drop for repositoryDigestMirrors? Do we add the new repositoryMirrors and drop the old one at the same time in openshift/api?
Should this enhancement mention we are going to drop the repositoryDigestMirrors?
| // If true, mirrors will only be used for digest pulls. Pulling images by | ||
| // tag can potentially yield different images, depending on which endpoint | ||
| // we pull from. Forcing digest-pulls for mirrors avoids that issue. | ||
| MirrorByDigestOnly bool `toml:"mirror-by-digest-only,omitempty"` |
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.
Isn't mirror by digest the default behavior today? If that is the case then then new API needs to be opt-in, as suggested with AllowMirrorByTags
e8d6272 to
c6150fb
Compare
|
The comment has disagreements about https://issues.redhat.com/browse/RFE-1608. Adding a new spec |
c6150fb to
1f74550
Compare
|
@wking @adambkaplan PTAL. |
|
@mrunalp PTAL |
1f74550 to
2bbf6b2
Compare
2bbf6b2 to
b6a804b
Compare
|
@wking @mrunalp @adambkaplan PTAL. can we merge this enhancement? |
|
|
||
| ## Summary | ||
|
|
||
| Today, the ImageContentSourcePolicy object sets up mirror with `mirror-by-digest-only` property set to true. Requires images be pulled by digest only. This enhancement plans to add new spec to ImageContentSourcePolicy with configurable field `allowMirrorByTags`, so that mirror-by-digest-only` can be configured by ImageContentSourcePolicy. |
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.
nit: unbalanced backticks around the second mirror-by-digest-only.
Request for enhancement: https://issues.redhat.com/browse/RFE-1608 Epic: https://issues.redhat.com/browse/OCPNODE-521 Ref: openshift/api#636 Registry mirror set by ImageContentSourcePolicy registryDigestMirrors only will be used if the image is referenced by digest because the mirror-by-digest of /etc/containers/registries.conf is set to true. This causes issue since there are use cases where no digests are available. In ImageContentSourcePolicy, add repositoryMirrors spec, so user can easily configure it in the same spot they set post-installation mirror configuration. Signed-off-by: Qi Wang <[email protected]>
b6a804b to
d716c68
Compare
|
/lgtm We can fix the nits in follow-on PRs. |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mrunalp The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Epic: https://issues.redhat.com/browse/OCPNODE-521 Follow up PR for openshift#690 Update the Removing a deprecated feature part of the enhancement. Explain that the new ICSP will be added to v1 with the new field repositoryMirrors added. Signed-off-by: Qi Wang <[email protected]>
| // tag can potentially yield different images, depending on which endpoint | ||
| // we pull from. Forcing digest-pulls for mirrors avoids that issue. | ||
| // +optional | ||
| AllowMirrorByTags bool `json:"allowMirrorByTags"` |
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.
Why is this necessary? If I want digest only mirroring, I would already just use RepositoryDigestMirrors. Why would I ever use RepositoryMirrors with this false?
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.
Another reason this is a problematic design, the order of precedence for digest mirrors and tag mirrors provides wildly different behavior. We specifically specced RepositoryDigestMirrors to provide ordering, including putting source at the lowest priority. That does not work for tag users - for a tag user, source is generally prefered. So already this is missing one of the key distinctions between a desgin focused on ensuring users get the right content to a "users may get the wrong behavior".
So I probably don't think that these should be represenetd in a single struct.
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.
If I want digest only mirroring, I would already just use RepositoryDigestMirrors.
Having one set of mirrors where both tags and digests are allowed and another set where only digests are allowed seemed redundant, so I'd suggested (or maybe Miloslav did 🤷) the new slice allow for both. Argument about different priorities sounds... like it needs more detail. But say you prefer registry B over registry A, because B is closer. But A is more canonical, so is likely to have more current tags. Hopefully the latency in tag-mirroring from A -> B isn't too bad, but it's possible there's significant delay because it requires manual steps. However, if you're comfortable falling back to B's tag, when you can't reach A, you risk rollbacks like:
- v1 content pushed to
some-tagon A. - v1 content mirrored to
some-tagon B. - v2 content pushed to
some-tagon A. - Cluster can reach A, pulls v2 content from
some-tag. - Workload drained off the node; rescheduled elsewhere. Or drained and uses
Alwayspull policy, or whatever. - Cluster tries to reach A, but network hiccup, so it fails.
- Cluster falls back to B, pulls v1 content from
some-tag. - Workload mysteriously regresses from v2 to v1.
Now, if you have multiple mirrors B, C, ..., there's no reason that B would always have newer content than C. And maybe you have flows where v2 has bin mirrored to B, but then someone rolls back to v1 for the tag on A. It's all a big mess that's hard to reason about generically (by-digest pullspecs for the win). Is the argument for by-tag-specific mirror ordering that "no generic reason, but admin Alice knows that for her cluster there will be no rollbacks on A, and B will always lag, but never lead, in promotion for all tags covered by this mirroring stanza"?
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 the general assumption for allowing tag references in mirrors is that this would just never happen; tags must be immutable (e.g. v1.2.3, as opposed to a floating latest or v1).
I don’t see that there’s any way to achieve consistency if we assume all of:
- Workloads are defined by tags and tags are looked up by individual nodes, not resolved into digests at a single authoritative point (e.g. when a Deployment creates a ReplicaSet)
- The same tag can point to different images over time
- Different mirrors of the same repo can get out of sync about what image the tag points to
- Mirrors can become unreachable over time.
3. and 4. are AFAICS always true in practice, 1. seems to be true as well (I can’t find a single non-test reference to Image in openshift/kubernetes/pkg/controller, at least); so the only “give” is 2. [Actually, 3. and 4. is not even relevant, 2. is sufficient even for non-mirrored single-registry clusters: if a Deployment refers to a tag, and the tag changes in the middle of a rollout, half of the replicas is going to be on v1 and half on v2, isn’t it?]
I don’t see that worrying about the priority of tag resolution between mirrors helps. Tags must not move, and if they do, it’s (given current workload controllers AFAICS), a user error that can’t be fixed by mirror priority,
| // RepositoryMirrors holds cluster-wide information about how to handle mirrors in the registries config. | ||
| // Note: this is different from the RepositoryDigestMirrors that the mirrors only | ||
| // work when pulling the images that are referenced by their digests. | ||
| type RepositoryMirrors struct { |
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.
If a source is already defined with RepositoryDigestMirrors, by definition it ignores tags. So this section implies "we will be mirroring tags", since digests are already covered.
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 the overall idea was to replace v1alpha1.RepositoryDigestMirrors with v1.RepositoryMirrors which includes the allowMirrorByTags boolean; RepositoryMirrors was not intended to define an exclusive tag-only mirror configuration.
Originally the CR had a RepositoryDigestMirrors with a allowMirrorByTags boolean, which is a confusing naming, so I proposed renaming to just RepositoryMirrors which fits both.
Not having the allowMirrorByTags boolean, and instead defining separate RepositoryDigestMirrors and RepositoryTagMirrors is certainly an option. A difference is that with two separate arrays, it’s not possible to create a CR that says “Here’s a mirror, use it, I am not defining a tag/digest policy for how it’s used” (which I imagine a mirror-maintenance/replication operator might want to do, but that’s pure speculation).
|
|
||
| #### Removing a deprecated feature | ||
|
|
||
| - With `repositoryMirrors` getting in, the current `repositoryDigestMirrors` can be deprecated since its functionality will also be fully satisfied by `repositoryMirrors` and we don't have to keep duplicated APIs. |
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 isn't a very strong argument, changing behavior without understanding the difference in behavior is a bug.
So I would probably put a hold on this feature with this as is without stronger justification.
| ### Upgrade / Downgrade Strategy | ||
|
|
||
| Upgrades should not be affect. But the downgrade will be affected. | ||
| Users upgraded and configured the `repositoryMirrors` spec will presumably have their CRI-O configurations clobbered and break their tag-mirroring-dependent workflows after they downgrade to a version that lacks support for the `repositoryMirrors` spec. |
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.
In a single version, during an upgrade, both new and old api versions should be ready and transformed into crio config. After a release has gone by, the old version can be removed. The flow described here doesn't meet our historical guarantees for upgrade.
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.
In fact, the better approach is to simply read the old objects as long as their are available, then read new objects, and the merge order is that the behavior provided by the old object is honored as long as old objects are described.
| AllowMirrorByTags bool `json:"allowMirrorByTags"` | ||
| // mirrors is one or more repositories that may also contain the same images. | ||
| // The order of mirrors in this list is treated as the user's desired priority, while source | ||
| // is by default considered lower priority than all mirrors. Other cluster configuration, |
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.
Specifically "source being last" only makes sense for digest, it DOES not make sense for tag in all use cases. Tag is fundamentally dependent on hoping you get the most up to date version of a tag during upgrade scenarios.
Both image stream import and crio can use repository digest order consistently. However, I'm not sure without an understanding of image import tag mirroring what we do here.
Is there another enhancement that covers ImageStream import behavior with repository tag design? We should not be introducing a V1 api without a full design covering how import will interpret this, because mirroring of tags may actually need these fields to be designed. If there is no additional design, I'd like to see one before I withdraw my hold on the implementation.
| - example.io/example/ubi-minimal | ||
| source: registry.access.redhat.com/ubi8/ubi-minimal | ||
| allowMirrorByTags: false # or equivalently, by leaving allowMirrorByTags unset | ||
| ``` |
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.
Expect to see a section here describing how to compose RepositoryMirrors of type digest and non-digest. Also, expect to see a defined order of composition for order (so that different nodes have consistent orders).
Finally, there is a missing section here on the security implications of repository tag mirroring - tag mirroring allows anyone who can craft a source ICSP to hijack all workloads, which existing digest mirroring does not. So right there that may point to the need to define a separate object with clearly differentiated security characteristics.
Digest mirroring has some attack vectors (for instance, someone could define a bunch of useless mirrors that return error continuously), but tag mirroring could allow escalation.
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 would probably recommend defining composition of mirrors in name order (ICSP A mirrors go before ICSP B mirrors)
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 v1alpha1 behavior is, when composing mirrors for the same repo, to honor the relative ordering if possible (and a stable, but unspecified, handling of ordering loops).
E.g. ICSP1: source -> A,B; ICSP2: source -> B,C is defined to compose to A,B,C, in that order.
Request for enhancement: https://issues.redhat.com/browse/RFE-1608
Epic: https://issues.redhat.com/browse/OCPNODE-521
Ref: openshift/api#636
Registry mirror set by ImageContentSourcePolicy only will be used if the image
is referenced by digest because the mirror-by-digest of /etc/containers/registries.conf is set to true.
This causes issue since there are use cases where no digests are available.
In ImageContentSourcePolicy, add repositoryMirrors spec, so user can
easily configure it in the same spot they set post-installation mirror configuration.
Signed-off-by: Qi Wang [email protected]