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

Enable Release Namespace Creation in Helm3 #6794

Closed
ichekrygin opened this issue Oct 25, 2019 · 47 comments · Fixed by #7648
Closed

Enable Release Namespace Creation in Helm3 #6794

ichekrygin opened this issue Oct 25, 2019 · 47 comments · Fixed by #7648
Labels
proposal v3.x Issues and Pull Requests related to the major version v3
Milestone

Comments

@ichekrygin
Copy link

Overview

Helm2 provided support for the Release namespace {{ .Release.Namespace }} via --namespace option if the release namespace did not exist. This functionality was considered rudimentary, and there were several requests from the community captured in #3503

Helm3 took a more opinionated approach on how to handle --namespace option w/non-existing namespaces by removing support for the release namespace creation. Irrespective of the --namespace option, the {{ .Release.Namespace }} is expected to exist before installing/upgrading any helm chart that utilizes --namespace option.

By dropping support for the Release Namespace creation via --namespace option in Helm3, we also dropped any possibility to install a Helm chart with non-existent namespace! As a result, the chart authors and chart users must rely on additional, external to Helm3 tools like kubectl to
prepare (create) Release Namespace before Helm chart installation.

It is understood that --namespace option to create namespace was sub-optimal in Helm2, which prompted requests from the helm user community similar to #3503.

Proposed Change

Rather than to remove support for the Release Namespace creation altogether, we can provide accommodations for helm chart authors to create the release namespace inline during the helm chart install by allow to define release namespace Inside as a template resource. Moreover, the helm chart authors will also be able to tailor the release namespace to the needs of the applications by including all necessary labels, annotations.

Consider following template for the Release Namespace manifest.

{{- if and .Release.Namespace (.Values.createReleaseNamespace | default false) -}}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Release.Namespace }}
  annotations:
    my-annoation: {{ .Values.MyAnnotation }}
  labels:
    release: {{ .Release.Name }}
    my-other-label: other-label
{{- end -}}

In the example above, we chose to emulate current Helm3 chart functionality, i.e., do not create the release namespace by default.

The chart authors can decide whether or not allow multiple instances of their application to target the same namespace. For example, removing {{- if ... end -}} lines, effectively ensure that a given chart can only be installed into a newly created namespace and no two chart instances for this application can share the same namespace.

Processing and Assumptions

While the Release Namespace resource resembles other Helm template resources very closely, the processing of this resource is different.

Helm3 can perform a "special" pre-installation check to see if the Release Namespace is defined in the templates section. If it is - Helm3 will attempt to create the release namespace before recording release history, which utilizes the release namespace.

The "special" handling of the Release Namespace hs following assumptions/implications:

  • The release namespace creation will be considered as a "special" functionality, i.e., since it is processed separately from the rest of the template resources (similar to crds)
  • The release namespace artifact will be defined in the templates section, thus will be fully rendered just like any other templates resource (unlike crds)
  • The release namespace resource will be "immutable," i.e., Helm3 will support only "Create" and "Delete" life-cycle events, and will not support "Update."
  • Installing two charts that result in the resource namespace collision will be handled just like any other collision in templates resources.

Input Result Matrix (Helm3 Current)

Note: here and below, Namespace is synonymous to Release Namespace.

Note: in this example for simplicity we assume that all Helm chart artifacts are installed into the Release Namespace

# Namespace Precondition Namespace Option Result Explanation
1 Does not exist None Success: the helm chart is successfully installed into default namespace The Release Namespace is neither existed, provided nor used
2 Does exist None Success: the helm chart is successfully installed into default namespace The Release Namespace exists, however, neither provided nor used
3 Does not exist Provided Failure: the helm chart installation failed with "namespace not found" The Release Namespace does not exist, and Helm3 will fail to perform all operations against this namespace
4 Does exist Provided Success: the helm chart is successfully installed into Provided release namespace As expected

Input Result Matrix (Proposed)

Same use cases as above, but this time with proposed changed and with Helm chart that includes template definition for the Release Namespace.

# Namespace Namespace Option Create Namespace Value Result Explanation
1 Does not exist None False Success: the helm chart is successfully installed into default namespace Same as current behavior: since the Release Namespace is provided yet it neither created nor used.
2 Does exits None False Success: the helm chart is successfully installed into default namespace Same as current behavior
3.0 Does not exist Provided False Failure: the helm chart installation failed with "namespace not found" Same as current behavior, since CreateNamespaceValue is set to false`
3.1 Does not exist Provided True Success: the helm chart is installed into newly created release namespace This is the new/proposed behavior
4.0 Does exist Provided False Success: the helm chart is successfully installed into Provided release namespace Same as current behavior
4.1 Does exist Provided True Failure: namespace collision Not "really a new" behavior since in this case the release namespace collision is no different than any Helm2/3 existing artifacts collision errors

Summary

The goal of this proposal is to entertain a possibility to provide Helm chart authors with functionality to define and provide support in terms of the properties when it comes down to the Release Namespace artifact.

With this proposal: Helm chart authors can allow users to:

  • Install helm chart into an existing namespace (as currently supported)
  • Install helm chart into a non-existing namespace (currently not supported)

while maintaining all the current Helm3 chart behaviors when it comes to storing Helm release information.

@thomastaylor312
Copy link
Contributor

@ichekrygin Thanks for the detailed proposal and POC on this! Because this is a feature add (yes, it did exist in Helm 2, but was an explicit decision to remove), I have put this into the 3.1 milestone. We will come back around to this after we get through the Helm 3.0 release in a few weeks

@bacongobbler bacongobbler added the v3.x Issues and Pull Requests related to the major version v3 label Oct 30, 2019
@stevebail
Copy link

Good to know support for namespace creation during helm install might be back in v3.1. Is it possible to know the background about why it is considered "sub-optimal" in helm2? namespace creation with helm2 is working fine as far as I know.

@thomastaylor312
Copy link
Contributor

Sure thing @stevebail. So the tl;dr is that we wanted helm to follow the same lines as kubectl and also that some users want to modify the namespace that Helm creates. Instead of trying to force everyone to do it a specific way, we leave it up to the user. See this comment for some more details: #5753 (comment)

@ichekrygin
Copy link
Author

ichekrygin commented Oct 31, 2019

@stevebail @thomastaylor312 I had (and still have) a hard time finding "reasonable" justifications for [--namespace create the release namespace] functionality removal in Helm3. I understand the decision was made, i.e., what's done is done. However, I suspect many helm users will find this change to be "surprising" to say the least. Thus it is super important to have a clear and transparent explanation about the decision-making process behind this issue. Unfortunately for me, all the answers provided so far fell short of reaching that goal.

Focusing specifically on #5753 (comment)
tl;dr; on (#5753 (comment)) - there are two main themes:

  1. The concern for (lack of) RBAC permission level for the user installing helm chart, i.e., admin level permissions needed for user installing helm chart
  2. The accumulation of the requests from the helm community members dedicated to the "enhanced" functionality around --namespace creation.

I address 2. first for being the easiest. There could be multiple ways how we could have handled such requests, for example:

  • address and implement requested functionality if it makes sense and if time permits.
  • if time doesn't permit, create and assign such requests for up-coming Helm 3.+ releases
  • reject requests if it doesn't make sense or if it goes against established practices and paradigms, with sufficient explanation, i.e., help to educate users on the "right" way, etc.
    The main point, if we decided to use the latter two, we still would preserve the existing (Helm2) functionality.
    Instead, it appears Helm3's response to this issue was more in line with "NO SOOP FOR YOU!"
    image
    I.E., remove --namespace creation support altogether

As for 1., I have the following concerns.
It appears that Helm3 is trying to become "more opinionated" on what helm user RBAC permissions should be. While I can understand such a notion, I don't think I agree with it. I think Helm chart authors should decide on the installer RBAC permissions level since the author is the ultimate authority in that area. For the most part, this still holds (from Helm2->Helm3), i.e., helm chart authors can include cluster level scoped artifacts in the chart template.
Moreover, when it comes to CRD support, it appears Helm3 makes a decision in the opposite direction (in terms of RBAC + --namespace creation), and now includes support for CRD provisioning, which is excellent, but at the same time very inconsistent with the part of the rationale used for --namespace creation functionality deprecation.

Final point. I think to have Helm3 as a one-stop-shop tool is a highly desirable trait. Helm3 CRD support is both a welcomed addition and a step in the right direction. However, --namespace creation removal is a step (or a few) back, in my opinion.

P.S. at the end of #5753 (comment) @bacongobbler defers to @adamreese as to the authoritative source for information behind --namespace create removal, so I suspect there could be other motives not covered in the comment.

@stevebail
Copy link

stevebail commented Oct 31, 2019

@ichekrygin
Good info.

I am definitively not an authorize source and was definitively not involved in any decision :)
I am just trying to follow where this is going.
My personal view is:

  1. I understand the reasoning to align with kubectl create --namespace. It makes sense to me now.
  2. I also see why it is important to consider RBAC for managing cluster-level objects but maybe Helm3 went a little too far here.
  3. Maybe a "middle ground solution" with an extra flag allowing the helm chart installer to also (separately) request the NS creation if he/she feels has sufficient proviledges to do so. If no, don't use this new flag and apply the install to the specified NS (assuming it is already present in the cluster)

My 2 cents.

@thomastaylor312
Copy link
Contributor

It appears that Helm3 is trying to become "more opinionated" on what helm user RBAC permissions should be.

I'm not sure I understand the argument here. The goal behind any of these RBAC related decisions was explicitly to not be opinionated, meaning that we have no idea what kind of permissions a user may have. I don't think we can say the same for charts either, especially for charts in the stable repo.

I think you do have a point around CRD support. Perhaps we should make CRD installation opt-in instead of opt-out and namespace creation would behave the same way, but it might be too late for that.

@ichekrygin
Copy link
Author

I am definitively not an authorize source

My bad, I copied wrong GitHub user, now it is corrected.

@ichekrygin
Copy link
Author

I'm not sure I understand the argument here

@thomastaylor312 perhaps it is my misinterpretation of #5753 (comment):

Without this change, users must have cluster admin rights to install a chart, and we want to ensure that administrators can ensure users only have a restricted set of roles applied to each install.

I think the chart author is the authoritative source on what RBAC rights installing user should have, with or without the creation of --namespace. I.E., if the helm chart contains "cluster level scoped" artifacts, the treatment of those should be no different as --namespace artifact and inversely, the treatment of --namespace creation should be no different from any cluster-level chart artifacts. Thus, if users w/out propper RBAC permission attempt to install a chart with --namespace create option, they will get the same error when they try to install a chart with the template that contains cluster-level artifacts.

@thomastaylor312
Copy link
Contributor

Ok, I missed one of the issues where this has sprawled across and now have a better grasp on it.

Essentially there have been several design concerns around having the namespace auto created for you that have been documented and explained by @bacongobbler and others. What it boils down to is: The scope of the --namespace flag has ballooned into something we cannot sustain/write a good UX for. Also, seeing as kubectl requires the exact same steps before sending a deployment (e.g. creating the namespace beforehand), this seems like the correct decision for right now.

What it comes down to is that this is a design and shipping decision that we have agreed upon, but we do understand your desire and point of view. I know there are pain points here, but I think they are something that can be addressed with a plugin or feature after 3.0 comes out, so please let us know if you have ways to work around the aforementioned design concerns. We are not against the use case in any way, but we want a way to support this in a sustainable fashion.

@thomastaylor312
Copy link
Contributor

Well, I just gave in and whipped up a quick plugin for it: https://github.com/thomastaylor312/helm-namespace

@stevebail
Copy link

@thomastaylor312
Very good! Let me try it...
Does it mean your plugin or something equivalent will be considered for addition to 3.1?

@ichekrygin
Copy link
Author

@thomastaylor312 I think we are on the same page in terms of the timeline of the decision making.

It is the consistency (or lack thereof) what I have the gripe with, i.e., why we chose to support CRD's one way, yet, deprecate support for --namespace for seemingly the opposite reasons.
In that spirit, CRD's could be supported via helm plugin as well, couldn't it?

@ichekrygin
Copy link
Author

Also, seeing as kubectl requires the exact same steps before sending a deployment (e.g. creating the namespace beforehand), this seems like the correct decision for right now.

In light of "one-stop-shop", I think the closest analogy would be if all the sudden kubectl decided for whatever reasons to deprecate namespace creation and say recommended using curl to create namespace before proceeding to use any of the kubectl functionality targetting said namespace.

Also, I made this point in other threads, with kubectl I can place namespace definition and deployment definition targetting that namespace into the same yaml file to achieve the desired result. In Helm3 there is simply no way at all (bar suggested plugin) to do that.

@thomastaylor312
Copy link
Contributor

So I fully admit they are different, but that decision was made by several core maintainers working in tandem on the issue considering all the feedback we had on hand from users and came to the conclusion that it was the most simple and effective way to support CRDs. I was part of the process and we went back and forth for weeks on that decision. I'll admit that we didn't consider it together with the namespace, but based on all of the digging through the various edge cases around CRDs, we were ok with it. If I were to do it again, I might consider making it opt-in like I mentioned before

And like I said, we aren't against adding support for namespaces back in, but it needs to be well thought out to handle all of the aforementioned design problems

@thomastaylor312
Copy link
Contributor

Does it mean your plugin or something equivalent will be considered for addition to 3.1?
@stevebail It just means that people now have that plugin to restore the old behavior if they want it. What it would look like to add it back in to helm proper is more along the lines of the discussion here.

On a related note: @ichekrygin one option I could see here is making sure if there is a namespace manifest in a chart, that we install it first. Not sure if we could make that clean from a code perspective, but Helm does already know to install namespace objects first, but it doesn't get there because a namespace doesn't exist

@ichekrygin
Copy link
Author

Not sure if we could make that clean from a code perspective

@thomastaylor312 I would appreciate any feedback on #6795

@thomastaylor312
Copy link
Contributor

Yep, will get to that once we get past 3.0 release

@bacongobbler
Copy link
Member

bacongobbler commented Nov 7, 2019

I was just tipped off that Kubernetes has an admission controller that handles this case. It might be worth looking further into before considering alternatives. https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#namespaceautoprovision

For the lazy:

NamespaceAutoProvision

This admission controller examines all incoming requests on namespaced resources and checks if the referenced namespace does exist. It creates a namespace if it cannot be found. This admission controller is useful in deployments that do not want to restrict creation of a namespace prior to its usage.

@ichekrygin
Copy link
Author

@bacongobbler NamespaceAutoProvision is an interesting angle.

IMHO, using NamespaceAutoProvision functionality is related, yet somewhat orthogonal to the release namespace creation. With that said, (and of the top) I have following concerns with this leveraging NamespaceAutoProvision admission controller:

a. NamespaceAutoProvision admission controller is disabled by default, thus in most cases, it will require a cluster administrator to enable this functionality before we can install Helm3 chart with non-existing release namespace.

b. From my very high-level understanding of Helm3 implementation (and I am definitely sticking my neck here, basically asking to be proved wrong) even with NamespaceAutoProvision enabled, we would still get: Error: create: failed to create: namespaces "foo-bar" not found, since it appears Helm3 will try to "use" the release namespace for the Helm3 storage driver needs before installing (read: issuing POST request(s) to K8S API with) chart artifacts which in turn trigger the admission controller. I.E., it seems, we would still need to modify Helm3 functionally just to accommodate this specific use case of using NamespaceAutoProvision admission controller.

taylorsilva added a commit to concourse/concourse that referenced this issue Jan 24, 2020
Behaviour around namespaces changed a lot in Helm 3. Every helm command
is now scoped to a namespace just like kubectl. We now need to specify
the namespace in each helm command.

Tiller is no longer required either, the `init` command was removed
because of this.

TODO: installing a chart to a namespace that doesn't exist currently
fails. There's a proposal to bring this behaviour back:
helm/helm#6794

Signed-off-by: Taylor Silva <tsilva@pivotal.io>
@bacongobbler
Copy link
Member

bacongobbler commented Jan 30, 2020

This could be accomplished using the new lookup function once we merge #7474. #7473 (comment) demonstrates an example that accomplishes the same thing this PR is asking for: if the namespace does not exist, create it.

Because of that, I'm in favour of closing this, as the use case provided here can be accomplished using that pattern without introducing any further code.

@ichekrygin
Copy link
Author

@bacongobbler how does lookup help with Release Namespace creation?

@bacongobbler
Copy link
Member

I'm not sure how I can spell it out more clearly. The example provided in #7473 (comment) demonstrates how someone can use the lookup function to create the namespace if it didn't already exist.

@dudicoco
Copy link

dudicoco commented Feb 9, 2020

I agree with @mattfarina, a flag should be added to helm install and the charts creators should not have to modify their charts.

@ichekrygin
Copy link
Author

@mattfarina couple of clarifications

The PR at #6795 requires the chart author (Application Distributor) add the namespace creation feature to every chart to have it. But, as @bacongobbler noted, this is already possible to add to a chart using the lookup function

I just want to emphasize, this issue and proposal are dedicated to the specific namespace: Release.Namespace.

namespace

I understand there are many namespaces that chart can subsequently create, but those are out of the scope of this issue. The Release.Namespace is the one user provides via "--namespace" flag and lookup function do not help with this issue.

This means that all the chart authors do not need to add this to their charts.

First, the chart authors do not need to update anything, if they are satisfied with Helm3 changes in respect of Release.Namespace creation.
Second, I agree, chart update to facilitate Release.Namespace creation is less than ideal. Ideally, I would prefer that Release.Namespace creation functionality did not change in Helm3, i.e. worked as it used to.

To address, why more elaborate "Namespace" is added to the chart was partially satisfy the following reason:

Additionally, there have been several asks in the community to allow modifying the namespace helm install creates (e.g. #3503), and the UX to support use cases like that would be incredibly painful to achieve. Offloading the namespace creation to a separate tool (perhaps a plugin?) provides users a way to solve these issues without imposing a restrictive user experience around these use cases.

If we drop "modifying namespace" functionality, I totally see it would be possible to address this w/out any additional changes to existing charts. With that said, I did come across cases where some charts required additional modifications to the Release.Namespace, and I think it could be useful to leverage this proposal functionality, but I am not stuck on it. I also think it will be "win-win" if we could make it work both ways:

  • create Release.Namespace space during chart install (w/out changes to chart)
  • create Release.Namespace with modifications (requires Release.Namespace to be defined in the chart)

@paulczar
Copy link
Contributor

Love the idea of moving this functionality back to a flag so that we as the user can opt into having helm auto-create the Release Namespace. If we allow this flag for helm template commands as well, then we also help those people or tools who like to use helm just for templating such as spinnaker[1].

[1] helm/charts#18719 and lots more like it.

@bacongobbler
Copy link
Member

bacongobbler commented Feb 20, 2020

#7648 implements --create-namespace for helm install and helm upgrade --install. Please feel free to try it out.

@bacongobbler
Copy link
Member

bacongobbler commented Feb 20, 2020

The Release.Namespace is the one user provides via "--namespace" flag and lookup function do not help with this issue.

...Did you actually read my previous comments?

The example I provided earlier in #7473 (comment) SPECIFICALLY creates the release namespace if it isn't present. I will post the example again for posterity.

templates/namespace.yaml:

{{ if not (lookup "v1" "Namespace" .Release.Namespace .Release.Namespace) }}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Release.Namespace }}
{{ end }}

If lookup cannot find the .Release.Namespace in the cluster, it will go ahead and create it.

In other words, it accomplishes the exact same task #6795 proposes to solve, without introducing any code to Helm.

When #7648 is merged, we will have solved both cases:

  1. how can I as a chart author ensure that the release namespace will be created (lookup)
  2. how can I as a chart consumer create the release namespace before installing the chart (feat(install): introduce --create-namespace #7648, which reinstates Helm 2's functionality)

Hope that clears things up.

@ichekrygin
Copy link
Author

...Did you actually read my previous comments?

Yes, I did and replied on the same day - #7473 (comment)

I don't mind doing this again. There must be something embarrassingly simple that I don't see.
Maybe @bacongobbler can spot it where I go wrong:

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ kubectl version
Client Version: version.Info{Major:"1", Minor:"17", GitVersion:"v1.17.3", GitCommit:"06ad960bfd03b39c8310aaf92d1e7c12ce618213", GitTreeState:"clean", BuildDate:"2020-02-12T13:43:46Z", GoVersion:"go1.13.7", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ kubectl get ns
NAME              STATUS   AGE
default           Active   21d
kube-node-lease   Active   21d
kube-public       Active   21d
kube-system       Active   21d

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ ./helm version
version.BuildInfo{Version:"v3.1+unreleased", GitCommit:"694cf61aacba6bc4ed59a65d23acd20f6c8b95bd", GitTreeState:"dirty", GoVersion:"go1.12.12"}

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ git log | head
commit 694cf61aacba6bc4ed59a65d23acd20f6c8b95bd
Author: Matthew Fisher <matt.fisher@microsoft.com>
Date:   Thu Feb 20 11:56:03 2020 -0800

    feat(install): introduce --create-namespace
    
    Signed-off-by: Matthew Fisher <matt.fisher@microsoft.com>

commit f7bcdf194b8782c10ec476a77929807199ad9baf
Merge: 99304c86 2a742129

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ cat foo/templates/namespace.yaml
{{ if not (lookup "v1" "Namespace" .Release.Namespace .Release.Namespace) }}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Release.Namespace }}
{{ end }}

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ tree foo
foo
├── charts
├── Chart.yaml
├── templates
│   ├── _helpers.tpl
│   ├── namespace.yaml
│   └── NOTES.txt
└── values.yaml

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ ./helm install foo ./foo -n bar
Error: create: failed to create: namespaces "bar" not found

⋊> ~/g/s/g/h/h/bin on fix-6794 ⨯ ./helm install foo ./foo --namespace bar
Error: create: failed to create: namespaces "bar" not found

@bacongobbler
Copy link
Member

bacongobbler commented Feb 20, 2020

@adamreese and I paired together and discussed the implementation of helm install. I overlooked a design decision we intentionally made in Helm 3 which prevents my example from working. We wanted to prevent the chart from managing its own namespace (such as the proposal in #6795).

Here's the code where you're seeing that error occur:

helm/pkg/action/install.go

Lines 275 to 277 in d6fad6b

// Store the release in history before continuing (new in Helm 3). We always know
// that this is a create operation.
if err := i.cfg.Releases.Create(rel); err != nil {

Put simply, before we go ahead and create the resources that the chart declared, we create a release ledger (a secret) in the release namespace to record its status. This was intentional to prevent the chart the ability to manage its own namespace.

If we allow the chart to manage its own namespace, it brings up a huge design problem: should the chart ever decide to stop tracking the release namespace, the namespace and all its objects are removed... Including the release ledger, and any other charts installed within that namespace.

Taking #6795 as an example.

templates/namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Release.Namespace }}
$ helm version
version.BuildInfo{Version:"v3.0+unreleased", GitCommit:"9e44577768e1c3e70b450063ee14f4163e8a6013", GitTreeState:"dirty", GoVersion:"go1.13.8"}
$ helm install foo . --namespace foo

Great. We now have the ability to manipulate the namespace from within the chart.

But what if we remove it?

$ rm templates/namespace.yaml
$ helm upgrade foo .
Release "foo" has been upgraded. Happy Helming!
...
$ helm list --all-namespaces
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION

This scenario is relatively harmless, but it exposes a problem: It's too easy for the chart author to accidentally delete their own namespace (and everything within it, including the ledger). Or, in a more dangerous case, the chart author could delete OTHER user's resources, too.

Taking that same example, let's install multiple charts in the same namespace.

$ helm install bar . -n bar
NAME: bar
LAST DEPLOYED: Thu Feb 20 14:44:25 2020
NAMESPACE: bar
STATUS: deployed
REVISION: 1
...
$ helm install wordpress stable/wordpress -n bar
NAME: wordpress
LAST DEPLOYED: Thu Feb 20 14:44:25 2020
NAMESPACE: bar
STATUS: deployed
REVISION: 1
...

Now, we remove the namespace from the chart and upgrade.

$ rm templates/namespace.yaml 
$ helm upgrade bar . -n bar
Release "bar" has been upgraded. Happy Helming!
...
$ helm list -A
NAME    NAMESPACE       REVISION        UPDATED STATUS  CHART   APP VERSION

Going forward, it sounds like #7648 is the only safe option we can provide here, and we should close out #6795 as something we are not planning to support as per the above examples. #7648 would restore Helm 2's old functionality (as originally requested), without introducing any major design flaws.

@ichekrygin
Copy link
Author

ichekrygin commented Feb 20, 2020

Sorry, @bacongobbler, is it possible to TL;DR; the comment above?

Specifically, was I wrong in my previous comments stating that the lookup function does not help with the creation of non-existent {Relese.Namespace}?

@ichekrygin
Copy link
Author

ichekrygin commented Feb 21, 2020

I have mentioned earlier (most recently) that I am not "hard set" on having to provide {Release.Namespace} as part of the templates manifest.

{{- if and .Release.Namespace (.Values.createReleaseNamespace | default false) -}}
...

The only reason such functionality exists in this POC is to show one of the possible solution addressing:

Additionally, there have been several asks in the community to allow modifying the namespace helm install creates (e.g. #3503), and the UX to support use cases like that would be incredibly painful to achieve. Offloading the namespace creation to a separate tool (perhaps a plugin?) provides users a way to solve these issues without imposing a restrictive user experience around these use cases.

This POC can be "enhanced" to not remove {ReleaseNamespace} once created.
With that said, I am totally in favor of removing this part altogether, and possibly substituting with additional options like --releaseNamespaceAnnotation="foo=bar" and/or `--releaseNamespaceLabels", or something like that.

