Skip to content

Conversation

@umohnani8
Copy link
Contributor

@umohnani8 umohnani8 commented Jun 17, 2019

Adding a new operator/v1alpha1 definition caled ImageContentSourcePolicy
which will be used when using a CR to set the registry mirror rules
for resiliency and offline installs/upgrades.
A new CRD will be created to encompass this.

Signed-off-by: Urvashi Mohnani [email protected]

@openshift-ci-robot openshift-ci-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jun 17, 2019
@umohnani8
Copy link
Contributor Author

@mrunalp @abhinavdahiya @mtrmac PTAL

@abhinavdahiya
Copy link
Contributor

Talking with @smarterclayton it seemed like we don't want to add this API object to config/v1 as that has very high guarantee ..

Why not it to mirror.openshift.io v1alpha1 or v1beta1 ?

@umohnani8
Copy link
Contributor Author

@abhinavdahiya should I rename the CRD to mirror then as well? Also where is v1alpha1 or v1beta1 in openshift/api? I see a v1alpha1 for operator, so should I create a new directory mirror/v1alpha1 and add this there?

}

type ImageContentSourcePolicySpec struct {
// DigestMappingRules holds the registry mirroring rules that are written to
Copy link
Member

Choose a reason for hiding this comment

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

We can add a line saying that we only support pulling by digests from the mirrors and hence the name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@abhinavdahiya
Copy link
Contributor

@abhinavdahiya should I rename the CRD to mirror then as well? Also where is v1alpha1 or v1beta1 in openshift/api? I see a v1alpha1 for operator, so should I create a new directory mirror/v1alpha1 and add this there?

I think just moving this type to a new directorymirror/v1beta1 should be sufficient.
also add mirror:v1beta1 to https://github.com/openshift/api/blob/master/hack/update-deepcopy.sh#L13

@smarterclayton
Copy link
Contributor

smarterclayton commented Jun 19, 2019 via email

@abhinavdahiya
Copy link
Contributor

Or operators.openshift.io (which is our private api) in v1alpha1?

+1 for operators/v1apha1


// DigestMappingRules holds cluster-wide information about how to handle mirros in the registries config.
type DigestMappingRules struct {
// Sources are registries that are mirrors of each other.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this say “registries and/or repositories [(depending on the container runtime)]”, or something like that? (Per earlier conversations, CRI-O will support this at the level of individual repositories, and containerd could support this at registry level.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

}

type ImageContentSourcePolicySpec struct {
// DigestMappingRules holds the registry mirroring rules that are written to
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to document this as a general-purpose facility, or specifically restricted to OpenShift product images? It works just the same for both for unauthenticated registries, but we can only supply mirror credentials via a CRI-O-wide option (not via the CRI). Or maybe we don’t need to restrict this to OpenShift only, but say that non-OpenShift repositories that require credentials are {problematic,not recommended,not supported}.

// DigestMappingRules holds the registry mirroring rules that are written to
// /etc/containers/registries.conf to be used by the runtime to determine which
// repo to fall back on, if the original repo cannot be accessed.
// Will also be used for offline installs/upgrades.
Copy link
Contributor

@abhinavdahiya abhinavdahiya Jun 19, 2019

Choose a reason for hiding this comment

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

I think this should be changed to for example,

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@adambkaplan
Copy link
Contributor

Will the openshift apiserver need to consume this for image pullthrough?
Similarly will builds and imagestreams need to consume this for image references?

fyi @dmage

@dmage
Copy link
Contributor

dmage commented Jun 20, 2019

How will it be coordinated with

api/image/v1/types.go

Lines 241 to 253 in a77179b

// TagReferencePolicyType describes how pull-specs for images in an image stream tag are generated when
// image change triggers are fired.
type TagReferencePolicyType string
const (
// SourceTagReferencePolicy indicates the image's original location should be used when the image stream tag
// is resolved into other resources (builds and deployment configurations).
SourceTagReferencePolicy TagReferencePolicyType = "Source"
// LocalTagReferencePolicy indicates the image should prefer to pull via the local integrated registry,
// falling back to the remote location if the integrated registry has not been configured. The reference will
// use the internal DNS name or registry service IP.
LocalTagReferencePolicy TagReferencePolicyType = "Local"
)
?

@umohnani8 umohnani8 changed the title Add ImageContentSourcePolicy to config/v1 Add ImageContentSourcePolicy to operator/v1alpha1 Jun 20, 2019
@umohnani8
Copy link
Contributor Author

umohnani8 commented Jun 20, 2019

@abhinavdahiya @smarterclayton moved it to operator/v1alpha1

@abhinavdahiya
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jun 20, 2019
// We only support pulling by digests for mirrors, hence the name.
// Will also be used in cases such as offline installs/upgrades.
// +optional
DigestMappingRules DigestMappingRules `json:"digestMappingRules"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Other possible names repositoryDigestMappings

Copy link
Contributor

Choose a reason for hiding this comment

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

imageDigestMappings. imageDigestRetrieval.

Copy link
Contributor

@mtrmac mtrmac Jun 20, 2019

Choose a reason for hiding this comment

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

(To me as a non-native speaker), all of these names seem to say that digests are mapped, but they are not; digests are the only part of the image reference that don’t change.

mirroredRepositories, mirrorSets? OTOH to ensure that the digest restriction is not overlooked, that could end up with mirrorredRepositoriesInDigestReferences or something similarly horrible.

Copy link
Contributor Author

@umohnani8 umohnani8 Jun 21, 2019

Choose a reason for hiding this comment

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

Changed it to MirrorReposForDigests

Copy link
Contributor

Choose a reason for hiding this comment

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

For digests is probably not accurate - you're not mirroring for digests, your mirroring digests by mirrors. We generally do not use short names inside api objects (reference instead of ref, for example).

Copy link
Contributor

Choose a reason for hiding this comment

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

(I don’t really want to restart the naming discussion for this field, the current name is acceptable and I don’t think we’ll get a perfect one, just to minimize the use of this figure of speech:

We are never “mirroring digests”, we may not be mirroring [complete] repositories, we are mirroring OpenShift releases = sets of individual container images.


// DigestMappingRules holds cluster-wide information about how to handle mirros in the registries config.
type DigestMappingRules struct {
// Sources are registries and/or repositories depending on the container runtime
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we/should we document that these must be repositories (a.com/b/c) to start with, before we support wildcards in the future?

Copy link
Contributor

Choose a reason for hiding this comment

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

In the current implementation, there are no wildcards. There are hierarchical namespaces, i.e. you can say example.com to match example.com/*/…/*, or you can say example.com/mirror-of-red-hat to match example.com/mirror-of-red-hat/*/…/* including example.com/mirror-of-redhat/openshift.

There isn’t a way to express example.com/*/mirror-of-red-hat, and I hope we won’t need that. Do we need that?

Copy link
Contributor

Choose a reason for hiding this comment

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

I mean, I don't even want to support example.com from this API for now. So I would prefer to explicitly exclude that until we need it.

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ImageContentSourcePolicy holds cluster-wide information about how to handle registry mirror rules. The canonical name is `cluster`
type ImageContentSourcePolicy struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

Any other possible names we could use? Policy is fairly common. Is content source the best name? I don't want to be specific about "mirroring" or "disconnected", so trying out a name that implies "you can change where we source images" was the initial argument.

Maybe future might be "you have to have signatures from X for Y"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just ImageContentSource or ImageSources?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it to ImageContentSource

Copy link
Contributor

Choose a reason for hiding this comment

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

By "policy is fairly common" I meant "It's good to have Policy in there to distinguish this from a more concrete object". I don't think you have to change the name, just want to see some suggestions about what names could be that better describe what this object does.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed the name back

Copy link
Contributor

Choose a reason for hiding this comment

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

You’re right that “content source” is not a commonly used term for this. I’d just say one of “image {repositories,locations,(servers,storage?)}”; the “content” word adds nothing.


Per #354 (comment):

Do we want to document this as a general-purpose facility, or specifically restricted to OpenShift product images?

do we want this to be generic for all kinds of images, or actually say something entirely specific to the contemplated use, in the ballpark of OpenShiftReleasedImageLocations?

Copy link
Member

Choose a reason for hiding this comment

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

I think making it generic will allow us to reuse it for other use cases in the future.

Copy link
Contributor

Choose a reason for hiding this comment

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

The resource group usually contains the product namespace (operator.openshift.io) so it is redundant in the title.

@openshift-ci-robot openshift-ci-robot removed the lgtm Indicates that a PR is ready to be merged. label Jun 21, 2019
@umohnani8
Copy link
Contributor Author

@abhinavdahiya @smarterclayton fixed up based on reviews, PTAL

@abhinavdahiya
Copy link
Contributor

/lgtm

@umohnani8
Copy link
Contributor Author

@smarterclayton @abhinavdahiya comments addressed, PTAL.

@abhinavdahiya
Copy link
Contributor

@smarterclayton @abhinavdahiya comments addressed, PTAL.

/lgtm :)

type ImageContentSourcePolicySpec struct {
// repositoryDigestMirrors allows images referneced by image digests in pods to be
// pulled from alternative mirrored repository locations. The image pull specification
// provided to the pod will be compare to the source locations described in RepositoryDigestMirrors
Copy link
Member

Choose a reason for hiding this comment

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

s/compare/compared/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@umohnani8
Copy link
Contributor Author

@abhinavdahiya @smarterclayton @mrunalp addressed the comments. If we are good with this, can we get it in.

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ImageContentSourcePolicy holds cluster-wide information about how to handle registry mirror rules.
// The canonical name is `cluster`
Copy link
Contributor

@smarterclayton smarterclayton Jun 25, 2019

Choose a reason for hiding this comment

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

There should be no canonical name for this - clients may create multiple of these, it is not a singleton. We want individual components to be able to register their policies and manage them independently (trying to join a bunch of policies in a doc is very difficult to do with decelerate config models). That means that we have to define how merging happens, which should be done in the godoc for each field (repositoryDigestMirrors)

Please change the doc to "When multiple policies are defined, the outcome of the behavior is defined on each field". For the repositoryDigestMirrors field, add a sentence defining how this will work.

For instance, if I have

sources:
- a
- b
- c

in one object (provided by the installer) and

sources:
- c
- d
- e

in a second (provided by an operator)

we need to define how they are merged (probably by a zip merge with duplicates removed - a c b d e, although we can be loose about the ordering).

Copy link
Contributor

Choose a reason for hiding this comment

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

Keep in mind the use cases we're trying to target when you consider merging:

  1. operator on cluster potentially inserts the local registry as a targeted mirror (which probably means it wants to go first)
  2. OLM in the future may manage these objects, so it'll be adding them post-install

Copy link
Contributor Author

@umohnani8 umohnani8 Jun 25, 2019

Choose a reason for hiding this comment

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

Merged as in when we write these mirror rules to /etc/containers/registries.conf?

Copy link
Contributor

Choose a reason for hiding this comment

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

Merged as when they are written and interpreted by all consumers (whether it's registries.conf today, or a future image controller use case like image import). Documenting the rules of merging makes it clear to consumers and helps clarify the design of components

Copy link
Member

@mrunalp mrunalp Jun 25, 2019

Choose a reason for hiding this comment

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

As a counter, does it make sense to disallow having common repos between each config object? That way the administrator can be explicit in how they want the repos ordered.

Copy link
Member

Choose a reason for hiding this comment

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

I am thinking of a case where one user of the feature creates an ordering and then a second user comes up with an ordering that has the elements reversed. It might be better to just disallow so they can communicate with first user and come up with a commonly agreed ordering for the repos.

Copy link
Contributor

Choose a reason for hiding this comment

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

I find it a bit attractive to make all of this undefined (explicitly, if necessary).

Let the user declaratively define that some set of repositories is equivalent; let the cluster worry about checking whether they are up, ordering them, possibly load balancing between them, … . Sure, we do nothing of that kind now, but if we define the mirror set to have some kind of strict ordering and strict merging semantics, we’ll lose the opportunity to do something smart in the future (without an explicit opt-in, at least).

I’m especially dubious about the idea of transitively merging mirror sets; sure, it’s trivial to implement, but intuitively it seems to me that if something creates two mirror sets that have a common element but are otherwise distinct (neither a subset of the other), it’s more likely than not that something got very confused and the mirrors are not actually operated to be transitively equivalent that way.


Or is the idea that the OpenShift product will ship, and manage, a CRD object that claims the equivalence of r.a.rh.com/foo with r.rh.io/bar (and OpenShift the organization will commit to keeping the repositories in sync), while the local administrator will set up, and manage, the equivalence of r.a.rh.com/$foo with local-mirror.example.com/baz (and commit to keeping the two repositories in sync), and therefore we need merging to exist because we don’t want the administrator to edit the OpenShift-product-managed object?

If that is the case, does the administrator need to be able to say “only ever use my mirror without reaching to the internet at all”? That can only work if we define the order of accesses both within a mirror set, and between all the CRD objects (how? based on their name?). (And without an explicit “don’t use those mirrors at all”, the administrator can only put them at the end of the list, to be never contacted unless the local mirror is down. That seems good enough for me, at least in the initial version of this object; registries.conf can express “redirect all references to foo to bar without ever contacting foo”, but we’ll have enough trouble defining the semantics of merging of the ordering without having to worry about three CRD objects, setting up strict redirects of A→B, B→C, B→A.)

(Or, sure, we could leave the internet-accessible mirrors in and accept them being in the first locations, and just let pulls fail because the DNS or firewall rejects the connection attempts. It could easily be fast enough, but it will cause noise on the firewalls.)


(FWIW openshift/machine-config-operator#805 currently sets up the mirrors in registries.conf in a rotated fashion, so that different pull specs will result in different order of attempts. That’s just an initial guess, and there’s nothing at all to say that it matters because the pull specs from the different mirrors should not really exist in the cluster at the same time, it can of course be changed to any other semantics.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Or is the idea that the OpenShift product will ship, and manage, a CRD object that claims the equivalence of r.a.rh.com/foo with r.rh.io/bar (and OpenShift the organization will commit to keeping the repositories in sync),

this is the most likely near term. The most likely case will be r.rh.io/* to registry.internal.svc/x/y for digest mirroring of core public resources.

I’m especially dubious about the idea of transitively merging mirror sets; sure, it’s trivial to implement, but intuitively it seems to me that if something creates two mirror sets that have a common element but are otherwise distinct (neither a subset of the other), it’s more likely than not that something got very confused and the mirrors are not actually operated to be transitively equivalent that way.

Since we're pulling by digest the only expense is check time (which agree can be left as weakly undefined behavior). If you say A and B are candidates for pull by digest and B and C are candidates by digest and A and B are down I would prefer to check C (this feature is about availability first, performance / local pulls second).

I am not opposed to leaving it weakly undefined, but it needs to satisfy the intent.

As far as order, I would prefer that we preserve preferential rather than round robin, the requirements for this feature are to let you preferentially use a local proxy for performance, and round robin does not satisfy that.

Adding a new operator/v1alpha1 definition caled ImageContentSource
which will be used when using a CR to set the registry mirror rules
for resiliency and offline installs/upgrades.
A new CRD will be created to encompass this.

Signed-off-by: Urvashi Mohnani <[email protected]>
@umohnani8
Copy link
Contributor Author

@abhinavdahiya @smarterclayton can we please get this in so we can continue the work that is relying on this. We can figure out the merging criteria later if that is okay? It would just be a PR to update the comments here.

// When multiple policies are defined, any overlaps found will be merged together when the mirror
// rules are written to `/etc/containers/registries.conf`. For example, if policy A has sources `a, b, c`
// and policy B has sources `c, d, e`. Then the mirror rule written to `registries.conf` will be `a, b, c, d, e`
// where the duplicate `c` is removed.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment is fine for now, I'm ok with discussing the policy in a follow up before 4.2 GA but after this feature has been prototyped.

@smarterclayton
Copy link
Contributor

Sufficient for first round of prototyping (with the known topics still to be resolved for 4.2)

/lgtm
/approve

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Jun 26, 2019
@openshift-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: abhinavdahiya, smarterclayton, umohnani8

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants