Kubernetes kümelerinde en yaygın risklerden biri, gereğinden fazla yetkiyle çalışan pod'lardır. Privileged bir konteyner ana makinenin ağ alanına, dosya sistemine veya çekirdek yeteneklerine erişebilir. Bu rehberde yerleşik Pod Security Admission (PSA) denetleyicisini namespace etiketleriyle yönetmeyi, mevcut iş yüklerini bozmadan sıkılaştırmayı ve RBAC yetkilerini kubectl auth can-i ile denetlemeyi adım adım uygulayacaksınız. PSA, v1.23'te beta olarak varsayılan açıldı ve v1.25'ten beri kararlıdır; ek bileşen gerekmez. Bakımı süren sürümler 1.37, 1.36 ve 1.35'tir; örneklerde v1.37 kullanılmıştır.

Üç profil: Pod Security Standards

PSA, Pod Security Standards (PSS) adlı üç birikimli profili uygular:

ProfilAmaç
PrivilegedKısıtlama yok; güvenilir altyapı iş yükleri için
BaselineBilinen yetki yükseltmelerini engeller; çoğu uygulama için uygun
RestrictedSıkılaştırma en iyi uygulamalarını izler; en kısıtlayıcı profil


Baseline; privileged konteynerleri, host ağ/PID/IPC ad alanlarını, hostPath birimlerini ve Unconfined seccomp profilini yasaklar, capability'leri bir izin listesiyle sınırlar. Restricted, Baseline'ın tüm kurallarına ek olarak konteyner düzeyinde şunları ister:

CODE TERMINAL
securityContext:
  allowPrivilegeEscalation: false
  runAsNonRoot: true
  seccompProfile:
    type: RuntimeDefault
  capabilities:
    drop:
      - ALL


Restricted'da geri eklenebilecek tek capability NET_BIND_SERVICE'tir. İmajın da root olmayan bir kullanıcıyla çalışabilmesi gerekir.

Etiket sözdizimi ve üç mod

PSA, namespace üzerindeki şu etiketleri okur:

CODE TERMINAL
pod-security.kubernetes.io/: 
pod-security.kubernetes.io/-version:


Seviye privileged, baseline veya restricted; sürüm v1.37 gibi bir minor sürüm ya da latest olabilir.

ModDavranış
enforceİhlal eden pod reddedilir
auditİhlal denetim günlüğüne yazılır, pod kabul edilir
warnKullanıcıya uyarı gösterilir, pod kabul edilir


Önemli ayrıntı: audit ve warn, Deployment ve Job gibi iş yükü kaynaklarına da uygulanır; enforce ise yalnızca ortaya çıkan Pod nesnelerine uygulanır. Yani Deployment oluşur ama pod'ları reddedilirse sorunu ReplicaSet olaylarında görürsünüz. Bu yüzden warn ve audit'i enforce ile birlikte açmak iyi bir pratiktir.

Yeni namespace için etiketleme

Aşağıdaki örnek Baseline'ı zorlar, Restricted ihlallerini ise yalnızca uyarı ve denetim kaydı olarak raporlar:

CODE TERMINAL
apiVersion: v1
kind: Namespace
metadata:
  name: my-baseline-namespace
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/enforce-version: v1.37
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: v1.37
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: v1.37


Sürümü sabitlemek, küme yükseltildiğinde politika tanımının beklenmedik biçimde değişmesini önler.

Mevcut kümede dry-run ile güvenli geçiş

Çalışan bir kümede enforce etiketini doğrudan koymak iş yüklerini kırabilir. Önce sunucu tarafı dry-run ile etkiyi ölçün; bu komut hiçbir şeyi değiştirmez, ihlal eden pod'lar için uyarı üretir:

CODE TERMINAL
kubectl label --dry-run=server --overwrite ns --all \
    pod-security.kubernetes.io/enforce=baseline


Ardından tüm namespace'lerde yalnızca audit ve warn açarak gerçek trafiği gözlemleyin:

