- Kubernetes gibi yapılandırma hedeflerinin arttığı ortamlarda YAML dosyalarını elle çoğaltma yaklaşımı kısa sürede sınırına ulaşır; YAML şablonları yerine yapılandırma verisi üretme yaklaşımı daha uygun hâle gelir
- Helm chart, değerleri
values.yaml ve Go şablonlarıyla enjekte eder; ancak isteğe bağlı alanlar, diziler ve map’ler devreye girdiği anda koşullu ifadeler ve girinti yükü artar
- YAML’in boşluk kuralları katıdır; Helm şablon ayrıştırıcısı YAML yapısını anlamadığı için
toYaml ve indent kombinasyonu kolayca kırılgan yapılandırma üretimine yol açar
- YAML, JSON’ın üst kümesi olduğundan karşılıklı dönüşüm basittir; Jsonnet dış değişkenler, koşullu alanlar, map birleştirme ve nesne birleştirme ile yapılandırma nesnesi üretimini kod yazar gibi ele alır
- kr8, Jsonnet tabanlı bir akışla birden çok Kubernetes kümesinin yapılandırmasını oluşturur ve işler; karmaşık YAML string’leri birleştirmek yerine nesneleri doğrudan oluşturup dönüştürmeyi seçer
Yapılandırma karmaşıklığı YAML dosyalarının sayısı arttığında başlar
- Uygulama ve altyapı belli bir ölçeği aştığında yapılandırma karmaşıklığı hızla artar
- Dağıtım hedefi 1-2 adetse YAML yapılandırma dosyalarını elle yazmak yeterli olabilir; ancak bunun ötesine geçildiğinde yapılandırmayı sistematik biçimde yönetmek gerekir
- Birden fazla yapılandırma dosyasına ihtiyaç duyulmasının nedeni genellikle aynı hedef için bile bazı değerlerin birbirinden farklı olmasıdır
dev, stg, prod gibi ortama göre dağıtımlar
- Europe, North America gibi bölgeye göre dağıtımlar
- Tüm yapılandırmalar farklı değildir; ancak farklar yeterince büyükse ortak kısımları ve farklı kısımları ayırarak yönetmek gerekir
- Yapılandırma yönetimi alanı bu tür sorunlarla uzun zamandır uğraşıyor ve çeşitli araçlar YAML’i kendi yöntemleriyle kullanıyor
- Puppet içinde yer alan hiera, değişkenleri hiyerarşik olarak sorgulayabildiği için güçlü ve esnektir; YAML’in kendisini şablonlaştırma ihtiyacını büyük ölçüde azaltır
Helm chart’larda ortaya çıkan YAML şablonu sorunu
- Bulut bilişim ve Kubernetes ile yapılandırma hedefleri işletim sistemi üzerindeki katmanlara kadar genişledikçe CloudFormation ve Helm gibi araçlar ortaya çıktı
- Helm chart,
values.yaml içinde tanımlanan dış parametreleri alıp render edebilir
- Basit string değerleri görece kolaydır
image: "{{ .Values.image }}"
values.yaml içinde image değeri belirtildiğinde bu değer şablona girer
- İsteğe bağlı alanlar gibi daha karmaşık yapılandırmaları ele almaya başladığınızda sorun büyür
{{- with .resourceGroup }}
resourceGroup: {{ . }}
{{- end }}
- İsteğe bağlı değerler boş bırakılamayacağı için koşullu ifadeler ve döngüler gerekir; şablon kolayca dağınık hâle gelir
- Dizi veya map eklerken
toYaml ile indent kombinasyonunu kullanmak gerekir
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 8 }}
{{- end }}
toYaml ile YAML’i yeniden YAML’e çeviren bir fonksiyon çağrısı yapmak zaten tuhaf görünür; ancak daha büyük sorun boşluk işlemedir
YAML boşluk kuralları ile şablon motorunun çatışması
- YAML’in girinti ve boşluk kuralları katıdır
- Aşağıdaki örnek geçerli ya da eksiksiz YAML değildir
something: nothing
hello: goodbye
- Bunu bir insan elle yazıyorsa birkaç kez backspace’e basıp düzeltebilir; ancak bir şablon sistemiyle YAML üretirken iş bu kadar basit değildir
- Yapılandırma dosyalarının sayısı 5-10’u aşan bir düzeye geldiyse elle yazmak yerine yapılandırma üretimi gerekir
.Values.podAnnotations değerini zaten girintilenmiş annotations altına koymak için değerin kendisi de tam doğru seviyede girintilenmelidir
- Go şablon ayrıştırıcısı YAML’i anlamadığı için, şablon söz dizimini okunabilir olacak şekilde girintilemeye çalışmak bile sorun çıkarır
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | indent 6 }}
{{- end }}
- Şablon sistemi YAML yapısını bilmeden boşlukları ve koşulları birlikte ele aldığında, karmaşık yapılandırma üretimi giderek zorlaşır
- JSON’ı doğrudan yazma yaklaşımı da yorum eksikliği ve virgül unutma sorunları nedeniyle uygun değildir; bu rahatsızlıklar yüzünden YAML kullanılmaya başlanmıştır
Jsonnet, JSON yapılandırması üreten bir veri şablonlama dilidir
- YAML, JSON’ın üst kümesi olduğundan JSON ile YAML arasındaki dönüşüm basittir
- Birçok uygulama ve programlama dili JSON ve YAML’i doğal olarak ayrıştırabilir ya da dönüştürebilir
- Python’da da YAML okunup JSON olarak çıktı alınabilir
python -c 'import json, sys, yaml ; y=yaml.safe_load(sys.stdin.read()) ; print(json.dumps(y))'
- Jsonnet kendisini veri şablonlama dili olarak tanımlar; temel amacı JSON yapılandırmaları üretmektir
- Jsonnet’in tasarım arka planı design rationale belgesinde görülebilir
Dış değişkenler ve isteğe bağlı alanları işleme
- Jsonnet, yapılandırma değerlerini enjekte etmek için dış değişkenler kullanabilir
{
image: std.extVar('image'),
}
- CLI’dan dış değişken verildiğinde JSON sonucu üretilir
jsonnet image.jsonnet -V image="my-image"
{
"image": "my-image"
}
- İsteğe bağlı alanlar, şablon koşullarını string içine sıkıştırmadan kodun koşullu ifadeleriyle temsil edilebilir
// define a variable - yes, jsonnet also has comments
local rg = null;
{
image: std.extVar('image'),
// if the variable is null, this will be blank
[if rg != null then 'resourceGroup']: rg,
}
rg null ise resourceGroup alanı sonuca dahil edilmez
- Değer belirtilirse ilgili alan çıktıya eklenir
Map ve nesne işlemleri YAML girintisinden daha basittir
- Kubernetes pod annotation’ı gibi bir map’i yapılandırmaya eklerken Jsonnet’te değer bir değişken olarak tanımlanıp nesneye yerleştirilebilir
local annotations = {
'nginx.ingress.kubernetes.io/app-root': '/',
'nginx.ingress.kubernetes.io/enable-cors': true,
};
{
metadata: { // annotations are nested under the metadata of a pod
annotations: annotations,
},
}
- Bu yöntem, YAML şablonlarında girintiyi tutturmaktan çok daha basittir
- Üretilen sonuç,
metadata.annotations altında annotation map’i bulunan bir JSON nesnesidir
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true
}
}
}
- Mevcut bir nesneye annotation ekleme işi de Jsonnet’te
+ operatörüyle yapılabilir
local annotations = {
'nginx.ingress.kubernetes.io/app-root': '/',
'nginx.ingress.kubernetes.io/enable-cors': true,
};
{
metadata: {
annotations: annotations,
},
} + { // this adds another JSON object
metadata+: { // I'm using the + operator, so we'll append to the existing metadata
annotations+: { // same as above
something: 'nothing',
},
},
}
- Sonuç nesnesinde mevcut annotation’lara
something: "nothing" eklenir
{
"metadata": {
"annotations": {
"nginx.ingress.kubernetes.io/app-root": "/",
"nginx.ingress.kubernetes.io/enable-cors": true,
"something": "nothing"
}
}
}
- Basit örnekte kod daha uzun görünebilir; ancak yapılandırma karmaşıklaştıkça nesneleri bu şekilde işleyebilme özelliği kullanışlı hâle gelir
kr8, Kubernetes yapılandırmasını Jsonnet yöntemiyle ele alır
- kr8, birden çok Kubernetes kümesinin yapılandırmasını kolay ve basit biçimde oluşturup işlemek için bu yöntemleri kullanır
- Temel akış, YAML şablonlarını boşluklar ve koşullu ifadelerle birleştirmek yerine JSON yapılandırma nesneleri üretmek ve bunları gerekli biçimde dönüştürmektir
1 yorum
Hacker News yorumları
YAML ile yazılmış yapılandırmalardan artık tamamen bıktım. GitHub Actions’ta en sevmediğim kısım bu; kararlılıktan bile daha kötü
Harika bir aracın yapılandırma için YAML dosyası istemesini görünce hemen huzursuz oluyorum. Terraform’un HCL’i, AWS Step Functions’ın ASL’i gibi özel yapılandırma dilleri için de aynısı geçerli
Bildirimsel API istemek sorun değil; ama o bildirimin programatik olarak üretilmesine izin verseler keşke. Kodla bildirip üretilen yapılandırmalar çok daha iyi bir deneyimdi ve AWS CDK bunu gerçekten iyi yaptı
Tip güvenli bir dil ve iyi IDE desteğiyle bulut altyapısı tanımlarını yazabiliyorsunuz; iki yıldır güncellenmemiş eklentilere bel bağlamak zorunda kalmıyorsunuz
deno fmtiçinde JSON biçimlendiricisi varken YAML biçimlendiricisi olmamasıydıJSON biçimlendiricisi milisaniyeler içinde çalışan tek bir binary iken, YAML’ı otomatik biçimlendirmek için fiilen Prettier kullanmak gerekiyor; Prettier da NPM’in yarısına bağımlı ve başlatılıp çalışması yaklaşık 2 saniye sürüyor
Bu yüzden şirket deposunda JSON’a çevrilebilecek tüm YAML dosyalarını JSON’a taşıdım; en azından ben çok daha memnunum. Kimse de şikâyet etmedi
Birçok editör JSON’daki
$schemaetiketini de destekliyor. Ürüne bu özelliği ekledim; dokümanları okumadan sadece Tab’a basarak yapılandırma dosyası oluşturabilmek gerçekten güzelYAML’da da YAML language server ile bu mümkün, ama Tab tuşu girintileme için de gerektiğinden kullanılabilirliği pek iyi değil. JSON da mükemmel değil; ama en azından
"no"metni doğru değerine dönüşmüyorYapılandırmayı okumadan önce yorumları kaldıran bir filtre ekleseniz olmaz mı? Bunun YAML’a geçmekten daha zor olması mümkün değil
YAML’ın okunması kolay olduğu iddiasını da pek anlayamıyorum. Yapılandırmayla uğraşmanın acısı, süslü parantezleri ve köşeli parantezleri birkaç saniye daha az ayrıştırmaktan değil; yüzlerce satırlık yapılandırma içinde eksik bir boşluk ya da tab yüzünden neyin yanlış olduğunu anlamanın zor olmasından geliyor
Ansible da aynı hatayı yapıyor; sayısız araç da öyle
CDK’nın bu şekilde çalışıp çalışmadığından pek emin değilim. Biraz kurcaladığımda, benim yaptığım “CloudFormation üretme” deneyiminden epey farklıydı ve CDK’nın avantajını tam kavrayamadım
YAML/şablon sorununu kalıtım/sihir sorunuyla değiştiriyor gibi hissettirdi. AWS CDK, Terraform CDK ve Pulumi kullanmış olanların deneyimlerini daha fazla duymak isterim
https://github.com/actions/runner/issues/1182
YAML şablonlarının epey çılgınca bir iş olduğuna katılıyorum, ama sahte dilleri bırakıp neden gerçek bir programlama dili kullanmadığımızı hep anlayamıyorum.
Karmaşık mantık gerekiyorsa, bir programlama diliyle YAML/JSON/ne gerekiyorsa üretilebilir. Ruby, Python ya da başka herhangi bir dil; Jsonnet veya Go şablonları gibi tuhaf sözde dillere gerek kalmadan gerekeni sağlar.
Doğrudan kod yazarsanız şablon motorlarının opak ve tuhaf sorunlarına çok daha az takılırsınız. Hangi gerçek dili kullanırsanız kullanın çok daha iyi olur.
Benzer işler için Chef kullanmıştım; Ruby olduğu için istediğim mantığı kolayca tanımlayabilmek, döngüler ve düzgün değişkenler kullanabilmek güzeldi.
Ansible’ın programcı olmayanlar için tasarlandığını anlıyorum, ama temel programlamaya aşina biri için koşullu işler ve yinelemelerle dolu Ansible playbook’larını Jinja şablonlarının laf kalabalığı yapan söz dizimine hapsetmekten daha büyük cehennem yok.
Ama şimdi genelde bir JSON/TOML/YAML ayrıştırıcısı alıp
readConfigfonksiyonu yazıyoruz; gömülü bir yorumlayıcının daha uygun olacağı yerlerde bile böyle yapılıyor.Geliştirici açısından, tam teşekküllü bir dil gömme ve uygulama bağlama sağlamaktansa bir yapılandırma formatına karmaşıklık eklemek daha kolay. Bu yüzden yöntemin kendisini unutmuşlar ya da bunun mümkün olduğunu bile düşünmüyorlar gibi.
Chef/Puppet döneminde IaC’ye mantık eklemeye başlayıp yükseltmesi de bakımı da imkânsız devasa bir karmaşaya dönüşen çok yer oldu. Chef/Pulumi yaklaşımı da mümkün, ama stil ve bakım konusunda çok katı birine ihtiyaç duyuyor.
Büyük ekipler ve uzun vadeli bakım için Terraform/Puppet modelinin daha iyi olduğunu düşünüyorum. HCL sinir bozucu olsa ve Python/TypeScript vb. kullanmak özgürleştirici hissettirse de, saf bildirime dayalı kod çok fazla spagettiyi engeller.
O an moda olan dil tasarımı unsurlarını eklemek istiyorlar, self-hosting istiyorlar, hızlı çok iş parçacıklı web sunucusu da yazılabilsin istiyorlar; sonuçta kavramsal olarak karmaşıklaşıyor.
Sistem mühendisleri/DevOps için Logo gibi basit bir oyuncak dile ihtiyaç var. İdeal olarak K&R C kitabı büyüklüğünde tek bir kitapla açıklanabilmeli.
Dinamik tipler, bir hafta sonunda öğrenilebilecek kontrol yapıları, iş parçacığı veya eşzamanlılık yok, nesne yönelimlilik veya kalıtım yok, fonksiyonel/modüler tasarım ve başka diller ile framework’ler tarafından kolayca çağrılıp onları çağırabilecek bir FFI modeli gerekiyor.
Sorun şu ki dil meraklıları kendilerini kontrol edemeyip sürekli özellik ekliyor; bunlar da çekirdek kütüphanelere ve stil kılavuzlarına giriyor, böylece yeni başlayanların bile hepsini öğrenmesi gerekiyor.
Ben de dizilere/hashmap’lere
each/maptürü fonksiyonlar eklemek, birinci sınıf fonksiyonlar ve closure’lar koymak isterdim; ama bu bir hata olabilir. Zaten yapılandırma için değişmez fonksiyonel diller var, fakat şablon YAML kullananların %95’ten fazlası programlamayı bu şekilde öğrenmek istemediği için yaygınlaşmaları zor.Yapılandırma daha basit, tüketmesi daha kolay ve belgelemesi daha iyi olur. Ama yapılandırma dosyasını yazarken bir programlama dili kullanılmalı; mümkünse hata denetimi, otomatik tamamlama ve satır içi dokümantasyon sağlayan statik tipli bir dil daha iyi.
AWS CDK iyi bir örnek. Saf CloudFormation yazmak acı verici, ama CDK CloudFormation’a programlama özellikleri eklemez; CloudFormation üretir. AWS’nin tükettiği girdi hâlâ nispeten basit ve kararlı CloudFormation’dır.
Başlığı görür görmez Kubernetes’ten bahsedeceğini sandım
Kubernetes API oldukça sezgisel ve iyi tanımlanmış bir JSON şemasına sahip. k8s öğrenme süresinin büyük kısmının API’nin nasıl kullanılacağını anlamaya gitmesi gerekirken, pratikte Helm chart’larının nasıl kullanılacağını çözmeye gidiyor
Jsonnet, Ksonnet, Nu, CUE’nun o kadar büyük popülerlik kazandığını sanmıyorum. Çoğu kişi Kustomize kullanıyor gibi; nedeni de görece sezgisel olması ve
kubectliçine gömülü gelmesiİstediğim araç, tanım yazan kişiye k8s şeması için tip denetimi, doğrulama ve sürümden kaldırma uyarıları sunmalı; kullanıcının kolayca inceleyebileceği tek bir çıktı üretmeli; küme herhangi bir nesneyi/sürümü desteklemiyorsa atomik olarak başarısız olmalı ve temel araç zincirine yerleşik olmalı
Bun veya Deno TypeScript betiğinin argüman alan bir fonksiyon dışa aktarıp tanım listesi döndürmesini sağlamak,
deno compilevb. ile iyi uyacak gibi; ama temel araç zincirine yerleşik olma şartını ihlal ediyorAlt seviye ayrıntılardan korunuyorsunuz, ama sorun çıkınca teşhis ve hata ayıklamayı zorlaştıran dev bir soyutlama yığınıyla uğraşmak zorunda kalıyorsunuz
Gerçekte ne olduğunu anlamak çok daha zorlaşıyor; soyutlama katmanına bağımlı hale gelip sağlayıcının çıkardığı güncellemeleri ve bağımlılık grafiğindeki diğer sorunları da üstleniyorsunuz
İhtiyacımız olan işi neredeyse sorunsuz yapıyor, çapraz platform ve birden fazla dilde kullanılabiliyor. C++, .NET ve JVM çalıştırılabilir dosyalarına gömdüm
Ortaya çıkan JSON yapılandırması, toml/yaml/hocon/ini gibi alternatiflerde bulması zor olan geniş bir araç ekosistemiyle kullanılabiliyor. HOCON’u JVM dışı dillerde kullanmaya çalıştım ama her zaman bir uç durum takılıyordu
Ama pratikte büyük sistemler yönetirken eninde sonunda şablonların faydasından kaçamıyorsunuz
Geliştiricilerin yapılandırmayı doğru ele alma yöntemi üzerine ne kadar az kafa yorduğunu görmek komik
Sadece bir dosyada saklanan veya kodla üretilen anahtar-değer kümeleri gibi görünüyor, ama aslında her şey bu. Programlamanın kendisi
Her şey yapılandırmadır; her fonksiyon argümanı da bir tür yapılandırmadır. Dış dosyalardaki tüm yapılandırmalar sonunda bir şekilde fonksiyon argümanı olur
Sorun, kodun düz metin temsilidir. Bildirimsel yapılandırma dosyaları her şeyi tek yerde görebildiğiniz için iyi görünür; ama yapılandırmayı program haline getirirseniz nereyi değiştirmeniz gerektiğini bulmak zorlaşır
Kod gerçek zamanlı çalışıp nihai yapılandırmanın temsilini gösterse ve her nihai yapılandırma değerinin nasıl üretildiğini izleyebilseydi bu sorun olmazdı. Oysa bu özellik oldukça basit olmasına rağmen bu şekilde tasarlanmış sistem yok. Yapılandırma her zaman sonradan düşünülen bir şey
Bu kavramı programlamanın tamamına genişletirsek, tek bir yapılandırma değerine bağlı olan tüm kodu ve dönüşümlerini görebilmeliyiz
Ayrıca çoğu yapılandırma ilişkisel/graf tabanlıdır; bu yüzden merkezi bir veritabanında tutmak daha iyi olabilir. Farklı yapılandırma değerleri birbiriyle ilişkilidir. Bu nedenle yapılandırmaya bir veritabanı/graf düzenleyicisinden bakmalıyız
Düz metinden uzaklaştığınızda işler çok daha basitleşmeye başlar; ama yukarıda bahsettiğim dil özelliklerine hâlâ ihtiyaç var
Yapılandırmalar, ilişkili değişkenleri gruplamak için adlandırma kuralları kullanmaya çalışıyor
Gerçek iç içe veri yapılarına, muhtemelen JSON’a geçmek istiyorum; ama mühendisler kesinlikle kod yazmak istemediği için kod olarak yapılandırma mümkün değil. Yukarıda söylenen dezavantajlar da var
Sonraki fikir, yapılandırmayı daha iyi gösterecek ve düzenleyecek bir yöntem olması gerektiği. Nihai ürünün temsilini gezmeyi, parçaları seçip parametreleri o şekilde düzenlemeyi sağlayan görsel bir UI düşündüm
Bu yönün doğru olup olmadığını merak ediyorum. Değilse biraz daha açıklamanızı isterim. Bu uygulamanın özü yapılandırma
Daha da kötüsü, CI/CD gibi yerlerde YAML’ın neredeyse bir programlama dili haline gelmesi. Üstelik çok laf kalabalığı yapan, sezgisel olmayan, kötü tanımlanmış ve sağlayıcıya göre değişen bir dil
DTD ve XML doğrulaması olmasına rağmen geç patlayan ve yorumlaması zor hata mesajları üreten tanıdık özelliklere sahipti
O zamanlar hayal kırıklığının çoğu XML’e yönelmişti; ama 2020’lerin ortasındaki YAML cehennemine bakınca sorunun işaretleme dilinin kendisi olmadığı görülüyor
YAML şablonunun bir yerlerine mantık gömmekten gerçekten nefret ediyorum
[0] https://tanzu.vmware.com/developer/guides/ytt-gs/
Helm’in kazanmış olması gerçekten üzücü. Şirkette açık kaynak k8s ile ilgili işler yapıyorum; kullanıcıların %100’ü Helm chart hazırlamamızı istediği için sonunda yapmak zorunda kaldık
Üzerinde çalışmak berbat. Dosya adı
foo.yamlgibi ama aslında YAML değil, bu yüzden editör yardımcı olamıyor. YAML hizalamasını tutturmak için tüm verileriindent 4üzerinden akıtmak gerekiyorEn moral bozucu tarafı, Kubernetes özelliklerinin tamamını kendi yönteminizle yeniden dışa açmanız gerekmesi. Birisi
deployment.spec.template.spec.fooBarseklemek istersevalues.yamliçinedeploymentFooBarsekleyip bağlamanız gerekiyor. Her özellik için aynı şey tekrarlanıyorGerçekten “kötü olan iyidir” yaklaşımının raydan çıkmış bir örneği. Ben de bir ara şablon uygulamak için
sed -e s/$FOO/foo/ggibi korkunç şeyler yapmıştım; muhtemelen Helm de böyle başlamıştır. Sonuç karmakarışıkKişisel olarak Kustomize’ı
kubectliçine girmeden önce bile kullanıyordum ve hep oldukça memnun kaldım. Tuhaf yanları çok ama en azından ürettiği nesnelerin anlamını anladığı için zaman kazandırıyorJsonnet çok daha iyi. k8s uygulamamızın bir parçası olarak karmaşık trafik yönlendirmesi için Envoy dağıtımını da birlikte sunuyoruz; Envoy yapılandırması laf kalabalığıyla dolu ama Jsonnet ile ele almak kolay: https://github.com/pachyderm/pachyderm/blob/master/etc/gener...
Ciddi ciddi jsonnet’i Go şablon diline transpile edip her şeyi Jsonnet ile uygulamayı düşünüyorum. En azından biraz daha sürdürülebilir olur ve
helm installolduğu gibi çalışacağı için kimse anlamazAma Helm’in Kubernetes’in sonunu getireceğini düşünüyorum. Ayarlar için düzgün bir dille gelen rakip bir bilgisayar tahsisi/konteyner çalıştırma aracı çıkarsa herkes bir gecede ona geçer
sed -e s/$FOO/foo/gkullanma isteği geldiğinde, biraz daha standart ve daha iyi bir çözüm olarak envsubst’e bakmak iyi olabilirHelm chart’larını jsonnet ile şablonlamak veya değiştirmek konusundaysa Tanka da yardımcı olabilir: https://tanka.dev/helm
Ancak çalıştığım yerler hâlâ değişimden korktukları için tf/hcl ve helm’i aynen kullanıyor. En azından kişisel projelerde biraz nefes alınıyor
Burada bir sorun olduğunu düşünüyorum. Yine de yapılandırma dili olarak YAML seçen tipte birinin bunu sorun olarak görüp görmeyeceğinden emin değilim
İnsan odaklı veri gösterimi ile bilgisayar odaklı veri gösterimi arasında doğrudan bir çatışma var. Bilgisayar Lisp’e benzer şeyleri sever, insan ise Python’a benzer şeyleri sever
Kubernetes yapılandırmasını bilgisayarla manipüle etmek isteyen biri için Kubernetes’in YAML kullanması içten içe sinir bozucu olacaktır. Ama Kubernetes topluluğu çoğunlukla YAML tarafındaki insanlara benziyor; o hâlde programlama mantığı girince yapılandırma dosyalarıyla çalışmanın berbat hâle gelmesini neden umursasınlar ki?
YAML’in dezavantajı tam da bu durum ve k8s ile uğraşanların çoğunun bunu öngörebilecek kadar zeki olduğunu düşünüyorum
“YAML, JSON’ın üst kümesidir” sözü, belirtim yazarları belgeye ne yazarsa yazsın pratikte doğru değil bence. Tüm YAML yapılandırmasını JSON’a çevirirseniz DevOps ekibi sinirlenir
İki veri biçimi aynı anlam temsiline sahip olabilir; aynı CPU mimarisine derlenen tüm diller için de bu geçerli. JSON ve YAML pratikte ayrıdır, ikisini karıştırmak iyi bir fikir değil
Elbette insanlar sonunda elle yazdı ve katlanılamaz hâle gelince şablon eklemeye başladılar. İşler hep böyle ilerliyor gibi
Elle yazılmış metin, makine tarafından üretilen yapılandırma serileştirme metniyle değiştirilmek yerine, aslında yine elle yazılmış metnin üzerine şablon eklenmiş hâliyle değiştiriliyor
Kişisel ilkem, makinelerin okuyacağı kodu üretmek için string interpolation kullanılmaması gerektiği. Şablon dilleri, havalı bir string interpolation’dan ibaret
SQL injection ve cross-site scripting’in sonuçlarını gördüm. Yorumlayıcıya rastgele metin sokmaya devam ettiğimiz sürece bunlar olmaya devam edecek
Bu yüzden HTML üretirken de şablon dosyaları kullanılmaması gerektiğini düşünüyorum
HTML için şablon dili alternatifleri olarak Ruby’de Haml, JavaScript’te Pug var. Bu diller etiketler, öznitelikler ve metin düğümlerinden oluşan tüm ağacı tanımlamak için belirlenmiş bir yöntem sunar
Python tarzı anlamlı girintilemeyi sevmiyorsanız JavaScript’te JSX var. JSX’in HTML’e benzeyen kısmı, web belge ağacını oluşturan
createElementifadelerine derlenir; bu ağaç da gerekirse HTML olarak çıktı verilebilirHaml, Pug, JSX HTML çıktısı üretebilse de şablon dili değildir. Aynı şekilde
JSON.stringify(myObj)da JSON için bir şablon dili değildirMakinelerin okuyacağı kod, mümkünse hedef dilin bilinen yapısını anlayan ve kullanan araçlarla üretilmelidir
Haml, web belgesindeki inline koddan kaçınmak ve HTML’i daha temiz hale getirmek için bir şablon sistemidir; Pug ise Node.js için zengin özellikli bir şablon motorudur
JSX’in teknik olarak bir şablon dili olmadığına katılabilirim
Sonuçta bunların hepsi HTML’e derlenir. Ancak string interpolation değil; sözdizim ağacı olarak ayrıştırılan ve geçerli yapıya dair içsel bir anlayışa dayanarak HTML’e render edilen dillerdir
YAML şablonları havalı string interpolation’dır; şablon dili değildir ya da en azından berbat uygulanmış bir şablon dilidir
Kişisel kuralım, bir değer bir string’in içine her girdiğinde mutlaka doğru şekilde encode edilmesi gerektiği
Daha önce bu konuda yazmıştım: https://kevincox.ca/2022/02/08/escape-everything/
Özetle, her string’in HTML, SQL, insanların okuyacağı terminal çıktısı gibi uyması gereken bir biçimi vardır. Bir değeri bir string’e her koyduğumuzda o biçime uygun şekilde doğru encode etmeliyiz; ama bunu neredeyse hiç yapmıyoruz
cuelang’e geçiyoruz [1]. Şahsen tasarımının Jsonette’ten daha iyi olduğunu düşünüyorum
Kubernetes’te zaten durum uzlaştırma var; bu yapılandırmada eksik olan tek şey silmeydi, o da artık prune özelliğiyle çözülebiliyor [2]
[1] https://cuelang.org/docs/integrations/k8s/
[2] https://kubernetes.io/blog/2023/05/09/introducing-kubectl-ap...
Bazı hata mesajlarını yorumlamak biraz zor, ama önceden yakaladığı hata sayısı o kadar fazla ki kabul edilebilir. Artık doğrudan yaml yazmak zorunda kaldığım birkaç an, kıyaslayınca fazlasıyla sıkıcı geliyor
Böyle durumlarda genelde “Kurtarıcımız CUELang’i duydunuz mu?” diye araya giriyorum: https://cuelang.org/
Henüz Turing-complete değil, ama tekrarları gidermek için yeterince ifade gücüne sahip; aynı dilde şema ve veriyi aynı dosyada ya da ayrı dosyalarda tanımlayabiliyorsunuz ve union type’lar da var
YAML veya JSON üretebiliyor; kendisini ya da YAML/JSON dosyalarını doğrulayabiliyor
En büyük dezavantajı, mevcut uygulamanın yalnızca Go’da olması; bu yüzden alt süreç veya FFI gerekebilir
Ardından her uygulama için JSON dosyaları üretiyor, bir araç XML tanımları oluşturuyor; bu tanımlar mimarların sahip olduğu XLS’e uygulanıyor ve oradan Helm chart’larına uygulanacak YAML çıkarılıyor
Chart, k8s istemcisini deploy ediyor; bu istemci de API üzerinden JSON ile ana cluster’la etkileşime giriyor
Biraz zaman aldı, ama her iş için en iyi aracı kullanıyoruz