RBAC + ServiceAccounts + NetworkPolicy (End-to-End)
π― Goal
Understand who can do what and who can talk to whom inside Kubernetes.
You will:
- Lock down API access using RBAC
- Restrict pod-to-pod traffic using NetworkPolicy
- See real failures (403, connection refused)
- Learn how security incidents are prevented
Architecture
User
ββ kubectl (admin)
β
ββ Pod A (frontend)
β β allowed
ββ Pod B (backend)
β β blocked
ββ Pod C (db)
1οΈβ£ Create Namespace
kubectl create namespace secure-lab
2οΈβ£ Create ServiceAccount (Non-Admin)
# sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: secure-lab
kubectl apply -f sa.yaml
3οΈβ£ Create Restricted Role (RBAC)
β No delete
β No secrets
β
Only read pods & services
# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: secure-lab
name: read-only-role
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]
4οΈβ£ Bind Role to ServiceAccount
# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-only-binding
namespace: secure-lab
subjects:
- kind: ServiceAccount
name: app-sa
namespace: secure-lab
roleRef:
kind: Role
name: read-only-role
apiGroup: rbac.authorization.k8s.io
kubectl apply -f rolebinding.yaml
5οΈβ£ Test RBAC FROM INSIDE A POD
kubectl run test-pod \
-n secure-lab \
--image=bitnami/kubectl \
--serviceaccount=app-sa \
--restart=Never \
--rm -it -- sh
Inside pod:
kubectl get pods # β
allowed
kubectl delete pod x # β forbidden
kubectl get secrets # β forbidden
Expected error
Error from server (Forbidden)
6οΈβ£ Deploy 3-Tier App
Frontend
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: secure-lab
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx
Backend
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: secure-lab
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: app
image: hashicorp/http-echo
args: ["-text=backend"]
Database
apiVersion: apps/v1
kind: Deployment
metadata:
name: db
namespace: secure-lab
spec:
replicas: 1
selector:
matchLabels:
app: db
template:
metadata:
labels:
app: db
spec:
containers:
- name: app
image: hashicorp/http-echo
args: ["-text=db"]
7οΈβ£ Test Networking (NO NetworkPolicy Yet)
kubectl run curl \
-n secure-lab \
--image=curlimages/curl \
--rm -it -- sh
curl backend
curl db
β Everything works (DEFAULT = allow all)
8οΈβ£ Apply NetworkPolicy (DENY ALL)
# deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: secure-lab
spec:
podSelector: {}
policyTypes:
- Ingress
kubectl apply -f deny-all.yaml
9οΈβ£ Allow ONLY frontend β backend
# allow-frontend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: secure-lab
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
π Test Again
curl backend # β
works
curl db # β blocked
1οΈβ£1οΈβ£ What You Just Learned (INTERVIEW GOLD)
RBAC
- Controls API access
- Based on ServiceAccount
- Prevents cluster takeover
NetworkPolicy
- Controls pod-to-pod traffic
- Default allow β must deny explicitly
- Requires CNI support
π¨ Real Production Incident You Now Understand
βA compromised pod could not access secrets or other services because RBAC and NetworkPolicy limited blast radius.β
FINAL INTERVIEW ANSWER (MEMORIZE)
βRBAC controls who can talk to the Kubernetes API.
NetworkPolicies control who can talk on the network.
Together they enforce least privilege and zero trust inside the cluster.β
Cleanup
kubectl delete namespace secure-lab
Top comments (0)