Joe Beda’nın erken Kubernetes tercihlerine — deklaratif API'ler, kontrol döngüleri, Pod'lar, Service'ler ve etiketler — net bir bakış ve bunların modern uygulama platformlarını nasıl şekillendirdiği.

Joe Beda, Kubernetes'in en erken tasarımında kilit kişilerden biriydi—Google'un iç sistemlerinden çıkarılan dersleri açık bir platforma taşıyan kurucularla birlikte. Onun etkisi moda özelliklerin peşinden koşmak değildi; gerçek üretim karmaşasıyla başa çıkabilecek ve günlük ekiplerin anlayabileceği basit ilkelere odaklanmaktı.
Bu erken kararlar Kubernetes'i sadece “bir konteyner aracı” olmaktan çıkardı. Modern uygulama platformları için yeniden kullanılabilir bir çekirdeğe dönüştürdü.
“Konteyner orkestrasyonu”, makineler bozulduğunda, trafik yükseldiğinde veya yeni bir sürüm dağıtıldığında uygulamanızın çalışır halde kalmasını sağlayan kurallar ve otomasyon setidir. Bir insan sunucuları el ile gözetlemek yerine, sistem konteynerleri bilgisayarlara zamanlar, çöktüklerinde yeniden başlatır, dayanıklılık için dağıtır ve kullanıcıların onlara ulaşabilmesi için ağ yapılandırmasını sağlar.
Kubernetes yaygınlaşmadan önce ekipler genellikle temel soruları cevaplamak için betikler ve özel araçlar birleştiriyordu:
Bu kendin-yap (DIY) sistemleri işe yarıyordu—ta ki yaramayana kadar. Her yeni uygulama veya ekip daha fazla tekil mantık ekledi ve operasyonel tutarlılık sağlamak zorlaştı.
Bu makale, erken Kubernetes tasarım seçimlerini (Kubernetes’in “şekli”) ve bunların neden modern platformları etkilemeye devam ettiğini anlatıyor: deklaratif model, kontrolcüler, Pod'lar, etiketler, Service'ler, güçlü bir API, tutarlı küme durumu, eklenti ile zamanlama ve genişletilebilirlik. Kubernetes'i doğrudan çalıştırmıyor olsanız bile, büyük olasılıkla bu fikirlerin üzerine kurulmuş bir platform kullanıyorsunuz—veya aynı sorunlarla uğraşıyorsunuz.
Kubernetes'ten önce, “konteyner çalıştırmak” genellikle birkaç konteyner çalıştırmak anlamına geliyordu. Ekipler dağıtımı sağlamak için bash betikleri, cron işleri, golden imajlar ve birkaç geçici araç bir araya getiriyordu. Bir şey bozulduğunda, düzeltme genellikle birinin kafasında ya da kimsenin güvenmediği bir README'de yaşıyordu. Operasyon, süreçleri yeniden başlatmak, load balancer'ları yeniden yönlendirmek, diski temizlemek ve hangi makineye dokunmanın güvenli olduğunu tahmin etmek gibi tek seferlik müdahaleler akışıydı.
Konteynerler paketlemeyi kolaylaştırdı, ama üretimdeki karmaşayı ortadan kaldırmadı. Ölçeklendiğinizde sistem daha sık ve farklı şekillerde başarısız olur: node'lar kaybolur, ağlar bölünür, imajlar tutarsız yayılır ve iş yükleri beklediğinizden sapar. “Basit” bir dağıtım şelaleye dönüşebilir—bazı örnekler güncellendi, bazıları kalakaldı, bazıları takıldı, bazıları sağlıklı ama ulaşılamaz.
Gerçek sorun konteynerleri başlatmak değildi. Sorun doğru konteynerleri, doğru biçimde, sürekli değişime rağmen çalışır halde tutmaktı.
Ekipler ayrıca farklı ortamlarda denge kuruyordu: yerel donanım, VM'ler, erken bulut sağlayıcıları ve çeşitli ağ/disk düzenlemeleri. Her platformun kendi dili ve hata kalıpları vardı. Ortak bir model olmadan her geçiş operasyonel araçları yeniden yazmak ve insanları yeniden eğitmek demekti.
Kubernetes, makinelerin nerede olduğuna bakılmaksızın uygulamaları ve operasyonel ihtiyaçlarını tanımlamak için tek, tutarlı bir yol sunmayı hedefledi.
Geliştiriciler self-service istiyordu: bilet açmadan dağıt, kapasite için yalvarmadan ölçekle, drama olmadan geri al. Operasyon ekipleri öngörülebilirlik istedi: standart sağlık kontrolleri, tekrarlanabilir dağıtımlar ve neyin çalışıyor olduğuna dair net bir gerçek kaynağı.
Kubernetes gösterişli bir zamanlayıcı olmaya çalışmıyordu. Karmaşık gerçekliği akıl yürütebileceğiniz bir sisteme çeviren güvenilir bir uygulama platformunun temeli olmaya çalışıyordu.
Erken seçimlerden en etkili olanlardan biri Kubernetes'i deklaratif yapmak oldu: ne istediğinizi tarif edersiniz ve sistem gerçeği bu tanıma uydurmaya çalışır.
Bir termostat günlük hayattan faydalı bir örnektir. Isıtıcıyı her birkaç dakikada bir elle açıp kapatmazsınız. İstenen bir sıcaklık ayarlarsınız—örneğin 21°C—ve termostat o sıcaklığa yakın tutmak için odayı kontrol edip ısıtıcıyı ayarlar.
Kubernetes de aynı şekilde çalışır. Kümeye adım adım “şu konteyneri şu makinede başlat, sonra çökerse yeniden başlat” demek yerine sonucu beyan edersiniz: “Bu uygulamadan 3 kopya çalışmasını istiyorum.” Kubernetes sürekli olarak neyin gerçekten çalıştığını kontrol eder ve sapmayı düzeltir.
Deklaratif konfigürasyon, genellikle birinin kafasında veya yarım güncellenmiş bir runbook'ta kalan gizli “operasyon listesi”ni azaltır. Konfigürasyonu uygularsınız ve Kubernetes yerleştirme, yeniden başlatma ve değişiklikleri uzlaştırma mekaniklerini halleder.
Ayrıca değişiklik incelemeyi kolaylaştırır. Bir değişiklik, özel komutlar dizisi yerine konfigürasyondaki bir diff olarak görünür.
İstenen durum yazılı olduğu için aynı yaklaşımı geliştirme, staging ve üretimde tekrar kullanabilirsiniz. Ortam farklı olabilir ama niyet tutarlı kalır; bu da dağıtımları daha öngörülebilir ve denetlenebilir kılar.
Deklaratif sistemlerin öğrenme eğrisi vardır: “sonraki ne yapmalıyım” yerine “ne doğru olmalı” diye düşünmeyi gerektirir. Ayrıca iyi varsayılanlara ve net konvansiyonlara bağımlıdır—bunlar yoksa ekipler teknik olarak çalışan ama anlaşılması ve bakım yapılması zor konfigürasyonlar üretebilir.
Kubernetes sadece konteynerleri bir kere çalıştırabildiği için başarılı olmadı—zaman içinde onları doğru şekilde çalışır halde tutabildiği için başarılı oldu. Büyük tasarım hamlesi “kontrol döngüleri”ni (kontrolcüler) sistemin çekirdeği yapmaktı.
Bir kontrolcü basit bir döngüdür:
Bu tek seferlik bir görevden çok oto-pilot gibidir. İş yüklerini “gözetlemek” yerine niyeti beyan edersiniz ve kontrolcüler kümeyi o sonuca doğru sürekli çeker.
Bu desen Kubernetes'in gerçek dünya hatalarıyla karşılaştığında dayanıklı olmasını sağlar:
Hataları özel durumlar olarak ele almak yerine, kontrolcüler onları rutin “durum uyumsuzluğu” olarak görür ve her seferinde aynı şekilde düzeltir.
Geleneksel otomasyon betikleri genellikle kararlı bir ortam varsayar: önce A çalıştır, sonra B, sonra C. Dağıtık sistemlerde bu varsayımlar sık sık bozulur. Kontrolcüler daha iyi ölçeklenir çünkü idempotenttirler (tekrar tekrar güvenle çalıştırılabilir) ve nihai olarak tutarlıdırlar (hedefe ulaşana kadar denemeye devam ederler).
Eğer bir Deployment kullandıysanız, kontrol döngülerine güvenmişsinizdir. Altında Kubernetes, istenen pod sayısını sağlamak için bir ReplicaSet kontrolcüsü kullanır—ve Deployment kontrolcüsü ise rolling update ve rollback işlemlerini öngörülebilir şekilde yönetir.
Kubernetes “sadece konteynerleri” planlayabilirdi, ama Joe Beda ve ekibi makinede yerleştirilecek en küçük dağıtılabilir birim olarak Podları getirdi. Temel fikir: birçok gerçek uygulama tek bir süreç değildir. Onlar, birlikte yaşaması gereken küçük bir grup sıkı bağlı süreçtir.
Pod, aynı kaderi paylaşan bir veya daha fazla konteynerin sarmalayıcısıdır: birlikte başlarlar, aynı node'da çalışırlar ve birlikte ölçeklenirler. Bu, sidecar desenlerini doğal kılar—log shipper, proxy, konfigürasyon yeniden yükleyici veya güvenlik ajanı gibi ana uygulamayı her zaman takip etmesi gereken yardımcılar düşünün.
Bu yardımcıları her uygulamaya entegre etmeye çalışmak yerine, Kubernetes onları ayrı konteynerler olarak paketlemenize izin verir ama yine de tek bir birim gibi davranmalarını sağlar.
Pod'lar iki önemli varsayımı pratik hale getirdi:
localhost üzerinden konuşabilir; bu basit ve hızlıdır.Bu seçimler özel yapıştırıcı kod ihtiyacını azalttı ve konteynerleri işlem düzeyinde izole tutmaya devam etti.
Yeni kullanıcılar genellikle “bir konteyner = bir uygulama” bekler, sonra Pod düzeyi kavramlarla kafaları karışır: yeniden başlatmalar, IP'ler ve ölçeklendirme. Birçok platform, ekiplerin her gün Pod mekaniklerini düşünmesine gerek kalmadan sidecar ve paylaşılan kaynakların faydalarını almasını sağlamak için akıllı şablonlar sunar (örneğin “web servisi”, “worker” veya “job”).
Kubernetes'te sessiz ama güçlü bir erken seçim, etiketleri birinci sınıf metadata ve seçicileri nesneleri “bulmanın” birincil yolu olarak görmek oldu. Tam olarak üç makinenin benim uygulamamı çalıştırdığı gibi sert ilişkilendirmeler yapmak yerine, Kubernetes paylaşılan özelliklerle grupları tanımlamanızı teşvik eder.
Etiket, kaynaklara—Pod'lara, Deployment'lara, Node'lara, Namespace'lere ve daha fazlasına—eklediğiniz basit anahtar/değer çiftidir. Sorgulanabilir “tag” gibi davranırlar:
app=checkoutenv=prodtier=frontendEtiketler hafif ve kullanıcı tanımlıdır, bu yüzden organizasyonunuzun gerçekliğini modelleyebilirsiniz: ekipler, maliyet merkezleri, uyumluluk bölgeleri, sürüm kanalları veya işletme açısından önemli olan herhangi bir şey.
Seçiciler etiketler üzerinde sorgudur (örneğin, “app=checkout ve env=prod olan tüm Pod'lar”). Bu, pod'lar yeniden zamanlandıkça, ölçeklendikçe veya roll out sırasında değiştikçe sistemin uyum sağlamasını sağlar. Yapılandırmanız altında yatan örnekler sürekli değişse bile kararlı kalır.
Bu tasarım operasyonel olarak ölçeklenir: binlerce örnek kimliğini yönetmezsiniz—birkaç anlamlı etiket setini yönetirsiniz. Bu gevşek bağlanmanın özü: bileşenler üyeliği güvenle değişebilen gruplara bağlanır.
Etiketler bir kez var olduğunda platform genelinde ortak bir sözlük haline gelir. Trafik yönlendirme (Service'ler), politika sınırları (NetworkPolicy), gözlemlenebilirlik filtreleri (metrikler/loglar) ve hatta maliyet takibi ve faturalandırma için kullanılır. Bir basit fikir—nesneleri tutarlı şekilde etiketleme—birçok otomasyon fırsatını açar.
Kubernetes, konteynerların kesinlikle öngörülemez olduğu bir ortamda ağın öngörülebilir hissetmesini sağlamaya ihtiyaç duydu. Pod'lar değiştirildiği, yeniden zamanlandığı ve ölçeklendiği için IP'leri ve çalıştıkları makineler sürekli değişir. Service fikri basittir: değişen Pod kümesine sabit bir “ön kapı” sağlayın.
Bir Service size tutarlı bir sanal IP ve DNS adı verir (örneğin payments). Bu adın arkasında Kubernetes, Service'in seçicisiyle eşleşen Pod'ları sürekli takip eder ve trafiği ona göre yönlendirir. Bir Pod ölür ve yenisi ortaya çıkarsa, Service hâlâ doğru yere işaret eder; uygulama ayarlarını elle değiştirmek zorunda kalmazsınız.
Bu yaklaşım birçok elle yapılan bağlantıyı ortadan kaldırdı. IP'leri konfigürasyon dosyalarına sabitlemek yerine, uygulamalar isimlere güvenebilir. Uygulamayı dağıtın, Service'i dağıtın ve diğer bileşenler DNS üzerinden bulur—özel bir kayıt defterine gerek yok, sabit uç noktalar yok.
Service'ler aynı zamanda sağlıklı uç noktalar arasında varsayılan yük dengeleme davranışı getirdi. Bu, ekiplerin her dahili mikroservis için kendi yük dengeleyicisini inşa etmek zorunda kalmaması demekti. Trafiğin dağıtılması tek bir Pod başarısızlığının patlama alanını azaltır ve rolling update'leri daha az riskli kılar.
Service L4 (TCP/UDP) trafiği için iyidir, ama HTTP yönlendirme kuralları, TLS terminasyonu veya kenar politikalarını modellemez. Bu durumlarda Ingress ve giderek daha fazla Gateway API devreye girer: Service'lerin üzerine hostname, yol ve dış giriş noktalarını daha temiz şekilde inşa ederler.
Erken yapılan en radikal seçimlerden biri Kubernetes'i bir API olarak sunmaktı—tıklanacak tek bir monolitik ürün değil. Bu API-öncelikli duruş Kubernetes'i uzatılabilir, scriptlenebilir ve yönetilebilir bir platform gibi hissettirdi.
API yüzey alanı olduğunda, platform ekipleri uygulamaların nasıl tanımlanıp yönetileceğini standardize edebilir; hangi UI, pipeline veya dahili portalın üstte olduğunun önemi azalır. “Bir uygulama dağıtmak”, “API nesneleri göndermek ve güncellemek” (Deployment, Service, ConfigMap gibi) anlamına gelir; bu da uygulama ekipleri ile platform arasında daha temiz bir sözleşme sağlar.
Her şey aynı API üzerinden geçtiği için yeni araçlar ayrıcalıklı arka kapılara ihtiyaç duymaz. Dashboard'lar, GitOps kontrolörleri, politika motorları ve CI/CD sistemleri hepsi normal API istemcisi olarak, sınırlandırılmış izinlerle çalışabilir.
Bu simetri önemlidir: istek bir kişiden, bir betikten veya dahili bir platform UI'sından gelsin, aynı kurallar, yetki, denetim ve admission kontrolleri uygulanır.
API sürümlendirme, Kubernetes'i bir gecede her kümeyi veya her aracı kırmadan evrimleştirilebilir kıldı. Kullanımdan kaldırma aşamalı yapılabilir; uyumluluk test edilebilir; yükseltmeler planlanabilir. Yıllarca küme çalıştıran organizasyonlar için bu, “güncelleyebiliyoruz” ile “takıldık” arasındaki farktır.
kubectl gerçekte neyi temsil ederkubectl Kubernetes değildir—o bir istemcidir. Bu zihniyet ekipleri API iş akışları etrafında düşünmeye iter: kubectl'i otomasyonla, bir web UI ile veya özel bir portal ile değiştirebilirsiniz ve sistem API sözleşmesi sayesinde tutarlı kalır.
Container orkestrasyonu, makineler başarısız olduğunda, trafik değiştiğinde ve dağıtımlar gerçekleştiğinde uygulamaların çalışır halde kalmasını sağlayan otomasyondur. Pratikte şunları yönetir:
Kubernetes, bunu farklı altyapı ortamlarında tutarlı bir modelle yapmayı popülerleştirdi.
Asıl sorun konteynerleri başlatmak değildi—asıl sorun doğru konteynerlerin, doğru biçimde, sürekli değişen koşullara rağmen çalışır durumda tutulmasıydı. Ölçeklendikçe aşağıdaki rutin sorunlar ortaya çıkar:
Kubernetes, operasyonu tekrarlanabilir ve öngörülebilir kılmak için standart bir kontrol düzlemi ve ortak bir sözlük sunmayı hedefledi.
Deklaratif bir sistemde, ne yapmak istediğinizi (örneğin “3 replika çalıştır”) tanımlarsınız ve sistem gerçekliği bu istenen duruma uygun hale getirmek için sürekli çalışır.
Pratik akış:
kubectl apply veya GitOps)Bu, gizli çalışma talimatlarını azaltır ve değişiklikleri rastgele komutlar yerine diffler olarak gözden geçirmeyi mümkün kılar.
Kontrolcüler, tekrar eden bir şekilde çalışan şu basit döngüyü uygular:
Bu tasarım, yaygın hataları özel durumlar olarak ele almak yerine rutin hale getirir. Örneğin bir Pod çökerse veya bir node kaybolursa, ilgili kontrolcü “istenen replika sayısı azalmış” diye görür ve yerine yenilerini başlatır.
Kubernetes, bireysel konteynerleri değil Podları planlar çünkü gerçek dünyadaki birçok iş yükü birbirine sıkı sıkıya bağlı yardımcı süreçlere ihtiyaç duyar.
Pod'lar aşağıdaki desenleri mümkün kılar:
localhost üzerinden konuşur)Pratik kural: Yaşam döngüsünü, ağ kimliğini veya yerel veriyi paylaşması gereken konteynerleri aynı Pod içinde gruplayın.
Etiketler, örneğin app=checkout veya env=prod gibi anahtar/değer çiftleridir. Seçiciler (selectors) bu etiketler üzerinde sorgu yapar ve dinamik gruplar oluşturur.
Bu, Pod'ların yeniden planlanma, ölçeklendirme veya değiştirilme sırasında üyelerin değişmesine rağmen sabit ilişkiler kurmanızı sağlar.
Operasyonel ipucu: Küçük ve standart bir etiket sözlüğü (app, team, env, tier) belirleyin ve politikalarla zorlayın, ileride kargaşayı önlemek için.
Service, seçiciyle eşleşen değişen bir Pod kümesine yönelik kararlı bir sanal IP ve DNS adı sağlar.
Ne zaman Service kullanmalı:
HTTP yönlendirme, TLS terminasyonu ve kenar politikaları için genellikle Service üstüne Ingress veya Gateway API eklenir.
Kubernetes API'yi ana ürün yüzeyi olarak ele alır: Deployments, Services, ConfigMaps gibi her şey API nesneleridir ve kubectl bunlardan sadece bir istemcidir.
Pratik faydalar:
İç platform kuruyorsanız, iş akışlarını bir UI yerine API sözleşmeleri etrafında tasarlayın.
etcd, kontrol düzleminin veritabanıdır ve kümenin şu an ne olması gerektiğinin kaynağıdır. Bir Deployment oluşturduğunuzda, ReplicaSet'i ölçeklendirdiğinizde veya bir Service güncellediğinizde, istenen yapılandırma etcd'ye yazılır. Kontrolcüler ve diğer bileşenler bu depolanmış durumu izler ve gerçeği eşitlemeye çalışır.
Pratik rehber:
Yönetilen Kubernetes kullanıyorsanız, sağlayıcınızın neleri yedeklediğini öğrenin—örneğin kalıcı hacimler ve uygulama verileri genellikle sizin sorumluluğunuzda kalır.
Kubernetes çekirdeği küçük tutup yetenekleri eklenti yoluyla genişletmeye izin verir:
Bu, “Kubernetes üzerinde platform” modeline olanak verir ama araç bolluğu ve uyumsuz konvansiyonlar riskini de getirir. Değerlendirirken sormalısınız: