Skip to content

Kubernetes

This chapter covers Kubernetes container orchestration basics.


Kubernetes is the industry-standard for container orchestration - essential for managing containerized applications at scale. Understanding K8s is critical for cloud-native development and DevOps roles.

┌─────────────────────────────────────────────────────────────────────────────┐
│ KUBERNETES IN DEVOPS │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ WHY KUBERNETES │ │
│ │ │ │
│ │ • Container orchestration at scale │ │
│ │ • Self-healing and automated rollouts │ │
│ │ • Service discovery and load balancing │ │
│ │ • Declarative configuration (GitOps ready) │ │
│ │ • Runs on any infrastructure (cloud, on-prem, edge) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ KEY CONCEPTS │ │
│ │ │ │
│ │ • Pod: Smallest deployable unit │ │
│ │ • Deployment: Manages replica sets and updates │ │
│ │ • Service: Network abstraction for pods │ │
│ │ • ReplicaSet: Ensures desired number of pods │ │
│ │ • Namespace: Resource isolation │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Kubernetes Architecture
+------------------------------------------------------------------+
| |
| +------------------+ |
| | Control Plane | |
| | +--------------+ | |
| | | kube-apiserver| |
| | | etcd | |
| | | kube-scheduler| |
| | | kube-controller| |
| | +--------------+ | |
| +------------------+ |
| | |
| | |
| +------------------+ +------------------+ |
| | Worker Nodes | | Worker Nodes | |
| | +--------------+ | | +--------------+ | |
| | | kubelet | | | | kubelet | | |
| | | kube-proxy | | | | kube-proxy | | |
| | | containerd | | | | containerd | | |
| | +--------------+ | | +--------------+ | |
| +------------------+ +------------------+ |
| |
+------------------------------------------------------------------+

Terminal window
# Cluster info
kubectl cluster-info
kubectl get nodes
# Pods
kubectl get pods
kubectl get pods -o wide
kubectl describe pod pod_name
kubectl logs pod_name
kubectl exec -it pod_name -- /bin/sh
# Deployments
kubectl get deployments
kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=3
kubectl rollout status deployment nginx
# Services
kubectl get services
kubectl expose deployment nginx --port=80

pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80
resources:
limits:
memory: "128Mi"
cpu: "500m"
requests:
memory: "64Mi"
cpu: "250m"

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24
ports:
- containerPort: 80

service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP # or NodePort, LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
Terminal window
# NodePort example
kubectl expose deployment nginx --type=NodePort
# LoadBalancer
kubectl expose deployment nginx --type=LoadBalancer

configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: "postgres://db:5432/app"
cache_enabled: "true"
secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
stringData:
username: admin
password: changeme

Terminal window
# List namespaces
kubectl get namespaces
# Create namespace
kubectl create namespace dev
# Use namespace
kubectl config set-context --current --namespace=dev
# Get in namespace
kubectl get pods -n dev

WRONG:

spec:
containers:
- name: app
image: myapp
# No resources defined - pod can consume all node resources

CORRECT:

spec:
containers:
- name: app
image: myapp
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"

Why: Without limits, one pod can starve others; also enables scheduling decisions.


WRONG:

Terminal window
# All resources in default namespace
kubectl get pods
# Mixed dev, staging, production

CORRECT:

Terminal window
# Separate namespaces for environments
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production
# Use RBAC to restrict access

Why: Namespaces provide isolation and prevent accidental deletion.


WRONG:

apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database-password: "secretpassword" # WRONG!

CORRECT:

apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
database-password: "secretpassword"

Why: Secrets are base64 encoded, not encrypted - but better than ConfigMaps.


WRONG:

spec:
containers:
- name: app
image: myapp
# No health checks - unhealthy pods stay in service

CORRECT:

spec:
containers:
- name: app
image: myapp
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5

Why: Probes enable self-healing and proper traffic routing.


WRONG:

spec:
containers:
- name: app
image: myapp:latest # Changes over time!

CORRECT:

spec:
containers:
- name: app
image: myapp:v1.2.3 # Pin to specific version

Why: latest changes - non-reproducible deployments.


In this chapter, you learned:

  • ✅ Kubernetes architecture
  • ✅ kubectl commands
  • ✅ Pods
  • ✅ Deployments
  • ✅ Services
  • ✅ ConfigMaps and Secrets
  • ✅ Namespaces

Chapter 60: Container Security


Last Updated: February 2026