Kubernetes v1.36 User Namespaces GA: Root Artık Gerçek Root Değil
Açıkçası, Yıllardır beklenen şey sonunda öldü. Kubernetes v1.36 ile User Namespaces desteği GA seviyesine çıktı. Bunu duyunca ilk tepkim, hiç süslemeden söyleyeyim, “nihayet be!” öldü; çünkü bu özelliği alpha günlerinden beri uzaktan izliyordum. Tahmin eder mısınız? Her sürümde içimden aynı cümle geçiyordu: “Belki bir sonraki sürümde gelir.” Ama artık iş değişti, production’da kullanılacak seviyeye geldi.
Şimdi haklı olarak “tamam da bunun olayı ne?” diye sorabilirsiniz. Peki neden? Basit anlatayım: Container içinde root gibi çalışan bir süreç, Linux kernel tarafından host üzerinde de root gibi algılanıyor. Yanı container’dan kaçmayı başaran biri — ister kernel açığıyla olsun, ister yanlış ayarlanmış bir mount yüzünden olsun — host tarafında da root’a çok yakın dürüyor. Kısacası, mesele bu kadar sade ve bu kadar tatsız.
UID 0 Problemi: Neden Bu Kadar Büyük Bir Olay?
Bak şimdi, container güvenliği konuşulunca herkesin ağzına seccomp, AppArmor, read-only filesystem düşüyor. Bunlar boş değil, tartışmam. Ama küçük bir açıkları var: sürecin kimliğini değiştirmiyorlar (evet, doğru duydunuz). Container içindeki root hâlâ kernel gözünde root’un ta kendisi sayılıyor. Capabilities’i kıssan da, cgroups ile sıkıştırsa da, o sürecin UID’si 0 kalıyor (ciddiyim). Nokta.
Aslında, 2023’ün sonlarında bir finans kuruluşunda güvenlik denetimi yapıyorduk. Kubernetes cluster’larını didik didik inceliyoruz, baktım pod’ların neredeyse hepsi root olarak çalışıyor. Ekibe sordum “neden böyle?”, cevap klasik geldi: “uygulama root istiyor, yoksa dosya yazamıyor”. İşte User Namespaces tam burada devreye giriyor; container içinde root gibi görünen süreç, host tarafında 65534 gibi yüksek bir UID’ye map ediliyor (yanı kabaca sıradan kullanıcı seviyesine indiriliyor). Saldırgan container’dan kaçsa bile host’ta eli kolu bağlı kalıyor.
Açık konuşayım: bu sadece “iyi fikir” falan değil. HIGH seviyede değerlendirilen birkaç CVE’nın User Namespaces sayesinde etkisiz kaldığı gösterildi. Kağıt üstünde hoş duran bir detay değil yanı; gerçekten işe yarıyor.
ID-Mapped Mounts: İşin Perde Arkasındaki Kahraman
Vallahi, User Namespaces’in GA’ya gelmesi öyle kolay olmadı. En büyük takılma noktası neydi biliyor musunuz? Volume’lar. Evet, bildiğiniz dosya sahipliği meselesi.
Aslında, Şöyle düşünün: container içindeki kullanıcıyı yüksek bir UID aralığına map ettiniz. Güzel. Ama volume üzerindeki dosyalar hâlâ UID 0’a ait dürüyor. Container bunlara erişemiyor. Eski çözüm ne? Kubelet’in volume içindeki her dosyaya recursive chown atması. Büyük volume’larda bu iş dakikalar sürüyor; hatta bir müşterimizde 200 GB’lık persistent volume yüzünden pod startup süresi 4 dakikayı geçmişti. Hani olur ya, insanın canı sıkılır; aynen öyle bir durum.
İşte tam burada Linux 5.12 ile gelen ID-mapped mounts devreye giriyor. Bu mekanizma diskteki sahipliği değiştirmiyor. Mount sırasında kernel seviyesinde şeffaf bir UID/GID çevirisi yapıyor (bir nevi perde arkasında tercüman gibi çalışıyor). Container açısından dosyalar UID 0’a ait görünüyor ama diskte hiçbir şey oynanmamış oluyor. Bu da O(1) operasyon demek; yanı anlık sayılır. Volume büyüklüğü fark etmiyor.
ID-mapped mounts olmadan User Namespaces pratikte kullanılamazdı. Kernel ekibinin bu özelliği geliştirmesi, Kubernetes tarafındaki yılların çalışmasının temelini oluşturdu.
Bir dakika, bunu da söylemem lazım: bu özellik sadece Linux’ta çalışıyor. Windows container’ları şu an kapsam dışında kalıyor. Karma bir cluster kullanıyorsanız node selector ya da taints ile Linux node’larına yönlendirme yapmanız gerekiyor; ufak gibi görünen ama sonra insanı uğraştıran bir detay bu.
Kubernetes v1.36’da Nasıl Kullanılıyor?
Aslında, E tabi asıl soru şu geliyor: “Tamam ikna oldum, bunu nasıl açacağım?” Cevap şaşırtıcı derecede sade aslında:
apiVersion: v1
kind: Pod
metadata:
name: isolated-workload
spec:
hostUsers: false
containers:
— name: app
image: fedora:42
securityContext:
runAsUser: 0
hostUsers: false — mesele bu kadar basit görünüyor ve evet gerçekten de öyle çalışıyor en azından kağıt üstünde değil pratikte de fena gitmiyor; container image’ınızı ellemiyorsunuz, konfigürasyonu dağıtmıyorsunuz, ekstra karmaşa çıkmıyor.
Bunu ilk denediğimde kendi kendime “bu kadar mı?” dedim sonra pod içine girip cat /proc/self/uid_map çalıştırdım. Mapping’in gerçekten oluştuğunu gördüm; açıkçası insan biraz şaşırıyor (şaşırtıcı ama gerçek)
Ama Dur, Her Şey Gül Bahçesi Değil
Burada biraz frene basmak lazım çünkü GA öldü diye her runtime aynı tadı vermiyor olabilir, hatta bazen hiç vermiyor bile diyebilirim; CRI-O ile denediğim senaryolar gayet düzgündü (şaşırtıcı ama gerçek). Containerd tarafında v1.7+ kullanınca rahat ettim.
Buna karşılık eski runtime sürümlerinde can sıkıcı sorunlar çıkabiliyor. Geçen ay bir müşteride containerd 1.6 ile test yaptık ve düzgün sonuç alamadık; yükseltme sonrası toparladı ama yine de gözden kaçmaması gereken bir nokta olarak kenarda dürüyor.
Bir de şu var ki neredeyse tüm volume plugin’leri ID-mapped mounts’u desteklemiyor olabilir; özellikle bazı CSI driver’ları henüz hazır değil gibi davranabiliyorlar. Biraz nazlılar diyelim. Bu konuyla ilgili Gemini ile Hayatını Düzenle: 8 Yapay Zeka Destekli İpucu yazımıza da göz atmanızı tavsiye ederim.
Türkiye’deki Kurumsal Ortamda Bu Ne Anlama Geliyor?
Bence, Şimdi gelelim benim asıl kafama takılan yere. Türkiye’deki şirketlerin Kubernetes kullanım olgunluğu son 3-4 yılda baya arttı desem abartmış olmam sanırım. Bankacılıkta başka, telekomda başka, e-ticarette başka… herkes ciddi workload koşturuyor artık. Ama güvenlik tarafında hâlâ açık kapılar var. Axios npm Saldırısı: Azure Pipelines’ta Ne Yapmalı? yazımızda bu konuya da değinmiştik.
Logosoft’ta danışmanlık verdiğim kurumsal müşterilerin çoğunda pod security standartlarına bakıyorum. Gördüğüm tablo pek değişmiyor: container’ların büyük kısmı hâlâ root olarak koşuyor. Neden? Çünkü “uygulama öyle istiyor” ya da “dockerfile’a dokunmaya vakit yok” denip geçiliyor. User Namespaces bu bahaneyi baya zayıflatıyor — uygulama içeride root gibi devam edebilir ama host tarafında artık root olmuyor.
Durun, bir saniye. Daha fazla bilgi için Kubelet API Yetkilendirmesi GA Oldu: Güvenlik Devrimi yazımıza bakabilirsiniz.
Şahsen, Bilhassa KVKK ve BDDK denetimleri açısından bakınca container breakout senaryolarına karşı koruma sağlamak artık lüks değil. Bir bankacılık projesinde güvenlik denetçisi bana “container’dan host’a erişim mümkün mü?” diye sorduğunda User Namespaces’i göstermek insana ayrı bir rahatlık veriyor; çünkü cevap daha net hâle geliyor.
Enterprise vs Startup: Kim Nasıl Yaklaşmalı?
Bir şey dikkatimi çekti: Küçük bir ekipseniz ve 5-10 pod çalıştırıyorsanız bence çok uzatmayın; bugün hostUsers: false ekleyip deneyin. Test edin, çalışıyorsa — ki büyük ihtimalle çalışacak — production’a alın. Burada filozofi yapmaya pek gerek yok. Daha fazla bilgi için GitHub Pull Requests Dashboard: Herkes İçin Açılan Yeni Deneyim yazımıza bakabilirsiniz.
Peki neden? Daha fazla bilgi için AI Agent’larda Sohbet Geçmişi: Nerede Saklamalı? yazımıza bakabilirsiniz.
Ama enterprise seviyede 500+ pod’unuz varsa iş biraz daha planlı yürür. Aşağıdaki tabloyu hazırladım, belki işinizi görür:
| Kriter | Startup / Küçük Ekip | Enterprise / Büyük Kurum |
|---|---|---|
| Uygulama stratejisi | Tüm pod’lara hemen ekle | Önce kritik workload’lardan başla, aşamalı geçiş yap |
| Test süresi | 1-2 gün yeterli olur | En az 2 hafta staging ortamında test et |
| Runtime gereksinimleri | Güncel sürüm çoğu zaman yeterli olur | Runtime,kernel ve CSI driver uyumluluğunu doğrula |
| Maliyet etkisi | Neredeyse yok | Eğer eski kernel kullanıyorsan node yükseltmesi gerekebilir |
| Sorun izleme | AUDIT loglarında UID mapping’i kontrol et |
Name Space Edilmiş Capability Meselesi Ne Oluyor?
hostUsers:false<;/code> işaretlenmiş konteйneplerde verilen capability'ler namespace içinde sınırlı kalır. apiVersion: "v1"
kind: "Pod"
metadata:
name: "isolated-workload"
spec:
hostUsers: false
containers:
->
name:"app"
image:"fedora42"
securityContext:
runAsUser:"0"
-
Kernel sürümü kontrol et:<;/span>
Container runtime doğrula:<;/span>
Sıkça Sorulan Sorular
User Namespaces için container image’ımı değiştirmem gerekiyor mu?
Hayır, hiçbir image değişikliğine gerek yok. Pod spec’ine hostUsers: false eklersen yeterli. Uygulama container içinde yine root olarak çalışıyor, yanı aslında hiçbir şey değişmemiş gibi görünüyor — ama host tarafında yüksek bir UID’ye map ediliyor.
Windows container’larında da çalışıyor mu?
İşte, hayır. Bu büyük ölçüde Linux’a özgü bir şey, yanı Linux kernel’ındaki user namespace mekanizmasına dayanıyor. Windows node’larınız varsa bu pod’ları Linux node’larına yönlendirmeniz gerekiyor.
ID-mapped mounts için minimum kernel sürümü ne olmalı?
Bence, Teknik olarak Linux 5.12 ile geldi ama sonraki sürümlerde ciddi iyileştirmeler yapıldı. Tecrübeme göre pratikte 5.15 LTS veya üzerini kullanmak çok daha mantıklı. Eski kernel’larda beklenmedik davranışlarla karşılaşabiliyorsunuz, açıkçası gereksiz bir risk.
User Namespaces açınca performans düşer mi?
Hayır. ID-mapped mounts sayesinde volume erişiminde herhangi bir kayıp yaşanmıyor — O(1) operasyon (kendi tecrübem). Genel çalışma zamanında da ölçülebilir bir fark görmedim bence. Hatta eski yöntemdeki recursive chown’la kıyaslandığında performans kazancı bile sağlıyor.
Mevcut pod’larıma hostUsers: false eklersem ne olur?
Pod yeniden oluşturulacağı için bir restart yaşanıyor. Uygulama genelde sorunsuz çalışıyor, yanı büyük bir sorun beklemiyorum ama yine de volume erişimleri. Dosya izinlerini staging ortamında test etmek şart. Bilhassa de hostPath volume kullanan pod’larda dikkatli olun — mesela orada sürprizler çıkabiliyor.
Kaynaklar ve İleri Okuma
Kubernetes v1.36: User Namespaces GA Duyuru Yazısı
Kubernetes User Namespaces Resmî Dokümantasyonu
Linux User Namespaces Man Page (man7.org)
İçeriği paylaş:
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.







Yorum gönder