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

Kustomize Resource Ordering Proposal #865

Closed
wants to merge 2 commits into from

Conversation

pwittrock
Copy link
Member

@pwittrock pwittrock commented Mar 1, 2019

Proposal to address

kubernetes-sigs/kustomize#836

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Mar 1, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: pwittrock

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

The pull request process is described here

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

@k8s-ci-robot k8s-ci-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. kind/kep Categorizes KEP tracking issues and PRs modifying the KEP directory sig/cli Categorizes an issue or PR as relevant to SIG CLI. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Mar 1, 2019
@pwittrock
Copy link
Member Author

pwittrock commented Mar 1, 2019

/assign @monopole

@pwittrock pwittrock requested review from apelisse and anguslees and removed request for seans3 March 1, 2019 19:24
@pwittrock pwittrock added the help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. label Mar 1, 2019
@pwittrock pwittrock removed the request for review from soltysh March 1, 2019 19:26
@pwittrock
Copy link
Member Author

cc @donbowman


Kustomize orders Resource creation by sorting the Resources it emits based off their type. While
this works well for most types (e.g. create Namespaces before other things), it doesn't work
in all cases and users will need the ability to break glass.
Copy link
Member

@apelisse apelisse Mar 1, 2019

Choose a reason for hiding this comment

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

I can guess why, but it's not obvious when this ordering becomes problematic and when you can't rely on type ordering anymore (or at least an example would be useful)

Copy link
Member Author

Choose a reason for hiding this comment

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

Did you look at the example in the motivation?

Copy link
Member

Choose a reason for hiding this comment

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

You mean in the body of the PR, not in that KEP right?

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you replace "break glass" with a more direct but short mention of using labels and annotaitons?

Also, can we just get by with one or the other at the outset? I.e. ship label-based ordering then add annos if someone asks for it (or vice versa)

Copy link
Member

Choose a reason for hiding this comment

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

Also, can we just get by with one or the other at the outset? I.e. ship label-based ordering then add annos if someone asks for it (or vice versa)

I like this idea, I think it's fine to be opinionated. You could almost enforce a specific annotation and have kustomize remove it. Giving people the chance to use any label/annotation is maybe not restrictive enough, as they will be able to build arbitrary complex things with a poor semantic (noted in "risk & mitigation", I know), but I think we could help them by making a reasonable decision on what annotations to use (e.g. I know you won't like it: kustomize.io-order-priority: X).

Alternative solutions:
I don't know if the order should be in each object (more implicit, and less coupled) or in the kustomize file directly (stronger coupling, more explicit).
You could also build something like an "edge"/graph based solution, e.g. this object before that one, or this after that.


### Goals

- Provide the ability for users to break glass and override Kustomize's sort ordering.
Copy link
Member

Choose a reason for hiding this comment

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

See, I didn't even realized that kubectl had to apply the resources in the order they are received. Kubectl could also parallelize the requests to make order "less important". A lot of this is still going to be flaky because it has to assume that the resources will be created "within time-limit" (not just in-order), since we're talking about an asynchronous system here.

Copy link
Member Author

@pwittrock pwittrock Mar 1, 2019

Choose a reason for hiding this comment

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

Resource Creation and Resource Actuation are different things. This is concerned only with the former, which will be serial.

@donbowman
Copy link

OK so in my original example the 'order dependent' bits, and their needed order, are:

  • Namespace
  • Namespace label
  • ValidatingWebhookConfiguration
  • CRD

So with the above proposal, I can achieve this by adding these lines to the base kustomization.yaml:

resourceOrdering:
- type: label
  key: MyBeautifulOrder
  value: 1
- type: label
  key: MyBeautifulOrder
  value: 2
- type: label
  key: MyBeautifulOrder
  value: 3

And then in my config I would have:

---
apiVersion: v1
kind: Namespace
metadata:
  name: dev-fluent-bit
  labels:
    mylabel: value
    MyBeautifulOrder: 1
---
apiVersion: v1
kind: ValidatingWebhookConfiguration
metadata:
  name: MyVWC
  labels:
    MyBeautifulOrder: 2
---
apiVersion: v2
kind: CustomResourceDefinition
metadata:
  name: MyCRD
  labels:
    MyBeautifulOrder: 3

So...

Do i think it fixes? Yes.
Is it relatively idiot proof? Yes
Is it relatively convenient to do? Yes. Its a bit of a PITA since i end up with a label in the 'runtime' that really only relates to the 'build time', but I can live w/ that.

It leaves the question of... when i'm doing a delete, I may want the opposite order, would we have a --reverse flag to specify reversing the order?

