Neil Kuan
May 6, 2024

Helm 101

Posted on May 6, 2024  •  8 minutes  • 1578 words
  1. Install nginx chart into default namespace
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install nginx bitnami/nginx --namespace default
  1. List all release in that namespace
helm ls -n default
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
nginx   default         1               2023-11-09 11:20:06.581867 +0800 CST    deployed        nginx-15.4.0    1.25.3

### List all namespace helm released
helm ls -A 
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
nginx   default         1               2023-11-09 11:20:06.581867 +0800 CST    deployed        nginx-15.4.0    1.25.3
  1. Get installed released values
helm get values nginx 
USER-SUPPLIED VALUES:
null
  1. Show default chart values
helm show values bitnami/nginx > values-nginx.yaml

--- cat values-nginx.yaml ---
...
# Copyright VMware, Inc.
# SPDX-License-Identifier: APACHE-2.0

## @section Global parameters
## Global Docker image parameters
## Please, note that this will override the image parameters, including dependencies, configured to use the global value
## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass

## @param global.imageRegistry Global Docker image registry
## @param global.imagePullSecrets Global Docker registry secret names as an array
##
global:
  imageRegistry: ""
  ## E.g.
  ## imagePullSecrets:
  ##   - myRegistryKeySecretName
  ##
  imagePullSecrets: []
... etc ...
  1. helm add/remove repo
#           [repo-name] [repo-url] 
helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been removed from your repositories

# update repo 
helm repo update [repo-name]

helm repo remove bitnami
  1. helm diff with plugin , get released and will released chart diff
# step 0. install helm-diff plugin (Using Helm plugin manager (> 2.3.x)
helm plugin install https://github.com/databus23/helm-diff

# step 1. helm install released named nginx from "bitnami/nginx" chart.

helm install nginx bitnami/nginx 
NAME: nginx
LAST DEPLOYED: Thu Nov  9 16:04:32 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 15.4.0
APP VERSION: 1.25.3

** Please be patient while the chart is being deployed **
NGINX can be accessed through the following DNS name from within your cluster:

    nginx.default.svc.cluster.local (port 80)

To access NGINX from outside the cluster, follow the steps below:

