Deploying helm release forcefully when same name deployments, svcs, etc. are running in the same namespace

Viewed 6780

How to deploy the helm release for the first time when there's already the deployment, svc, etc. running with the same name.

Is there's any way to import the config running, which is not being handled by helm?

Or deleting the same name objects is the only solution to deploy the helm release first time?(As I don't want to change the release names because it will break the communication between the microservices) Deleting the objects will cause downtime and I want to avoid that.

Error getting while deploying with the same name:

Error: rendered manifests contain a resource that already exists. Unable to continue with install: Service "abc" in namespace "default" exists and cannot be imported into the current release: invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "abc"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "default"

Is their any other approach?

Thanks

3 Answers

Addressing the error message and part of the question:

How to deploy the helm release for the first time when there's already the deployment, svc, etc. running with the same name.

You can't deploy resources with Helm that weren't created by Helm. It will give you the same message as you've encountered. You can annotate the existing resources that were not added by Helm to "import" the existing resources and act on them. Please try to run your workload on a test environment first before trying it as it could redeploy some resources.

There is already similar answer on how to annotate resources:

see this feature of helm3 Adopt resources into release with correct instance and managed-by labels

Helm will no longer error when attempting to create a resource that already exists in the target cluster if the existing resource has the correct meta.helm.sh/release-name and meta.helm.sh/release-namespace annotations, and matches the label selector app.kubernetes.io/managed-by=Helm. This facilitates zero-downtime migrations to Helm 3 for managing existing deployments, and allows Helm to "adopt" existing resources that it previously created.

In order to allow an existing resource to be adopted by Helm, add release metadata and the managed-by label:

KIND=deployment
NAME=my-app-staging
RELEASE=staging
NAMESPACE=default
kubectl annotate $KIND $NAME meta.helm.sh/release-name=$RELEASE
kubectl annotate $KIND $NAME meta.helm.sh/release-namespace=$NAMESPACE
kubectl label $KIND $NAME app.kubernetes.io/managed-by=Helm

Assuming following situation:

  • Deployment created outside of Helm (example below).
  • Helm Chart with equivalent templated Deployment in templates/ (example below).

Creating below Deployment without Helm:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

Assuming that above file is used with kubectl apply and it's also residing in templates/ directory (templated) of your Chart, you will get the following error (when you try to run $ helm install release_name .):

Error: rendered manifests contain a resource that already exists. Unable to continue with install: Deployment "nginx" in namespace "default" exists and cannot be imported into the current release: ... 

By running the script that was mentioned in the answer I linked, you can annotate and label your resources for Helm to not produce mentioned error message.

After that you can run $ helm install release_name . and provision your resources with desired changes.


Additional resources:

A nice oneliner to annotate all resources in a helm release to be adopted by the new release:

x=`mktemp` && helm -n $NAMESPACE get manifest $RELEASE >$x && kubectl annotate -f $x --overwrite "meta.helm.sh/release-name"=$NEW_RELEASE && rm -rf "$x"

Or, if you also moved the release to a new namespace:

x=`mktemp` && helm -n $NAMESPACE get manifest $RELEASE >$x && kubectl annotate -f $x --overwrite "meta.helm.sh/release-name"=$NEW_RELEASE  "meta.helm.sh/release-namespace"=$NEW_NAMESPACE && rm -rf "$x"
Related