@apelisse
Copy link
Member

apelisse commented Mar 1, 2019

It leaves the question of... when i'm doing a delete, I may want the opposite order, would we have a --reverse flag to specify reversing the order?

If you're running kubectl delete -k ..., then it could automatically delete in the reverse order?

@pwittrock
Copy link
Member Author

@donbowman There are a couple of ideas being kicked around for delete. I think this will align with at least one of them - using annotations.

One of the deletion proposals is to leave the resource and annotate with something special like kubectl.k8s.io/delete=true. The approach here would allow you to control the deletion order using the same mechanism.

Copy link
Contributor

@monopole monopole left a comment

Choose a reason for hiding this comment

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

Thanks!


## Docs

Update Kubectl Book and Kustomize Documentation
Copy link
Contributor

Choose a reason for hiding this comment

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

+1

- [ ] Having multiple labels / annotations with different keys and the same values works correctly
- [ ] Mixing labels and annotations works
- [ ] Unrecognized type values throw and error
- [ ] Resources that don't appear in the ordering overrides appear last and are sorted by type
Copy link
Contributor

Choose a reason for hiding this comment

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

Well, that will be one of the most thoroughly tested features we have, thanks!

The place to most of these is perhaps in pkg/target (see any test file in there).


Kustomize orders Resource creation by sorting the Resources it emits based off their type. While
this works well for most types (e.g. create Namespaces before other things), it doesn't work
in all cases and users will need the ability to break glass.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you replace "break glass" with a more direct but short mention of using labels and annotaitons?

Also, can we just get by with one or the other at the outset? I.e. ship label-based ordering then add annos if someone asks for it (or vice versa)

@pwittrock
Copy link
Member Author

Also, can we just get by with one or the other at the outset? I.e. ship label-based ordering then add annos if someone asks for it (or vice versa)

Yes I think so. Probably start with annotations as we have been discussing using them to configure kubectl apply behavior (e.g. deletions, cluster targeting, etc)

@pwittrock
Copy link
Member Author

Simplified the API a bit. PTAL.


## Motivation

Users may need direct control of the Resource create / update / delete ordering in cases were
Copy link
Member

Choose a reason for hiding this comment

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

The ordering for each of those operations may not always be the same


## Implementation History

## Alternatives
Copy link
Member

Choose a reason for hiding this comment

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

Please include a discussion of at least some alternatives, otherwise what's the point of the KEP?
(If there is only one possible option, then there is no need for a KEP doc. If there are alternatives, then better to have the rationale for selecting this particular approach expounded by the original authors)

In particular for this doc: The obvious alternative that I think needs to be considered is just process the resources in original document order. This is presumably the order intended by the upstream manifest author (since this is kubectl's behaviour). We would need a bit of explanation for the kustomize corner cases like newly-inserted resources, and when multiple upstreams are merged (conceivably any order that preserves the original separtae document order(s) is fine here).

Copy link
Member Author

Choose a reason for hiding this comment

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

Please include a discussion of at least some alternatives, otherwise what's the point of the KEP?

To get other community members to come up with alternatives :)

Copy link
Member Author

Choose a reason for hiding this comment

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

The obvious alternative that I think needs to be considered is just process the resources in original document order

Would this be mutually exclusive with the sorted order, so users would need to manually put CRDs first, etc?

Copy link
Member

Choose a reason for hiding this comment

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

Would this be mutually exclusive with the sorted order

I don't understand... Obviously you can't primary-sort by both document order and some other (eg: type-based) order.

users would need to manually put CRDs first, etc?

Yes, "document order" assumes that the user (or some other tool) has appropriately sorted the resources in the input document. Again: kubectl works in document order, so this is already quite a common workaround/technique.

@anguslees
Copy link
Member

anguslees commented Mar 5, 2019

Fwiw, the create/update sort order in kubecfg is:

  • CRD/TPR first (special case)
  • all non-namespaced resources
  • all resources that don't fit somewhere else
  • all resources that contain a PodSpec
  • (to be done) webhooks last (special case)

'delete' reverses that order. In practice there's a secondary alphabetic sort within those tiers, just for output stability.

That's obviously not a "break glass" approach, but it has worked very well so far and seems to have been more robust than the hard-coded lists used by helm and kustomize. Just mentioning it here, because I think this is the only reflection-based sort heuristic I've seen in use in k8s tools.

@pwittrock
Copy link
Member Author

@anguslees Would the order you described address the issue linked in the PR?

@pwittrock
Copy link
Member Author

'delete' reverses that order.

How does kubecfg perform deletions?