1. Get the NGINX URL by running these commands:

  NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        Watch the status with: 'kubectl get svc --namespace default -w nginx'

    export SERVICE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].port}" services nginx)
    export SERVICE_IP=$(kubectl get svc --namespace default nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo "http://${SERVICE_IP}:${SERVICE_PORT}"



# step2. use helm-diff get diff
helm diff upgrade nginx bitnami/nginx --set image.tag=latest    
default, nginx, Deployment (apps) has changed:
...
        initContainers:
        containers:
          - name: nginx
-           image: docker.io/bitnami/nginx:1.25.3-debian-11-r0
+           image: docker.io/bitnami/nginx:latest
            imagePullPolicy: "IfNotPresent"
            securityContext:
              allowPrivilegeEscalation: false
...

1.png 2.png

  1. helm upgrade –dry-run vs helm template helm upgrade –dry-run

The helm upgrade –dry-run command serves as a valuable tool for validating and testing Helm chart deployments without altering the Kubernetes cluster. It performs a simulated upgrade of the chart, rendering the configuration and identifying potential conflicts without making any actual changes to the cluster’s resources. This functionality is particularly useful for thoroughly testing the deployment process, ensuring the desired configuration is generated, and detecting any potential issues before deploying the chart to a production environment.

helm template

The helm template command provides a detailed view of the rendered configuration generated by a Helm chart template. It outputs the YAML manifest that would be applied to the cluster if the chart were upgraded using the helm upgrade command. This detailed representation allows for thorough inspection of the generated configuration, enabling users to identify any necessary adjustments before proceeding with the deployment. Understanding the evaluated Helm templates and the resulting configuration is crucial for ensuring the chart is deployed as intended.

Feature helm upgrade –dry-run helm template
Purpose Simulated chart upgrade without changes Renders chart template into YAML manifest
Level of detail Shows rendered configuration and conflicts Shows rendered configuration in YAML format
Deployment impact No impact on cluster No impact on cluster
Usage Scenarios Validating deployment process, identifying conflicts, validating configuration before deployment Inspecting rendered configuration, understanding template evaluation, making manual adjustments
  1. Search chart name contain nginx
helm search repo nginx
NAME                                            CHART VERSION   APP VERSION     DESCRIPTION                                       
bitnami/nginx                                   15.4.0          1.25.3          NGINX Open Source is a web server that can be a...
bitnami/nginx-ingress-controller                9.9.2           1.9.3           NGINX Ingress Controller is an Ingress controll...
bitnami/nginx-intel                             2.1.15          0.4.9           DEPRECATED NGINX Open Source for Intel is a lig...
prometheus-community/prometheus-nginx-exporter  0.2.0           0.11.0          A Helm chart for the Prometheus NGINX Exporter    



# List all chart and version (show the long listing)
helm search repo nginx -l                                   
NAME                                            CHART VERSION   APP VERSION     DESCRIPTION                                       
bitnami/nginx                                   15.4.0          1.25.3          NGINX Open Source is a web server that can be a...
bitnami/nginx                                   15.3.5          1.25.3          NGINX Open Source is a web server that can be a...
bitnami/nginx                                   15.3.4          1.25.2          NGINX Open Source is a web server that can be a...
...
bitnami/nginx                                   12.0.2          1.22.0          NGINX Open Source is a web server that can be a...
bitnami/nginx                                   12.0.1          1.22.0          NGINX Open Source is a web server that can be a...
bitnami/nginx-ingress-controller                9.9.2           1.9.3           NGINX Ingress Controller is an Ingress controll...
bitnami/nginx-ingress-controller                9.9.1           1.9.1           NGINX Ingress Controller is an Ingress controll...
...
bitnami/nginx-ingress-controller                9.2.8           1.2.1           NGINX Ingress Controller is an Ingress controll...
bitnami/nginx-ingress-controller                9.2.6           1.2.1           NGINX Ingress Controller is an Ingress controll...
bitnami/nginx-intel                             2.1.15          0.4.9           DEPRECATED NGINX Open Source for Intel is a lig...
bitnami/nginx-intel                             2.1.14          0.4.9           NGINX Open Source for Intel is a lightweight se...
...
bitnami/nginx-intel                             2.0.7           0.4.7           NGINX Open Source for Intel is a lightweight se...
prometheus-community/prometheus-nginx-exporter  0.2.0           0.11.0          A Helm chart for the Prometheus NGINX Exporter    
prometheus-community/prometheus-nginx-exporter  0.1.1           0.11.0          A Helm chart for the Prometheus NGINX Exporter    
prometheus-community/prometheus-nginx-exporter  0.1.0           0.11.0          A Helm chart for the Prometheus NGINX Exporter
  1. Download the chart from repo to local.
## download nginx chart version 15.1.2 from bitnami/nginx repo 
helm pull bitnami/nginx --version 15.1.2

ls -l nginx-15.1.2.tgz            
.rw-r--r-- neil.kuan staff 37 KB Thu Nov  9 16:15:06 2023  nginx-15.1.2.tgz
  1. Publish helm chart to AWS ECR docs: https://splashtop.atlassian.net/wiki/spaces/~712020e6d0f2d2753c4a999b035548993f6100/pages/942670252/Helm+101#docs%3A-Push-Helm-Chart---Amazon-ECR

a. 建立一個名為 helm-test-chart 的 Helm Chart 並清除 templates 目錄的內容。

helm create helm-test-chart
rm -rf ./helm-test-chart/templates/*

b. 在 templates 資料夾中建立 ConfigMap。

cd helm-test-chart/templates
cat <<EOF > configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: helm-test-chart-configmap
data:
  myvalue: "Hello World"
EOF

c. 封裝圖表。輸出將包含您在推送 Helm Chart 時使用的封裝圖表的檔案名稱。

cd ../..
helm package helm-test-chart
--- output ---
Successfully packaged chart and saved it to: /Users/username/helm-test-chart-0.1.0.tgz

d. 建立儲存庫以存放 Helm Chart。儲存庫的名稱應與您在步驟 2 中建立 Helm Chart 時使用的名稱相符。如需更多詳細資訊

aws ecr create-repository \
     --repository-name helm-test-chart \
     --region us-west-2

e. 將您的 Helm 用戶端驗證到您打算將 Helm Chart 推送到的 Amazon ECR 登錄檔。所用的每個登錄檔皆必須取得身分驗證字符,字符有效期間為 12 個小時。如需更多詳細資訊,請參閱 私有登錄檔身分驗證。

aws ecr get-login-password \
     --region us-west-2 | helm registry login \
     --username AWS \
     --password-stdin aws_account_id.dkr.ecr.us-west-2.amazonaws.com

f. 使用 helm push 命令推送 Helm Chart。輸出應該包括 Amazon ECR 儲存庫 URI 和 SHA 摘要。

helm push helm-test-chart-0.1.0.tgz oci://aws_account_id.dkr.ecr.us-west-2.amazonaws.com/

g. 描述您的 Helm Chart。

aws ecr describe-images \
     --repository-name helm-test-chart \
     --region us-west-2
--- output ---
{
    "imageDetails": [
        {
            "registryId": "aws_account_id",
            "repositoryName": "helm-test-chart",
            "imageDigest": "sha256:dd8aebdda7df991a0ffe0b3d6c0cf315fd582cd26f9755a347a52adEXAMPLE",
            "imageTags": [
                "0.1.0"
            ],
            "imageSizeInBytes": 1620,
            "imagePushedAt": "2021-09-23T11:39:30-05:00",
            "imageManifestMediaType": "application/vnd.oci.image.manifest.v1+json",
            "artifactMediaType": "application/vnd.cncf.helm.config.v1+json"
        }
    ]
}
  1. Helm diif plugin update version
helm diff version 
3.8.1

helm plugin update diff     

Downloading https://github.com/databus23/helm-diff/releases/latest/download/helm-diff-macos-arm64.tgz
Preparing to install into /Users/neil.kuan/Library/helm/plugins/helm-diff
helm-diff installed into /Users/neil.kuan/Library/helm/plugins/helm-diff/helm-diff


helm diff version                                         
3.9.4
  1. Helm imported existed resource to managed ref: https://github.com/helm/helm/pull/7649

從 Helm 3.2 開始,可以將現有資源導入/採用到 helm 版本¹ 中。要實現這一點,您只需要在資源中添加以下註釋和標籤:

annotations:
  meta.helm.sh/release-name: app-release-name
  meta.helm.sh/release-namespace: app-deploy-namespace-name
labels:
  app.kubernetes.io/managed-by: Helm 

a. Example create namespace name app-ns

$ kubectl create namespace app-ns
namespace/app-ns created

b. Get Namespace

$ kubectl get namespace app-ns -o yaml
--- output ---
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2024-05-06T00:30:46Z"
  labels:
    kubernetes.io/metadata.name: app-ns
  name: app-ns
  resourceVersion: "1039976"
  uid: a2f0c6b0-06d4-480c-bf2b-41532f1973c4
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

c. Add labels and annotates by which release name and release namespace

KIND=namespace
NAME=app-ns
RELEASE_NAME=<????>
NAMESPACE=app-ns
kubectl annotate $KIND $NAME meta.helm.sh/release-name=$RELEASE_NAME
kubectl annotate $KIND $NAME meta.helm.sh/release-namespace=$NAMESPACE
kubectl label $KIND $NAME app.kubernetes.io/managed-by=Helm

d. Example I want to managed this namespace in helm release name app-v1

KIND=namespace
NAME=app-ns
RELEASE_NAME=app-v1
NAMESPACE=app-ns
kubectl annotate $KIND $NAME meta.helm.sh/release-name=$RELEASE_NAME
kubectl annotate $KIND $NAME meta.helm.sh/release-namespace=$NAMESPACE
kubectl label $KIND $NAME app.kubernetes.io/managed-by=Helm
namespace/app-ns annotated
namespace/app-ns annotated
namespace/app-ns labeled

e. After added labels and annotates

$ kubectl get namespace app-ns -o yaml
--- output ---
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    meta.helm.sh/release-name: app-v1
    meta.helm.sh/release-namespace: app-ns
  creationTimestamp: "2024-05-06T00:30:46Z"
  labels:
    app.kubernetes.io/managed-by: Helm
    kubernetes.io/metadata.name: app-ns
  name: app-ns
  resourceVersion: "1040072"
  uid: a2f0c6b0-06d4-480c-bf2b-41532f1973c4
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
  1. Troubleshooting Try to import app-ns namespace into helm chart helm-lab in app-v1 release. 3.png

🚨 🚨 🚨 Meet this error 🚨 🚨 🚨

Error: INSTALLATION FAILED: Unable to continue with install:
Namespace "app-ns" in namespace "" exists and cannot be imported into the current release: 
  invalid ownership metadata;
annotation validation error: key "meta.helm.sh/release-namespace" 
must equal "app-ns": current value is "app"

4.png Check out the labels and annotates at app-ns namespace

$ kubectl get namespace app-ns -o yaml

--- output ---
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    meta.helm.sh/release-name: app-v1
    meta.helm.sh/release-namespace: app
  creationTimestamp: "2024-05-06T00:30:46Z"
  labels:
    app.kubernetes.io/managed-by: Helm
    kubernetes.io/metadata.name: app-ns
  name: app-ns
  resourceVersion: "1040199"
  uid: a2f0c6b0-06d4-480c-bf2b-41532f1973c4
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

This issue case by annotate meta.helm.sh/release-namespace: app, no equal at helm install helm-lab chart that use namespace app-ns. 5.png 6.png

Let’s fix this issue by overwrite this annotate

$ kubectl annotate ns app-ns 'meta.helm.sh/release-namespace=app-ns' --overwrite

Check app-ns namespace again

$ kubectl get namespace app-ns -o yaml

--- output ---
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    meta.helm.sh/release-name: app-v1
    meta.helm.sh/release-namespace: app-ns
  creationTimestamp: "2024-05-06T00:30:46Z"
  labels:
    app.kubernetes.io/managed-by: Helm
    kubernetes.io/metadata.name: app-ns
  name: app-ns
  resourceVersion: "1040489"
  uid: a2f0c6b0-06d4-480c-bf2b-41532f1973c4
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

Install helm chart helm-lab release name app-v1 success!!! 7.png

Check app-ns namespace again

$ kubectl get namespace app-ns -o yaml

--- output ---
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    meta.helm.sh/release-name: app-v1
    meta.helm.sh/release-namespace: app-ns
  creationTimestamp: "2024-05-06T00:30:46Z"
  labels:
    app.kubernetes.io/managed-by: Helm
    kubernetes.io/metadata.name: app-ns
  name: app-ns
  resourceVersion: "1040489"
  uid: a2f0c6b0-06d4-480c-bf2b-41532f1973c4
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

20240326 Neil Kuan Updated

Follow me

Here's where I hang out in social media