Helm Nedir, Kustomize'dan Farkı Ne? Chart, Release, Repository ve Helm 4 Kurulumu
Helm, Kubernetes manifest'lerini template'leyen, chart olarak paketleyen ve kurulumları release olarak kaydedip upgrade, rollback ve history sağlayan araçtır; Kustomize ise yalnızca düz YAML üzerine overlay yapar. Helm 4'ü kurup Artifact Hub'dan Valkey chart'ını kuruyor, release'in cluster'da Secret olarak nasıl saklandığını açıyor ve Bitnami'nin 2025 katalog değişikliğiyle 'deployed' görünen ama hiç başlamayan bir release'i gerçek çıktılarla inceliyoruz.
Sürüm notu: Bu yazıdaki örnekler Helm 4.3.2, kind 0.33 ile Kubernetes 1.37 ve kubectl 1.37 ile denenmiştir.
Önce Tahmin Et
Artifact Hub'da en çok bilinen Redis chart'larından birinin 2025 yazında çıkmış bir sürümünü kuruyorsun. Komut sorunsuz bitiyor ve Helm ekrana STATUS: deployed yazıyor. Soru şu: Redis şu an çalışıyor mu? "deployed" kelimesi pod'ların ayağa kalktığını mı, yoksa başka bir şeyi mi söylüyor? Cevap bu yazının son bölümlerinde, gerçek çıktısıyla duruyor. Bu soru seri boyunca karşımıza çıkacak.
Sorun: Environment Başına Kopyalanan YAML
Kubernetes serisinde Bookstore'u (sitedeki serilerin ortak örnek uygulaması, bir online kitapçı) cluster'a düz YAML (manifest'lerin yazıldığı metin formatı) dosyalarıyla taşıdık: Deployment, Service, ConfigMap, Secret, probe'lar, Job. Bir environment için bu dosyalar okunaklı ve yeterli. İkinci environment geldiğinde ilk refleks klasörü kopyalamak oluyor. Üçüncüsünde image tag'i, replica sayısı, connection string'in Secret adı ve resource'lar üç yerde ayrı ayrı güncelleniyor; altı ay sonra hangisinin doğru olduğunu kimse bilmiyor. Kubernetes serisinin 14. yazısında Kustomize'ın bu soruna base ve overlay ile verdiği cevabı gördük.
Helm aynı soruna farklı bir yerden yaklaşır ve üç iş birden yapar. Birincisi template'leme: manifest'ler Go template dosyalarıdır, değişen her şey values'tan gelir. İkincisi paketleme: template'ler, varsayılan values ve metadata tek bir chart olarak sürümlenir, bir repository'ye konur ve başkası tek komutla kurar. Üçüncüsü release yaşam döngüsü: Helm cluster'a ne kurduğunu kaydeder; upgrade, rollback, history ve uninstall bu kayıt üzerinden çalışır. Kustomize yalnızca birinci işin karşılığıdır, diğer ikisi onun konusu değildir.
Helm ile Kustomize: Aynı Sorun, İki Cevap
| Konu | Kustomize | Helm |
|---|---|---|
| Yöntem | Düz YAML üzerine patch ve overlay | Go template ve values |
| Kaynak dosya | Her dosya geçerli bir manifest | Template'ler render edilmeden geçerli YAML değil |
| Dağıtım | Git'teki klasör | Sürümlü chart paketi (repository ya da registry) |
| Cluster'daki kayıt | Yok, kubectl apply sonuçları | Release ve revision geçmişi |
| Geri alma | Git'te geri dönüp tekrar apply | helm rollback |
| Uygun olduğu yer | Kendi uygulamanın environment farkları | Başkalarının kuracağı, çok ayarlı paketler |
Bu ikisi birbirinin rakibi değil. Sık görülen düzen, üçüncü parti bileşenleri (ingress controller, cert-manager, veritabanı operator'ü) Helm chart'larıyla kurmak, kendi uygulamanın farklarını Kustomize ile yönetmek. Bu seride Bookstore için kendi chart'ımızı yazıyoruz, çünkü hook, sürümlü paket ve release geçmişi bizim için de işe yarıyor. İkisini birleştirmek de mümkün: Kustomize'ın helmCharts alanı bir chart'ı render edip üzerine patch uygulayabilir, Helm 4'ün post-renderer plugin'leri ise render edilmiş çıktıyı başka bir araçtan geçirebilir (serinin yedinci yazısı).
Kavramlar: Chart, Values, Release, Revision, Repository

Chart, bir uygulamayı Kubernetes'e kurmak için gereken her şeyi içeren klasördür: Chart.yaml (ad, sürüm, bağımlılıklar), values.yaml (varsayılan ayarlar) ve templates/ altındaki template'ler. Values, template'lere giren ayarlardır; chart'ın varsayılanları -f ile verilen dosyalar ve --set ile verilen tek tek değerlerle ezilir. Helm bu ikisini birleştirip template'leri render eder, ortaya düz YAML manifest'ler çıkar ve bunlar API server'a gönderilir.
Release, bir chart'ın belirli bir isimle belirli bir namespace'e kurulmuş hâlidir. Aynı chart aynı cluster'a cache ve sessions adıyla iki kez kurulabilir; ikisi ayrı release'tir. Her install, upgrade ve rollback release'in yeni bir revision'ını üretir. Rollback eski revision'a "geri gitmez", eski revision'ın içeriğini yeni bir revision olarak tekrar uygular; bunu beşinci yazıda gerçek çıktılarla göreceğiz.
Repository iki türlüdür. Klasik repository bir HTTP sunucusundaki index.yaml dosyası ve yanındaki .tgz paketleridir; helm repo add ile eklenir. OCI (Open Container Initiative; container image'ları için açık standart) registry'lerinde ise chart, container image'ı gibi bir artifact olarak saklanır ve oci:// adresiyle doğrudan kullanılır; repo add gerekmez. Docker Hub, GHCR (GitHub Container Registry; GitHub'ın registry servisi) ve bulut sağlayıcıların registry'leri chart saklayabiliyor. Altıncı yazıda Bookstore chart'ını kendi OCI registry'mize push edeceğiz.
Helm 4'ü Kurmak
Helm 4.0.0, 12 Kasım 2025'te KubeCon'da çıktı; altı yıl sonraki ilk major sürüm. Bu yazının yazıldığı gün güncel sürüm 4.3.2 (13 Kasım 2026). Windows'ta resmî kurulum sayfasındaki paket yöneticilerinden birini kullanabilirsin (bu komutları bu yazı için çalıştırmadım; winget'teki paket 4.3.2'yi gösteriyor):
# Windows (PowerShell): üç paket yöneticisinden biri yeter
winget install Helm.Helm
choco install kubernetes-helm
scoop install helm
Kurulumdan sonra sürümü ve hangi cluster'a konuşacağını kontrol et. Helm, kubectl ile aynı kubeconfig'i ve aynı current context'i kullanır; yanlış context'te bir helm uninstall kubectl'deki kadar can yakar.
helm version
version.BuildInfo{Version:"v4.3.2", GitCommit:"8346aaa55e7161f7c547212d0a87f01367976727", GitTreeState:"clean", GoVersion:"go1.27.4", KubeClientVersion:"v1.37"}
kubectl config current-context
kind-helmseries-1
KubeClientVersion, Helm'in derlendiği Kubernetes client kütüphanesinin sürümü. Bu sürüm, helm template gibi cluster'a bağlanmayan komutlarda varsayılan Kubernetes sürümü olarak kullanılır; ikinci yazıda bunun ne anlama geldiğine bakacağız. Bu seride lab cluster'ı kind ile kuruldu; kurulumu Kubernetes serisinin ikinci yazısında anlatılıyor.
Artifact Hub'dan Hazır Bir Chart Kurmak
Artifact Hub, CNCF'in (Cloud Native Computing Foundation; Kubernetes'i ve Helm'i barındıran vakıf) chart'lar ve başka paketler için arama sitesi. Helm'den doğrudan aranabilir:
helm search hub redis --max-col-width 60
URL CHART VERSION APP VERSION DESCRIPTION
https://artifacthub.io/packages/helm/scalified-redis/redis 8.8.4 8.8.4 Redis Helm Chart
https://artifacthub.io/packages/helm/magefleet-redis/redis 0.1.0 7.2 A Helm chart for Redis 7.2 with persistence and configura...
https://artifacthub.io/packages/helm/redis-arm/redis 17.8.0 7.0.8 Redis(R) is an open source, advanced key-value store. It ...
https://artifacthub.io/packages/helm/redis/redis 0.1.1 6.0.8.9 A Helm chart for Redis.
https://artifacthub.io/packages/helm/ot-container-kit/redis 0.16.10 0.16.10 Provides easy redis setup definitions for Kubernetes serv...
...
"redis" araması onlarca chart döndürüyor; hepsinin adı redis, çoğunun kimin bakımında olduğu belli değil. Chart seçmek, bir NuGet paketi seçmekten farklı değil: bakımcı kim, son sürüm ne zaman çıktı, hangi image'ı nereden çekiyor, lisansı ne. Bu örnekte Redis'in açık kaynak çatalı Valkey'in kendi projesinin yayımladığı chart'ı kullanıyoruz. Artifact Hub'da yayımcısı doğrulanmış görünüyor, image'ı Docker Hub'daki resmî valkey/valkey. Bu chart klasik bir repository'de duruyor:
helm repo add valkey https://valkey.io/valkey-helm/
helm repo update
helm search repo valkey
"valkey" has been added to your repositories
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "valkey" chart repository
Update Complete. ⎈Happy Helming!⎈
NAME CHART VERSION APP VERSION DESCRIPTION
valkey/valkey 1.0.0 9.1.3 Valkey, an open source, high-performance in-mem...
valkey/valkey-operator 0.9.0 v0.9.0 A Helm chart for the Valkey Operator
valkey/valkey-resources 0.6.0 v0.9.0 Helm chart for operator-managed Valkey resource...
Kurulum, release adı ve namespace ile:
helm install cache valkey/valkey --version 1.0.0 -n cache --create-namespace --wait --timeout 3m
NAME: cache
LAST DEPLOYED: Sun Nov 15 07:00:17 2026
NAMESPACE: cache
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
⭐ Valkey has been deployed!
Release: cache
Namespace: cache
Chart: valkey 1.0.0
App version: 9.1.3
...
🔓 Authentication is DISABLED
- Enable with: `--set auth.enabled=true` and provide `.auth.aclUsers`.
...
💾 Persistence
- Persistence is DISABLED. Data will not survive Pod restarts.
Buradaki --wait önemli: Helm 4 bu bayrakla kaynakları kstatus kütüphanesiyle izler ve Deployment hazır olana kadar komutu bitirmez. Bayrak yoksa Helm manifest'leri API server'a gönderdikten hemen sonra döner. NOTES bölümü chart yazarının kurulumdan sonra gösterdiği metin; burada authentication'ın ve persistence'ın kapalı olduğunu açıkça söylüyor. Varsayılan values'ın production için uygun olduğunu varsayma; helm show values valkey/valkey --version 1.0.0 ile kurmadan önce bütün ayarları okuyabilirsin.
helm list -n cache
kubectl -n cache get pods,svc
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
cache cache 1 2026-11-15 07:00:17.714917 +0300 +03 deployed valkey-1.0.0 9.1.3
NAME READY STATUS RESTARTS AGE
pod/cache-valkey-7577b98f4f-6qg2s 1/1 Running 0 11s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cache-valkey ClusterIP <cluster-ip> <none> 6379/TCP 12s
helm status release'in son durumunu ve Helm 4'te varsayılan olarak release'e ait resource'ları gösterir:
helm status cache -n cache
NAME: cache
LAST DEPLOYED: Sun Nov 15 07:06:13 2026
NAMESPACE: cache
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
RESOURCES:
==> v1/ServiceAccount
NAME AGE
cache-valkey 12s
==> v1/ConfigMap
NAME DATA AGE
cache-valkey-init-scripts 1 12s
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cache-valkey ClusterIP <cluster-ip> <none> 6379/TCP 12s
==> v1/Deployment
NAME READY UP-TO-DATE AVAILABLE AGE
cache-valkey 1/1 1 1 12s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
cache-valkey-7577b98f4f-t2jfc 1/1 Running 0 12s
Release Bilgisi Nerede Durur?
Helm 2'de bu bilgi cluster'daki Tiller adlı bir sunucu bileşeninde tutuluyordu. Helm 3'ten beri sunucu tarafı yok: release kaydı, release'in namespace'inde bir Secret olarak saklanıyor. Helm 4 aynı yapıyı kullanıyor:
kubectl -n cache get secrets -l owner=helm --show-labels
NAME TYPE DATA AGE LABELS
sh.helm.release.v1.cache.v1 helm.sh/release.v1 1 20s modifiedAt=1794715229,name=cache,owner=helm,status=deployed,version=1
Bir upgrade yapıp history'ye bakalım. Upgrade'de memory request'ini değiştirdik:
helm upgrade cache valkey/valkey --version 1.0.0 -n cache --set resources.requests.memory=64Mi --wait
helm history cache -n cache
Release "cache" has been upgraded. Happy Helming!
...
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Sun Nov 15 07:00:17 2026 superseded valkey-1.0.0 9.1.3 Install complete
2 Sun Nov 15 07:00:37 2026 deployed valkey-1.0.0 9.1.3 Upgrade complete
Artık iki Secret var: sh.helm.release.v1.cache.v1 ve .v2. Her biri o revision'ın chart'ını, kullanıcının verdiği values'ı ve render edilmiş manifest'i içeriyor. İçine bakmak, Helm'in ne bildiğini anlamanın en kısa yolu:
# Secret içindeki release: base64 (Kubernetes) + base64 + gzip ile sıkıştırılmış JSON
kubectl -n cache get secret sh.helm.release.v1.cache.v2 -o jsonpath='{.data.release}' \
| base64 -d | base64 -d | gunzip \
| jq -c '{name, version, status: .info.status, chart: .chart.metadata.version, config}'
{"name":"cache","version":2,"status":"deployed","chart":"1.0.0","config":{"resources":{"requests":{"memory":"64Mi"}}}}
config alanında yalnızca bizim verdiğimiz değer var, chart'ın varsayılanları yok; dördüncü yazıda --reuse-values tuzağını anlatırken bu ayrıntı önem kazanacak. Aynı JSON'da Helm 4'e özgü bir alan da var: apply_method, değeri ssa. Helm 4 yeni release'leri SSA (server-side apply; değişikliği API server'ın birleştirdiği apply yöntemi) ile kuruyor; beşinci ve yedinci yazıda bunun upgrade'lere etkisine bakacağız. Release Secret'larında chart'ın bütün values'ı açık durduğu için bu Secret'ları okuyabilen herkes uygulamanın ayarlarını da okuyabilir; Secret okuma yetkisini RBAC (rol tabanlı yetkilendirme) ile kısıtlamak bu yüzden önemli.
helm uninstall cache -n cache
kubectl -n cache get secrets -l owner=helm
release "cache" uninstalled
No resources found in cache namespace.
Uninstall release'in resource'larını ve bütün revision kayıtlarını siler. İki istisna akılda kalmalı: StatefulSet'lerin oluşturduğu PVC'ler (PersistentVolumeClaim; pod'un kalıcı disk talebi) silinmez, helm.sh/resource-policy: keep annotation'ı taşıyan resource'lar da yerinde kalır. Kaydı silmeden kaldırmak için --keep-history var; o zaman release uninstalled durumunda listede görünmeye devam eder.
Üçüncü Parti Chart Riski: Bitnami Örneği
Şimdi baştaki soruya dönelim. Bitnami uzun yıllar en yaygın kullanılan ücretsiz chart ve image kataloğuydu. Ağustos 2025'te katalog değişti: ücretsiz image'ların sürümlü etiketleri docker.io/bitnamilegacy adlı, güncelleme almayan bir arşive taşındı, ücretsiz katmanda yalnızca latest etiketli küçük bir image seti kaldı, Docker Hub'daki sürümlü image'lar da sonradan silindi. Değişiklikten önce yayımlanmış bir Redis chart sürümü:
helm install old-redis oci://registry-1.docker.io/bitnamicharts/redis --version 21.2.13 \
-n legacy --create-namespace --set architecture=standalone
kubectl -n legacy get pods
Pulled: registry-1.docker.io/bitnamicharts/redis:21.2.13
Digest: sha256:efb1a25cf784…
NAME: old-redis
LAST DEPLOYED: Sun Nov 15 07:00:58 2026
NAMESPACE: legacy
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
...
NAME READY STATUS RESTARTS AGE
old-redis-master-0 0/1 ImagePullBackOff 0 45s
kubectl -n legacy describe pod old-redis-master-0
Warning Failed 1s (x3 over 40s) kubelet spec.containers{redis}: Failed to pull image "docker.io/bitnami/redis:8.0.3-debian-12-r1": rpc error: code = NotFound desc = failed to pull and unpack image "docker.io/bitnami/redis:8.0.3-debian-12-r1": failed to resolve reference "docker.io/bitnami/redis:8.0.3-debian-12-r1": docker.io/bitnami/redis:8.0.3-debian-12-r1: not found
Helm "deployed" dedi, çünkü --wait vermedik ve Helm'in işi manifest'leri API server'a göndermekle bitti. Pod ise hiç başlamadı: chart'ın gösterdiği image artık yok. Helm'in "deployed" dediği şey release kaydının durumu, uygulamanın sağlığı değil. Ön tahmindeki sorunun cevabı bu. İlk akla gelen çözüm image'ı arşive yönlendirmek; chart buna kendi kontrolüyle itiraz ediyor:
helm upgrade old-redis oci://registry-1.docker.io/bitnamicharts/redis --version 21.2.13 -n legacy \
--reuse-values --set image.repository=bitnamilegacy/redis
Error: UPGRADE FAILED: execution error at (redis/templates/NOTES.txt:216:4):
⚠ ERROR: Original containers have been substituted for unrecognized ones. Deploying this chart with non-standard containers is likely to cause degraded security and performance, broken chart features, and missing environment variables.
Unrecognized images:
- docker.io/bitnamilegacy/redis:8.0.3-debian-12-r1
If you are sure you want to proceed with non-standard containers, you can skip container image verification by setting the global parameter 'global.security.allowInsecureImages' to true.
Bu kontrolü global.security.allowInsecureImages=true ile kapatmak mümkün, ama sonunda güvenlik güncellemesi almayan bir image'ı production'a koymuş olursun. Güncel Bitnami chart'ları ise ücretsiz katmanda image'ları latest etiketiyle gösteriyor:
helm show chart oci://registry-1.docker.io/bitnamicharts/redis | head -15
Pulled: registry-1.docker.io/bitnamicharts/redis:28.3.12
Digest: sha256:a80baff98e6d…
annotations:
fips: "true"
images: |
- name: kubectl
version: 1.37.2
image: registry-1.docker.io/bitnami/kubectl:latest
- name: os-shell
version: "5"
image: registry-1.docker.io/bitnami/os-shell:latest
- name: redis
version: 8.10.3
image: registry-1.docker.io/bitnami/redis:latest
Değişken bir etiket, aynı chart sürümüyle bugün ve yarın farklı bir image kurmak demek. Ders şu: chart seçmek bir bağımlılık kararıdır. Kurmadan önce chart'ın kimin bakımında olduğuna, son sürümün tarihine, helm show values ile image'ların nereden geldiğine ve lisansa bak. Production'da kullandığın chart'ları ve image'ları kendi registry'ne kopyalamak, bir sağlayıcının kararıyla bir sabah deploy edemez hâle gelmeni önler.
Üretimde Dikkat
Komutu çalıştırmadan önce context'i ve namespace'i kontrol et; Helm, kubectl'in context'ini kullanır ve -n verilmezse current namespace'e kurar. Her kurulumda --version ver; vermezsen Helm en son sürümü kurar ve aynı komut bir ay sonra başka bir chart kurar. CI'da --wait ile birlikte makul bir --timeout kullan, yoksa pipeline yeşil, uygulama kırmızı olur. Release Secret'ları her revision için birikir; Helm varsayılan olarak 10 revision saklar (--history-max), bu sayıyı sıfıra çekmek namespace'te biriken Secret'ların boyutunu büyütür. Values içinde parola tutan release'lerin Secret'larını kimlerin okuyabildiğini RBAC ile sınırla.
Sık Düşülen Tuzaklar
"deployed" durumunu uygulamanın çalıştığı anlamında okumak. --version vermeden kurup bir sonraki kurulumda farklı chart sürümü almak. Artifact Hub'daki ilk sonucu, bakımcısına ve image kaynağına bakmadan seçmek. Güncelleme almayan bir arşive işaret eden image'larla production'da kalmak. Uninstall'un PVC'leri ve keep politikalı resource'ları da sileceğini sanmak. Release Secret'larının içinde values'ın düz durduğunu unutmak. Yanlış kube context'inde komut çalıştırmak.
Küçük Bir Deneme
★☆☆ Valkey chart'ını --version vermeden kur, sonra helm list çıktısındaki chart sürümünü helm search repo valkey --versions ile karşılaştır. Aynı komutu bir CI script'inde kullanmak neden risklidir?
★★☆ Release'i iki kez upgrade et, sonra helm rollback cache 1 çalıştır. helm history çıktısında rollback'in revision 1'i değil yeni bir revision'ı "deployed" yaptığını gör ve release Secret'larının sayısını say.
★★★ Bir chart seçme checklist'i yaz: bakımcı, son sürüm tarihi, image kaynakları (helm show values ve helm template çıktısındaki image: satırları), değişken etiketler, lisans. Valkey ve güncel Bitnami Redis chart'larını bu listeye göre karşılaştır.
Hazır bir chart'ı kurmayı ve release'in nasıl kaydedildiğini gördük. Bir sonraki yazıda kendi chart'ımızı yazıyoruz: helm create ile başlayıp Bookstore.Api'nin Deployment, Service ve ServiceAccount'unu template'e çeviriyoruz.