Provide a simple mechanism allowing users to override the order that
Resource operations are Applied. Add a new field `sortOrder` that is
a list of `ResourceSelector`s which match Resources based
off their annotations.
Copy link
Contributor

Choose a reason for hiding this comment

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

Within one kustomization target, I think this solves the ordering problem. I'd like to see explanations or examples covering bases and overlays. Given an overlay composed from multiple bases. Does the order from each base get inherited in overlays? What if I want resources from one base to be prior to resources from another base?

Copy link
Member

Choose a reason for hiding this comment

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

Good point, what about conflicting orderings (cycles)

everything that the second selector does, and it will have no effect.

```
sortOrder:
Copy link
Contributor

Choose a reason for hiding this comment

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

How about generating the output in the same order as they are listed in resources. If one resource file containing multiple resource configs, keep their original order? Moreover, keep the order of bases.
In Kustomization.yaml, we can add one field to switch to this behavior:

keepOriginalOrder: true

@anguslees
Copy link
Member

anguslees commented Mar 12, 2019

(I don't want this to be about kubecfg, and I'm happy to follow this up in some other forum)

@anguslees Would the order you described address the issue linked in the PR?

Yes, I think so - although the bug is a bit difficult to dissect and contains a number of inaccurate/overspecified requirements (iiuc).

I think the original issue is that (after kustomize re-sorting) the ValidatingWebhook is declared before the Deployment, etc that implements the Webhook. Then a resource is created that triggers the Webhook, and the apiserver rejects the creation, because the webhook isn't ready yet (and the WebhookConfiguration has failurePolicy=Fail).

There are numerous changes that would satisfy the original issue:

  • Sort WebhookConfiguration declarations after Deployment (ie: the opposite of Capture and iterate on KEP template feedback #822). The "kubecfg order" I described above would also do this.
  • Preserve original document order
  • Change cert-manager upstream to use failurePolicy=Ignore

How does kubecfg perform deletions?

It has a garbage collection mechanism that determines what is eligible for deletion. To actually perform the deletions, it just sorts in the reverse creation order, and calls client-go Delete() on each in turn.

@pwittrock
Copy link
Member Author

@anguslees

Thanks for the comments. Not sure what the best next steps are. IMHO, GC is more urgent and critical than this issue. I opened the KEP because a user mentioned it as a problem, but it can be worked around by creating separate kustomization.yamls and applying them separately.

Trying to solve whether or not one resource is ready before another does not seem like a problem that should be solved at this layer (i.e. in kubectl or kustomize)

@anguslees
Copy link
Member

anguslees commented Mar 13, 2019

... but it can be worked around by creating separate kustomization.yamls and applying them separately.
Trying to solve whether or not one resource is ready before another does not seem like a problem that should be solved at this layer (i.e. in kubectl or kustomize)

I'm still confused why we haven't discussed "preserve document order" anywhere here (with some hand-waving around resources that are newly introduced by kustomize (configmap/secret generators)).

At the moment, applying an empty kustomize file to an existing kubectl input file makes things worse, and that seems like something we could at least fix, even if we want to punt on the actually-hard cases for now.

@pwittrock
Copy link
Member Author

I'm still confused why we haven't discussed "preserve document order" anywhere here

Generally I have concerns about this solution. A simple refactoring of configs, or sorting the resources alphabetically would break this. I don't think this is a solution we would want to recommend, but might be ok as a break glass feature for users that are ok with the risks it introduces.

@apelisse
Copy link
Member

Generally I have concerns about this solution. A simple refactoring of configs, or sorting the resources alphabetically would break this. I don't think this is a solution we would want to recommend, but might be ok as a break glass feature for users that are ok with the risks it introduces.

Agreed, it's very implicit and fragile.

@pwittrock
Copy link
Member Author

@anguslees @donbowman

I'd like to see someone from the community drive this (and hopefully implement it). I think we have a good conversation started here for someone from the community to pick up and incorporate the feedback. Plan on closing this to make room for others to step up.

@pwittrock
Copy link
Member Author

Closing so that someone else can take lead on this.

@pwittrock pwittrock closed this Mar 14, 2019
@anguslees
Copy link
Member

Agreed, it's very implicit and fragile.

Sure, I'm not claiming it's great and that we can't do better. This (document order) is the way kubectl apply (and other verbs) works, the community has built up around this assumption, and things like the original motivating bug here rely on this. It just seemed super-odd to have a sig-cli KEP that talked about resource ordering that didn't acknowledge/consider the existing sig-cli approach 😕

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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. kind/kep Categorizes KEP tracking issues and PRs modifying the KEP directory sig/cli Categorizes an issue or PR as relevant to SIG CLI. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants