Mert Özen Her Satırda Daha İleri
DevOps Helm — #02

İlk Chart: helm create, Chart.yaml, templates/ ve values.yaml ile Bookstore.Api'yi Paketlemek

Mert Özen 15 Kas 2026 13 dk 4 görüntülenme
İlk Chart: helm create, Chart.yaml, templates/ ve values.yaml ile Bookstore.Api'yi Paketlemek

Bir Helm chart'ı Chart.yaml (chart'ın version'ı ve uygulamanın appVersion'ı), values.yaml (chart'ın arayüzü) ve templates/ klasöründeki Go template'lerinden oluşur. helm create iskeletini sadeleştirip Bookstore.Api'nin Deployment, Service ve ServiceAccount'unu template'e çeviriyor, built-in object'leri, helm template ile --dry-run=server farkını ve sabit resource adları ile appVersion'dan habersiz image tag'i tuzaklarını gerçek çıktılarla görüyoruz.

Sürüm notu: Bu yazıdaki örnekler Helm 4.3.2, kind 0.33 ile Kubernetes 1.37, kubectl 1.37 ve .NET 10 ile denenmiştir.

Önce Tahmin Et

Chart'ın Chart.yaml dosyasında appVersion'ı 1.0.0'dan 1.1.0'a çıkardın ve upgrade ettin. helm list çıktısındaki APP VERSION sütunu 1.1.0 diyor. Ama bir hafta önce bir sorunu ayıklarken image tag'ini --set image.tag=1.0.0 ile elle vermiştin. Pod'da hangi image çalışıyor ve bunu kim söyler? Cevap bu yazının sonundaki tuzaklar bölümünde, gerçek çıktısıyla. Cevaba giden yolda Helm'in values'ı hatırlama biçimiyle de ilgili bir sürpriz var.

helm create ile İskelet

Serinin ilk yazısında hazır bir chart kurduk. Bu yazıda Bookstore'un (sitedeki serilerin ortak örnek uygulaması, bir online kitapçı) API'si için kendi chart'ımızı yazıyoruz. Başlangıç noktası Kubernetes serisindeki manifest'ler: Deployment, Service, ServiceAccount, probe'lar ve Pod Security Standards'ın restricted profiline uyan bir securityContext. Chart, uygulamanın repo'sunda helm/charts/bookstore altında duruyor. helm create çalışan bir örnek iskelet üretir:

mkdir charts
cd charts
helm create bookstore
Creating bookstore
bookstore/.helmignore
bookstore/Chart.yaml
bookstore/templates/NOTES.txt
bookstore/templates/_helpers.tpl
bookstore/templates/deployment.yaml
bookstore/templates/hpa.yaml
bookstore/templates/httproute.yaml
bookstore/templates/ingress.yaml
bookstore/templates/service.yaml
bookstore/templates/serviceaccount.yaml
bookstore/templates/tests/test-connection.yaml
bookstore/values.yaml

Bu iskelet bir nginx kurmak için yazılmış ve her şeyi values'a açıyor: ingress, HTTPRoute, HPA (yüke göre pod sayısını ayarlayan autoscaler), test pod'u, tolerations, affinity. Bookstore.Api için şimdilik gereken üç resource var. Gerisini siliyoruz; ihtiyaç olduğunda bilerek ekleyeceğiz, test pod'u altıncı yazıda geri gelecek:

cd bookstore
rm templates/hpa.yaml templates/ingress.yaml templates/httproute.yaml
rm -r templates/tests

_helpers.tpl ve .helmignore kalıyor. Helper dosyasındaki isim ve label fonksiyonlarını bu yazıda olduğu gibi kullanıyoruz, üçüncü yazıda kendi ihtiyacımıza göre yeniden yazacağız. .helmignore, helm package çalışırken pakete girmeyecek dosyaları listeler, .gitignore gibi çalışır.

Chart.yaml ve values.yaml

apiVersion: v2
name: bookstore
description: Bookstore API (ASP.NET Core 10) on Kubernetes
type: application
# Chart'ın sürümü: template veya values değişince artar
version: 0.1.0
# Uygulamanın sürümü: image tag'i boşsa bu kullanılır
appVersion: "1.0.0"

apiVersion: v2 Helm 3 ile gelen chart formatı ve Helm 4'te de geçerli olan format bu. Helm 2 dönemi chart'lar v1 kullanır; yedinci yazıda onları okumaya bakacağız. Asıl önemli ayrım version ile appVersion arasında. version chart'ın kendi sürümüdür ve semver olmak zorundadır; bir template'i, values.yaml'daki bir varsayılanı ya da bir dependency'yi değiştirdiğinde artar. appVersion chart'ın kurduğu uygulamanın sürümüdür, serbest metindir ve Bookstore.Api'nin release numarasını izler. İkisi bağımsız hareket eder: uygulama değişmeden chart düzeltmesi yapabilir ya da chart'a dokunmadan yeni bir uygulama sürümünü paketleyebilirsin. Tırnak işaretleri tesadüf değil: appVersion: 1.10 yazarsan YAML (manifest'lerin yazıldığı metin formatı) bunu sayı olarak okur ve sürüm 1.1 olur; helm lint bunu appVersion should be of type string but it's of type float64 hatasıyla yakalıyor.

replicaCount: 1

image:
  repository: helmseries-bookstore-api
  # Boş tag: chart, Chart.yaml'daki appVersion'ı kullanır.
  tag: ""
  pullPolicy: IfNotPresent

environment: Development

database:
  # InMemory veritabanı sunucusu istemez; SqlServer dördüncü yazıda geliyor.
  provider: InMemory

service:
  type: ClusterIP
  port: 8080

probes:
  livePath: /health/live
  readyPath: /health/ready

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    memory: 256Mi

values.yaml chart'ın arayüzüdür. Buraya koyduğun her anahtar, chart'ı kullanan herkesin bağımlı olacağı bir sözleşmeye dönüşür; adını değiştirmek bir breaking change'tir. Bu yüzden yalnızca environment'tan environment'a gerçekten değişecek ayarları açıyoruz: replica sayısı, image, environment adı, veritabanı provider'ı, service tipi ve resource'lar. Container portu (8080) ve securityContext açık değil, çünkü Bookstore image'ı bunları kendisi belirliyor ve bir environment'ta farklı olmaları için bir sebep yok. Lab'da image adları helmseries- önekiyle kind'a yüklendi; gerçek bir kurulumda burada ghcr.io/<org>/bookstore-api gibi bir registry adresi olur. database.provider: InMemory, Bookstore.Api'ye bu seri için eklediğimiz bir ayar: API'yi veritabanı sunucusu olmadan, Entity Framework Core'un (EF Core; .NET'in veritabanı erişim kütüphanesi) in-memory provider'ıyla ve seed verisiyle başlatıyor. Bookstore'un asıl veritabanı SQL Server; dördüncü ve beşinci yazıda ona geçeceğiz. Kubernetes serisinde PostgreSQL kullanmıştık, bu seride Bookstore'un varsayılanına döndük.

Template'ler: Deployment, Service, ServiceAccount

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "bookstore.fullname" . }}-api
  labels:
    {{- include "bookstore.labels" . | nindent 4 }}
    app.kubernetes.io/component: api
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "bookstore.selectorLabels" . | nindent 6 }}
      app.kubernetes.io/component: api
  template:
    metadata:
      labels:
        {{- include "bookstore.selectorLabels" . | nindent 8 }}
        app.kubernetes.io/component: api
    spec:
      serviceAccountName: {{ include "bookstore.fullname" . }}-api
      automountServiceAccountToken: false
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: api
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 8080
          env:
            - name: ASPNETCORE_ENVIRONMENT
              value: {{ .Values.environment }}
            - name: Database__Provider
              value: {{ .Values.database.provider }}
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop: ["ALL"]
          startupProbe:
            httpGet:
              path: {{ .Values.probes.livePath }}
              port: http
            periodSeconds: 2
            failureThreshold: 30
          livenessProbe:
            httpGet:
              path: {{ .Values.probes.livePath }}
              port: http
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: {{ .Values.probes.readyPath }}
              port: http
            periodSeconds: 5
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          volumeMounts:
            - name: tmp
              mountPath: /tmp
      volumes:
        - name: tmp
          emptyDir:
            sizeLimit: 64Mi

Kubernetes serisindeki Deployment'tan iki fark var. Değişen her şey {{ .Values... }} ile values'tan geliyor ve isimler sabit değil: {{ include "bookstore.fullname" . }}-api. Image satırındaki {{ .Values.image.tag | default .Chart.AppVersion }} bir pipeline: tag boşsa appVersion kullanılır. toYaml ... | nindent 12, values'taki resources map'ini YAML'a çevirip 12 boşlukla girintiler; template dilinin ayrıntıları bir sonraki yazının konusu. Label'lara app.kubernetes.io/component: api ekledik, çünkü üçüncü yazıda aynı chart'a ikinci bir component (bookstore-web) gelecek ve iki Deployment'ın selector'larının çakışmaması gerekiyor. Selector'lar bir kere kurulduktan sonra değiştirilemez; Kubernetes serisinin dördüncü yazısında bunun nedenini görmüştük.

apiVersion: v1
kind: Service
metadata:
  name: {{ include "bookstore.fullname" . }}-api
  labels:
    {{- include "bookstore.labels" . | nindent 4 }}
    app.kubernetes.io/component: api
spec:
  type: {{ .Values.service.type }}
  ports:
    - name: http
      port: {{ .Values.service.port }}
      targetPort: http
  selector:
    {{- include "bookstore.selectorLabels" . | nindent 4 }}
    app.kubernetes.io/component: api
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ include "bookstore.fullname" . }}-api
  labels:
    {{- include "bookstore.labels" . | nindent 4 }}
    app.kubernetes.io/component: api
automountServiceAccountToken: false

İsmin nereden geldiğini görmek için helm create'in ürettiği helper'a bakalım:

