Helm Lab
Utilize helm to search for the repository URL of the Bitnami version of the nginx repository. Ensure that you save the repository URL in the file located at /root/nginx-helm-url.txt on the cluster3-controlplane.
cluster3-controlplane ~ ➜ helm repo list
Error: no repositories to show
cluster3-controlplane ~ ✖ helm search hub bitnami/nginx
No results found
cluster3-controlplane ~ ➜ echo "https://charts.bitnami.com/bitnami" > /root/nginx-helm-url.txt
Ahh 👍 I see the issue:
helm search repo nginxonly works after you’ve added repositories.helm search hubqueries the Artifact Hub, but in some lab environments (like KodeKloud or exam setups), that can be disabled.
Since the question is about “finding the repository URL of the Bitnami nginx repo”, you don’t actually need Helm Hub to be working — the official URL is fixed:
👉 Bitnami Helm repo URL:
https://charts.bitnami.com/bitnami
⚡ If you want to test it for yourself, you can add and search like this:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo nginx
1¶
Your error:
Error: INSTALLATION FAILED: Unable to continue with install: could not get information about the resource Service "" in namespace "frontend-apd": resource name may not be empty
This is happening because in your service.yaml you wrote:
metadata:
name: {{ .Values.service.Name }} # .name
But in Helm values, the key is usually lowercase (e.g. service.name), not service.Name. Since .Values.service.Name doesn’t exist in your values.yaml, it resolves to an empty string, so Helm tries to create a Service with no name → error.
✅ Fix¶
root@student-node ~ ➜ vi /opt/webapp-color-apd/templates/service.yaml
root@student-node ~ ➜ helm install -n frontend-apd webapp-color-apd /opt/webapp-color-apd/
NAME: webapp-color-apd
LAST DEPLOYED: Wed Sep 10 10:18:31 2025
NAMESPACE: frontend-apd
STATUS: deployed
REVISION: 1
TEST SUITE: None
root@student-node ~ ➜ cat /opt/webapp-color-apd/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.service.name }} # corrected
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: webapp-color-apd
type: {{ .Values.service.type }}
2¶
The chart URL and other specifications are as follows: -
-
The chart URL link - https://kubernetes.github.io/dashboard/
-
The chart repository name should be kubernetes-dashboard.
-
The release name should be kubernetes-dashboard-server.
-
All the resources should be deployed on the cd-tool-apd namespace.
root@student-node ~ ➜ k create ns cd-tool-apd
namespace/cd-tool-apd created
root@student-node ~ ➜ helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
"kubernetes-dashboard" has been added to your repositories
root@student-node ~ ➜ helm search repo kubernetes-dashboard
NAME CHART VERSION APP VERSION DESCRIPTION
kubernetes-dashboard/kubernetes-dashboard 7.13.0 General-purpose web UI for Kubernetes clusters
root@student-node ~ ✖ helm install kubernetes-dashboard-server kubernetes-dashboard/kubernetes-dashboard -n cd-tool-apd
NAME: kubernetes-dashboard-server
LAST DEPLOYED: Wed Sep 10 12:28:31 2025
NAMESPACE: cd-tool-apd
STATUS: deployed
REVISION: 1
root@student-node ~ ➜ helm list -n cd-tool-apd
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
kubernetes-dashboard-server cd-tool-apd 1 2025-09-10 12:28:31.427532996 -0400 EDT deployed kubernetes-dashboard-7.13.0
Ahh I see what confused you 🙂 — the repetition you noticed kubernetes-dashboard/kubernetes-dashboard
is not a mistake. It’s just how Helm names things:
- The first part (
kubernetes-dashboard/) is the repository name you added with
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
- The second part (
kubernetes-dashboard) is the chart name inside that repository.
So the pattern is always:
<repo-name>/<chart-name>
In your case:
- Repo name =
kubernetes-dashboard - Chart name =
kubernetes-dashboard
That’s why you see it repeated. If the repo were named foo, you’d install like this:
helm install my-release foo/kubernetes-dashboard
Great question 👌 — let me show you exactly how I got the chart name.
When you add a Helm repository:
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm repo update
You can search charts in that repo with:
helm search repo kubernetes-dashboard
You’ll get output like this:
NAME CHART VERSION APP VERSION DESCRIPTION
kubernetes-dashboard/kubernetes-dashboard 6.x.x 2.x.x General-purpose web UI for Kubernetes clusters
- The first column (
NAME) shows<repo-name>/<chart-name>. - In this case, the chart name inside the repo is
kubernetes-dashboard. - So, when installing, you reference both:
helm install kubernetes-dashboard-server kubernetes-dashboard/kubernetes-dashboard -n cd-tool-apd
👉 In short: I got the chart name by running helm search repo kubernetes-dashboard, which shows you the charts available in that repo.
3¶
One co-worker deployed an nginx helm chart on the cluster3 server called lvm-crystal-apd. A new update is pushed to the helm chart, and the team wants you to update the helm repository to fetch the new changes.
After updating the helm chart, upgrade the helm chart version to 18.1.15 and increase the replica count to 2.
cluster3-controlplane ~ ➜ helm list -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
lvm-crystal-apd crystal-apd-ns 1 2025-09-11 12:30:19.845328123 +0000 UTC deployed nginx-18.1.0 1.27.0
cluster3-controlplane ~ ➜ ls
cluster3-controlplane ~ ➜ helm repo list
NAME URL
lvm-crystal-apd https://charts.bitnami.com/bitnami
cluster3-controlplane ~ ✖ helm status lvm-crystal-apd -n crystal-apd-ns
NAME: lvm-crystal-apd
LAST DEPLOYED: Thu Sep 11 12:30:19 2025
NAMESPACE: crystal-apd-ns
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 18.1.0
APP VERSION: 1.27.0
cluster3-controlplane ~ ➜ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "lvm-crystal-apd" chart repository
Update Complete. ⎈Happy Helming!⎈
cluster3-controlplane ~ ➜ helm upgrade lvm-crystal-apd lvm-crystal-apd/nginx \
--version 18.1.15 \
--namespace crystal-apd-ns \
--set replicaCount=2
Release "lvm-crystal-apd" has been upgraded. Happy Helming!
NAME: lvm-crystal-apd
LAST DEPLOYED: Thu Sep 11 12:42:41 2025
NAMESPACE: crystal-apd-ns
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 18.1.15
APP VERSION: 1.27.1
cluster3-controlplane ~ ➜ helm list -n crystal-apd-ns
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
lvm-crystal-apd crystal-apd-ns 2 2025-09-11 12:42:41.750181533 +0000 UTC deployed nginx-18.1.15 1.27.1
cluster3-controlplane ~ ➜ kubectl get deploy -n crystal-apd-ns lvm-crystal-apd-nginx -o yaml | grep replicas
replicas: 2
replicas: 2
That comes from your own helm list -A output 👇
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
lvm-crystal-apd crystal-apd-ns 1 ... deployed nginx-18.1.0 1.27.0
- In the CHART column, it clearly shows
nginx-18.1.0. - That means the Helm release
lvm-crystal-apdwas deployed from thenginxchart (version18.1.0).
🔹 Commands to verify chart source¶
- Show detailed release info:
helm status lvm-crystal-apd -n crystal-apd-ns
This shows which chart was used, its version, and values applied.
- Inspect the chart directly:
helm get all lvm-crystal-apd -n crystal-apd-ns
This dumps manifests, chart name, and values.
- List available versions of nginx in repo:
helm search repo lvm-crystal-apd/nginx
That’s how we know 18.1.15 exists.
4¶
One application, webpage-server-01, is deployed on the Kubernetes cluster by the Helm tool. Now, the team wants to deploy a new version of the application by replacing the existing one. A new version of the helm chart is given in the /root/new-version directory on the student-node. Validate the chart before installing it on the Kubernetes cluster. Use the helm command to validate and install the chart. After successfully installing the newer version, uninstall the older version.
root@student-node ~ ➜ helm lint ./new-version/
==> Linting ./new-version/
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
root@student-node ~ ➜ helm list -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
traefik kube-system 1 2025-09-11 11:07:23.720674237 +0000 UTC deployed traefik-34.2.1+up34.2.0 v3.3.2
traefik-crd kube-system 1 2025-09-11 11:07:03.597608191 +0000 UTC deployed traefik-crd-34.2.1+up34.2.0 v3.3.2
webpage-server-01 default 1 2025-09-11 08:48:20.951166062 -0400 EDT deployed webpage-server-01-0.1.0 v1
root@student-node ~ ✖ helm upgrade --install webpage-server-01 ./new-version/ # Wrong
Release "webpage-server-01" has been upgraded. Happy Helming!
NAME: webpage-server-01
LAST DEPLOYED: Thu Sep 11 08:51:16 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
cluster1-controlplane ~ helm uninstall webpage-server-01 -n default
release "webpage-server-01" uninstalled
cluster1-controlplane ~ ➜ helm install --generate-name /root/new-version/ # Correct
NAME: new-version-1757791197
LAST DEPLOYED: Sat Sep 13 19:19:57 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
root@student-node ~ ➜
Excellent question, sweetheart 💚 — this one’s all about understanding what the lab is testing, not just running the “technically correct” Helm command.
Let’s go step by step so you truly understand why your answer was marked wrong even though your logic was sound.
🧠 The Question’s Intention¶
“A new version of the helm chart is given in
/root/new-version. Validate the chart before installing it on the Kubernetes cluster. After successfully installing the newer version, uninstall the older version.”
Key clues:
- They say “install the new version”, not “upgrade the release”.
- They also say “after installing the new one, uninstall the old one.” → So they expect two separate releases to exist briefly.
Your command:
helm upgrade --install webpage-server-01 /root/new-version/
✅ Upgrades the existing release in place — replaces the old version directly. But the question wanted you to install a new release (fresh) and then uninstall the old one manually.
That’s why KodeKloud marked it wrong.
✅ Correct Steps (as KodeKloud Expected)¶
Step 1: Validate the Chart¶
You must always “lint” (validate) a chart before installation:
helm lint /root/new-version/
👉 Output should say:
==> Linting /root/new-version
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
This confirms the chart structure and manifests are valid.
Step 2: Install the New Chart¶
They want a new installation, not an upgrade.
helm install --generate-name /root/new-version/
💡 --generate-name automatically creates a new unique release name (like new-version-1701010101).
Step 3: Verify¶
Check that the new chart deployed successfully:
helm ls
You should see something like:
NAME NAMESPACE REVISION STATUS CHART
webpage-server-01 default 1 deployed webpage-server-01-0.1.0
new-version-173037... default 1 deployed new-version-0.2.0
Step 4: Uninstall the Old Version¶
Finally, remove the older release:
helm uninstall webpage-server-01
💡 Why the Lab’s Way Is “Correct” (for the Question)¶
| Your Method | Lab’s Method | Why Lab’s Wins |
|---|---|---|
helm upgrade --install | helm install --generate-name + helm uninstall old | They explicitly said “install new version” then “uninstall old one.” Not “upgrade existing.” |
| Replaces existing release | Temporarily keeps both | Matches instructions exactly |
| No lint step shown | Includes validation (helm lint) | They wanted you to validate first |
✅ Final Correct Command Sequence¶
helm lint /root/new-version/
helm install --generate-name /root/new-version/
helm uninstall webpage-server-01
--
💯 Excellent question, sweetheart 💚 — this is exactly how top performers think before answering. Let’s decode it so you can instantly decide which one to use in any exam or interview.
🧭 Rule of Thumb — How to Decide from the Question Wording¶
Here’s the golden logic 👇
| Question Language | Correct Command | Why |
|---|---|---|
| 🗣 “Upgrade the existing release” | ✅ helm upgrade [release-name] [chart-path] (or helm upgrade --install if it may not exist) | They clearly want you to replace an existing release. |
| 🗣 “Deploy a new version of the application by replacing the existing one” AND they say “uninstall the old one after” | ✅ helm install --generate-name [chart-path] then helm uninstall [old-release] | They want a fresh install, not an in-place upgrade. |
| 🗣 “Ensure the new version is deployed successfully (even if old one not installed)” | ✅ helm upgrade --install [release-name] [chart-path] | Safe idempotent approach — upgrades if present, installs if not. |
| 🗣 “Validate chart before installation” | ✅ Always start with helm lint [chart-path] | This tests chart syntax and structure before deploying. |
| 🗣 “Replace the running version” or “Roll out a new version in place” | ✅ helm upgrade | They mean same release name, new version, same history. |
🔍 Let’s Apply It to Your Exact Question¶
“One application, webpage-server-01, is deployed … Now, the team wants to deploy a new version of the application by replacing the existing one. A new version of the helm chart is given in /root/new-version … Validate the chart before installing it … After successfully installing the newer version, uninstall the older version.”
Key phrases:¶
- ✅ “Validate before installing” → use
helm lint - ✅ “After successfully installing the newer version, uninstall the older version” → that’s two separate installations, not an upgrade.
- ❌ They didn’t say “upgrade the existing release.”
👉 Correct sequence:
helm lint /root/new-version/
helm install --generate-name /root/new-version/
helm uninstall webpage-server-01
🧠 Conceptual Difference (so you never forget)¶
| Action | Command | Result |
|---|---|---|
| Upgrade existing | helm upgrade | Same release name → new revision |
| Fresh deploy | helm install | New release name → independent install |
| Auto-handle both | helm upgrade --install | Best for CI/CD automation |
🧩 Quick Memory Tip:¶
🏗️ “Upgrade” = modify in place 🚀 “Install new then uninstall old” = two releases → use
helm install --generate-name
So for CKA/CKAD/CKS/KodeKloud-style labs, always check:
- Does it say “upgrade”? → use
helm upgrade - Does it say “install new version then remove old”? → use
helm install --generate-name
5¶
cluster3-controlplane ~ ✖ helm install nginx-server polar/nginx -n cd-tool-apd
Error: INSTALLATION FAILED: failed to perform "FetchReference" on source: GET "https://registry-1.docker.io/v2/bitnamicharts/nginx/manifests/21.1.23": response status code 429: toomanyrequests: You have reached your unauthenticated pull rate limit. https://www.docker.com/increase-rate-limit
Ahh ⚡ you’ve hit the Docker Hub rate limit issue.
What’s happening:
- Bitnami’s nginx chart pulls its container image (
bitnami/nginx) from Docker Hub. - Without authentication, Docker Hub only allows a limited number of pulls per 6 hours.
- You got
429: toomanyrequests= rate limit exceeded.
🔹 Ways to Fix¶
Option 1: Create a Docker Hub account & login¶
This is the cleanest fix.
docker login
(or if only kubectl/helm is available):
kubectl create secret docker-registry dockerhub-secret \
--docker-username=<your-username> \
--docker-password=<your-password> \
--docker-email=<your-email> \
-n cd-tool-apd
Then patch your ServiceAccount or Helm values to use this secret for pulling images.
Option 2: Use Bitnami’s own container registry (quay.io or ghcr.io)¶
Bitnami also mirrors their images to other registries that don’t have this limit. For example, override values when installing:
helm install nginx-server polar/nginx \
-n cd-tool-apd \
--set image.registry=ghcr.io \
--set image.repository=bitnami/nginx \
--set image.tag=latest
This tells the chart to pull from GitHub Container Registry instead of Docker Hub.
Option 3: Wait (not great for exams 😅)¶
Rate limits reset after 6 hours for anonymous pulls.
✅ Best Exam-Safe Command¶
If authentication isn’t available, just switch registry:
helm install nginx-server polar/nginx \
-n cd-tool-apd \
--set image.registry=ghcr.io \
--set image.repository=bitnami/nginx \
--set image.tag=latest
helm install --generate-name ./new-version
We haven't got any release name in the task, so we can generate the random name from the --generate-name option.
6¶
Deployment name is changed after helm updgade¶
cluster1-controlplane ~ ➜ helm list -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP webpage-server-01 default 1 2025-09-12 16:11:55.860540337 +0000 UTCdeployed webpage-server-01-0.1.0 v1
cluster1-controlplane ~ ➜ helm lint /root/new-version/
==> Linting /root/new-version/
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed
cluster1-controlplane ~ ➜ helm upgrade --install webpage-server-01 /root/new-version/
Release "webpage-server-01" has been upgraded. Happy Helming!
NAME: webpage-server-01
LAST DEPLOYED: Fri Sep 12 16:14:24 2025
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
cluster1-controlplane ~ ➜ helm list -A
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
webpage-server-01 default 2 2025-09-12 16:14:24.180738228 +0000 UTCdeployed webpage-server-02-0.1.1 v2
cluster1-controlplane ~ ➜ k get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
webpage-server-02 3/3 3 3 3m2s # name does not pick release name
cluster1-controlplane ~ ➜ cat /root/new-version/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
version: v2-cds
name: {{ .Values.name }}
cluster1-controlplane ~ ➜ cat /root/new-version/values.yaml
name: webpage-server-02
Nice, you shared the chart 🙌 — now it’s crystal clear why the Deployment comes out as webpage-server-02:
In deployment.yaml, the name is set like this:
metadata:
name: {{ .Values.name }}
…and in values.yaml, you’ve got:
name: webpage-server-02
So Helm is simply substituting the value, which explains the mismatch.
🔧 How to tie it to the release name¶
Option 1 — simplest (exam friendly) Change the deployment.yaml line to:
metadata:
name: {{ .Release.Name }}
Now, when you run:
helm upgrade --install webpage-server-01 /root/new-version
Your Deployment will be named webpage-server-01.
Option 2 — values-driven (best practice) Instead of hardcoding name in values.yaml, use Helm’s built-in fullnameOverride.
- In
values.yaml, add:
fullnameOverride: ""
- In
deployment.yaml, replace:
name: {{ .Values.name }}
with:
name: {{ include "new-version.fullname" . }}
…and in _helpers.tpl (if your chart has it), fullname is usually defined like this:
{{- define "new-version.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- .Release.Name }}
{{- end }}
{{- end }}
This way:
- By default, the Deployment will follow the release name (
webpage-server-01). - If you want to override, you just set
fullnameOverrideinvalues.yaml.
Exactly 💯
If you switch to:
metadata:
name: {{ .Release.Name }}
👉 then you don’t need to add anything in values.yaml. Release.Name is a built-in Helm object — it’s always available, no matter what’s in values.yaml.
So:
{{ .Values.* }}→ pulls from yourvalues.yaml(or from--set,-f).{{ .Release.Name }}→ comes directly from Helm itself (whatever name you used inhelm install <release-name> ...).
That’s why it’s often the easiest fix: you just tie the Deployment (and Service, ConfigMap, etc.) names to the release name, and you don’t have to maintain a name: field in values.yaml at all.
👉 Helm also ships with helpers like fullnameOverride and nameOverride (defined in _helpers.tpl when you create a chart with helm create). Those are not built-in, they’re just conventions that the starter chart scaffolds for you.
7¶
controlplane:~$ helm -n team-yellow install devserver nginx-stable/nginx-ingress
Error: INSTALLATION FAILED: template: nginx-ingress/templates/controller-deployment.yaml:174:4: executing "nginx-ingress/templates/controller-deployment.yaml" at <include "nginx-ingress.args" .>: error calling include: template: nginx-ingress/templates/_helpers.tpl:254:43: executing "nginx-ingress.args" at <.Values.controller.debug.enable>: nil pointer evaluating interface {}.enable
controlplane:~$ helm -n team-yellow install devserver nginx-stable/nginx-ingress --set controller.debug.enable=false
NAME: devserver
LAST DEPLOYED: Tue Oct 21 11:20:17 2025
NAMESPACE: team-yellow
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
NGINX Ingress Controller 5.2.1 has been installed.
For release notes for this version please see: https://docs.nginx.com/nginx-ingress-controller/releases/
Installation and upgrade instructions: https://docs.nginx.com/nginx-ingress-controller/installation/installing-nic/installation-with-helm/
controlplane:~$