Kubernetes cluster’ınızı kurdunuz, uygulamalarınız çalışıyor, her şey harika görünüyor. Peki kim neye erişebiliyor? Geliştirici takımınızdaki bir junior developer production namespace’ine pod silebiliyor mu? DevOps mühendisleriniz tüm cluster’a tam yetkiyle erişiyor mu? Eğer bu sorulara net cevap veremiyorsanız, RBAC konusunu ciddiye almanın tam zamanı.
Kubernetes’te Role-Based Access Control (RBAC), kullanıcıların ve servislerin cluster kaynakları üzerinde ne yapabileceğini tanımlayan yetki yönetim sistemidir. Doğru yapılandırılmış bir RBAC mimarisi, hem güvenlik açıklarını kapatır hem de ekiplerin kendi sorumluluk alanlarında rahatça çalışmasını sağlar. Bu yazıda gerçek dünya senaryolarıyla RBAC’ı A’dan Z’ye ele alacağız.
RBAC Nedir ve Neden Önemlidir?
Kubernetes 1.8 sürümünden itibaren varsayılan olarak aktif olan RBAC, “kim, neyi, nerede yapabilir?” sorusunu yanıtlar. Üç temel bileşenden oluşur:
- Subject (Özne): Kim? Kullanıcılar, gruplar veya servis hesapları
- Resource (Kaynak): Ne? Pod’lar, deployment’lar, secret’lar, node’lar
- Verb (Eylem): Ne yapabilir? get, list, create, delete, update, patch, watch
RBAC olmadan veya kötü yapılandırılmış bir RBAC ile karşılaşabileceğiniz senaryolar şunlardır:
- Bir geliştirici yanlışlıkla production secret’larını görüntüler
- CI/CD pipeline’ı gereksiz yere cluster-admin yetkisiyle çalışır
- Bir namespace’teki servis hesabı başka namespace’lerin kaynaklarına erişir
- Stajyer hesabından kritik deployment silinir
Bu senaryoların her biri gerçek olaylardan ilham almıştır. RBAC bu riskleri minimize etmenin en etkili yoludur.
Temel Kavramlar: Role, ClusterRole, RoleBinding, ClusterRoleBinding
Role ve ClusterRole
Role, belirli bir namespace içinde geçerlidir. ClusterRole ise tüm cluster genelinde veya namespace bazlı kullanılabilir. Farkı şöyle düşünebilirsiniz: Role bir binadaki belirli bir odanın anahtarı, ClusterRole ise tüm binanın ana anahtarıdır.
# Mevcut role'leri listele
kubectl get roles -n development
# Mevcut clusterrole'leri listele
kubectl get clusterroles
# Bir role'ün detaylarını gör
kubectl describe role pod-reader -n development
RoleBinding ve ClusterRoleBinding
Role tanımlamak yetmez, bu rolleri öznelere bağlamanız gerekir. RoleBinding bir Role veya ClusterRole’ü belirli bir namespace içinde bir özneye bağlar. ClusterRoleBinding ise cluster genelinde bağlama yapar.
# Mevcut rolebinding'leri listele
kubectl get rolebindings -n development
# ClusterRoleBinding'leri listele
kubectl get clusterrolebindings
# Detaylı inceleme
kubectl describe rolebinding dev-pod-reader -n development
İlk RBAC Yapılandırması: Geliştirici Rolü Oluşturma
Gelin pratik bir senaryo üzerinden gidelim. Bir e-ticaret platformu yönetiyorsunuz ve şu namespace yapınız var: development, staging, production. Geliştirici ekibinizin development namespace’inde tam yetkiye, staging’de sadece okuma yetkisine, production’da ise hiçbir erişimi olmamasını istiyorsunuz.
Development Namespace için Role
# dev-full-access-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: development
name: developer-full-access
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "pods/exec", "services", "configmaps"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
kubectl apply -f dev-full-access-role.yaml
Dikkat edin: Secret’lar için sadece get ve list verdik, create veya delete vermedik. Geliştirici secret içeriğini görebilir ama yeni secret oluşturamaz veya mevcut olanı silemez. Bu pratikte çok işe yarayan bir ayrıntıdır.
Staging Namespace için ReadOnly Role
# staging-readonly-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: staging
name: developer-readonly
rules:
- apiGroups: [""]
resources: ["pods", "pods/log", "services", "configmaps", "endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "replicasets", "statefulsets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list", "watch"]
kubectl apply -f staging-readonly-role.yaml
RoleBinding ile Kullanıcıya Atama
# dev-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ahmet-dev-access
namespace: development
subjects:
- kind: User
name: [email protected]
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer-full-access
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ahmet-staging-access
namespace: staging
subjects:
- kind: User
name: [email protected]
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer-readonly
apiGroup: rbac.authorization.k8s.io
kubectl apply -f dev-rolebinding.yaml
# Ahmet'in yetkilerini doğrula
kubectl auth can-i create pods --namespace=development [email protected]
kubectl auth can-i delete secrets --namespace=development [email protected]
kubectl auth can-i create deployments --namespace=staging [email protected]
kubectl auth can-i get pods --namespace=production [email protected]
kubectl auth can-i komutu RBAC yapılandırmanızı test etmenin en hızlı yoludur. Bu komutu sık kullanın.
Servis Hesapları ve RBAC
Gerçek dünyada RBAC sadece insan kullanıcılar için değil, aynı zamanda pod’ların kullandığı servis hesapları için de kritiktir. Özellikle CI/CD araçları, monitoring sistemleri ve operatörler bu hesapları kullanır.
CI/CD Pipeline için Servis Hesabı
Bir Jenkins veya GitLab CI pipeline’ının deployment yapabilmesi için gereken minimum yetkiyi tanımlayalım:
# cicd-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: cicd-deployer
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: deployer-role
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "update", "patch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["replicasets"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cicd-deployer-binding
namespace: production
subjects:
- kind: ServiceAccount
name: cicd-deployer
namespace: production
roleRef:
kind: Role
name: deployer-role
apiGroup: rbac.authorization.k8s.io
kubectl apply -f cicd-serviceaccount.yaml
# Servis hesabının tokenını al (Kubernetes 1.24 ve sonrası için)
kubectl create token cicd-deployer -n production --duration=8h
Bu yapılandırmayla CI/CD pipeline’ınız sadece deployment’ları güncelleyebilir, başka hiçbir şeye dokunamaz. “En az yetki prensibi” (principle of least privilege) budur.
ClusterRole ile Cluster Geneli Yetki Yönetimi
Monitoring ve logging sistemleri genellikle tüm namespace’lerdeki kaynaklara okuma yetkisi ister. Prometheus, Grafana Agent, Datadog gibi araçlar için ClusterRole kullanmak kaçınılmazdır.
# monitoring-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-reader
rules:
- apiGroups: [""]
resources: ["nodes", "nodes/metrics", "pods", "services", "endpoints", "namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics", "/healthz", "/readyz"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-monitoring
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
roleRef:
kind: ClusterRole
name: monitoring-reader
apiGroup: rbac.authorization.k8s.io
kubectl apply -f monitoring-clusterrole.yaml
# Tüm cluster'da yetkileri doğrula
kubectl auth can-i list pods --all-namespaces --as=system:serviceaccount:monitoring:prometheus
Grup Bazlı Yetki Yönetimi
Büyük ekiplerde her kullanıcı için ayrı RoleBinding oluşturmak sürdürülemez hale gelir. OIDC veya LDAP entegrasyonuyla grup bazlı yetki yönetimi hayatı kolaylaştırır.
# group-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: backend-team-dev
namespace: development
subjects:
- kind: Group
name: backend-developers
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: senior-developers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer-full-access
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: devops-team-admin
subjects:
- kind: Group
name: devops-engineers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
Grup bazlı yönetimde dikkat edilmesi gereken nokta: cluster-admin rolünü gruba vermeden önce iki kez düşünün. Gerçekten tüm DevOps mühendislerinin cluster-admin olması gerekiyor mu? Çoğu durumda cevap hayırdır.
RBAC Audit ve Sorun Giderme
Mevcut Yetkileri Keşfetme
# Bir kullanıcının tüm yetkilerini listele
kubectl auth can-i --list [email protected] -n development
# Belirli bir servis hesabının yetkilerini kontrol et
kubectl auth can-i --list --as=system:serviceaccount:production:cicd-deployer -n production
# Tüm rolebinding'leri belirli bir kullanıcı için bul
kubectl get rolebindings,clusterrolebindings -A -o json |
jq '.items[] | select(.subjects[]?.name=="[email protected]") | .metadata.name'
API Server Audit Log ile RBAC İzleme
Production ortamında audit log etkinleştirmek RBAC sorunlarını tespit etmek için şarttır. API server’a şu parametreleri ekleyin:
# /etc/kubernetes/manifests/kube-apiserver.yaml içine eklenecek argümanlar
--audit-log-path=/var/log/kubernetes/audit/audit.log
--audit-log-maxage=30
--audit-log-maxbackup=10
--audit-log-maxsize=100
--audit-policy-file=/etc/kubernetes/audit-policy.yaml
Audit policy dosyası:
# audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: RequestResponse
users: ["system:anonymous"]
verbs: ["create", "update", "patch", "delete"]
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "apps"
resources: ["deployments"]
- level: None
verbs: ["get", "list", "watch"]
resources:
- group: ""
resources: ["pods"]
Yaygın Hatalar ve Bunlardan Kaçınma Yolları
Üretim ortamlarında defalarca karşılaştığım hataları paylaşayım:
Wildcards Kullanımı
# YANLIS - Bunu yapmayın
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
# DOGRU - Açıkça tanımlayın
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "update", "patch"]
Wildcard kullanımı güvenlik açığı kapısı açar. “Şimdilik çalışıyor” dediğiniz şey ileride büyük sorun haline gelir.
Default Servis Hesabı Sorunları
Her namespace’te otomatik oluşan default servis hesabına herhangi bir yetki vermeyin. Pod’larınız için özel servis hesapları oluşturun:
# Her namespace'te automounting'i devre dışı bırak
kubectl patch serviceaccount default -n production -p '{"automountServiceAccountToken": false}'
# Yeni pod'lar için aynı ayarı varsayılan yap
# deployment yaml'ında:
# spec.template.spec.automountServiceAccountToken: false
ClusterRole ile Namespace Karışıklığı
# Bir ClusterRole, RoleBinding ile namespace'e özgü hale getirilebilir
# Bu yaygın ama gözden kaçan bir detay
# cluster-admin ClusterRole'ünü sadece development namespace'ine bağla
kubectl create rolebinding temp-admin
--clusterrole=cluster-admin
[email protected]
--namespace=development
Bu yaklaşım hem esneklik sağlar hem de ClusterRoleBinding’in tam cluster erişiminden kaçınmanıza yardımcı olur.
Gerçek Dünya Senaryo: Çok Ekipli Platform Yönetimi
Bir fintech şirketinde çalıştığınızı düşünün. Backend, Frontend, Data, SRE olmak üzere dört ekibiniz var. Her ekibin kendi namespace’i mevcut ve şu ihtiyaçları var:
- Backend ekibi: Kendi namespace’inde tam yetki
- Frontend ekibi: Kendi namespace’inde tam yetki, ama backend namespace’ini göremez
- Data ekibi: Tüm namespace’lerde pod log’larını okuyabilir
- SRE ekibi: Tüm cluster yönetimi yetkisi, ama node silme yetkisi yok
# sre-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: sre-engineer
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["namespaces", "pods", "services", "configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets", "replicasets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses", "networkpolicies"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Node silme yetkisi kasıtlı olarak dışarıda bırakıldı
kubectl apply -f sre-clusterrole.yaml
# SRE grubuna bağla
kubectl create clusterrolebinding sre-team-binding
--clusterrole=sre-engineer
--group=sre-engineers
# Test et - node silme olmamalı
kubectl auth can-i delete nodes --as-group=sre-engineers --as=test-user
Data ekibi için cross-namespace log okuma:
# Data ekibi için ClusterRole oluştur
kubectl create clusterrole data-log-reader
--verb=get,list,watch
--resource=pods,pods/log
# Data grubuna bağla
kubectl create clusterrolebinding data-team-logs
--clusterrole=data-log-reader
--group=data-engineers
RBAC Güvenlik Kontrolleri için Araçlar
Manuel kontroller yetersiz kalır. Birkaç araç sürecinizi otomatize etmenize yardımcı olur:
- kubectl-who-can: Belirli bir kaynak üzerinde kim ne yapabilir sorusunu yanıtlar
- rbac-lookup: Kullanıcı veya servis hesabı bazında yetki özeti çıkarır
- kube-bench: CIS Kubernetes benchmark kontrolü yapar, RBAC ayarlarını da denetler
- Polaris: Deployment konfigürasyonlarını tarar, RBAC best practice ihlallerini işaretler
# kubectl-who-can kurulumu ve kullanımı
kubectl krew install who-can
kubectl who-can delete pods -n production
kubectl who-can create secrets -n production
# Tüm cluster'da secret oluşturabilecekleri bul
kubectl who-can create secrets --all-namespaces
Bu komutun çıktısı genellikle şok edicidir. Production’da ilk çalıştırdığınızda beklenmedik kullanıcı ve servis hesaplarının hassas kaynaklara erişebildiğini görebilirsiniz.
RBAC Politika Belgeleme ve Sürdürülebilirlik
RBAC yapılandırmalarını Git’te tutmak ve her değişikliği pull request sürecinden geçirmek altın standarttır. Önerilen repo yapısı:
rbac/roles/klasörü altında namespace bazlı Role dosyalarırbac/clusterroles/altında ClusterRole tanımlamalarırbac/bindings/altında tüm binding dosyaları- Her dosyada
# Son güncelleme,# Güncellemeyi yapan,# Nedenyorumları
Ayrıca RBAC değişikliklerini otomatik denetlemek için CI pipeline’ınıza şunu ekleyin:
# RBAC diff kontrolü - PR öncesi çalıştır
kubectl diff -f rbac/ -R
# Dry-run ile güvenli uygulama
kubectl apply -f rbac/ -R --dry-run=server
Sonuç
RBAC, Kubernetes güvenliğinin temel taşıdır ve doğru yapılandırılmadığında cluster’ınız ciddi risk altında demektir. Bu yazıda ele aldığımız konuları özetlersek:
- Role ve ClusterRole arasındaki farkı ve ne zaman hangisini kullanacağınızı artık biliyorsunuz
- En az yetki prensibi her yapılandırmada rehberiniz olmalı
- Servis hesapları insan kullanıcılar kadar önemli, onları da RBAC kapsamına alın
kubectl auth can-ikomutu en iyi arkadaşınız, sık kullanın- Wildcard yetki tanımlarından kesinlikle kaçının
- Değişiklikleri Git’te takip edin, review sürecinden geçirin
kubectl-who-cangibi araçlarla periyodik denetim yapın
RBAC bir kez kurulup unutulan bir şey değildir. Ekip büyüdükçe, yeni servisler eklendikçe ve organizasyon yapısı değiştikçe RBAC yapılandırmanızı gözden geçirmeniz gerekir. Altı ayda bir kapsamlı bir RBAC audit yapma alışkanlığı edinin. Prodüksiyon’da “kim neye erişebilir?” sorusunu her zaman yanıtlayabilmek, hem güvenlik hem de compliance açısından hayat kurtarır.