Namespaces & RBAC
IntermediateNamespaces provide logical isolation within a cluster. RBAC (Role-Based Access Control) controls who can do what to which resources — the foundation of multi-team Kubernetes security.
Overview
A single Kubernetes cluster can serve multiple teams and environments using Namespaces. Namespaces provide logical isolation: resource names are unique within a namespace but can repeat across namespaces. They enable per-namespace resource quotas, network policies, and RBAC rules. RBAC defines what actions (verbs: get, list, create, delete) users and service accounts can perform on which resources (pods, secrets, deployments) in which namespaces. Every pod also runs under a ServiceAccount that determines its API permissions.
Namespaces
Namespaces are virtual clusters within a physical cluster. Use them to separate environments (staging/production), teams (frontend/backend), or concerns (monitoring/application).
# Built-in namespaces:
# default → where resources go without explicit namespace
# kube-system → Kubernetes system components (CoreDNS, kube-proxy)
# kube-public → publicly readable cluster info
# kube-node-lease → node heartbeat leases
kubectl get namespaces
# Create namespace
kubectl create namespace production
kubectl create namespace staging
# Set default namespace for current context (avoid typing -n every time)
kubectl config set-context --current --namespace=production
# Namespace in resource manifests
metadata:
name: my-app
namespace: production
# Cross-namespace service DNS:
# Service in production: my-api.production.svc.cluster.local
# Service in staging: my-api.staging.svc.cluster.local
# Resource Quotas — limit resources per namespace
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
pods: "50"
services: "10"
secrets: "20"RBAC — Roles and RoleBindings
RBAC uses Roles (namespace-scoped) or ClusterRoles (cluster-wide) to define permissions, and RoleBindings to grant them to users or ServiceAccounts.
# Role — namespace-scoped permissions
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: production
rules:
- apiGroups: [""] # "" = core API group (pods, services, configmaps)
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
# RoleBinding — grant the Role to a user or ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: alice-pod-reader
namespace: production
subjects:
- kind: User
name: alice@company.com
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
---
# ClusterRole — cluster-wide permissions (for non-namespaced resources)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes", "persistentvolumes"]
verbs: ["get", "list", "watch"]
---
# ServiceAccount — identity for pods (not humans)
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-app-sa
namespace: production
# Bind ClusterRole to ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-app-binding
namespace: production
subjects:
- kind: ServiceAccount
name: my-app-sa
namespace: production
roleRef:
kind: ClusterRole
name: pod-readerServiceAccounts & Pod Identity
Every pod runs under a ServiceAccount. By default, it is the "default" ServiceAccount with minimal permissions. Use dedicated ServiceAccounts to grant only the AWS/GCP/K8s permissions each workload actually needs.
# Assign ServiceAccount to a Deployment
spec:
template:
spec:
serviceAccountName: my-app-sa # pod gets this SA's token
automountServiceAccountToken: false # disable if pod doesn't call K8s API
# The SA token is mounted at /var/run/secrets/kubernetes.io/serviceaccount/token
# App can call K8s API with this token (e.g., Vault, operators, controllers)
# IRSA — IAM Roles for Service Accounts (EKS)
# Link AWS IAM role to K8s ServiceAccount for AWS API access
eksctl create iamserviceaccount \
--name my-app-sa \
--namespace production \
--cluster my-cluster \
--attach-policy-arn arn:aws:iam::123456789:policy/my-app-policy \
--approve
# Pod then gets AWS credentials via token projection (no hardcoded keys!)
# Pod can call: aws s3 cp file s3://my-bucket/
# Check RBAC permissions
kubectl auth can-i list pods --namespace production
kubectl auth can-i list pods --as alice@company.com --namespace production
kubectl auth can-i create deployments --as system:serviceaccount:production:my-app-saKey Points to Remember
- 1Namespaces provide logical isolation, per-namespace quotas, and scoped RBAC.
- 2Cross-namespace service access uses full DNS: service.namespace.svc.cluster.local.
- 3Role is namespace-scoped; ClusterRole applies cluster-wide (useful for non-namespaced resources).
- 4RoleBinding grants a Role to a user or ServiceAccount within a namespace.
- 5Every pod runs under a ServiceAccount — use dedicated SAs with minimal permissions, not the default SA.
- 6kubectl auth can-i is the fastest way to check if a user or SA has a specific permission.
Interview Questions
Sign in to ask AriaWhat is the difference between a Role and a ClusterRole?
Why should pods use dedicated ServiceAccounts instead of the default one?
Ask Aria about Namespaces & RBAC
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.