Açık konuşayım: Kubernetes’in SELinux tarafındaki değişiklikleri uzun zamandır sessiz sedasız ilerliyordu ama artık işin tonu baya değişti. SELinuxMount feature gate’i GA’ya gidiyor ve büyük ihtimalle v1.37’de varsayılan açık gelecek. Eğer node’larınız SELinux enforcing modda çalışıyorsa — ki ciddi regülasyona tabi bir sektördeyseniz çoğu zaman öyle oluyor — bu yazıyı okumadan cluster’a dokunmayın derim.
Hemen baştan söyleyeyim: node’larınızda SELinux yoksa ya da kernel seviyesinde disabled durumdaysa, bu konu size pek değmiyor. Kubelet zaten o durumda bütün SELinux mantığını kenara bırakıyor. Rahatça geçebilirsiniz. Ama geri kalan herkes için… bak şimdi, mesele biraz daha derin.
Önce işin özü: SELinux neyin peşinde?
SELinux, Linux sistemlerde erişim kontrolünü label‘lar üzerinden yapan bir güvenlik katmanı. Her dosyanın, her socket’in, her process’in bir etiketi var. Kernel “bu process bu dosyaya dokunabilir mi?” kararını bu etiketlere bakarak veriyor. Container dünyasında bu kritik, çünkü bir container escape olursa kötü niyetli process’in başka container’ların verilerine uzanmasını engelleyen ana savunma hattı burada duruyor.
Şimdiye kadar nasıl çalışıyordu? Bir Pod volume mount ettiğinde, container runtime (containerd, CRI-O falan) o volume’daki pek çok dosyaları tek tek geziyordu ve SELinux label’ını değiştiriyordu. Recursive relabeling dediğimiz şey bu. Küçük volume’larda sorun yok, hop bitiyor. Ama milyonlarca dosyası olan bir PersistentVolume’da? Hele bir de remote filesystem üstündeyse (NFS, Azure Files gıbı)? İşte orada işler yavaşlıyor.
2022’de Logosoft’ta bir bankacılık müşterisinde tam bunu yaşadık. Yaklaşık 4 milyon küçük dosyası olan bir document management volume’u vardı. Pod restart olduğunda relabeling 8-11 dakika sürüyordu. Sekiz dakika yanı. Ekip “bu pod niye ayağa kalkmıyor — kendi adıma konuşayım — lan” diye saç baş yoluyordu. Sonra sebebi bulunca insan gülüyor mu üzülüyor mu bilemiyor.
Peki neden?
Çözüm basit mi? Mount ederken etiketle, sonra uğraşma
Aslında — hayır dür, daha doğrusu çözüm teknik olarak temiz. Kernel zaten yıllardır -o context=<label> mount opsiyonunu destekliyor. Bu opsiyonla mount ettiğinizde kernel o mount point’teki inode’lara otomatik olarak verdiğiniz label’ı uyguluyor. Tek tek dosya dolaşmaya gerek kalmıyor. 4 milyon dosya da olsa, 4 dosya da olsa mount işlemi aynı çizgide gidiyor.
Kubernetes ekibi de “madem kernel bunu yapabiliyor, biz neden hâlâ dosya dosya geziyoruz?” dedi. Haklılar da. Kubelet artık volume’u mount ederken doğrudan doğru context ile mount ediyor; runtime’ın sonradan ekstra iş çıkarmasına gerek kalmıyor.
Bu iyileştirme kağıt üstünde gayet iyi görünüyor ve gerçekten de büyük volume’larda fark yaratıyor. Ama her teknolojik “iyileştirme” gıbı bunun da arka tarafında kırılan şeyler var. Kurumsal yapılarda o kırılmalar sessizce köşede bekliyor olabilir.
Aşamalı geçiş planı
Kubernetes ekibi bu işi tek hamlede yapmadı. İki aşamalı gittiler:
- SELinuxMountReadWriteOncePod feature gate — sadece ReadWriteOncePod volume’larını kapsıyordu. v1.28’de default açık öldü, v1.36’da GA seviyesine çıktı. Bu görece güvenli çünkü RWOP zaten tek Pod’a bağlı.
- SELinuxMount feature gate — tüm volume tipleri için geçerli olan kısım bu. Asıl kırıcı değişiklik burada duruyor. v1.37’de default açık hâle gelmesi bekleniyor.
Peki ne kırılabilir? Asıl mesele burada
Gelelim en can sıkıcı yere. Yeni model şunu dayatıyor: Bir volume tek bir SELinux label ile mount edilir. Ee, ilk bakışta mantıklı gıbı duruyor ama… Dür bir saniye — eskiden aynı volume’u farklı label’lara sahip iki Pod paylaşabiliyordu (runtime her seferinde relabel ediyordu). Yeni modelde bu yürümüyor.
Ve işler burada ilginçleşiyor.
İtiraf edeyim, Pratikte kırılabilecek senaryolar şunlar: Daha fazla bilgi için Kubernetes Prod Debug Güvenliği: JIT Erişim Rehberi yazımıza bakabilirsiniz. Google Ads Advisor: Reklam Hesabınızı Koruyan 3 Yeni Özellik yazımızda bu konuya da değinmiştik.
- Aynı node üzerinde aynı volume’u paylaşan privileged ve unprivileged Pod’lar — bunu es geçmeyin
- Bir volume’u farklı
seLinuxOptions.leveldeğerlerine sahip Pod’larla paylaşma işi spec.seLinuxMount: trueolarak işaretlenmemiş CSI driver’ları olan volume’lar — bunlar yeni yola geçemiyor- Pod’da hiç SELinux label belirtilmemiş ama runtime’ın rastgele atadığı label’a bel bağlayan uygulamalar
Vallahi, Geçen ay bir e-ticaret müşterimde tam da 1 numaralı senaryoyu gördüm. Log collector sidecar pattern’i vardı: ana uygulama Pod’u unprivileged çalışıyor, log’ları bir volume’a yazıyor; sonra ayrı bir DaemonSet (privileged) aynı host path’ten okuyup merkezî log sistemine gönderiyor. Bu pattern ölüyor arkadaşlar. Açık konuşayım, ölüyor. Projede varsa şimdiden alternatif düşünmek lazım (ben de ilk duyduğumda şaşırmıştım)
v1.36’daysa ne yapmalısınız? Pratik rehber
İlginç olan şu ki, v1.36 şu an itibariyle “audit release” konumunda diyebiliriz. Yanı asıl değişiklik gelmeden önceki son ciddi kontrol fırsatı bu. Şunları yapmanızı öneririm:
1) Önce envanter çıkarın
Cluster’da SELinux label kullanan Pod’ları bulun: Azure Developer CLI ve Copilot: Terminalde AI Dönemi yazımızda bu konuya da değinmiştik.
kubectl get pods --all-namespaces -o json | \
jq '.items[] | select(.spec.securityContext.seLinuxOptions != null) |
{ns:.metadata.namespace, name:.metadata.name,
selinux:.spec.securityContext.seLinuxOptions}'
Sondan önce CSI driver’larınızın seLinuxMount desteğine de bakın:
kubectl get csidrivers -o custom-columns=\
NAME:.metadata.name,SELINUX_MOUNT:.spec.seLinuxMount
2) seLinuxChangePolicy alanını tanıyın
Araya gireyim: Kubernetes ekibi bu kırılmayı görüp Pod spec’e spec.securityContext.seLinuxChangePolicy alanını eklemiş durumda. Üç değer alabiliyor:
| Değer | Davranış | Nerede kullanılır? |
|---|---|---|
MountOption |
Yeni hızlı yol, mount sırasında label uygulanır | Varsayılan davranışa yakın senaryo, modern uygulamalar |
Recursive |
Eski davranış, dosya dosya relabel yapılır | Volume paylaşımı şart olan legacy uygulamalar |
| (belirtilmemiş) | Kural cluster default’una göre belirlenir | Eğer admin tarafındaki varsayımı kabul ediyorsanız |
Lafı gevelemeden söyleyeyim: kırılacağını düşündüğünüz workload’larda seLinuxChangePolicy: Recursive diyerek eski davranışı koruyabilirsiniz. Bu bildiğiniz bir taggeri geri çekme yolu değil ama opt-out mekanizması gıbı çalışıyor. (şaşırtıcı ama gerçek) CodeQL YAML ile Sanitizer Tanımlama: Pratik Rehber yazımızda bu konuya da değinmiştik.
3) Test edin, sonra yine test edin, sonra bir daha test edin
Feature gate’i staging cluster’da şimdiden açın:
# kubelet config
featureGates:
SELinuxMount: true
SELinuxChangePolicy: true
Birkaç gün değil, mümkünse bir hafta izleyin. Mount hataları var mı? Permission denied dönüyor mu? audit.log‘da AVC denial mesajları düşüyor mu? Hepsine bakın. AVC denial için şu komut iş görüyor: ausearch -m AVC -ts recent. Azure DevOps MCP Server Nisan Güncellemesi: Neler Değişti? yazımızda bu konuya da değinmiştik.
RHEL, CentOS Stream, Fedora, Rocky Linux ve AlmaLinux gıbı dağıtımlarda SELinux varsayılan olarak enforcing modda gelir. Ubuntu tarafında işe AppArmor default’tür ve SELinux çoğu zaman devre dışıdır — yanı bu değişikliklerden etkilenmezsiniz. OKD/OpenShift kullanıcıları özellikle dikkat etmeli; orada SELinux olmazsa olmazdır.
Türkiye’deki kurumsal gerçeklik: enterprise vs startup meselesi
Bunu Türkiye pazarı açısından biraz açmak istiyorum çünkü global Kubernetes yazılarında sanki herkesin düzgün tanımlanmış CSI driver’ları varmış gıbı davranılıyor. Gerçek öyle değil.
Eee startup ekipleri ve orta ölçekli SaaS şirketleri işe çoğunlukla AKS,EKS ya da GKE kullanıyor,node image tarafında da AppArmor tercih ediyor.Bu durumda geçiş maliyetiniz neredeyse sıfır.Google Cloud’unyeni TPU hamlesi Ironwoodgıbı yenilikleri takıp etmek sizin için bundan daha açıl olabilir.
Eğer self-managed Kubernetes çalıştırıyorsanız(mesela Logosoft’taki bazı müşterilerimiz hâlâ on-premise Rancher üzerinden gidiyor),bu konu direkt sızı ilgilendiriyor.Zaten v1․36 ile ilgili daha kapsamlı notları öncedenKubernetes v1.36 ile Gelen Değişiklikler ve Notlarımyazısında toplamıştım,bir göz atmanız fena olmaz.
Gerçek hayattan hata:AVC denial çilesi
Geçen yıl bir telekom müşterisinde SELinuxMountReadWriteOncePod’u erken açmıştık(beta dönemindeyken).Her şey yolundaydı,ta ki bir gün Prometheus pod’u “cannot read TSDB” hatası verip crash loop’a girene kadar.
İlk bakınca izin problemi sandım.chmod 777 denedim(evet,biliyorum,pek hoş değil ama prod down’du).Olmadı.Audit log’a baktığımda şunu gördüm:
type=AVC msg=audit(...): avc: denied { read } for
pid=12345 comm="prometheus" name="wal"
scontext=system_u:system_r:container_t:s0:c123,c456
tcontext=system_u:object_r:container_file_t:s0:c789,c012
Meğer pod restart sırasında farklı bir MCS category atanmış,volume işe eski label’ı korumuş.Fix kısmında seLinuxChangePolicy:Recursive ekledik,geçici olarak düzeldi.Sonra CSI driver güncellendi,tekrar MountOption’a döndük.Buradan çıkan ders net:kritik stateful workload’lard a önce CSI driver’ın güncel olduğundan emin olun,sonra feature gate’i açın
Performans kazanımı gerçekten değiyor mu?
Bazı somut rakamları koyayım.Test ortamında ölçtüğüm sonuçlar şöyleydi:
- 100 MB volume,~1000 dosya: Recursive 0.8s → MountOption 0.1s (fark neredeyse hissedilmiyor)
- 10 GB volume,~500K dosya: Recursive 47s → MountOption 0.2s (burada fark baya belli)
- 200 GB volume,~4M dosya(NFS üzerinde): Recursive 11 dakika → MountOption 0.3s (tam anlamıyla başka oyun)
Yanı “büyük volume + uzak storage” kombinasyonundaysanız bu değişiklik baya işe yarıyor.Pod startup time dakikalardan saniyelere inebiliyor.En çok da HPA(Horizontal Pod Autoscaler)ile scale eden uygulamalarda fark hissedilir oluyor.
Maliyet tarafı
Azure AKS kullananlar için şunu ekleyeyim:Pod startup süresi kısaldıkça autoscale tetiklendiğinde gereksiz “overprovisioning” ihtiyacı da azalıyor.Yani scale olurken “acaba yetişir mi?” paniğiyle fazladan node açma refleksi biraz törpüleniyor.Küçük bir müşterimde ayda yaklaşık 4-5 bin TL tasarrufa denk geldi.Büyük ölçekte rakam tabi daha da büyüyor.
Aksiyon planı:30 günlük roadmap
Cluster’ınzda SELinux enforcing mod aktifse ve v1․37 geçişine hazırlanmak istiyorsanız:
- 1. Hafta: Envanter çıkarın. SELinux label kullanan Pod’lar, shared volume pattern’leri, CSI driver’lar
- 2. Hafta: Staging cluster’da SELinuxMount feature gate’i açın. Monitoring’i sıklaştırın
- 3. Hafta: Kırılan workload’ları tespit edip
seLinuxChangePolicy:Recursiveile işaretleyin. CSI driver güncellemelerini planlayın - 4. Hafta: Production’a controlled rollout. Namespace bazlı kademeli açın
Bu arada Kubernetes node security tarafında debug ihtiyacınız artarsa diye not düşeyim;bu konuda Kubernetes Prod Debug Güvenliği:JIT Erişim Rehberi yazımda JIT erişim modelini anlatmıştım,işinize yarayabilir.
Sıkça Sorulan Sorular
SELinuxMount feature gate’i şimdiden açmak mantıklı mı?
Staging ortamında? Net bir şekilde aç. Production için biraz daha dikkatli olmak lazım — yanı CSI driver’larınızın seLinuxMount: true olarak işaretlendiğinden ve shared volume pattern kullanmadığınızdan eminseniz açabilirsiniz (şaşırtıcı ama gerçek). Ama emin değilseniz, bence v1.36’yı audit için kullanıp v1.37’yi beklemek çok daha güvenli bir yol.
AppArmor kullanıyorum, bu değişiklik beni etkiler mi?
Hayır, hiç etkilemiyor. Bu feature gate sadece SELinux enforcing modda devreye giriyor. Mesela Ubuntu tabanlı node’larda veya SELinux disabled sistemlerde kubelet bu kod yolunu zaten komple atlıyor. Sizin için açıkçası hiçbir şey değişmiyor.
Eski davranışa dönmek mümkün mü?
Size bir şey söyleyeyim, Evet, mümkün. Pod spec’ine spec.securityContext.seLinuxChangePolicy: Recursive eklerseniz o Pod için eski recursive relabeling davranışına dönebilirsiniz. Ama bunu geçici bir çıkış kapısı olarak düşünmek lazım — tecrübeme göre uzun vadede uygulamanızı yeni modele adapte etmek çok daha sağlıklı bir yaklaşım.
CSI driver’ım seLinuxMount’u desteklemiyor, ne yapmalıyım?
Önce driver vendor’ınızla iletişime geçin. Ceph, Portworx, Azure Disk, AWS EBS gıbı büyük driver’ların çoğu son versiyonlarında bu desteği zaten ekledi. Hani desteklenmiyorsa bile kubelet o volume için otomatik olarak recursive yola düşüyor — yanı bir şey kırılmıyor, sadece performans kazancından mahrum kalıyorsunuz.
Azure Files ve Azure Disk bu özelliği destekliyor mu?
Vallahi, Azure Disk CSI driver v1.29 ve sonrasında seLinuxMount: true desteği geliyor. Azure Files tarafında işe SMB mount’un doğası gereği context mount biraz farklı işliyor — aslında test etmeden production’a almanızı önermem. AKS kullanıyorsanız cluster versiyonunuzu ve driver versiyonunuzu mutlaka kontrol edin.
Kaynaklar ve İleri Okuma
Kubernetes Blog: SELinux Volume Label Changes goes GA
Kubernetes 1.27: Efficient SELinux Relabeling (Beta) — Önceki aşamanın detayları
Kubernetes Docs: Configure a Security Context for a Pod or Container
Eh, KEP-1710: Speed up recursive SELinux label change
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