Moreover, I will be OK, if we add neither manifest nor flags. The bare minimum ask is to restore Helm2 {ReleaseNamespace} creation functionality. I gladly modify this POC (or create a new one) that accomplishes that in code w/out any additional flags and manifest.

As for {ReleaseNamespace} clean up, my suggestion is to leave it behind and require the user to perform any additional cleanup if needed. I.E., the same way it was in Helm2 or the same we treat CRD's in Helm3

@ichekrygin
Copy link
Author

ichekrygin commented Feb 21, 2020

This POC can be "enhanced" to not remove {ReleaseNamespace} once created.

@bacongobbler - we can preserve {ReleaseNamespace} even w/out any additional changes to this POC, by leveraging: helm.sh/resource-policy: keep :)

{{- if and .Release.Namespace (.Values.createReleaseNamespace | default true) -}}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Release.Namespace }}
  annotations:
    helm.sh/resource-policy: keep # <-- keeps namespace from being deleted
    my-annoation: test-annotation
  labels:
    release: {{ .Release.Name }}
    my-other-label: other-label
  {{- end -}}

@ichekrygin
Copy link
Author

Consider this as an example of ^:

⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ ./helm version
version.BuildInfo{Version:"v3.0+unreleased", GitCommit:"9e44577768e1c3e70b450063ee14f4163e8a6013", GitTreeState:"clean", GoVersion:"go1.12.12"}

⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ kubectl get ns
NAME              STATUS   AGE
default           Active   21d
kube-node-lease   Active   21d
kube-public       Active   21d
kube-system       Active   21d

⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ cat bar/templates/namespace.yaml
{{- if and .Release.Namespace (.Values.createReleaseNamespace | default true) -}}
apiVersion: v1
kind: Namespace
metadata:
  name: {{ .Release.Namespace }}
  annotations:
    helm.sh/resource-policy: keep # <-- keeps namespace from being deleted
    my-annoation: test-annotation
  labels:
    release: {{ .Release.Name }}
    my-other-label: other-label
  {{- end -}}⏎                                     

⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ ./helm install bar ./bar -n bar
NAME: bar
LAST DEPLOYED: Thu Feb 20 17:27:24 2020
NAMESPACE: bar
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace bar -l "app.kubernetes.io/name=bar,app.kubernetes.io/instance=bar" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace bar port-forward $POD_NAME 8080:80
⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ ./helm list -n bar
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
bar     bar             1               2020-02-20 17:27:24.798023098 -0800 PST deployed        bar-0.1.0       1.16.0     
⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ kubectl get all -n bar
NAME                       READY   STATUS    RESTARTS   AGE
pod/bar-85db4d59bc-bqkb7   1/1     Running   0          19s

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/bar   ClusterIP   10.96.247.203   <none>        80/TCP    19s

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/bar   1/1     1            1           19s

