Kubernetes v1.36 User Namespaces GA: Root Artık Gerçek Root Değil
Açık konuşayım, yıllardır beklenen şey sonunda geldi. Kubernetes v1.36 ile User Namespaces desteği GA seviyesine çıktı. Bunu duyunca ilk tepkim, hiç süslemeden söyleyeyim, “nihayet be!” oldu; çünkü bu özelliği alpha günlerinden beri uzaktan izliyordum (buna dikkat edin). Tahmin eder misiniz? 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.
İtiraf edeyim, Ş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. Yani 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 duruyor. 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) (ki bu çoğu kişinin gözünden kaçıyor). 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 (yani kabaca sıradan kullanıcı seviyesine indiriliyor). Saldırgan container’dan kaçsa bile host’ta eli kolu bağlı kalıyor.
Açıkçası, 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 yani; 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.
Size bir şey söyleyeyim, Aslında şöyle düşünün: container içindeki kullanıcıyı yüksek bir UID aralığına map ettiniz (ki bu çoğu kişinin gözünden kaçıyor). Güzel. Ama volume üzerindeki dosyalar hâlâ UID 0’a ait duruyor. 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; yani 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?
Şöyle ki, Asıl soru şu geliyor tabi: “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 oldu diye her runtime aynı tadı vermiyor olabilir; hatta bazen hiç vermiyor bile diyebilirim. CRI-O ile denediğim senaryolar — kendi adıma konuşayım — gayet düzgündü (şaşırtıcı ama gerçek) (bu konuda ikircikliyim). 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 16 ile test yaptık. Düzgün sonuç alamadık; yükseltme sonrası toparladı ama yine de gözden kaçmaması gereken bir nokta olarak kenarda duruyor.
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 — dürüst olayım, biraz hayal kırıklığı —. Biraz nazlılar diyelim. Bu konuyla ilgili Gemini ile Hayatını Düzenle: 8 Yapay Zekâ Destekli İpucu yazımıza da göz atmanızı tavsiye ederim (inanın bana)
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.
Kısa bir not düşeyim buraya.
İlginç olan şu ki, Logosoft’ta danışmanlık verdiğim kurumsal müşterilerin çoğunda pod security standartlarına bakıyorum (en azından benim deneyimim böyle). Gördüğüm tablo pek değişmiyor:container’ların büyük kısmı hâlâ root olarak koşuyor (şaşırtıcı ama gerçek). 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. Host tarafında artık root olmuyor.
Durun,bir saniye.Daha fazla bilgi için Kubelet API Yetkilendirmesi GA Öldü: 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. 5-10 pod çalıştırıyorsanız bence (söylemesi ayıp) ç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ı?
| Kriter | Startup / Küçük Ekip | Enterprise / Büyük Kurum | ||||||
|---|---|---|---|---|---|---|---|---|
| Önce kritik workload’lardan başla, aşamalı geçiş yapTest süresi1-2 gün yeterli olurEn az 2 hafta staging ortamında test etMaliyet etkisiNeredeyse yokEğer eski kernel kullanıyorsan node yükseltmesi gerekebilirSorun izlemeAUDIT loglarında UID mapping’i kontrol et | Test süresi1-2 gün yeterli olurEn az 2 hafta staging ortamında test etMaliyet etkisiNeredeyse yokEğer eski kernel kullanıyorsan node yükseltmesi gerekebilirSorun izlemeAUDIT loglarında UID mapping’i kontrol et | 1-2 gün yeterli olurEn az 2 hafta staging ortamında test etMaliyet etkisiNeredeyse yokEğer eski kernel kullanıyorsan node yükseltmesi gerekebilirSorun izlemeAUDIT loglarında UID mapping’i kontrol et | En az 2 hafta staging ortamında test etMaliyet etkisiNeredeyse yokEğer eski kernel kullanıyorsan node yükseltmesi gerekebilirSorun izlemeAUDIT loglarında UID mapping’i kontrol et | Maliyet etkisi | Neredeyse yok | Eğer eski kernel kullanıyorsan node yükseltmesi gerekebilir | Sorun izleme | AUDIT loglarında UID mapping’i kontrol et |
| Test süresi1-2 gün yeterli olurEn az 2 hafta staging ortamında test etMaliyet etkisiNeredeyse yokEğer eski kernel kullanıyorsan node yükseltmesi gerekebilirSorun izlemeAUDIT loglarında UID mapping’i kontrol et | 1-2 gün yeterli olurEn az 2 hafta staging ortamında test etMaliyet etkisiNeredeyse yokEğer eski kernel kullanıyorsan node yükseltmesi gerekebilirSorun izlemeAUDIT loglarında UID mapping’i kontrol et | En az 2 hafta staging ortamında test etMaliyet etkisiNeredeyse yokEğer eski kernel kullanıyorsan node yükseltmesi gerekebilirSorun izlemeAUDIT loglarında UID mapping’i kontrol et | Maliyet etkisi | Neredeyse yok | Eğer eski kernel kullanıyorsan node yükseltmesi gerekebilir | Sorun izleme | AUDIT loglarında UID mapping’i kontrol et | |
| Maliyet etkisi | Neredeyse yok | Eğer eski kernel kullanıyorsan node yükseltmesi gerekebilir | Sorun izleme | AUDIT loglarında UID mapping’i kontrol et | ||||
| 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>
Çok konuştum, örnekle göstereyim.
`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 (ciddiyim). Pod spec’ine hostUsers: false eklesen yeterli. Uygulama container içinde yine root olarak çalışıyor, yani 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?
Hayır, çalışmıyor. Bu büyük ölçüde Linux’a özgü bir şey — yani 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ı?
Bak şimdi, 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 (inanın bana)
User Namespaces açınca performans düşer mi?
Hayır, düşmüyor. ID-mapped mounts sayesinde volume erişiminde herhangi bir kayıp yaşanmıyor — yani O(1) operasyon. Genel çalışma zamanında da bence ölçülebilir bir fark göremiyorsunuz. Hatta eski yöntemdeki recursive chown’la kıyaslandığında mesela 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, yani büyük bir sorun beklemiyorum — ama yine de volume erişimlerini ve dosya izinlerini staging ortamında test etmek şart. En çok da hostPath volume kullanan pod’larda dikkatli olun, aslında 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)
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.








2 comments