-
Notifications
You must be signed in to change notification settings - Fork 181
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
H4HIP: Helm Sequencing Proposal #373
base: main
Are you sure you want to change the base?
Changes from 7 commits
e805ed5
3d754ea
78075e2
163c6bf
a54be4d
9fe061a
de97e1c
e83cb0a
6712256
778b4d1
66b3861
c018bbb
4834758
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,192 @@ | ||
--- | ||
hip: 9999 | ||
title: "Better Support for Resource Creation Sequencing" | ||
authors: [ "Joe Beck <[email protected]>", "Evans Mungai <[email protected]>" ] | ||
created: "2024-11-15" | ||
type: "feature" | ||
status: "draft" | ||
--- | ||
|
||
## Abstract | ||
|
||
This HIP is to propose a new featureset in Helm 4 to provide Application developers, who create heam charts for their applications, a well supported way of defining what order chart resources and chart dependencies should be deployed to Kubernetes. | ||
|
||
## Motivation | ||
|
||
Today, to accomplish resource sequencing you have two options. The first is leveraging helm hooks, the second is building required sequencing into the application (via startup code or init containers). The existing hooks and weights can be tedious to build and maintain for Application developers, and built-in app sequencing can unecessarily increase complexity of a Helm application that needs to be maintained by Application Developers. Helm as a package manager should be capable of enabling developers to properly sequence how their applications are deployed, and by providing such a mechanism to developers, this will significantly improve the Application developer's experience. | ||
|
||
Additionally, Helm currently doesn't provide a way to sequence when chart dependencies are deployed, and this featureset would ideally address this. | ||
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. When it comes to sequencing, I'm not sure what you mean is clear in the document. I could come to two different conclusions:
Can you please provide some more clarity on what you mean. 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. 2 is what we're going for here. I'll make a note to try and make that more clear. 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. Clarified what "resource sequencing" meant in the HIP |
||
|
||
## Rationale | ||
|
||
### Proposal 1: Named Dependencies | ||
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. Personally, I quite like the general direction of proposal 1—as a replacement of numeric weights entirely—over proposal 2, which extends that. My point of view is I would like to move the numeric weighting into the "alternatives considered" section. But would like to hear other maintainers and community feedback on this. I have wanted to introduce a depends_on functionality for helm resources—as a dynamic alternative to weights—to allow users to specify a specific order they are applied (a similar concept is used by used by projects like terraform, flux, and docker-compose). My main reasoning for this is numbered weights are static—you must know the entire list of how all resources should be ordered, and this often takes a lot of finagling and fussing to get it right. While named dependencies are dynamic—creating a DAG on the fly, based only on when and if certain resources have an actual dependency on one or more other resources. It might be good to note some of this in the proposal. I could sketch up some suggested text for this if you prefer, but would also be happy for you to take a stab at it in your HIP. What do you think? 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. Go ahead! I'll add you as a contributor, I appreciate the assistance. 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 moved the weights proposal to rejected ideas and tried to capture some of the points you made here in why. |
||
This design was chosen due to simplicity and clarity of how it works for both the Helm developer and Application Operator | ||
|
||
### Proposal 2: Weighted Resouces (without hooks) | ||
This design was proposed as an alternative that functions very similarly to hooks today, to provide the same sequencing functionality outside of the scope of hooks. | ||
|
||
## Specification | ||
|
||
### Proposal 1: Named Dependencies | ||
At a high level, allow Chart Developers to assign named dependency annotations to both their Helm templated resources and Helm chart dependencies that Helm then uses to generate a deployment sequence at installation time. Three new annotations would be added to enable this described next. | ||
|
||
- `helm.sh/layer`: Declare a layer that a given resource belongs to. Any numebr of resources can belong to a layer. | ||
- `helm.sh/depends-on/layer`: Declare a layer that must exist and in a ready state before this resource can be deployed. | ||
- `helm.sh/depends-on/chart`: Declare a chart dependency that must exist and in a ready state before this resource can be deployed. For the chart to be declared ready, all of its resources, with their sequencing order taken into consideration, would need to be deployed and declared ready. | ||
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. To be clear,
My other question here is, do we want to allow depending on other named k8s resources that are not defined by a chart? Eg, 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 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 we need to add a section explaining how
I think 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. A suggestion came my way regarding reasoning around sequencing chart dependencies/subcharts. Chart authors would want to place such annotations on a chart-level definition rather than deep inside chart templates. Defining once also makes sense because only one reference of the chart dependency is needed. Any other references are repetition since helm will wait for the chart before deploying the parent chart. We came up with something like below. We'd move In the parent name: MyChart
annotations:
# List of charts that need to be installed before MyChart
helm.sh/depends-on/charts: "subchart, minio, rabbitmq"
dependencies:
- name: rabbitmq
version: "1.2.3"
- name: minio
version: "5.0.0" |
||
|
||
A layer would not be considered "ready" and the next layer deployed until all resources in that layer are considered "ready". Readiness is described in a later section. | ||
|
||
#### Example: | ||
```yaml | ||
# resource 1 | ||
metadata: | ||
name: foo | ||
annotations: | ||
helm.sh/layer: layer1 | ||
--- | ||
# resource 2 | ||
metadata: | ||
name: bar | ||
annotations: | ||
helm.sh/layer: layer2 | ||
helm.sh/depends-on/layer: layer1 | ||
--- | ||
# resource 3 | ||
metadata: | ||
name: fizz | ||
annotations: | ||
helm.sh/layer: layer3 | ||
helm.sh/depends-on/layer: layer1 | ||
helm.sh/depends-on/chart: someChartDependency | ||
``` | ||
In this example, Helm would be responsible for resolving the annotations on these three resources and deploy all resources in the following order: | ||
|
||
``` | ||
layer1: [foo] | ||
|| | ||
|| [someChartDependency] | ||
|| || | ||
\/ || | ||
layer2: [bar] || | ||
\\ // | ||
\/ \/ | ||
layer3: [fizz] | ||
``` | ||
|
||
This approach is prone to circular dependencies. During the templating phase, Helm will have logic to detect, and report any circular dependencies found in the chart templates. | ||
|
||
### Proposal 2: Weighted Resouces (without hooks) | ||
|
||
Expand on the the weight capabilities of hooks, but allow them to be defined outside of the context of hooks for the chart. Add a new annotation `helm.sh/weight` that helm then uses to order when resources are deployed based on the same weighting rules that hooks use today. | ||
|
||
#### Example: | ||
```yaml | ||
# resource 1 | ||
metadata: | ||
name: foo | ||
annotations: | ||
helm.sh/weight: "-2" | ||
--- | ||
# resource 2 | ||
metadata: | ||
name: bar | ||
annotations: | ||
helm.sh/weight: "-1" | ||
--- | ||
# resource 3 | ||
metadata: | ||
name: fizz | ||
annotations: | ||
helm.sh/weight: 0 | ||
``` | ||
In this example, Helm would be responsible for resolving the annotations on these three resources and deploy all resources in the following order: | ||
|
||
``` | ||
-2: [foo] | ||
|| | ||
\/ | ||
-1: [bar] | ||
|| | ||
\/ | ||
0: [fizz] | ||
``` | ||
|
||
### Readiness | ||
|
||
In order to enforce sequencing, new `helm.sh/resource-ready` annotation would be used to determine when a resource is ready, allowing helm to proceed deploying the next group of resources, or failing a deployment. Helm would query, using jsonpath syntax, status fields of the annotated resource. Some native kubernetes resources that have stable APIs e.g `v1` resources such as `Pod` and `Deployment`, would have default queries which can be overriden. In Helm cannot determine how to check a resource's readiness when it should, it will do nothing and log this. | ||
banjoh marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#### Example | ||
```yaml | ||
kind: Job | ||
metadata: | ||
name: barz | ||
annotations: | ||
helm.sh/resource-ready: "status.succeeded==1" | ||
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. Is the idea that this would be a check that Helm could use to override—kstatus ready condition (as an example implementation)? https://github.com/kubernetes-sigs/cli-utils/blob/master/pkg/kstatus/README.md#the-ready-condition 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. Yeah |
||
status: | ||
succeeded: 1 | ||
``` | ||
|
||
#### Sequencing order | ||
|
||
Resources with sequencing annotations would be deployed first followed by resources without. If a resource has a `helm.sh/depends-on/chart` annotation, all resources of the referred subchart would be deployed and checked for readiness before deploying the dependant resource. Only resources that Helm can determine their readiness for will be checked. Chart authors would need to annotate their chart resources accordingly. Helm will use default readiness checks for subcharts that do have their templates annotated. | ||
|
||
Helm would scope each subchart layer annotation names using a delimiter e.g `someChartDependency#mylayer` to avoid any name collisions. This is an internal implementation detail rather than feature chart authors or operators would need to know. | ||
|
||
`helm template` would print all resources in the order they would be deployed. Groups of resources in a layer would be delimited using a `## Layer: <name>` comment indicate the beginning of each layer | ||
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. The 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. For reference, the
---
# Source: foo/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata: |
||
|
||
```yaml | ||
## Layer: layer1 | ||
# resource 1 | ||
metadata: | ||
name: foo | ||
annotations: | ||
helm.sh/weight: "-2" | ||
--- | ||
# resource 2 | ||
metadata: | ||
name: bar | ||
annotations: | ||
helm.sh/weight: "-1" | ||
--- | ||
## Layer: layer2 | ||
# resource 3 | ||
metadata: | ||
name: fizz | ||
annotations: | ||
helm.sh/weight: 0 | ||
|
||
``` | ||
|
||
## Backwards compatibility | ||
|
||
Helm will continue to deploy all resources and dependencies at once, as adding the above defined annotations is when the installation behavior would change. If a template in a chart defines `helm.sh/depends-on/chart: someChartDependency` annotation, Helm will wait for the subchart to be ready for all resources with default readiness checks. This will also apply to subcharts that do not have any sequencing annotations. | ||
|
||
## Security implications | ||
|
||
None. | ||
|
||
## How to teach this | ||
|
||
TBD upon deciding on a design. | ||
|
||
## Reference implementation | ||
|
||
N/A | ||
|
||
## Rejected ideas | ||
|
||
N/A | ||
|
||
## Open issues | ||
|
||
- Choose between Proposal 1 and Proposal 2 | ||
- Should this featureset take into account allowing Application developers to declare custom "readiness" definitions for given resources, besides the default? | ||
|
||
## Prior raised issues | ||
|
||
- https://github.com/helm/helm/pull/12541 | ||
- https://github.com/helm/helm/pull/9534 | ||
- https://github.com/helm/helm/issues/8439 | ||
- https://github.com/helm/community/pull/230 | ||
|
||
N/A |
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.
Does this proposal also include sequencing for uninstall, or only install/upgrade? For example, waiting to uninstall a resource until all that depends on it have completely uninstalled?
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.
Good point I didn't think about that. At least with uninstall it can just be done backwards to the installation, but upgrade would add some complexity that I'm not sure how to tackle.
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 added a section to clarify that this would apply to all 3, installation/uninstall/upgrade