NAME                             DESIRED   CURRENT   READY   AGE
replicaset.apps/bar-85db4d59bc   1         1         1       19s

⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ ./helm delete bar -n bar
manifest-0

release "bar" uninstalled

⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ kubectl get ns
NAME              STATUS   AGE
bar               Active   31s // <-- namespace left behind
default           Active   21d
kube-node-lease   Active   21d
kube-public       Active   21d
kube-system       Active   21d

⋊> ~/g/s/g/h/h/bin on helm3-namespace ◦ kubectl get all -n bar
No resources found in bar namespace. // <-- namespace bar is empty

@ichekrygin
Copy link
Author

On the upside, there was quite a bit of activity here! I love it.

Quickly to sum up today's activity:

  • Unfortunately lookup function does not help with {ReleaseNamespace} creation as expected
  • There is a valid concern that we need to be careful not removing {ReleaseNamespace} as defined in this POC.
  • The {ReleaseNamespace} removal can be avoided by adding helm annotation serving this specific purpose: helm.sh/resource-policy: keep
    • In fact, this policy applies to ANY resource
  • Additionally, the {ReleaseNamespace} removal prevention can be handled in code (similar to creation) if we want it.

@mattfarina
Copy link
Collaborator

@bacongobbler after a little digging... you can't use the lookup function to create the release namespace. The release object (a secret by default) is stored in the release namespace just prior to uploading the manifests for the chart.

