# 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
