-
Notifications
You must be signed in to change notification settings - Fork 38.8k
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
Proposal: Enable purging resources in kubectl apply
#29551
Changes from 2 commits
7437728
36e28e3
266d061
17b0e39
f10b071
777ea82
b076039
18de1a8
24efbc9
0a014ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
# Enable purging resources in `kubectl apply` | ||
|
||
## Motivation | ||
|
||
See [#19805](https://github.com/kubernetes/kubernetes/issues/19805). | ||
|
||
Currently `kubectl apply` will create any new resources that exist in the resource file(s) it is supplied with, but it has no way of deleting anything that has been removed from such files. | ||
|
||
This makes it difficult to use `kubectl apply` to update reality to match the declarative definitions of resources when that definition evolves over time, since changes can include deletions. | ||
|
||
The primary driver for this use-case is to be able to manage cluster add-ons using `kubectl apply`. | ||
|
||
## Proposed Solution | ||
|
||
In a "simplest possible idea first" approach, this proposal suggests that we reuse namespaces as a de-facto way of grouping resources for the purpose of _purging_ (removing) resources which no longer exist. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prune seems like a more appropriate than purge for this feature. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @mikedanese |
||
|
||
Most add-ons reside in `kube-system` namespace, therefore for add-ons, an implementation based on namespaces would be reasonable. | ||
The benefit of this is that no new abstraction (such as a new way of grouping resources) is required for this use-case. | ||
|
||
Therefore, the proposal is to introduce an optional `--purge-from-namespace` flag to `kubectl apply`, which will allow a user to automatically purge resources from the given namespace, if they haven't been explicitly declared in files that are arguments to the same `kubectl apply` invocation. | ||
|
||
All resources referred to must be explicitly labelled with a non-default namespace in order for the `--purge-from-namespace` argument to succeed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/a non-default/one non-default/ |
||
|
||
This flag will require `--namespace` not to be set. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not a big fan of hardcoding namespaces in manifests. This makes workloads less portable. E.g. in continuous deployment environments I might need to deploy/apply a workloads in a different namespace, depending on prod/testing/staging. Hence, my immediate thought was to enforce There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I think this is quite reasonable. The intention was that namespace must be explicit to ensure good user experience of this feature. There is wasn't a particularly big reason for doing that way, it's just that we had to pick something. I'm happy to change this over, unless @lukemarsden has something to add. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've changed this. |
||
All referenced resources must be explicitly defined as being in the same namespace, set in each of the resource definitions. | ||
|
||
The goal here is to avoid a negative user experience where the user accidentally deletes all the resources in some other namespace just because they accidentally refer to (e.g.) a single resource in some other namespace. | ||
|
||
## Managing Add-ons | ||
|
||
Let's first consider the add-ons use case. | ||
|
||
There exists a `/etc/kubernetes/addons` directory with some number of files. All resources declared in those files belong to the same namespace (`kube-system`), which is set explicitly in each of the resources. | ||
|
||
When `kubectl apply --purge-from-namespace -f /etc/kubernetes/addons` runs for the first time all the resources will be created. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section should be updated when we agree on the syntax. |
||
|
||
Eventually some new files appear in `/etc/kubernetes/addons` and some are modified. | ||
|
||
Subsequent invocations of `kubectl apply --purge-from-namespace -f /etc/kubernetes/addons` result in new resources being created and modified resources being updated. | ||
|
||
When user deletes some of the files or resources within files from `/etc/kubernetes/addons`, `kubectl apply --purge-from-namespace` would ensure the resources that were referenced in the deleted files are deleted, based on the assumption that `/etc/kubernetes/addons` represents all resources that are supposed to be present in `kube-system` namespace. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are other resources in kube-system. |
||
|
||
|
||
## Managing Any Other Application | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section needs to be updated with the label-selector proposal. |
||
|
||
It should be possible to apply the same approach to any other applications, with the assumption that single application occupies a namespace of its own. | ||
|
||
The usage may look like this: | ||
|
||
``` | ||
kubectl apply --purge-from-namespace -f https://example.com/myapp1.json | ||
``` | ||
|
||
Given resources in `myapp1.json` set their namespaces explicitly, resource that are no longer in this file would be purged, if no longer defined. | ||
|
||
``` | ||
kubectl apply --purge-from-namespace -f https://example.com/myapp-part1.json -f https://example.com/myapp-part2.json | ||
``` | ||
|
||
If `myapp1.json` and `myapp2.json` are in the same namespaces and it is explicitly defined, removing either of the URLs from the invocations arguments will result in all the resources that URL has defined to be purged. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. insert |
||
|
||
## Flag Discovery User Experience | ||
|
||
As stated above, the `--purge-from-namespace` flag shouldn't be enabled by default, however it should be discoverable. | ||
|
||
So, if a `kubectl apply` command is run without `--purge-from-namespace`, and the referenced files are all in the same namespace, then the command could output something like: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how keen I am to do this. It will make apply significantly more expensive (to discover all available resources within the namespace) and make the user experience significantly different than other forms of updates.
Mentioning this in the short help snippet for kubectl apply would be useful. A tutorial that shows how to manage resources using apply would be useful. |
||
|
||
``` | ||
$ kubectl apply -f resources.yaml | ||
Updating ServiceA... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently the output doesn't even reflect whether something is being created or updated, so we will need to investigate that... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be useful. The precise syntax should follow the output convention of other commands, including both the resource type and resource name in a form that could be copy+pasted to other commands verbatim, and should support |
||
Updating ServiceB... | ||
Updating DeploymentA... | ||
The following resources in namespace `foo` are not referenced in the files you provided: | ||
|
||
DeploymentB | ||
ServiceC | ||
|
||
You can automatically delete them, if you wish, using: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
kubectl apply --purge-from-namespace -f resources.yaml | ||
|
||
$ kubectl apply --purge-from-namespace -f resources.yaml | ||
Updating ServiceA... | ||
Updating ServiceB... | ||
Updating DeploymentA... | ||
Deleting DeploymentB... | ||
Deleting ServiceC... | ||
Done! | ||
``` | ||
|
||
If there are > 5 resources which match, we could just list the first 5. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kubectl displays all resources modified. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't cover everything, but take a look at kubectl conventions: |
||
|
||
If no namespace, or conflicting namespaces are provided in the resource file(s), this output would not be shown. | ||
|
||
# Alternatives Considered | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would just remove these. |
||
|
||
A new Kubernetes API-level concept "Versioned ApplySets" could record all the `kubectl apply` commands that were ever executed against a cluster. | ||
This would allow deletions to be automatically detected and applied between invocations of `kubectl apply` without the onus of having to put resources into namespaces. | ||
|
||
This adds complexity, since a new Kubernetes API object type would need to be invented. | ||
|
||
It's not obvious how to make this concept work correctly in the case where one user runs `kubectl apply X` and later `kubectl apply X'` and a different user runs `kubectl apply Y` where `X'` is intended as an update to `X` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is that a problem? The same issue exists already with a simple There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @lukemarsden added this, I'm not sure what exactly was he trying to say. As this is a kind of non-critical background information, I'd vote for removing this paragraph. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was in context of the alternative considered. Feel free to kill it, it was only ever a half-thought anyway. |
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.
We have refereed to this process as "configuration reconciliation" in the past. #1702