{{- define "bookstore.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

Release adı chart adını içeriyorsa (bookstore, bookstore-dev) isim release adının kendisi olur; içermiyorsa (preview) preview-bookstore olur. 63 karakter sınırı Kubernetes'in DNS uyumlu isim kuralından geliyor. Bu fonksiyonun asıl işi, aynı chart'ın aynı namespace'e iki kez kurulabilmesini sağlamak; aşağıdaki tuzak bölümünde bunun önemini göreceğiz.

Built-in Object'ler: .Values, .Release, .Chart, .Capabilities

Template'lerde .Values dışında Helm'in doldurduğu birkaç object daha var. .Release release'in adını, namespace'ini, revision numarasını ve kurulum mu upgrade mi olduğunu (.Release.IsInstall, .Release.IsUpgrade) taşır. .Chart, Chart.yaml'ın içeriğidir; alan adları büyük harfle başlar (.Chart.AppVersion). .Capabilities cluster'ın Kubernetes sürümünü ve desteklediği API'leri söyler; örneğin .Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1" ile Gateway API kurulu değilse HTTPRoute üretmemek mümkün. .Files chart içindeki dosyaları okur, .Template o an render edilen dosyanın adını verir. Hepsini birden görmek için NOTES.txt'yi yeniden yazdık; bu dosya da bir template ve kurulumun sonunda ekrana basılıyor:

Bookstore API {{ .Chart.AppVersion }} (chart {{ .Chart.Name }}-{{ .Chart.Version }})
Release {{ .Release.Name }} in namespace {{ .Release.Namespace }}, revision {{ .Release.Revision }}{{ if .Release.IsUpgrade }} (upgrade){{ end }}
Cluster: Kubernetes {{ .Capabilities.KubeVersion.Version }}

Try it:
  kubectl -n {{ .Release.Namespace }} port-forward svc/{{ include "bookstore.fullname" . }}-api 8080:{{ .Values.service.port }}
  curl http://127.0.0.1:8080/api/info

Render'ı Görmek: helm template ve --dry-run=server

Cluster'a bir şey göndermeden önce iki adım: helm lint chart'ın yapısını ve template'lerin render edilebildiğini kontrol eder, helm template render sonucunu ekrana basar.

helm lint bookstore
helm template bookstore ./bookstore -n bookstore-dev
==> Linting bookstore
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed
---
# Source: bookstore/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: bookstore-api
  labels:
    helm.sh/chart: bookstore-0.1.0
    app.kubernetes.io/name: bookstore
    app.kubernetes.io/instance: bookstore
    app.kubernetes.io/version: "1.0.0"
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: api
automountServiceAccountToken: false
...
---
# Source: bookstore/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bookstore-api
...
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: bookstore
      app.kubernetes.io/instance: bookstore
      app.kubernetes.io/component: api
...
      containers:
        - name: api
          image: "helmseries-bookstore-api:1.0.0"

helm template cluster'a hiç bağlanmaz. Bu yüzden .Capabilities Helm'in derlendiği client kütüphanesinin varsayılanlarını taşır (Helm 4.3.2'de Kubernetes 1.37) ve lookup fonksiyonu her zaman boş döner. Gerçek cluster bilgisini kullanmak için --dry-run=server var:

kubectl create namespace bookstore-dev
helm install bookstore ./bookstore -n bookstore-dev --dry-run=server
NAME: bookstore
LAST DEPLOYED: Sun Nov 15 07:07:32 2026
NAMESPACE: bookstore-dev
STATUS: pending-install
REVISION: 1
DESCRIPTION: Dry run complete
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: bookstore/templates/serviceaccount.yaml
...
NOTES:
Bookstore API 1.0.0 (chart bookstore-0.1.0)
Release bookstore in namespace bookstore-dev, revision 1
Cluster: Kubernetes v1.37.0

Bu cluster da 1.37 olduğu için iki sürüm aynı çıktı; eski bir cluster'da fark hemen görünür, helm template --kube-version 1.30.0 ile de taklit edilebilir. Bir yanılgıyı da burada düzeltelim: --dry-run=server manifest'leri API server'ın doğrulamasından geçirmez. Geçersiz bir replica sayısıyla denedik:

helm template bookstore ./bookstore --set replicaCount=-1 --show-only templates/deployment.yaml | grep replicas
helm install bookstore ./bookstore -n bookstore-dev --set replicaCount=-1 --dry-run=server | tail -3
  replicas: -1
Try it:
  kubectl -n bookstore-dev port-forward svc/bookstore-api 8080:8080
  curl http://127.0.0.1:8080/api/info

Helm "dry run complete" diyor. Server tarafı doğrulamayı görmek için render sonucunu kubectl'in server-side dry run'ına vermek gerekiyor:

helm template bookstore ./bookstore --set replicaCount=-1 | kubectl -n bookstore-dev apply --dry-run=server -f -
serviceaccount/bookstore-api created (server dry run)
service/bookstore-api created (server dry run)
The Deployment "bookstore-api" is invalid: spec.replicas: Invalid value: -1: must be greater than or equal to 0

Gerçek kurulumda ise hata ortaya çıkıyor, ama ondan önce gönderilen resource'lar yerinde kalıyor:

helm install bookstore ./bookstore -n bookstore-dev --set replicaCount=-1
kubectl -n bookstore-dev get sa,svc,deploy
helm list -n bookstore-dev
Error: INSTALLATION FAILED: server-side apply failed for object bookstore-dev/bookstore-api apps/v1, Kind=Deployment: Deployment.apps "bookstore-api" is invalid: spec.replicas: Invalid value: -1: must be greater than or equal to 0
NAME                           AGE
serviceaccount/bookstore-api   5s
serviceaccount/default         26s

NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/bookstore-api   ClusterIP   <cluster-ip>   <none>        8080/TCP   5s
NAME     	NAMESPACE    	REVISION	UPDATED                             	STATUS	CHART          	APP VERSION
bookstore	bookstore-dev	1       	2026-11-15 07:07:53.400995 +0300 +03	failed	bookstore-0.1.0	1.0.0

ServiceAccount ve Service oluştu, Deployment reddedildi, release failed. Helm bir kurulumu tek bir transaction olarak yapmaz; resource'ları sırayla gönderir. helm uninstall release kaydındaki bütün resource'ları temizler. Bu yüzden CI'da helm template | kubectl apply --dry-run=server adımı, hatayı cluster'da yarım kalmış bir release'e dönüşmeden yakalamanın ucuz yolu. Altıncı yazıda buna kubeconform ile şema doğrulamasını ekleyeceğiz.

Kurulum ve İlk İstek

helm uninstall bookstore -n bookstore-dev
helm install bookstore ./bookstore -n bookstore-dev --wait
release "bookstore" uninstalled
NAME: bookstore
LAST DEPLOYED: Sun Nov 15 07:08:26 2026
NAMESPACE: bookstore-dev
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
Bookstore API 1.0.0 (chart bookstore-0.1.0)
Release bookstore in namespace bookstore-dev, revision 1
Cluster: Kubernetes v1.37.0

Try it:
  kubectl -n bookstore-dev port-forward svc/bookstore-api 8080:8080
  curl http://127.0.0.1:8080/api/info
# Cluster içinden, kısa ömürlü bir curl pod'uyla
kubectl -n bookstore-dev run curl --rm -i --restart=Never --image=curlimages/curl:8.17.0 -- \
    -s http://bookstore-api:8080/api/info
{"version":"1.0.0","environment":"Development","pod":"bookstore-api-5b5b68b956-8cmv9","database":"InMemory","storeName":"Bookstore"}

/api/info bu seri için API'ye eklediğimiz küçük bir endpoint: image'ın sürümünü, environment'ı, pod adını ve veritabanı provider'ını döner. Katalog da cevap veriyor, in-memory veritabanında seed edilmiş 20 kitap var:

{"items":[{"isbn":"9780451524935","title":"1984","author":"George Orwell","category":"Dystopian","price":279.00,"publishedYear":1949},{"isbn":"9780143035008","title":"Anna Karenina","author":"Leo Tolstoy","category":"Classics","price":429.00,"publishedYear":1878}],"total":20,"page":1,"pageSize":2}

İki Tuzak: Sabit İsimler ve Sabit Image Tag'i

Release adını resource adlarında kullanmamak

Template'lerde name: bookstore-api yazdığını düşün. İlk kurulum çalışır. Aynı namespace'e bir preview ortamı kurmak istediğinde ikincisi çakışır:

# Template'lerde isim sabit: name: bookstore-api
helm install bookstore ./hardcoded -n bookstore-qa
helm install preview ./hardcoded -n bookstore-qa
NAME: bookstore
LAST DEPLOYED: Sun Nov 15 07:08:49 2026
NAMESPACE: bookstore-qa
...
Error: INSTALLATION FAILED: unable to continue with install: ServiceAccount "bookstore-api" in namespace "bookstore-qa" exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error: key "meta.helm.sh/release-name" must equal "preview": current value is "bookstore"

Helm her resource'a sahibi olan release'in adını meta.helm.sh/release-name annotation'ıyla yazar ve başka bir release'in resource'unu sahiplenmeyi reddeder. Bu koruma iyi bir şey; sorun isimlerin sabit olması. fullname helper'ıyla:

helm install bookstore ./bookstore -n bookstore-qa
helm install preview ./bookstore -n bookstore-qa
kubectl -n bookstore-qa get deploy,svc -o name
deployment.apps/bookstore-api
deployment.apps/preview-bookstore-api
service/bookstore-api
service/preview-bookstore-api

appVersion'dan habersiz image tag'i

Şimdi Önce Tahmin Et'teki senaryo. Chart.yaml'da version'ı 0.1.1'e, appVersion'ı 1.1.0'a çıkardık ve upgrade sırasında tag'i elle verdik:

# Chart.yaml: version 0.1.0 -> 0.1.1, appVersion "1.0.0" -> "1.1.0"
helm upgrade bookstore ./bookstore -n bookstore-dev --set image.tag=1.0.0 --wait
helm list -n bookstore-dev
kubectl -n bookstore-dev get deploy bookstore-api -o jsonpath='{.spec.template.spec.containers[0].image}'
NAME     	NAMESPACE    	REVISION	UPDATED                             	STATUS  	CHART          	APP VERSION
bookstore	bookstore-dev	2       	2026-11-15 07:09:02.307547 +0300 +03	deployed	bookstore-0.1.1	1.1.0
helmseries-bookstore-api:1.0.0

API'nin /api/info cevabı da aynı şeyi söylüyor:

{"version":"1.0.0","environment":"Development","pod":"bookstore-api-5b5b68b956-8cmv9","database":"InMemory","storeName":"Bookstore"}

helm list 1.1.0 diyor, pod 1.0.0 çalıştırıyor. APP VERSION sütunu yalnızca Chart.yaml'dan okunur; image'ın gerçekte ne olduğunu bilmez. Asıl sürpriz bir sonraki adımda: --set'i kaldırıp tekrar upgrade ettik.

helm upgrade bookstore ./bookstore -n bookstore-dev --wait
kubectl -n bookstore-dev get deploy bookstore-api -o jsonpath='{.spec.template.spec.containers[0].image}'
helm get values bookstore -n bookstore-dev
helmseries-bookstore-api:1.0.0
USER-SUPPLIED VALUES:
image:
  tag: 1.0.0

Image hâlâ 1.0.0. helm upgrade'e hiç -f ya da --set verilmezse Helm önceki release'in kullanıcı values'ını yeniden kullanır; elle verdiğimiz tag sessizce taşınıyor. Values'ı chart varsayılanlarına döndürmek için --reset-values gerekiyor:

helm upgrade bookstore ./bookstore -n bookstore-dev --reset-values --wait
kubectl -n bookstore-dev get deploy bookstore-api -o jsonpath='{.spec.template.spec.containers[0].image}'
helmseries-bookstore-api:1.1.0

Önce Tahmin Et'in cevabı: pod 1.0.0 çalıştırıyordu, bunu helm list değil Deployment'ın kendisi ve uygulamanın sürüm endpoint'i söyledi. Values'ın birleşme kurallarını ve --reuse-values ailesini dördüncü yazıda ayrıntısıyla ele alacağız. Pratik kural şu: image tag'ini bir environment'ta sabitlemen gerekiyorsa bunu o environment'ın values dosyasına yaz, komut satırında bırakma.

Üretimde Dikkat

Chart sürümünü her değişiklikte artır; aynı sürüm numarasıyla farklı içerik dağıtmak, hangi cluster'da neyin kurulu olduğunu bilinmez hâle getirir. Production'da tag yerine image digest'i kullanmak, aynı tag'in yeniden push edilmesine karşı korur; chart'a image.digest gibi bir alan eklemek bunun en temiz yolu. helm lint yalnızca chart yapısını kontrol eder, Kubernetes'in kabul edip etmeyeceğini söylemez; render çıktısını server-side dry run'dan geçirmek bu boşluğu kapatır. Release adlarını environment başına sabit tut (her environment'ta bookstore); adı değiştirmek bütün resource adlarını ve dolayısıyla Service DNS adını da değiştirir.

Sık Düşülen Tuzaklar

helm create iskeletini hiç sadeleştirmeden kullanıp kimsenin bilmediği ayarlarla production'a çıkmak. Resource adlarını sabit yazıp aynı namespace'e ikinci kurulumu imkânsız hâle getirmek. appVersion'ı tırnaksız yazıp 1.10'un 1.1 olmasına şaşırmak. helm list'teki APP VERSION'ı çalışan image'ın sürümü sanmak. --dry-run=server'ın Kubernetes doğrulamasını yaptığını varsaymak. Bir sorun ayıklarken komut satırından verilen bir değerin sonraki bütün upgrade'lere taşınacağını unutmak. Selector label'larına sürüm gibi değişen bir değer koymak.

Küçük Bir Deneme

★☆☆ Release'i bookstore-dev yerine shop adıyla kur ve resource adlarını kontrol et. Sonra fullnameOverride=bookstore vererek aynı adları geri al.

★★☆ NOTES.txt'ye .Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1" sonucunu yazdır. helm template, --dry-run=client ve --dry-run=server ile çalıştırıp hangisinin cluster'daki gerçek durumu gösterdiğine bak.

★★★ Chart'a image.digest değeri ekle: digest varsa image repository@sha256:... biçiminde yazılsın, yoksa tag kullanılsın. Kind'a yüklediğin image'ın digest'ini docker image inspect ile bulup kurulumu digest ile yap.

Chart'ımız çalışıyor ama template'ler hâlâ helm create'in helper'larına yaslanıyor ve web arayüzü yok. Bir sonraki yazıda Helm'in template dilini ayrıntılı ele alıyoruz: fonksiyonlar, _helpers.tpl, include, flow control, whitespace ve bookstore-web için ikinci component.