Kubernetes üzerinde uygulama dağıtımı yaparken bir noktadan sonra onlarca YAML dosyasıyla boğuştuğunuzu fark edersiniz. Deployment, Service, ConfigMap, Secret, Ingress… Bunların hepsini tek tek yönetmek hem zaman alıcı hem de hata yapmaya açık bir süreç. İşte tam burada Helm devreye giriyor ve hayatınızı ciddi ölçüde kolaylaştırıyor.
Helm Nedir ve Neden Kullanmalıyız?
Helm, Kubernetes için geliştirilmiş bir paket yöneticisidir. Nasıl ki Linux’ta apt ya da yum ile uygulama kuruyorsanız, Kubernetes’te de Helm ile kompleks uygulamaları tek komutla kurabilir, güncelleyebilir ve kaldırabilirsiniz.
Helm’in temel bileşenleri şunlardır:
- Chart: Bir uygulamanın tüm Kubernetes kaynaklarını tanımlayan şablon dosyaları koleksiyonu
- Release: Bir chart’ın Kubernetes cluster’ına kurulmuş hali
- Repository: Chart’ların depolandığı ve paylaşıldığı merkezi yer
- Values: Chart şablonlarını özelleştirmek için kullanılan konfigürasyon değerleri
Gerçek dünya senaryosunu düşünelim: Şirketinizde test, staging ve production ortamları var. Her ortam için farklı resource limit’leri, replica sayıları ve konfigürasyonlar gerekiyor. Helm olmadan her ortam için ayrı YAML setleri tutmanız gerekir. Helm ile sadece tek bir chart yazıp farklı values.yaml dosyalarıyla her ortamı yönetebilirsiniz.
Helm Kurulumu
Helm kurulumu oldukça basit. Linux sistemlerde şu yöntemle kurabilirsiniz:
# Script ile kurulum
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Paket yöneticisi ile (Ubuntu/Debian)
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt update && sudo apt install helm
# Kurulumu doğrulama
helm version
Helm 3 ile birlikte Tiller bileşeni ortadan kalktı, bu yüzden cluster tarafında ekstra bir şey kurmanıza gerek yok. Helm direkt olarak kubectl credential’larınızı kullanarak cluster ile iletişim kurar.
Repository Yönetimi
Helm chart’larını bulabileceğiniz birçok repository var. En yaygın kullanılanları ekleyelim:
# Artifact Hub üzerinden popüler repo'ları ekleme
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add cert-manager https://charts.jetstack.io
# Tüm repo'ları güncelleme
helm repo update
# Mevcut repo'ları listeleme
helm repo list
# Belirli bir chart'ı arama
helm search repo nginx
helm search repo bitnami/wordpress
# Artifact Hub'da arama (internet üzerinden)
helm search hub prometheus
Repo ekledikten sonra helm search repo komutu ile istediğiniz uygulamayı arayabilirsiniz. Ben genellikle Bitnami repo’sunu tercih ediyorum çünkü chart’ları düzenli olarak güncelleniyor ve güvenlik yamaları hızlıca uygulanıyor.
İlk Chart Kurulumu
Teoriden pratiğe geçelim. Bir Nginx kurulumu yapalım ve Helm’in gücünü görelim:
# Namespace oluşturma
kubectl create namespace web-apps
# Chart hakkında bilgi alma
helm show values bitnami/nginx
# Basit kurulum
helm install my-nginx bitnami/nginx --namespace web-apps
# Kurulumu doğrulama
helm list --namespace web-apps
kubectl get pods --namespace web-apps
# Release detaylarını görme
helm status my-nginx --namespace web-apps
helm install komutunun yapısı şu şekildedir: helm install [RELEASE_ADI] [CHART_ADI] [PARAMETRELER]
Kurulum sırasında önemli parametreler:
- –namespace: Hangi namespace’e kurulacağı
- –create-namespace: Namespace yoksa otomatik oluştur
- –values / -f: Özel values dosyası kullan
- –set: Komut satırından değer geç
- –dry-run: Gerçekten kurmadan test et
- –debug: Detaylı çıktı göster
- –wait: Pod’lar hazır olana kadar bekle
- –timeout: Bekleme süresi limiti
Kendi Chart’ınızı Oluşturma
İşte Helm’in asıl gücü burada ortaya çıkıyor. Kendi uygulamanız için chart oluşturabilirsiniz:
# Yeni chart oluşturma
helm create my-webapp
# Oluşturulan yapı
tree my-webapp/
# my-webapp/
# ├── Chart.yaml # Chart metadata
# ├── values.yaml # Default değerler
# ├── charts/ # Bağımlı chart'lar
# └── templates/ # Kubernetes manifest şablonları
# ├── deployment.yaml
# ├── service.yaml
# ├── ingress.yaml
# ├── _helpers.tpl
# └── NOTES.txt
Basit bir web uygulaması için values.yaml dosyasını düzenleyelim:
# values.yaml
replicaCount: 2
image:
repository: nginx
tag: "1.25"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 250m
memory: 64Mi
autoscaling:
enabled: false
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
env:
APP_ENV: production
LOG_LEVEL: info
configMap:
enabled: true
data:
nginx.conf: |
server {
listen 80;
location /health {
return 200 'healthy';
}
}
Şimdi deployment şablonunu inceleyelim:
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-webapp.fullname" . }}
labels:
{{- include "my-webapp.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-webapp.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-webapp.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 80
resources:
{{- toYaml .Values.resources | nindent 12 }}
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
Chart’ı test etmeden önce her zaman lint ve dry-run yapın:
# Chart syntax kontrolü
helm lint my-webapp/
# Oluşturulacak manifest'leri görme (kurulum yapmadan)
helm template my-webapp my-webapp/ --values my-webapp/values.yaml
# Dry run ile test
helm install my-webapp-test my-webapp/ --dry-run --debug --namespace test
Çoklu Ortam Yönetimi
En sık karşılaşılan gerçek dünya senaryolarından biri çoklu ortam yönetimidir. Tek chart, birden fazla ortam:
# Ortam bazlı values dosyaları oluşturma
# values-dev.yaml, values-staging.yaml, values-prod.yaml
# Development ortamı kurulumu
helm install my-webapp-dev my-webapp/
--namespace development
--create-namespace
-f my-webapp/values.yaml
-f environments/values-dev.yaml
# Production ortamı kurulumu
helm install my-webapp-prod my-webapp/
--namespace production
--create-namespace
-f my-webapp/values.yaml
-f environments/values-prod.yaml
--set image.tag=v2.1.0
--wait
--timeout 5m
values-prod.yaml örneği:
# environments/values-prod.yaml
replicaCount: 5
image:
tag: "v2.1.0"
resources:
limits:
cpu: 2000m
memory: 512Mi
requests:
cpu: 500m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 20
targetCPUUtilizationPercentage: 70
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: myapp.company.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: myapp-tls
hosts:
- myapp.company.com
env:
APP_ENV: production
LOG_LEVEL: warn
Güncelleme ve Rollback
Helm’in en değerli özelliklerinden biri versiyonlama ve rollback yeteneğidir:
# Mevcut release'leri listeleme
helm list --all-namespaces
# Release güncelleme
helm upgrade my-webapp-prod my-webapp/
--namespace production
-f my-webapp/values.yaml
-f environments/values-prod.yaml
--set image.tag=v2.2.0
--wait
# Release geçmişini görme
helm history my-webapp-prod --namespace production
# Önceki versiyona rollback
helm rollback my-webapp-prod 1 --namespace production
# Belirli bir versiyona rollback
helm rollback my-webapp-prod 3 --namespace production
# Upgrade + otomatik rollback (başarısız olursa)
helm upgrade my-webapp-prod my-webapp/
--namespace production
--atomic
--cleanup-on-fail
--set image.tag=v2.3.0
--atomic parametresi özellikle önemli: Eğer upgrade başarısız olursa Helm otomatik olarak önceki versiyona döner. Production ortamında bu parametreyi mutlaka kullanın.
Helm Secrets ve Hassas Veri Yönetimi
Gerçek dünyada en kritik konulardan biri hassas verilerin yönetimidir. Helm values dosyalarını git’e commit ettiğinizde şifrelerin açıkta kalmaması gerekiyor. Bunun için helm-secrets plugin’i kullanabilirsiniz:
# helm-secrets plugin kurulumu
helm plugin install https://github.com/jkroepke/helm-secrets
# SOPS ile şifreleme (AWS KMS, GCP KMS veya GPG key kullanabilirsiniz)
# GPG key oluşturma
gpg --gen-key
# Secrets dosyası oluşturma
cat > secrets.yaml << EOF
database:
password: super-secret-password
connectionString: postgresql://user:pass@db:5432/mydb
redis:
password: redis-secret-pass
EOF
# Dosyayı şifreleme
sops --encrypt --pgp YOUR_GPG_KEY_ID secrets.yaml > secrets.enc.yaml
# Şifreli dosya ile deployment
helm secrets upgrade my-webapp-prod my-webapp/
--namespace production
-f environments/values-prod.yaml
-f secrets.enc.yaml
Alternatif olarak Kubernetes Secret’larını direkt referans etmek de yaygın bir pratiktir:
# Secret'ı Kubernetes'te manuel oluştur, Helm sadece referans etsin
kubectl create secret generic db-credentials
--from-literal=password=supersecret
--namespace production
# values.yaml'da external secret referansı
# existingSecret: db-credentials
Chart Bağımlılıkları
Gerçek uygulamalar genellikle veritabanı, cache gibi bileşenlere ihtiyaç duyar. Helm’in bağımlılık yönetimi bu durumu çözer:
# Chart.yaml
apiVersion: v2
name: my-fullstack-app
description: Full stack uygulama chart'ı
type: application
version: 1.0.0
appVersion: "2.1.0"
dependencies:
- name: postgresql
version: "12.x.x"
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: "17.x.x"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
# Bağımlılıkları indirme
helm dependency update my-fullstack-app/
# Bağımlılıkları listeleme
helm dependency list my-fullstack-app/
# Bağımlılıklar dahil kurulum
helm install my-app my-fullstack-app/
--namespace production
--set postgresql.enabled=true
--set postgresql.auth.password=dbpassword
--set redis.enabled=true
Helm Hooks
Hooks, belirli lifecycle event’lerinde özel işlemler yapmanıza olanak tanır. Örneğin kurulum öncesi database migration çalıştırabilirsiniz:
# templates/pre-install-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "my-webapp.fullname" . }}-migrations
annotations:
"helm.sh/hook": pre-upgrade,pre-install
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
spec:
containers:
- name: migrations
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["python", "manage.py", "migrate"]
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
restartPolicy: Never
Hook tipleri:
- pre-install: Kurulumdan önce çalışır
- post-install: Kurulumdan sonra çalışır
- pre-upgrade: Güncellemeden önce çalışır
- post-upgrade: Güncellemeden sonra çalışır
- pre-rollback: Rollback öncesi çalışır
- pre-delete: Silme işlemi öncesi çalışır
OCI Registry ile Chart Yönetimi
Modern Helm workflow’larında chart’ları OCI registry’lerde saklamak giderek yaygınlaşıyor:
# OCI registry login (Docker Hub örneği)
helm registry login registry-1.docker.io
# Chart'ı OCI formatında push etme
helm package my-webapp/
helm push my-webapp-1.0.0.tgz oci://registry-1.docker.io/mycompany
# OCI registry'den kurulum
helm install my-webapp
oci://registry-1.docker.io/mycompany/my-webapp
--version 1.0.0
--namespace production
# AWS ECR için
aws ecr get-login-password --region us-east-1 |
helm registry login --username AWS --password-stdin
123456789.dkr.ecr.us-east-1.amazonaws.com
helm push my-webapp-1.0.0.tgz
oci://123456789.dkr.ecr.us-east-1.amazonaws.com/helm-charts
GitOps ile Helm Entegrasyonu
Argocd veya Flux kullananlar için Helm chart’larını GitOps pipeline’ına entegre etmek çok yaygın:
# ArgoCD Application manifest örneği
# Bu YAML'ı git repo'nuzda saklayın, ArgoCD otomatik senkronize eder
cat > argocd-app.yaml << 'EOF'
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-webapp-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/mycompany/helm-charts
targetRevision: HEAD
path: my-webapp
helm:
valueFiles:
- values.yaml
- environments/values-prod.yaml
parameters:
- name: image.tag
value: v2.1.0
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
EOF
kubectl apply -f argocd-app.yaml
Faydalı Helm Komutları
Günlük operasyonlarda sık kullandığım komutlar:
# Tüm namespace'lerdeki release'leri listeleme
helm list --all-namespaces
# Başarısız release'leri bulma
helm list --all-namespaces --failed
# Release'in manifest'lerini görme
helm get manifest my-webapp-prod --namespace production
# Kullanılan values'ları görme
helm get values my-webapp-prod --namespace production
# Tüm values'ları görme (default + custom)
helm get values my-webapp-prod --namespace production --all
# Release'i silme (PV'ler dahil tüm kaynaklar)
helm uninstall my-webapp-prod --namespace production
# Eski release geçmişini temizleme
helm history my-webapp-prod --namespace production --max 10
# Chart'ın tüm notlarını görme
helm get notes my-webapp-prod --namespace production
Yaygın Sorunlar ve Çözümleri
Release pending durumunda kalıyorsa:
# Pending release'leri temizleme
helm list --all-namespaces --pending
helm rollback my-webapp-prod --namespace production
# veya
helm uninstall my-webapp-prod --namespace production
kubectl delete secret -l owner=helm,name=my-webapp-prod --namespace production
Values override çalışmıyorsa dikkat edilecekler:
--setkomutları her zaman-fdosyalarını override eder- Nested değerler için
--set parent.child=valuekullanın - Nokta içeren key’ler için
--set "annotations.kubernetes.io/ingress-class=nginx"escape kullanın - Array değerler için
--set "hosts[0]=example.com,hosts[1]=www.example.com"formatını kullanın
Sonuç
Helm, Kubernetes ekosisteminin vazgeçilmez bir parçası haline gelmiş durumda. Küçük bir side project’ten büyük kurumsal uygulamalara kadar her ölçekte işe yarıyor. Özellikle şu noktalarda değer katıyor:
- Tekrarlayan YAML yazma derdinden kurtarıyor
- Ortam yönetimini standardize ediyor
- Rollback mekanizmasıyla riskleri azaltıyor
- Ekip içinde uygulama paketleme standartları oluşturuyor
Başlangıçta community chart’larını kullanarak Helm’e alışın, sonra kendi chart’larınızı yazmaya başlayın. Chart yazarken helm lint, helm template ve --dry-run üçlüsünü asla atlamamanızı öneririm, bu üç komut production’da sizi çok kez kurtaracak.
GitOps tarafına geçtiğinizde ArgoCD veya Flux ile Helm’i birleştirmek, gerçek anlamda “uygulama git’te tanımlanır, cluster kendisi sync olur” yaklaşımını hayata geçirmenizi sağlıyor. Bu noktaya geldiğinizde Kubernetes yönetimi bambaşka bir boyut kazanıyor.