Day 10: Production Readiness and Best Practices
What You'll Learn Today
- Resource isolation with Namespaces
- Access control with RBAC
- ResourceQuota and LimitRange
- Monitoring and logging
- Production best practices
Namespace Resource Isolation
In Day 2, you learned Namespace basics. In production, Namespaces separate resources by environment or team.
flowchart TB
subgraph Cluster["Kubernetes Cluster"]
subgraph Dev["dev namespace"]
D1["App Pod"]
D2["DB Pod"]
end
subgraph Staging["staging namespace"]
S1["App Pod"]
S2["DB Pod"]
end
subgraph Prod["production namespace"]
P1["App Pod x3"]
P2["DB Pod"]
end
end
style Dev fill:#22c55e,color:#fff
style Staging fill:#f59e0b,color:#fff
style Prod fill:#3b82f6,color:#fff
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
environment: production
# Create namespaces
kubectl create namespace production
kubectl create namespace staging
# Deploy to a namespace
kubectl apply -f deployment.yaml -n production
# Set default namespace
kubectl config set-context --current --namespace=production
RBAC (Role-Based Access Control)
RBAC controls who can do what in the cluster.
flowchart LR
USER["User / ServiceAccount"] --> RB["RoleBinding"]
RB --> ROLE["Role"]
ROLE --> RES["Resources\n(Pods, Services...)"]
style ROLE fill:#3b82f6,color:#fff
style RB fill:#8b5cf6,color:#fff
Role and ClusterRole
| Resource | Scope | Purpose |
|---|---|---|
| Role | Within a Namespace | Access to resources in a specific Namespace |
| ClusterRole | Cluster-wide | Access across all Namespaces or cluster resources |
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
namespace: production
rules:
- apiGroups: [""]
resources: ["pods", "services", "configmaps"]
verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: production
subjects:
- kind: User
name: alice
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
ServiceAccount
Authentication identity for Pods accessing the Kubernetes API.
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-service-account
namespace: production
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
template:
spec:
serviceAccountName: app-service-account
containers:
- name: web
image: nginx:1.27
ResourceQuota and LimitRange
ResourceQuota
Sets resource usage limits 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: "20"
persistentvolumeclaims: "10"
LimitRange
Sets defaults and limits for individual Pods/containers.
apiVersion: v1
kind: LimitRange
metadata:
name: production-limits
namespace: production
spec:
limits:
- type: Container
default:
cpu: "250m"
memory: "256Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
max:
cpu: "2"
memory: "4Gi"
min:
cpu: "50m"
memory: "64Mi"
NetworkPolicy
Controls network traffic between Pods β an evolution of Docker network isolation.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-network-policy
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- protocol: TCP
port: 5432
flowchart LR
FE["frontend"] -->|"allow: 8080"| API["api"]
API -->|"allow: 5432"| DB["postgres"]
OTHER["other pods"] -->|"denied"| API
style API fill:#3b82f6,color:#fff
style OTHER fill:#ef4444,color:#fff
Monitoring and Logging
Metrics Server
# Node resource usage
kubectl top nodes
# Pod resource usage
kubectl top pods -n production
kubectl top pods --sort-by=cpu
kubectl top pods --sort-by=memory
Log Management
# Pod logs
kubectl logs deployment/web-app -n production
kubectl logs deployment/web-app -n production -f --tail=100
# All containers
kubectl logs deployment/web-app -n production --all-containers
# By label selector
kubectl logs -l app=web -n production
Prometheus + Grafana (Overview)
flowchart LR
PODS["Pods\n(/metrics)"] --> PROM["Prometheus\n(metrics collection)"]
PROM --> GRAF["Grafana\n(visualization)"]
PROM --> ALERT["AlertManager\n(alerts)"]
style PROM fill:#ef4444,color:#fff
style GRAF fill:#f59e0b,color:#fff
style ALERT fill:#8b5cf6,color:#fff
# Install with Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack -n monitoring --create-namespace
Production Checklist
Security
| Item | Description |
|---|---|
| RBAC | Principle of least privilege |
| NetworkPolicy | Restrict unnecessary Pod communication |
| Pod Security | Run containers as non-root |
| Secret management | Use external secret management tools |
| Image scanning | Scan for vulnerabilities |
Pod Security Configuration
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Reliability
| Item | Setting |
|---|---|
| Replicas | Minimum 2 |
| PodDisruptionBudget | Guarantee minimum running Pods |
| Probes | Configure liveness, readiness, startup |
| Resources | Always set requests/limits |
| Anti-Affinity | Spread Pods across nodes |
PodDisruptionBudget
Maintains minimum Pod count during maintenance.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web
Pod Anti-Affinity
Spreads Pods across different nodes.
spec:
template:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
Complete Production Configuration
apiVersion: v1
kind: Namespace
metadata:
name: production
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
pods: "50"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web
spec:
serviceAccountName: web-sa
securityContext:
runAsNonRoot: true
runAsUser: 1000
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: web
topologyKey: kubernetes.io/hostname
containers:
- name: web
image: myapp:1.0
ports:
- containerPort: 3000
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secret
---
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: production
spec:
selector:
app: web
ports:
- port: 80
targetPort: 3000
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
namespace: production
spec:
minAvailable: 2
selector:
matchLabels:
app: web
kubectl Command Reference
| Category | Command | Description |
|---|---|---|
| Info | kubectl get <resource> |
List resources |
kubectl describe <resource> <name> |
Resource details | |
kubectl logs <pod> |
View logs | |
kubectl top <nodes/pods> |
Resource usage | |
| Create/Update | kubectl apply -f <file> |
Declarative create/update |
kubectl create <resource> |
Create resource | |
kubectl scale deployment <name> --replicas=N |
Scale | |
kubectl set image deployment/<name> |
Update image | |
| Delete | kubectl delete -f <file> |
Delete from file |
kubectl delete <resource> <name> |
Delete specific resource | |
| Debug | kubectl exec -it <pod> -- /bin/sh |
Execute command in container |
kubectl port-forward <pod> <local>:<remote> |
Port forward | |
kubectl cp <pod>:<path> <local-path> |
Copy files | |
| Rollout | kubectl rollout status deployment/<name> |
Update status |
kubectl rollout undo deployment/<name> |
Rollback | |
kubectl rollout history deployment/<name> |
History |
Docker to Kubernetes Command Mapping
| Docker Command | Kubernetes Command |
|---|---|
docker run |
kubectl run / kubectl apply |
docker ps |
kubectl get pods |
docker logs |
kubectl logs |
docker exec |
kubectl exec |
docker stop |
kubectl delete pod |
docker-compose up |
kubectl apply -f |
docker-compose down |
kubectl delete -f |
docker volume |
kubectl get pv/pvc |
docker network |
kubectl get svc/ingress |
Summary
| Concept | Description |
|---|---|
| Namespace | Logical resource isolation |
| RBAC | Role-based access control |
| ResourceQuota | Per-Namespace resource limits |
| NetworkPolicy | Pod-to-Pod network access control |
| PodDisruptionBudget | Minimum Pod guarantee during maintenance |
| Pod Security | Non-root users, read-only filesystem, etc. |
Key Takeaways
- In production, use Namespaces, RBAC, and ResourceQuota for proper resource management and isolation
- Security is defense in depth β combine Pod Security, NetworkPolicy, and RBAC
- For reliability, configure Probes, PDB, Anti-Affinity, and HPA
Practice Exercises
Exercise 1: Namespace Design
Create three Namespaces (dev, staging, production) and set ResourceQuota for each.
Exercise 2: RBAC
Create RBAC settings allowing a development team full access to the dev Namespace but read-only Pod access in production.
Challenge
Build a 3-tier architecture (Web + API + Database) with Namespaces, RBAC, NetworkPolicy, HPA, and PDB all configured.
References
Conclusion
Over 10 days, you've built on the container skills from the Docker book to master Kubernetes for production operations.
| Day | Topic |
|---|---|
| 1 | Kubernetes overview and architecture |
| 2 | Cluster setup and kubectl |
| 3 | Pod details and health checks |
| 4 | ReplicaSets and Deployments |
| 5 | Networking with Services |
| 6 | Storage and data persistence |
| 7 | ConfigMaps and Secrets |
| 8 | Ingress and external access |
| 9 | Scaling and update strategies |
| 10 | Production readiness |
With Docker providing your container foundation and Kubernetes providing orchestration, you now have the skills to build and operate modern cloud-native applications. For next steps, explore Helm, GitOps (ArgoCD), and service meshes (Istio).