The specific error is in the form:

Error: create: failed to create: namespaces "testme" not found

lookup can be used for other namespace but not the release one.

@bacongobbler
Copy link
Member

bacongobbler commented Feb 24, 2020

after a little digging... you can't use the lookup function to create the release namespace.

Agreed. That was my mistake. I failed to remember a design decision we made in Helm 3. I tried to explain that in more depth with #6794 (comment) but I was not very clear with the messaging around that. Sorry about that.

@ichekrygin after reading your follow-up comments, it's still unclear to me how #6795 is intended to restore Helm 2's functionality.

As I understand, the goal of this ticket is to find a solution that allows a user to create the namespace on-the-fly as Helm 2 worked. Right?

When we talk about roles in Helm, we often talk about two specific roles: the chart author, and the chart operator. The author is the one who writes the chart, and the operator is the one that "consumes" the chart.

In Helm 2, the namespace was not something a chart author had to provide. The role of creating the namespace was a role for the chart operator as helm install --namespace.

However, when we look at #6795, its functionality relies on the chart author to introduce a namespace as a template into the chart. The role of creating the namespace shifts to the chart author. This is a large behavioral shift in how charts are maintained and operated, including

  • how templates are namespace-agnostic
  • the lifecycle management of the namespace (in this POC's case, through resource policies)
  • etc.

This is why I approached this with #7648. By creating the namespace on-the-fly with a feature flag, the roles remain the same as in Helm 2: chart authors do not have to maintain the lifecycle of the namespace, and Helm can continue to assume the lifecycle management of the namespace, including design concerns such as the one described earlier when the author fails to introduce a resource policy.

If we were to consider #6795, each and every chart would have to introduce the template to use this feature. That would mean that every chart is no longer compatible with older versions of Helm (i.e. we break backwards compatibility), and every single chart would have to be updated to introduce this functionality. If I'm understanding the proposal - to restore functionality without breaking compatibility - that would seem like a non-starter.

Do you have any other thoughts you'd like to add here?

@ichekrygin
Copy link
Author

I was able to verify #7648 --create-namespace functionality, it looks good.

YoussB pushed a commit to concourse/concourse that referenced this issue Aug 27, 2020
Behaviour around namespaces changed in Helm 3. Every helm command is now
scoped to a namespace just like kubectl. We now need to specify the
namespace in each helm command.

Namespaces are also not made automatically by helm if they don't exist.
This results in "Namespace does not exist" errors from helm when trying
to install a chart. This commit adds a function to create the namespace
right before installing a chart using kubectl. There's a proposal to
bring this behaviour back into helm:
helm/helm#6794

Tiller is no longer required either, the `init` command was removed
because of this.

Signed-off-by: Taylor Silva <tsilva@pivotal.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal v3.x Issues and Pull Requests related to the major version v3
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants