freeleaps-ops/docs/Kubernetes_Fundamentals_For_Junior_Engineers.md

833 lines
17 KiB
Markdown
Raw Normal View History

2025-09-03 23:59:04 +00:00
# Kubernetes Fundamentals for Junior Engineers
## 🎯 **Overview**
This guide is designed for junior engineers starting their DevOps journey. It covers the essential Kubernetes concepts you'll encounter daily, with practical examples and real-world scenarios.
---
## 📋 **Prerequisites**
Before diving into these concepts, make sure you understand:
-**Pods**: Basic container units
-**Namespaces**: Resource organization
-**PVCs**: Persistent storage
-**Basic kubectl commands**
---
## 🚀 **1. Deployments (The Right Way to Run Apps)**
### **Why Deployments?**
**Never create Pods directly!** Deployments are the standard way to run applications because they provide:
- **Replicas**: Run multiple copies of your app
- **Rolling updates**: Zero-downtime deployments
- **Rollback**: Easy recovery from failed deployments
- **Self-healing**: Automatically restart failed pods
### **Deployment Structure**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: my-app
labels:
app: web-app
version: v1
spec:
replicas: 3 # Run 3 copies
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
version: v1
spec:
containers:
- name: web-app
image: nginx:latest
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
```
### **Managing Deployments**
```bash
# Create deployment
kubectl apply -f deployment.yaml
# Check deployment status
kubectl get deployments
kubectl describe deployment web-app
# Scale deployment
kubectl scale deployment web-app --replicas=5
# Update deployment (change image)
kubectl set image deployment/web-app web-app=nginx:1.21
# Rollback to previous version
kubectl rollout undo deployment/web-app
# Check rollout status
kubectl rollout status deployment/web-app
# View rollout history
kubectl rollout history deployment/web-app
```
---
## 🌐 **2. Services (Network Communication)**
### **Why Services?**
Pods are ephemeral (temporary). Services provide:
- **Stable IP addresses** for your applications
- **Load balancing** across multiple pods
- **Service discovery** within the cluster
- **External access** to your applications
### **Service Types**
#### **ClusterIP (Internal Access)**
```yaml
apiVersion: v1
kind: Service
metadata:
name: web-app-service
namespace: my-app
spec:
type: ClusterIP
selector:
app: web-app
ports:
- port: 80
targetPort: 80
protocol: TCP
```
#### **NodePort (External Access via Node)**
```yaml
apiVersion: v1
kind: Service
metadata:
name: web-app-nodeport
namespace: my-app
spec:
type: NodePort
selector:
app: web-app
ports:
- port: 80
targetPort: 80
nodePort: 30080 # Access via node IP:30080
protocol: TCP
```
#### **LoadBalancer (Cloud Load Balancer)**
```yaml
apiVersion: v1
kind: Service
metadata:
name: web-app-lb
namespace: my-app
spec:
type: LoadBalancer
selector:
app: web-app
ports:
- port: 80
targetPort: 80
protocol: TCP
```
### **Managing Services**
```bash
# Create service
kubectl apply -f service.yaml
# List services
kubectl get services
kubectl get svc
# Get service details
kubectl describe service web-app-service
# Test service connectivity
kubectl run test-pod --image=busybox --rm -it --restart=Never -- wget -O- web-app-service:80
# Port forward for testing
kubectl port-forward service/web-app-service 8080:80
```
---
## 🔧 **3. ConfigMaps & Secrets (Configuration Management)**
### **Why ConfigMaps & Secrets?**
Applications need configuration. These provide:
- **Environment-specific settings** (dev, staging, prod)
- **Secure credential storage**
- **Configuration without rebuilding images**
- **Centralized configuration management**
### **ConfigMaps**
#### **Creating ConfigMaps**
```bash
# From literal values
kubectl create configmap app-config \
--from-literal=DB_HOST=postgres-service \
--from-literal=DB_PORT=5432 \
--from-literal=ENVIRONMENT=production
# From file
kubectl create configmap app-config --from-file=config.properties
# From YAML
kubectl apply -f configmap.yaml
```
#### **ConfigMap YAML**
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: my-app
data:
# Simple key-value pairs
DB_HOST: "postgres-service"
DB_PORT: "5432"
ENVIRONMENT: "production"
# File-like content
config.properties: |
server.port=8080
logging.level=INFO
cache.enabled=true
```
#### **Using ConfigMaps in Pods**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
template:
spec:
containers:
- name: web-app
image: my-app:latest
env:
# Environment variables
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DB_HOST
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: DB_PORT
volumeMounts:
# Mount as files
- name: config-volume
mountPath: /app/config
volumes:
- name: config-volume
configMap:
name: app-config
```
### **Secrets**
#### **Creating Secrets**
```bash
# From literal values
kubectl create secret generic db-secret \
--from-literal=DB_USERNAME=admin \
--from-literal=DB_PASSWORD=secret123
# From file
kubectl create secret generic tls-secret \
--from-file=tls.crt=cert.pem \
--from-file=tls.key=key.pem
```
#### **Secret YAML**
```yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: my-app
type: Opaque
data:
# Base64 encoded values
DB_USERNAME: YWRtaW4= # admin
DB_PASSWORD: c2VjcmV0MTIz # secret123
```
#### **Using Secrets in Pods**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
template:
spec:
containers:
- name: web-app
image: my-app:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
```
---
## 🎯 **4. Ingress (External Access & Routing)**
### **Why Ingress?**
Ingress provides:
- **URL-based routing** (example.com/api, example.com/web)
- **SSL/TLS termination**
- **Load balancing**
- **Name-based virtual hosting**
### **Ingress Controller**
First, ensure you have an Ingress controller (like nginx-ingress):
```bash
# Check if ingress controller exists
kubectl get pods -n ingress-nginx
# If not, install nginx-ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml
```
### **Ingress Resource**
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: my-app
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
```
### **Managing Ingress**
```bash
# Apply ingress
kubectl apply -f ingress.yaml
# Check ingress status
kubectl get ingress
kubectl describe ingress web-app-ingress
# Test ingress
curl -H "Host: myapp.example.com" http://your-cluster-ip/
```
---
## 🔄 **5. Jobs & CronJobs (Batch Processing)**
### **Why Jobs & CronJobs?**
For tasks that need to:
- **Run to completion** (not continuously)
- **Execute on schedule** (daily backups, reports)
- **Process data** (ETL jobs, batch processing)
### **Jobs**
```yaml
apiVersion: batch/v1
kind: Job
metadata:
name: data-processing-job
namespace: my-app
spec:
completions: 3 # Run 3 times
parallelism: 2 # Run 2 in parallel
template:
spec:
containers:
- name: data-processor
image: data-processor:latest
command: ["python", "process_data.py"]
env:
- name: INPUT_FILE
value: "/data/input.csv"
- name: OUTPUT_FILE
value: "/data/output.csv"
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: data-pvc
restartPolicy: Never
```
### **CronJobs**
```yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
namespace: my-app
spec:
schedule: "0 2 * * *" # Daily at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
command: ["/bin/bash", "-c"]
args:
- |
echo "Starting backup at $(date)"
pg_dump -h postgres-service -U admin mydb > /backup/backup-$(date +%Y%m%d).sql
echo "Backup completed at $(date)"
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_PASSWORD
volumeMounts:
- name: backup-volume
mountPath: /backup
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: backup-pvc
restartPolicy: OnFailure
```
### **Managing Jobs & CronJobs**
```bash
# Create job
kubectl apply -f job.yaml
# Check job status
kubectl get jobs
kubectl describe job data-processing-job
# View job logs
kubectl logs job/data-processing-job
# Create cronjob
kubectl apply -f cronjob.yaml
# Check cronjob status
kubectl get cronjobs
kubectl describe cronjob daily-backup
# Suspend cronjob
kubectl patch cronjob daily-backup -p '{"spec" : {"suspend" : true}}'
# Resume cronjob
kubectl patch cronjob daily-backup -p '{"spec" : {"suspend" : false}}'
```
---
## 📊 **6. Resource Management & Limits**
### **Why Resource Management?**
To prevent:
- **Resource starvation** (one app consuming all CPU/memory)
- **Node failures** (out of memory)
- **Poor performance** (over-subscription)
### **Resource Requests & Limits**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: resource-managed-app
spec:
template:
spec:
containers:
- name: app
image: my-app:latest
resources:
requests:
memory: "64Mi" # Minimum guaranteed
cpu: "250m" # 0.25 CPU cores
limits:
memory: "128Mi" # Maximum allowed
cpu: "500m" # 0.5 CPU cores
```
### **Resource Quotas**
```yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: namespace-quota
namespace: my-app
spec:
hard:
requests.cpu: "4" # 4 CPU cores total
requests.memory: 8Gi # 8GB memory total
limits.cpu: "8" # 8 CPU cores max
limits.memory: 16Gi # 16GB memory max
pods: "20" # 20 pods max
services: "10" # 10 services max
persistentvolumeclaims: "10" # 10 PVCs max
```
### **Managing Resources**
```bash
# Check resource usage
kubectl top pods
kubectl top nodes
# Check quotas
kubectl get resourcequota
kubectl describe resourcequota namespace-quota
# Check resource requests/limits
kubectl describe pod <pod-name> | grep -A 10 "Limits"
```
---
## 🔍 **7. Monitoring & Debugging**
### **Essential Commands**
```bash
# Check cluster health
kubectl get nodes
kubectl get pods --all-namespaces
# Check specific resources
kubectl get deployments,services,pods -n my-app
# View logs
kubectl logs <pod-name>
kubectl logs <pod-name> -f # Follow logs
kubectl logs <pod-name> --previous # Previous container
# Execute commands in pods
kubectl exec -it <pod-name> -- /bin/bash
kubectl exec <pod-name> -- ls /app
# Port forwarding for debugging
kubectl port-forward <pod-name> 8080:80
kubectl port-forward service/<service-name> 8080:80
# Check events
kubectl get events --sort-by='.lastTimestamp'
kubectl get events -n my-app
# Check resource usage
kubectl top pods
kubectl top nodes
```
### **Common Debugging Scenarios**
#### **Pod Stuck in Pending**
```bash
# Check why pod can't be scheduled
kubectl describe pod <pod-name>
# Check node resources
kubectl describe node <node-name>
# Check events
kubectl get events --sort-by='.lastTimestamp'
```
#### **Pod Crashing**
```bash
# Check pod status
kubectl get pods
kubectl describe pod <pod-name>
# Check logs
kubectl logs <pod-name>
kubectl logs <pod-name> --previous
# Check resource usage
kubectl top pod <pod-name>
```
#### **Service Not Working**
```bash
# Check service endpoints
kubectl get endpoints <service-name>
# Check service configuration
kubectl describe service <service-name>
# Test service connectivity
kubectl run test-pod --image=busybox --rm -it --restart=Never -- wget -O- <service-name>:<port>
```
---
## 🔒 **8. Security Best Practices**
### **Pod Security**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: app
image: my-app:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp-volume
mountPath: /tmp
volumes:
- name: tmp-volume
emptyDir: {}
```
### **Network Policies**
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-web-traffic
namespace: my-app
spec:
podSelector:
matchLabels:
app: web-app
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
ports:
- protocol: TCP
port: 80
```
---
## 📚 **9. Best Practices for Junior Engineers**
### **1. Always Use Deployments (Not Pods)**
```bash
# ❌ Don't do this
kubectl run nginx --image=nginx
# ✅ Do this
kubectl create deployment nginx --image=nginx
```
### **2. Use Namespaces for Organization**
```bash
# Create namespaces for different environments
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production
```
### **3. Set Resource Limits**
```yaml
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
```
### **4. Use Health Checks**
```yaml
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
```
### **5. Use Labels and Selectors**
```yaml
metadata:
labels:
app: web-app
version: v1
environment: production
team: backend
```
### **6. Use ConfigMaps and Secrets**
```bash
# Store configuration externally
kubectl create configmap app-config --from-literal=DB_HOST=postgres
kubectl create secret generic db-secret --from-literal=DB_PASSWORD=secret123
```
---
## 🚀 **10. Next Steps**
### **Advanced Concepts to Learn**
- **StatefulSets**: For stateful applications (databases)
- **DaemonSets**: For node-level services (monitoring agents)
- **Horizontal Pod Autoscaler (HPA)**: Automatic scaling
- **Vertical Pod Autoscaler (VPA)**: Resource optimization
- **Pod Disruption Budgets**: Availability guarantees
- **Pod Security Standards**: Security policies
### **Tools to Master**
- **Helm**: Package manager for Kubernetes
- **Kustomize**: Configuration management
- **ArgoCD**: GitOps deployment
- **Prometheus & Grafana**: Monitoring
- **Fluentd/Elasticsearch**: Logging
### **Practice Projects**
1. **Simple Web App**: Deploy nginx with database
2. **API Service**: Deploy REST API with authentication
3. **Batch Job**: Create data processing pipeline
4. **Monitoring Stack**: Deploy Prometheus + Grafana
5. **CI/CD Pipeline**: Automate deployments
---
## 🆘 **Troubleshooting Quick Reference**
### **Common Issues & Solutions**
| Issue | Command | What to Check |
|-------|---------|---------------|
| Pod not starting | `kubectl describe pod <name>` | Events, resource limits |
| Service not working | `kubectl get endpoints <service>` | Pod labels, service selector |
| Deployment stuck | `kubectl rollout status deployment/<name>` | Image pull, resource limits |
| Ingress not working | `kubectl describe ingress <name>` | Ingress controller, TLS |
| High resource usage | `kubectl top pods` | Resource limits, memory leaks |
### **Useful Aliases**
```bash
# Add to your .bashrc or .zshrc
alias k='kubectl'
alias kg='kubectl get'
alias kd='kubectl describe'
alias kl='kubectl logs'
alias ke='kubectl exec -it'
alias kp='kubectl port-forward'
```
---
**Last Updated**: September 3, 2025
**Version**: 1.0
**Maintainer**: Infrastructure Team