A proposal for Helm 3 using CRDs and a custom controller. This README comprises the proposal for CRDs in Helm 3. In addition to this document, there are other examples of what the objects will look like contained in this repo. This is not meant to be a completely exhaustive description of all behavior, but is intended to give a enough details as a starting point for actual implementation details should this proposal be accepted.
NOTE: Although I am a core maintainer, this does not represent the direction that the project will go. It is solely a proposal for what I personally think should be done for Helm 3
Originally, Helm was built as a way to share reusable components. However, as its usage has grown, many want to use Helm more as a configuration management tool. Also, many of the assumptions made when Helm 2 was first released have not proved true now that Kubernetes has evolved. Below is the list of issues current users of Helm 2 face and that can be addressed by this proposal.
- Lack of application lifecycle management
- The current Tiller model does not follow any of the prescribed ways for extending Kubernetes
- Security is difficult and not built in by default. Furthermore, there is no easy way to use the current RBAC model for authorization.
- The current method for storing releases is hard to read/understand and all parts of the release are stored together
The following points capture the high level changes compared to Helm 2.
- State is no longer stored and releases are now diff'd against the current state in the cluster.
- Helm will come built in with common lifecycle management patterns and have a
Lifecycle
object for registering custom lifecycles - Complete backwards compatibility with the Helm 2 chart spec will be maintained.
For example, hooks will be transparently converted to their equivalent
Lifecycle
object in Helm 3 - The current Release protobuf object has been decomposed into separate objects.
Namely,
Release
,Values
,Manifest
, andSecret
objects.
This is a simple list of logic that the controller will handle
- Tiller should watch for changes in the
Manifest
,Values
, orSecret
specified in theRelease
. It should also watch for changes in theRelease
object. When a change is observed, a new release occurs. - On the creation of a
Release
and on subsequent updates, aReleaseAudit
event is created to track the history of the release - All Kubernetes resources created will have an
OwnerRef
that points to theRelease
object that created it. - Tiller will publish a
LifecycleEvent
with the configuredeventKey
for eachLifecycle
specified in aRelease
. It will watch these events until the lifecycle controller responsible for handling that event marks it as done (or errored), update theRelease
object, and then delete the event. If it doesn't complete after a certain amount of time, the event will be cleaned up and failure information added to theRelease
status. - Each lifecycle will be handled by their own controller. The
Lifecycle
object specifies its name and what key the controller should watch for. This key will be used as the label value for filtering events in a lifecycle controller. Both built in and custom lifecycles will be registered in the same way.
This is a list of open questions that should be resolved before the proposal is fully accepted. If a larger discussion is needed, we will open an issue and link it to the question.
Should this be a simple controller or an extension API server? This could allow for custom storage backends but would be more difficult to program (and definitely harder for users to install). It may be the more robust optionJust a controller for ease of useShould rendering take place locally or in the controller?locally- How should we handle releases that are spread across multiple namespaces?
Possibly a
ClusterRelease
object that is non-namespaced - Should the controller enforce the given manifest again if changes are detected
in the objects created by a release? This could be a feature that is optional
and can be set by something like
enforce: true
in theRelease
- With state no longer being stored in a config map, how do we handle objects that should be deleted because they are no longer in the manifests?
- How will things like lifecycles be configured by the user? One idea is to
create a reserved key in
values.yaml
that can be used for configuring lifecycle behavior
This is an active proposal and feedback is definitely needed. If you see something you'd like to change, please open a Pull Request. We can discuss the change you add and either merge it in or close based on the outcome of the discussion.