CODE TERMINAL
kubectl label --overwrite ns --all \
  pod-security.kubernetes.io/audit=baseline \
  pod-security.kubernetes.io/warn=baseline


Uyarılar temizlenince namespace bazında enforce uygulayın:

CODE TERMINAL
kubectl label --overwrite ns my-existing-namespace \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=v1.37


Henüz enforce seviyesi olmayan namespace'leri listelemek için:

CODE TERMINAL
kubectl get namespaces --selector='!pod-security.kubernetes.io/enforce'


kube-system gibi sistem bileşenlerinin bulunduğu namespace'leri körlemesine Restricted yapmayın; önce dry-run çıktısına bakın.

Küme geneli varsayılan: AdmissionConfiguration

Etiketsiz namespace'lerin varsayılanı, kube-apiserver'a --admission-control-config-file bayrağıyla verilen dosyada tanımlanır (yönetilen kümelerde bu ayar sağlayıcıya bağlıdır):

CODE TERMINAL
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
  configuration:
    apiVersion: pod-security.admission.config.k8s.io/v1
    kind: PodSecurityConfiguration
    defaults:
      enforce: "baseline"
      enforce-version: "latest"
      audit: "restricted"
      audit-version: "latest"
      warn: "restricted"
      warn-version: "latest"
    exemptions:
      usernames: []
      runtimeClasses: []
      namespaces: ["kube-system"]


Belgelerdeki varsayılan seviye privileged'dır; yukarıdaki baseline/restricted değerleri ve kube-system muafiyeti bu rehberin önerisidir. Muafiyetler kullanıcı adı, RuntimeClass ve namespace bazında verilir ve kısa tutulmalıdır. PSA'nın sunduğu pod_security_evaluations_total, pod_security_exemptions_total ve pod_security_errors_total metrikleri, değerlendirmeleri ve muafiyet kullanımını izlemenizi sağlar.

RBAC yetkilerini kubectl auth can-i ile denetleme

PSA pod'ların ne yapabileceğini sınırlar; kimin ne yapabileceğini ise RBAC belirler. RBAC izinleri yalnızca toplamsaldır, "deny" kuralı yoktur. Namespace kapsamlı Role ve RoleBinding örneği:

CODE TERMINAL
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io


Yetkileri kubectl auth can-i ile test edin:

CODE TERMINAL
# Herhangi bir namespace'te pod oluşturabilir miyim?
kubectl auth can-i create pods --all-namespaces

# dev'deki foo servis hesabı prod'da pod listeleyebilir mi?
kubectl auth can-i list pods --as=system:serviceaccount:dev:foo -n prod

# Pod günlüklerini okuyabilir miyim?
kubectl auth can-i get pods --subresource=log

# foo namespace'inde izin verilen tüm eylemler
kubectl auth can-i --list --namespace=foo



  • Servis hesaplarının secrets ve pods/exec yetkilerini --as ile tek tek sorgulayın.
  • Kaynak veya fiil olarak "*" kullanan kuralları gözden geçirin.
  • Mümkün olduğunca ClusterRoleBinding yerine namespace kapsamlı RoleBinding kullanın; gereksiz cluster-admin bağlarını kaldırın.
  • escalate, bind ve impersonate fiillerini yalnızca zorunlu kimliklere verin; bunlar RBAC'ın yerleşik yetki yükseltme korumalarını aşmaya izin verir.



Önerilen sıra


  1. Dry-run ile etkiyi ölçün.
  2. audit ve warn ile gerçek trafiği gözlemleyin.
  3. Namespace namespace enforce uygulayın.
  4. AdmissionConfiguration ile küme varsayılanını yükseltin.
  5. auth can-i ile RBAC'ı düzenli denetleyin.



Pod trafiğini kısıtlamak için TRSiber'deki NetworkPolicy ve Cilium rehberine, iş yükü kimliği için SPIFFE/SPIRE rehberine bakabilirsiniz.

Kaynaklar
TR Siber Ekibi Yazar · TRSiber
← Ana sayfaya dön