---
title: "Kubernetes"
description: "Kubernetes is an open-source container orchestration platform for automating deployment, scaling, and management of containerized applications."
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/cheatsheets/kubernetes
---

# Kubernetes

Kubernetes is the de facto standard for container orchestration. It automates deployment, scaling, and management of containerized applications across clusters of machines, providing declarative configuration and powerful self-healing capabilities.

## Key Features

- **Automated Deployment**: Deploy containers to nodes automatically
- **Self-Healing**: Restarts failed containers, replaces unhealthy pods
- **Load Balancing**: Distribute traffic across pod replicas
- **Rolling Updates**: Gradually update application versions without downtime
- **Resource Management**: Optimize cluster resource utilization with quotas and limits
- **Security**: Network policies, RBAC, and secret management
- **Service Discovery**: Automatic DNS and load balancing for services
- **Storage Orchestration**: Manage persistent and ephemeral storage

## Quick Start

**Install kubectl**: Follow the Install and Configure kubectl section.

**Access cluster**: `kubectl cluster-info`

**Create deployment**: `kubectl create deployment web --image=nginx`

**List resources**: `kubectl get pods,svc,deployments`

**Check application status**: `kubectl describe deployment web`

## Common Workflows

1. **Deploy Application**: Create Deployment with image, replicas, and resources
2. **Expose Service**: Create Service to access pods internally or externally
3. **Configure Access**: Set up Ingress or LoadBalancer for external traffic
4. **Monitor Health**: Check pod status, logs, and events regularly
5. **Update Application**: Use rolling updates or blue-green deployments
6. **Scale Load**: Adjust replicas manually or enable HPA for automatic scaling
7. **Debug Issues**: Examine logs, describe resources, execute debugging containers

Explore the sections above to master Kubernetes from basic pod management to advanced security and operations.

## Getting Started

Core Kubernetes concepts and initial setup for beginners

### Kubernetes Basics

Introduction to Kubernetes architecture and core concepts

**Keywords:** kubernetes, container, orchestration, pods, clusters, nodes, master

#### Understand Kubernetes architecture

```bash
# Kubernetes architecture consists of:
# 1. Control Plane (Master): Manages cluster state and decisions
# 2. Worker Nodes: Run containerized applications
# 3. Pods: Smallest deployable units (wrappers around containers)
# 4. Services: Expose pods to network traffic
# 5. Storage: Persistent data storage for pods

# Analogy to VMs:
# Traditional: Cluster -> Node -> VM -> Application
# Kubernetes: Cluster -> Node -> Pod -> Container

# Key resources:
# - Pod: Single or multiple containers sharing network
# - Deployment: Manages pod replicas
# - Service: Network access to pods
# - ConfigMap: Configuration data
# - PersistentVolume: Storage resources
```

_exec_
```bash
kubectl cluster-info
```

_output_
```bash
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
```

Shows your Kubernetes cluster endpoints and components

- Requires kubectl and KUBECONFIG configured
- Control plane manages cluster operations
- Worker nodes run actual workloads

#### Check cluster nodes and capacity

```bash
# Get list of all nodes in cluster
kubectl get nodes

# Get detailed node information
kubectl get nodes -o wide

# View node resource capacities and allocations
kubectl top nodes

# Describe specific node
kubectl describe node node-1
```

_exec_
```bash
kubectl get nodes -o wide
```

_output_
```bash
NAME       STATUS   ROLES    AGE   VERSION   INTERNAL-IP   EXTERNAL-IP
minikube   Ready    master   10d   v1.24.0   192.168.1.1   <none>
```

Lists all nodes in your cluster with their status and information

- STATUS Ready means node is healthy and accepting workloads
- Roles indicate control plane vs worker nodes
- top requires metrics-server to be installed

#### Verify kubectl installation and context

```bash
# Check kubectl version
kubectl version --client

# View current context
kubectl config current-context

# List all available contexts
kubectl config get-contexts

# Switch to different context
kubectl config use-context docker-desktop

# Get cluster information
kubectl config view
```

_exec_
```bash
kubectl version --client
```

_output_
```bash
Client Version: v1.26.0
Kustomize Version: v4.5.4
```

Verifies kubectl installation and shows active cluster context

- Context determines which cluster kubectl connects to
- KUBECONFIG can contain multiple clusters
- Switch contexts for multi-cluster environments

**Best practices:**

- Understand cluster architecture before deploying applications
- Organize resources using namespaces for multi-team environments
- Monitor node capacity to prevent resource exhaustion

**Common errors:**

- **Unable to connect to the server**: Check KUBECONFIG, verify cluster availability with kubectl cluster-info

### Install and Configure kubectl

Set up kubectl CLI tool and configure cluster access

**Keywords:** install, kubectl, setup, kubeconfig, context

#### Install kubectl on Linux

```bash
# Download kubectl binary
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

# Make it executable
chmod +x kubectl

# Move to PATH
sudo mv kubectl /usr/local/bin/

# Verify installation
kubectl version --client

# Using package manager (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install -y kubectl
```

_exec_
```bash
kubectl version --client
```

_output_
```bash
Client Version: v1.26.0
Kustomize Version: v4.5.4
```

Installs kubectl CLI tool required for managing Kubernetes clusters

- Always download from official Kubernetes release repository
- Version should be within 1 minor version of cluster API

#### Configure kubectl with cloud clusters

```bash
# AWS EKS - Get cluster config
aws eks update-kubeconfig --region us-east-1 --name my-cluster

# Google GKE - Get cluster credentials
gcloud container clusters get-credentials my-cluster --zone us-central1-a

# Azure AKS - Get cluster credentials
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

# Verify kubectl can access cluster
kubectl cluster-info
```

_exec_
```bash
kubectl config view
```

_output_
```bash
apiVersion: v1
clusters:
- cluster:
    server: https://example.com
  name: my-cluster
contexts:
- context:
    cluster: my-cluster
    user: my-user
  name: my-context
```

Configures kubectl to access cloud-managed Kubernetes clusters

- Each cloud provider has specific commands for credential setup
- Kubeconfig stored in ~/.kube/config by default

#### Set up kubectl shell completion

```bash
# Bash completion
echo "source <(kubectl completion bash)" >> ~/.bashrc
source ~/.bashrc

# Zsh completion
echo "source <(kubectl completion zsh)" >> ~/.zshrc
source ~/.zshrc

# Fish completion
kubectl completion fish | source

# Temporary completion (current session)
source <(kubectl completion bash)
```

_exec_
```bash
kubectl completion bash
```

_output_
```bash
# bash completion for kubectl
_kubectl_complete() { ... }
```

Enables tab completion for kubectl commands in your shell

- Greatly improves command line productivity
- Available for bash, zsh, fish, and powershell

**Best practices:**

- Install kubectl matching cluster version (±1 minor version)
- Use kubeconfig file for cluster authentication
- Enable shell completion for faster CLI navigation

**Common errors:**

- **unknown command**: Ensure kubectl is in PATH with `which kubectl`

### Namespaces and Basic Navigation

Organize resources using namespaces and navigate clusters

**Keywords:** namespace, organize, isolation, multi-tenant

#### Explore and create namespaces

```bash
# List all namespaces
kubectl get namespaces

# Create new namespace
kubectl create namespace development

# Create namespace with YAML
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
  name: production
EOF

# Get default namespaces
# default - for user workloads
# kube-system - for system components
# kube-public - world-readable resources
# kube-node-lease - node heartbeats
```

_exec_
```bash
kubectl get ns
```

_output_
```bash
NAME              STATUS   AGE
default           Active   10d
kube-system       Active   10d
kube-public       Active   10d
kube-node-lease   Active   10d
```

Lists and creates Kubernetes namespaces for resource organization

- Default namespace is used if not specified
- Namespaces isolate resources within same cluster
- Good for multi-team or multi-environment setups

#### Set default namespace and switch between them

```bash
# Set permanent default namespace
kubectl config set-context --current --namespace=development

# View current namespace
kubectl config view --minify --output=jsonpath='{..namespace}'

# View resources in specific namespace
kubectl get pods --namespace=production
kubectl get pods -n production  # short form

# Switch context with different namespace
kubectl config use-context dev-context
```

_exec_
```bash
kubectl config set-context --current --namespace=default
```

_output_
```bash
Context "minikube" modified.
```

Sets default namespace for kubectl commands without -n flag

- Default context is stored in ~/.kube/config
- -n flag overrides default namespace per command

#### View all resources across namespaces

```bash
# List pods across all namespaces
kubectl get pods --all-namespaces
kubectl get pods -A  # short form

# View services across all namespaces
kubectl get svc -A

# Get all resources in all namespaces
kubectl get all -A

# Describe resource in specific namespace
kubectl describe pod my-pod -n production
```

_exec_
```bash
kubectl get pods -A
```

_output_
```bash
NAMESPACE     NAME                             READY   STATUS    RESTARTS
default       nginx-pod                        1/1     Running   0
kube-system   coredns-64897fb6d9-x8z5k         1/1     Running   0
production    app-deployment-abc123-xyz789     1/1     Running   1
```

Lists resources across all namespaces for cluster-wide visibility

- -A flag is equivalent to --all-namespaces
- Useful for troubleshooting across entire cluster

**Best practices:**

- Use namespaces for environment separation (dev, staging, prod)
- Apply RBAC policies per namespace for security
- Set default namespace in kubeconfig to reduce flag typing

**Common errors:**

- **pods not found in default namespace**: Check active namespace with kubectl config view or specify -n flag

## Cluster Management

Manage cluster configuration, nodes, resources, and monitoring

### Cluster Context and Configuration

Manage multiple clusters and kubeconfig contexts

**Keywords:** context, kubeconfig, configuration, cluster, authentication

#### Manage kubeconfig contexts and clusters

```bash
# View all contexts and clusters
kubectl config get-contexts
kubectl config get-clusters

# Get current context
kubectl config current-context

# Switch to different context
kubectl config use-context another-cluster

# Create new context
kubectl config set-context production --cluster=prod-cluster --user=prod-user

# Delete context
kubectl config delete-context old-context
```

_exec_
```bash
kubectl config get-contexts
```

_output_
```bash
CURRENT   NAME              CLUSTER         AUTHINFO        NAMESPACE
*         minikube          minikube        minikube        default
          docker-desktop    docker-desktop  docker-desktop  default
          kind-cluster1     kind-cluster1   kind-cluster1   default
```

Shows all available contexts and allows switching between clusters

- Context combines cluster, user, and namespace information
- * indicates current context

#### Configure cluster authentication

```bash
# Set cluster details
kubectl config set-cluster my-cluster \
  --server=https://kubernetes.example.com:6443 \
  --certificate-authority=/path/to/ca.crt

# Set user authentication
kubectl config set-credentials my-user \
  --client-certificate=/path/to/client.crt \
  --client-key=/path/to/client.key

# Create context binding user to cluster
kubectl config set-context my-context \
  --cluster=my-cluster \
  --user=my-user \
  --namespace=default

# Verify configuration
kubectl config view
```

_exec_
```bash
kubectl config view
```

_output_
```bash
apiVersion: v1
clusters:
- cluster:
    server: https://kubernetes.example.com:6443
users:
- name: my-user
contexts:
- context:
    cluster: my-cluster
    user: my-user
```

Manually configure cluster, user, and context settings

- Certificates can be base64-encoded in kubeconfig
- kubectl config view shows merged configuration

#### Merge kubeconfig files and manage credentials

```bash
# View kubeconfig location
echo $KUBECONFIG

# Merge multiple kubeconfig files
export KUBECONFIG=~/.kube/config:~/.kube/prod-config:/tmp/temp-config
kubectl config view --merge

# Flatten kubeconfig (consolidate into single file)
kubectl config view --flatten > ~/.kube/consolidated-config

# Set KUBECONFIG permanently
echo "export KUBECONFIG=$HOME/.kube/config" >> ~/.bashrc

# Verify current kubeconfig
kubectl config view --minify
```

_exec_
```bash
echo $KUBECONFIG
```

_output_
```bash
/home/user/.kube/config
```

Manage multiple kubeconfig files for different clusters

- Multiple KUBECONFIG files are separated by colon (:)
- Useful for managing dev, staging, and production clusters

**Best practices:**

- Organize kubeconfig for easy context switching
- Use meaningful names for contexts (e.g., prod-us-east)
- Limit kubeconfig credentials to necessary clusters

**Common errors:**

- **current-context is not set**: Set default context with kubectl config use-context

### Cluster Information and Monitoring

Monitor cluster health, resources, and component status

**Keywords:** cluster-info, monitoring, metrics, health, status

#### Check cluster health and component status

```bash
# Get cluster information
kubectl cluster-info

# Get system components (requires metrics-server)
kubectl get componentstatuses

# Check API server and cluster version
kubectl api-versions

# List all API resources available
kubectl api-resources

# View cluster details
kubectl describe cluster
```

_exec_
```bash
kubectl cluster-info
```

_output_
```bash
Kubernetes control plane is running at https://127.0.0.1:6443
CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
```

Shows running components and their endpoints

- Critical for verifying cluster connectivity
- Dump shows more detailed debug information

#### Monitor node resources and health

```bash
# List nodes with resource information
kubectl get nodes --show-labels

# Get node resource usage
kubectl top nodes

# Describe specific node for details
kubectl describe node minikube

# Check node logs (requires SSH or specific monitoring)
kubectl logs -f -n kube-system --tail=50 <pod-name>

# Get node conditions
kubectl get nodes -o jsonpath='{.items[*].status.conditions}' | jq .
```

_exec_
```bash
kubectl top nodes
```

_output_
```bash
NAME       CPU(cores)   CPU%   MEMORY(Mi)   MEMORY%
minikube   245m         12%    1234Mi       32%
```

Shows CPU and memory usage for all cluster nodes

- Requires metrics-server installed for top command
- CPU in millicores, memory in megabytes

#### Check persistent volume and storage status

```bash
# List persistent volumes
kubectl get pv

# List persistent volume claims
kubectl get pvc --all-namespaces

# Check storage classes
kubectl get storageclass

# Describe specific PV
kubectl describe pv pv-name

# Check PVC status
kubectl describe pvc pvc-name -n namespace
```

_exec_
```bash
kubectl get pv
```

_output_
```bash
NAME       CAPACITY   ACCESS MODES   RECLAIM   STATUS   CLAIM
pv-001     10Gi       RWO            Delete    Bound    ns/pvc-001
```

Lists persistent storage resources in the cluster

- PV is cluster-level, PVC is namespace-level
- Status should be Bound for normal operation

**Best practices:**

- Monitor node capacity regularly to avoid resource exhaustion
- Keep system components healthy in kube-system namespace
- Set up resource monitoring with Prometheus or similar

**Common errors:**

- **metrics not available**: Install metrics-server with kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

### Node and Resource Management

Manage cluster nodes, taints, and resource quotas

**Keywords:** node, taint, toleration, resource-quota, drain, cordon

#### Cordon and drain nodes for maintenance

```bash
# Cordon node (prevent new pods from scheduling)
kubectl cordon node-1

# Drain node (evict all pods safely)
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data

# Uncordon node (allow scheduling again)
kubectl uncordon node-1

# Check node status
kubectl get nodes
kubectl describe node node-1
```

_exec_
```bash
kubectl get nodes
```

_output_
```bash
NAME       STATUS                     ROLES   AGE
node-1     Ready,SchedulingDisabled   <none>  10d
node-2     Ready                      <none>  10d
```

Safely cordons and drains nodes for maintenance

- SchedulingDisabled status indicates cordoned node
- Drain ensures graceful pod termination

#### Add and remove node taints

```bash
# Add taint to node (prevents scheduling unless tolerated)
kubectl taint nodes node-1 key=value:NoSchedule

# Add effect types:
# NoSchedule - new pods won't be scheduled
# NoExecute - existing pods will be evicted
# PreferNoSchedule - prefer not to schedule but may

# Remove taint from node
kubectl taint nodes node-1 key=value:NoSchedule-

# View node taints
kubectl describe node node-1 | grep Taints
```

_exec_
```bash
kubectl describe node node-1 | grep Taints
```

_output_
```bash
Taints: gpu=true:NoSchedule
```

Adds and removes taints to control pod scheduling

- Pods need matching tolerations to schedule on tainted nodes
- Common for GPU nodes or specialized hardware

#### Set resource quotas and limits per namespace

```bash
# Create resource quota for namespace
kubectl create quota myrquota --hard=pods=10,cpu=3,memory=10Gi -n development

# View resource quotas
kubectl get resourcequota -n development

# Describe quota details
kubectl describe resourcequota myrquota -n development

# Create with YAML for more control
kubectl apply -f - <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
  namespace: development
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
EOF
```

_exec_
```bash
kubectl get resourcequota -A
```

_output_
```bash
NAMESPACE    NAME         AGE   REQUEST.CPU   REQUESTMEMORY
development  myrquota     5d    500m / 3      2Gi / 10Gi
```

Sets resource limits for namespaces to prevent overallocation

- Quotas prevent namespace from consuming excessive cluster resources
- Pods larger than quota cannot be created

**Best practices:**

- Drain nodes gracefully before maintenance or removal
- Use taints for specialized hardware (GPU, high-memory)
- Set resource quotas to prevent namespace resource hogging

**Common errors:**

- **cannot drain node, pods without controllers**: Use --force flag to forcefully remove pods (use with caution)

## Pod Management

Create, manage, inspect, and debug Kubernetes pods

### Creating and Listing Pods

Create pods imperatively and declaratively, list and filter them

**Keywords:** pod, create, run, yaml, manifest

#### Create pods imperatively with kubectl run

```bash
# Create simple pod from image
kubectl run nginx-pod --image=nginx

# Create pod with port mapping
kubectl run web --image=nginx --port=8080

# Create pod with resource requests/limits
kubectl run app --image=myapp --requests=cpu=100m,memory=128Mi --limits=cpu=500m,memory=512Mi

# Create pod with command
kubectl run busybox --image=busybox --command -- sleep 3600

# Create pod in specific namespace
kubectl run test-pod --image=alpine -n development

# Create pod and output YAML (dry-run)
kubectl run nginx-pod --image=nginx --dry-run=client -o yaml
```

_exec_
```bash
kubectl run test-pod --image=alpine --dry-run=client -o yaml
```

_output_
```bash
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  name: test-pod
spec:
  containers:
  - image: alpine
    name: test-pod
```

Creates pods using imperative kubectl run command

- Imperative approach is fast for quick testing
- Use dry-run to preview YAML before creating

#### Create pods declaratively with YAML manifests

```bash
# Create pod from YAML file
kubectl apply -f pod.yaml

# Create pod from inline YAML
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  namespace: default
  labels:
    app: web
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 500m
        memory: 512Mi
  - name: sidecar
    image: busybox
    command: ['sleep', '3600']
EOF

# Verify pod creation
kubectl get pods
```

_exec_
```bash
kubectl get pods
```

_output_
```bash
NAME      READY   STATUS    RESTARTS   AGE
web-pod   2/2     Running   0          2m
```

Creates pods using declarative YAML manifests

- Declarative approach is preferred for reproducibility
- YAML files can be version controlled
- Multiple containers can run in same pod

#### List and filter pods

```bash
# List pods in current namespace
kubectl get pods

# List pods with detailed info
kubectl get pods -o wide

# List pods across all namespaces
kubectl get pods -A

# List pods with labels
kubectl get pods --show-labels

# Filter pods by label
kubectl get pods -l app=web

# Filter by multiple labels
kubectl get pods -l app=web,tier=frontend

# List pods with custom columns
kubectl get pods -o custom-columns=NAME:metadata.name,STATUS:status.phase,IP:status.podIP
```

_exec_
```bash
kubectl get pods -o wide
```

_output_
```bash
NAME      STATUS   IP           NODE      NOMINATED
web-pod   Running  10.244.0.5   minikube  <none>
```

Lists pods with various filtering and output options

- Default shows only current namespace
- -o flag controls output format (json, yaml, custom-columns)

**Best practices:**

- Use Deployments instead of bare Pods for production
- Define resource requests and limits on all containers
- Use labels for organizing and filtering pods

**Common errors:**

- **pods are forbidden**: Check RBAC permissions with kubectl auth can-i get pods

### Inspecting and Debugging Pods

Describe, view logs, and debug pod issues

**Keywords:** describe, logs, events, debug, troubleshot

#### Describe pods and view details

```bash
# Get basic information about pod
kubectl get pod web-pod

# Get detailed pod information
kubectl describe pod web-pod

# View pod definition in YAML
kubectl get pod web-pod -o yaml

# View pod in JSON format
kubectl get pod web-pod -o json

# Extract specific fields with JSONPath
kubectl get pod web-pod -o jsonpath='{.status.phase}'
kubectl get pod web-pod -o jsonpath='{.spec.containers[0].image}'
```

_exec_
```bash
kubectl describe pod web-pod
```

_output_
```bash
Name:         web-pod
Namespace:    default
Status:       Running
IP:           10.244.0.5
Containers:
  nginx:
    Image: nginx:latest
  State: Running
```

Shows detailed pod information including events and status

- describe shows useful events and error messages
- Events help identify why pods fail to start

#### View pod logs and stream output

```bash
# View logs from pod
kubectl logs web-pod

# View logs from specific container in multi-container pod
kubectl logs web-pod -c nginx

# Stream logs in real-time
kubectl logs -f web-pod

# View logs from previous container (crashed pods)
kubectl logs web-pod --previous

# Show logs with timestamps
kubectl logs web-pod --timestamps=true

# Tail last 50 lines
kubectl logs web-pod --tail=50

# View logs from deployment pods
kubectl logs -l app=web --max-log-requests=10
```

_exec_
```bash
kubectl logs web-pod --tail=20
```

_output_
```bash
192.168.1.1 - - [28/Feb/2025:10:30:00] "GET / HTTP/1.1" 200 612
192.168.1.2 - - [28/Feb/2025:10:30:01] "GET /index.html HTTP/1.1" 200 612
```

Shows container logs for debugging application issues

- -f flag tails logs in real-time like tail -f
- --previous shows logs from before container restart

#### Interactive debugging and shell access

```bash
# Execute command in running pod
kubectl exec web-pod -- ls -la

# Get interactive shell in pod
kubectl exec -it web-pod -- /bin/bash
kubectl exec -it web-pod -- /bin/sh

# Execute command in specific container
kubectl exec -it web-pod -c nginx -- /bin/bash

# Run debugging sidecar in pod
kubectl debug web-pod -it --image=busybox

# Copy files from pod
kubectl cp web-pod:/var/www/html/index.html ./index.html
# Copy files to pod
kubectl cp ./config.yaml web-pod:/etc/config.yaml
```

_exec_
```bash
kubectl exec -it web-pod -- hostname
```

_output_
```bash
web-pod
```

Executes commands and provides shell access to running pods

- -i flag keeps stdin open, -t allocates tty
- Useful for runtime troubleshooting and inspection

**Best practices:**

- Always check describe and events first when debugging
- Use logs to find application errors and issues
- Create debug containers instead of modifying production pods

**Common errors:**

- **command not found in container**: Check if base image has the command (alpine lacks some utilities)

### Deleting and Cleaning Up Pods

Delete pods and manage pod lifecycle

**Keywords:** delete, remove, cleanup, termination, grace-period

#### Delete single and multiple pods

```bash
# Delete single pod
kubectl delete pod web-pod

# Delete multiple pods by name
kubectl delete pod web-pod app-pod db-pod

# Delete all pods in namespace
kubectl delete pods --all

# Delete all pods in all namespaces
kubectl delete pods -A --all

# Delete with confirmation
kubectl delete pod web-pod  # will prompt for confirmation
```

_exec_
```bash
kubectl delete pod web-pod
```

_output_
```bash
pod "web-pod" deleted
```

Deletes pods from the cluster

- Delete operations are immediate (use graceful termination)
- Bare pods are not recreated; use Deployments for self-healing

#### Graceful pod termination and force delete

```bash
# Delete with grace period (seconds to shutdown cleanly)
kubectl delete pod web-pod --grace-period=30

# Force delete immediately (no grace period)
kubectl delete pod web-pod --grace-period=0 --force

# Delete using label selector
kubectl delete pods -l app=web

# Delete using field selector
kubectl delete pods --field-selector=status.phase=Failed

# Check termination status during deletion
kubectl get pod web-pod --watch
```

_exec_
```bash
kubectl delete pod web-pod --grace-period=10
```

_output_
```bash
pod "web-pod" deleted
```

Gracefully terminates pods with shutdown timeout

- Default grace period is 30 seconds
- Pod has time to close connections and save state

**Best practices:**

- Let Deployments manage pod deletion instead of manual deletion
- Use graceful termination for stateful applications
- Clean up resources regularly to save cluster resources

**Common errors:**

- **the server doesn't have a resource type**: Check spelling of resource type (e.g., Pod vs pod)

## Deployment Management

Deploy applications, manage replicas, and perform rolling updates

### Creating Deployments

Create deployments imperatively and declaratively

**Keywords:** deployment, create, replicas, selector, template

#### Create deployments imperatively

```bash
# Create deployment from image
kubectl create deployment web --image=nginx

# Create deployment with replicas
kubectl create deployment web --image=nginx --replicas=3

# Create deployment and save YAML
kubectl create deployment web --image=nginx --dry-run=client -o yaml > web-deployment.yaml

# Create deployment with port
kubectl run web --image=nginx --port=80 --replicas=3

# Verify deployment creation
kubectl get deployments
kubectl get pods
```

_exec_
```bash
kubectl create deployment web --image=nginx --replicas=3
```

_output_
```bash
deployment.apps/web created
```

Creates deployments using imperative kubectl commands

- create is imperative, while apply is declarative
- Deployments automatically create ReplicaSet

#### Create deployments with YAML manifests

```bash
# Create deployment from YAML
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 10
EOF

# List deployments
kubectl get deployments
```

_exec_
```bash
kubectl get deployments -o wide
```

_output_
```bash
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
web-deployment   3/3     3            3           2m
```

Creates deployments declaratively with full control

- YAML approach is reproducible and version-controllable
- spec.replicas defines number of pod replicas
- selector must match template labels

#### Create deployments with health checks

```bash
# Create deployment with liveness and readiness probes
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
      - name: app
        image: myapp:v1
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
EOF
```

_exec_
```bash
kubectl describe deployment app-deployment
```

_output_
```bash
Name:                   app-deployment
Replicas:               2 desired | 2 updated | 2 ready
Strategy:               RollingUpdate
```

Creates deployments with health checks for better reliability

- Liveness probe restarts unhealthy containers
- Readiness probe controls traffic to pods

**Best practices:**

- Use deployments for stateless applications
- Always define resource requests and limits
- Include health checks for reliability

**Common errors:**

- **invalid value for selector**: Ensure label selectors match pod labels exactly

### Scaling Deployments

Scale deployments up and down dynamically

**Keywords:** scale, replicas, hpa, autoscale, load

#### Manually scale deployments

```bash
# Get deployment info
kubectl get deployments

# Scale deployment to 5 replicas
kubectl scale deployment web-deployment --replicas=5

# Scale multiple deployments
kubectl scale deployment web-deployment app-deployment --replicas=3

# Verify scaling
kubectl get deployments
kubectl get pods

# Scale down to 0 (stop deployment)
kubectl scale deployment web-deployment --replicas=0
```

_exec_
```bash
kubectl scale deployment web-deployment --replicas=5
```

_output_
```bash
deployment.apps/web-deployment scaled
```

Scales deployments manually by changing replica count

- Scaling is immediate
- Previous pods will be terminated gracefully

#### Set up horizontal pod autoscaling

```bash
# Create HPA imperatively
kubectl autoscale deployment web-deployment --min=1 --max=10 --cpu-percent=80

# View HPA status
kubectl get hpa

# Describe HPA details
kubectl describe hpa web-deployment

# Create HPA with YAML for more control
kubectl apply -f - <<EOF
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80
EOF
```

_exec_
```bash
kubectl get hpa
```

_output_
```bash
NAME          REFERENCE                  TARGETS   MINPODS  MAXPODS
web-hpa       Deployment/web-deployment  45%/80%   2        10
```

Sets up automatic scaling based on metrics

- Requires metrics-server for CPU/memory metrics
- HPA v2 supports custom metrics

#### Monitor scaling events and history

```bash
# Monitor scaling in real-time
kubectl get hpa --watch

# Check HPA events
kubectl describe hpa web-hpa

# View scaling history
kubectl get events --field-selector involvedObject.name=web-deployment

# Check deployment history
kubectl rollout history deployment web-deployment
```

_exec_
```bash
kubectl get hpa --watch
```

_output_
```bash
NAME      REFERENCE             TARGETS   MINPODS  MAXPODS  REPLICAS  AGE
web-hpa   Deployment/web-deploy 88%/80%   2        10       8         3m
```

Monitors horizontal pod autoscaling events

- HPA cooldown prevents rapid scaling churn
- Monitor targets to verify autoscaling behavior

**Best practices:**

- Set appropriate min/max replicas to prevent excessive scaling
- Use HPA for variable load applications (web servers)
- Monitor metrics to tune autoscaling thresholds

**Common errors:**

- **unable to compute replica count**: Ensure metrics-server is running and metrics are available

### Updating and Rolling Back Deployments

Update application versions and manage rollouts

**Keywords:** update, rollout, rollback, strategy, revision

#### Update deployment images

```bash
# Update image in deployment
kubectl set image deployment/web-deployment nginx=nginx:1.22

# Update multiple containers
kubectl set image deployment/app app=myapp:v2 sidecar=sidecar:v1 --record

# Update from file
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
spec:
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.22
EOF

# Watch rollout progress
kubectl rollout status deployment/web-deployment
```

_exec_
```bash
kubectl set image deployment/web-deployment nginx=nginx:1.22
```

_output_
```bash
deployment.apps/web-deployment image updated
```

Updates deployment image to new version

- Triggers rolling update by default
- Old pods are gradually replaced with new version

#### Perform rolling updates and monitor progress

```bash
# Apply updated deployment
kubectl apply -f web-deployment.yaml

# Watch rollout status
kubectl rollout status deployment/web-deployment

# Check rollout history
kubectl rollout history deployment/web-deployment

# View specific revision details
kubectl rollout history deployment/web-deployment --revision=2

# Pause rollout if issues detected
kubectl rollout pause deployment/web-deployment

# Resume paused rollout
kubectl rollout resume deployment/web-deployment
```

_exec_
```bash
kubectl rollout status deployment/web-deployment
```

_output_
```bash
deployment "web-deployment" successfully rolled out
```

Monitors and controls rolling update process

- Pause allows verification before continuing update
- History shows all previous revisions

#### Rollback deployments to previous versions

```bash
# Rollback to previous revision
kubectl rollout undo deployment/web-deployment

# Rollback to specific revision
kubectl rollout undo deployment/web-deployment --to-revision=2

# Check rollback status
kubectl rollout status deployment/web-deployment

# Verify rollback with describe
kubectl describe deployment web-deployment

# Check pod images to confirm rollback
kubectl get pods -o wide
```

_exec_
```bash
kubectl rollout undo deployment/web-deployment
```

_output_
```bash
deployment.apps/web-deployment rolled back
```

Reverts deployment to previous working version

- Undo creates new ReplicaSet with old version
- Useful for quick recovery from bad deployments

**Best practices:**

- Use image tags (not latest) for tracking versions
- Test updates in staging before production
- Keep revision limit to manage history

**Common errors:**

- **no change**: New image must be different from current (use new tag)

## Service & Ingress

Expose applications with Services and Ingress

### Creating Services

Expose pods with ClusterIP, NodePort, and LoadBalancer services

**Keywords:** service, expose, clusterip, nodeport, loadbalancer

#### Create services imperatively

```bash
# Expose deployment as ClusterIP service
kubectl expose deployment web-deployment --type=ClusterIP --port=80

# Expose as NodePort service
kubectl expose deployment web-deployment --type=NodePort --port=80 --target-port=8080

# Expose as LoadBalancer service
kubectl expose deployment web-deployment --type=LoadBalancer --port=80

# List created services
kubectl get svc

# Get service details
kubectl describe svc web-deployment
```

_exec_
```bash
kubectl expose deployment web-deployment --type=ClusterIP --port=80
```

_output_
```bash
service/web-deployment exposed
```

Creates services to expose deployments within or outside cluster

- ClusterIP: internal only
- NodePort: accessible on node IP
- LoadBalancer: managed external IP

#### Create services with YAML

```bash
# Create ClusterIP service
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  type: ClusterIP
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
EOF

# Create NodePort service
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: web-nodeport
spec:
  type: NodePort
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 30080
EOF

# Create LoadBalancer service
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: web-lb
spec:
  type: LoadBalancer
  selector:
    app: web
  ports:
  - port: 80
    targetPort: 8080
EOF
```

_exec_
```bash
kubectl get svc
```

_output_
```bash
NAME          TYPE        CLUSTER-IP  PORT(S)
web-service   ClusterIP   10.0.0.1    80/TCP
```

Creates services declaratively with full control

- selector determines which pods receive traffic
- targetPort is container port, port is service port

#### List and inspect services

```bash
# List services
kubectl get svc

# List in all namespaces
kubectl get svc -A

# Get service endpoints
kubectl get endpoints

# Describe service details
kubectl describe svc web-service

# Get service YAML
kubectl get svc web-service -o yaml

# Watch for external IP (LoadBalancer)
kubectl get svc -w
```

_exec_
```bash
kubectl get svc -o wide
```

_output_
```bash
NAME          TYPE       SELECTOR   IP         EXTERNAL-IP
web-service   ClusterIP  app=web    10.0.0.1   <none>
```

Lists services and their endpoints

- Endpoints show which pods the service routes to
- EXTERNAL-IP may take time for LoadBalancer type

**Best practices:**

- Use ClusterIP initially, add external access only when needed
- Avoid NodePort in production; use LoadBalancer or Ingress
- Use label selectors to control pod membership

**Common errors:**

- **service not found/no endpoints**: Check selector matches pod labels with kubectl get pods --show-labels

### Setting up Ingress

Configure Ingress for HTTP/HTTPS routing

**Keywords:** ingress, routing, hostname, tls, ingress-controller

#### Create basic Ingress routes

```bash
# Create simple path-based Ingress
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
EOF

# List ingresses
kubectl get ingress

# Get Ingress IP address
kubectl get ingress -o wide
```

_exec_
```bash
kubectl get ingress
```

_output_
```bash
NAME          CLASS   HOSTS   ADDRESS       PORTS
web-ingress   nginx   *       192.168.1.1   80
```

Creates basic Ingress for routing HTTP traffic

- Requires Ingress Controller (nginx, traefik, etc.)
- Address is Ingress Controller's IP

#### Configure hostname-based routing

```bash
# Create host-based Ingress
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 8080
EOF
```

_exec_
```bash
kubectl describe ingress web-ingress
```

_output_
```bash
Name:             web-ingress
Rules:
  Host            Path Backends
  example.com     /    web-service:80
  api.example.com /    api-service:8080
```

Routes different hosts to different services

- Requires DNS pointing to Ingress IP
- Multiple rules for VHOST configuration

#### Configure TLS termination with Ingress

```bash
# Create TLS secret
kubectl create secret tls web-tls --cert=cert.pem --key=key.pem

# Create Ingress with TLS
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress-tls
spec:
  tls:
  - hosts:
    - example.com
      secretName: web-tls
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
EOF

# Verify TLS setup
kubectl describe ingress web-ingress-tls
```

_exec_
```bash
kubectl get secrets
```

_output_
```bash
NAME       TYPE                DATA   AGE
web-tls    kubernetes.io/tls   2      3m
```

Configures HTTPS/TLS termination for Ingress

- TLS certificate stored as Secret
- Ingress Controller terminates SSL

**Best practices:**

- Use Ingress for HTTP/HTTPS routing instead of NodePort
- Enable TLS for production Ingresses
- Use cert-manager with Let's Encrypt for automatic certificates

**Common errors:**

- **no ingress controller found**: Install Ingress Controller (nginx, traefik) first

### Port Forwarding and Debugging

Forward local ports to cluster resources for debugging

**Keywords:** port-forward, localhost, debug, testing

#### Forward local port to pod

```bash
# Forward local to pod
kubectl port-forward pod/web-pod 8000:80

# Forward with background process
kubectl port-forward pod/web-pod 8000:80 &

# Forward to specific pod in deployment
kubectl port-forward deployment/web-deployment 8000:80

# Forward with address binding
kubectl port-forward pod/web-pod 127.0.0.1:8000:80

# Forward random local port
kubectl port-forward pod/web-pod :80
```

_exec_
```bash
kubectl port-forward pod/web-pod 8000:80 &
```

_output_
```bash
Forwarding from 127.0.0.1:8000 -> 80
Forwarding from [::1]:8000 -> 80
```

Creates local port forward to pod

- Access pod at localhost:8000 from host
- Useful for testing without exposing service

#### Access services through port forwarding

```bash
# Forward to service
kubectl port-forward service/web-service 8000:80

# Forward to service in specific namespace
kubectl port-forward -n production service/db-service 5432:5432

# Forward multiple ports
kubectl port-forward pod/app 8000:8000 8080:8080

# Kill port forward
# Use Ctrl+C or kill process
ps aux | grep port-forward
kill <pid>
```

_exec_
```bash
kubectl port-forward service/web-service 8000:80
```

_output_
```bash
Forwarding from 127.0.0.1:8000 -> 80
```

Forwards to Service which routes to backend pods

- Service provides load balancing across pods
- Random pod is selected if multiple exist

**Best practices:**

- Use port-forward for temporary debugging only
- Use Services for permanent application access
- Close port-forward when done to free local ports

**Common errors:**

- **address already in use**: Kill existing process with same port or use different port

## Storage Management

Manage persistent storage with volumes and storage classes

### Persistent Volumes and Claims

Create and manage persistent storage

**Keywords:** pv, pvc, volume, storage, persistence

#### Create persistent volumes and claims

```bash
# Create Persistent Volume
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-001
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: manual
  hostPath:
    path: /data/pv-001
EOF

# Create Persistent Volume Claim
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-001
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: manual
  resources:
    requests:
      storage: 5Gi
EOF

# List PVs and PVCs
kubectl get pv
kubectl get pvc
```

_exec_
```bash
kubectl get pv,pvc
```

_output_
```bash
NAME     CAPACITY  ACCESSMODES  STATUS   CLAIM
pv-001   10Gi      RWO          Bound    default/pvc-001
```

Creates persistent storage volumes and claims

- PV is cluster resource, PVC is namespace resource
- Status Bound means PVC successfully claimed PV

#### Use volumes in pod specifications

```bash
# Create pod with PVC volume
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: data-app
spec:
  containers:
  - name: app
    image: busybox
    command: ['sleep', '3600']
    volumeMounts:
    - name: data-volume
      mountPath: /data
  volumes:
  - name: data-volume
    persistentVolumeClaim:
      claimName: pvc-001
EOF

# Verify PVC is mounted
kubectl get pod data-app -o yaml | grep -A5 volumes
```

_exec_
```bash
kubectl describe pod data-app | grep -A5 Mounts
```

_output_
```bash
Mounts:
  /data from data-volume (rw)
```

Mounts persistent volume in pod using PVC

- mountPath is where volume appears in container
- Volume must exist or pod will not start

#### Manage storage lifecycle

```bash
# Check PVC details
kubectl describe pvc pvc-001

# View PV details
kubectl describe pv pv-001

# Delete PVC
kubectl delete pvc pvc-001

# Delete PV
kubectl delete pv pv-001

# Check reclaim policy behavior
# - Retain: Keep PV after PVC deletion
# - Delete: Remove PV after PVC deletion
# - Recycle: Clear PV data (deprecated)
```

_exec_
```bash
kubectl describe pvc pvc-001
```

_output_
```bash
Name:          pvc-001
Status:        Bound
Volume:        pv-001
Capacity:      5Gi
```

Manages PV/PVC lifecycle and reclamation policies

- Reclaim policy determines what happens after PVC deletion
- Retain preserves data for manual recovery

**Best practices:**

- Use StorageClass for dynamic provisioning instead of manual PVs
- Set appropriate reclaim policies for your use case
- Monitor storage usage to prevent disk full

**Common errors:**

- **pod does not have permission to access volume**: Check volume access mode (RWO, RWX) and pod selector

### Storage Classes and Dynamic Provisioning

Use storage classes for dynamic volume provisioning

**Keywords:** storageclass, provisioner, dynamic, dynamic-provisioning

#### Create and list storage classes

```bash
# Create storage class
kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  iops: "3000"
  throughput: "125"
reclaimPolicy: Delete
allowVolumeExpansion: true
EOF

# List storage classes
kubectl get storageclass

# Set default storage class
kubectl patch storageclass fast-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
```

_exec_
```bash
kubectl get storageclass
```

_output_
```bash
NAME           PROVISIONER             RECLAIMPOLICY
fast-storage   kubernetes.io/aws-ebs   Delete
```

Creates storage classes for automatic volume provisioning

- Provisioner depends on cloud provider
- Parameters vary by provisioner

#### Use storage class in PVC

```bash
# Create PVC using storage class
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-storage
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-storage
  resources:
    requests:
      storage: 50Gi
EOF

# Monitor dynamic PV creation
kubectl get pv -w
```

_exec_
```bash
kubectl get pvc
```

_output_
```bash
NAME          STATUS   VOLUME         CAPACITY
app-storage   Bound    pvc-abc123     50Gi
```

Automatically provisions PV when PVC is created

- Storage class provisioner automatically creates PV
- No need to manually create PV first

#### Expand persistent volumes

```bash
# Edit PVC to increase size
kubectl patch pvc app-storage -p '{"spec":{"resources":{"requests":{"storage":"100Gi"}}}}'

# Or edit directly
kubectl edit pvc app-storage

# Monitor expansion progress
kubectl describe pvc app-storage

# Verify expansion in pod
kubectl exec -it <pod> -- df /data
```

_exec_
```bash
kubectl describe pvc app-storage
```

_output_
```bash
Name:          app-storage
Capacity:      100Gi
```

Expands PVC size without downtime

- allowVolumeExpansion must be true in StorageClass
- Some filesystems require filesystem expansion in pod

**Best practices:**

- Use storage classes for dynamic provisioning
- Set default storage class for convenience
- Enable volume expansion for flexibility

**Common errors:**

- **provisioner not found**: Ensure cloud provisioner is installed (CSI driver)

### Volume Types and EmptyDir

Use different volume types for various scenarios

**Keywords:** volume, emptydir, configmap, secret, hostpath

#### Use emptyDir and hostPath volumes

```bash
# Create pod with emptyDir and hostPath
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: app-with-volumes
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - name: cache
      mountPath: /cache
    - name: host-data
      mountPath: /host-data
  volumes:
  - name: cache
    emptyDir: {}
  - name: host-data
    hostPath:
      path: /data
      type: Directory
EOF
```

_exec_
```bash
kubectl get pod app-with-volumes -o yaml
```

_output_
```bash
volumes:
- name: cache
  emptyDir: {}
```

Uses emptyDir for temporary storage and hostPath for node access

- emptyDir deleted when pod terminates
- hostPath accesses node filesystem

#### Mount ConfigMaps and Secrets as volumes

```bash
# Create ConfigMap
kubectl create configmap app-config --from-literal=key1=value1

# Create Secret
kubectl create secret generic app-secret --from-literal=password=secret

# Create pod mounting both
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: app-with-config
spec:
  containers:
  - name: app
    image: busybox
    command: ['sleep', '3600']
    volumeMounts:
    - name: config
      mountPath: /etc/config
    - name: secret
      mountPath: /etc/secrets
  volumes:
  - name: config
    configMap:
      name: app-config
  - name: secret
    secret:
      secretName: app-secret
EOF
```

_exec_
```bash
kubectl get configmap,secret
```

_output_
```bash
NAME                 DATA   AGE
configmap/app-config 1      2m
```

Mounts ConfigMaps and Secrets as volumes

- ConfigMap/Secret updates appear in mounted files
- Good for configuration without pod restart

**Best practices:**

- Use ConfigMap/Secret volumes for configuration
- Use emptyDir for temporary pod data
- Avoid hostPath in production (not portable)

**Common errors:**

- **volume not found**: Ensure ConfigMap or Secret exists with correct name

## Security & RBAC

Secure cluster with authentication, authorization, and policies

### RBAC Roles and Bindings

Control access with Roles and RoleBindings

**Keywords:** rbac, role, rolebinding, serviceaccount, permission

#### Create RBAC roles and bindings

```bash
# Create service account
kubectl create serviceaccount app-sa -n development

# Create role with permissions
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: development
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods/logs"]
  verbs: ["get"]
EOF

# Create role binding
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-reader-binding
  namespace: development
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader
subjects:
- kind: ServiceAccount
  name: app-sa
  namespace: development
EOF

# List RBAC resources
kubectl get roles,rolebindings -n development
```

_exec_
```bash
kubectl get serviceaccounts,roles,rolebindings -n development
```

_output_
```bash
NAME                     SECRETS   AGE
serviceaccount/app-sa    1         2m
NAME                 CREATED AT
role.rbac...pod-reader  2m
```

Creates RBAC roles and grants permissions to service accounts

- verbs define allowed actions (get, list, create, delete)
- apiGroups depend on resource type (empty = core API)

#### Create ClusterRoles for cluster-wide permissions

```bash
# Create cluster role
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-reader
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["nodes/stats"]
  verbs: ["get"]
EOF

# Create cluster role binding
kubectl apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-reader-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: node-reader
subjects:
- kind: ServiceAccount
  name: monitoring-sa
  namespace: monitoring
EOF
```

_exec_
```bash
kubectl get clusterroles,clusterrolebindings
```

_output_
```bash
NAME                                           CREATED AT
clusterrole.rbac.../monitoring-binding     2m
```

Grants cluster-wide permissions across all namespaces

- ClusterRole is cluster-scoped, not namespace-scoped
- Use for cluster admins and system components

#### Check permissions and debug RBAC

```bash
# Check what user can do
kubectl auth can-i get pods -n development --as=system:serviceaccount:development:app-sa

# Check multiple permissions
kubectl auth can-i create deployments -n default
kubectl auth can-i delete pods -n default

# List all role bindings for user
kubectl get rolebinding,clusterrolebinding -A

# Describe role to see permissions
kubectl describe role pod-reader -n development
```

_exec_
```bash
kubectl auth can-i get pods --as=system:serviceaccount:development:app-sa
```

_output_
```bash
yes
```

Verifies RBAC permissions and troubleshoots access issues

- can-i helps verify permissions before assigning access
- Format: system:serviceaccount:namespace:name

**Best practices:**

- Follow least privilege principle (minimum needed permissions)
- Use namespace-scoped Roles instead of ClusterRole when possible
- Regularly audit and review RBAC configuration

**Common errors:**

- **forbidden - user cannot get pods**: Create appropriate Role/RoleBinding for the user

### Network Policies

Control network traffic with network policies

**Keywords:** networkpolicy, ingress, egress, network, traffic

#### Create network policies for traffic control

```bash
# Create deny-all network policy
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
EOF

# Create allow policy for specific pods
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-traffic
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 80
EOF
```

_exec_
```bash
kubectl get networkpolicies -n production
```

_output_
```bash
NAME               POD-SELECTOR   AGE
deny-all           <none>         2m
allow-web-traffic  app=web        1m
```

Creates network policies to restrict traffic

- NetworkPolicy requires network plugin with support
- podSelector: {} matches all pods

#### Configure egress policies

```bash
# Allow specific egress traffic
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Egress
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: UDP
      port: 53
EOF
```

_exec_
```bash
kubectl describe networkpolicy allow-egress -n production
```

_output_
```bash
Name:         allow-egress
Namespace:    production
Egress:
  To: app=database, port: 5432
```

Restricts outbound traffic from pods

- Egress allows specifying allowed destination pods
- DNS access usually required for pod-to-pod communication

**Best practices:**

- Start with deny-all policy, then add allowed traffic
- Use network policies to enforce security boundaries
- Test policies before production deployment

**Common errors:**

- **network policy not working**: Verify network plugin supports NetworkPolicy (Calico, Weave)

### Secrets and Secret Management

Securely store and manage sensitive data

**Keywords:** secret, sensitive, password, token, encryption

#### Create and manage secrets

```bash
# Create secret from literals
kubectl create secret generic db-secret \
  --from-literal=user=admin \
  --from-literal=password=secretpass

# Create secret from file
kubectl create secret generic app-config \
  --from-file=config.yaml

# Create docker registry secret
kubectl create secret docker-registry regcred \
  --docker-server=myregistry.com \
  --docker-username=user \
  --docker-password=pass

# List secrets
kubectl get secrets
```

_exec_
```bash
kubectl get secrets
```

_output_
```bash
NAME         TYPE                  DATA   AGE
db-secret    Opaque                2      2m
app-config   Opaque                1      1m
```

Creates secrets to store sensitive data

- Secrets are base64-encoded, not encrypted by default
- Consider using encryption at rest in production

#### Use secrets in pod specifications

```bash
# Create pod using secret as environment variables
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: app-with-secret
spec:
  containers:
  - name: app
    image: myapp
    env:
    - name: DB_USER
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: user
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
  imagePullSecrets:
  - name: regcred
EOF

# Verify secret is applied
kubectl describe pod app-with-secret
```

_exec_
```bash
kubectl get pod app-with-secret -o yaml
```

_output_
```bash
env:
- name: DB_USER
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: user
```

Uses secrets as environment variables in pods

- imagePullSecrets for private registry authentication
- Secret data injected at runtime

#### View and update secrets

```bash
# View decoded secret
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d

# Edit secret
kubectl edit secret db-secret

# Delete secret
kubectl delete secret db-secret

# Get secret as YAML
kubectl get secret db-secret -o yaml
```

_exec_
```bash
kubectl describe secret db-secret
```

_output_
```bash
Name:         db-secret
Type:         Opaque
Data
user:    5 bytes
password: 10 bytes
```

Views and manages secrets

- Base64 decoding shows actual values
- Be careful with secret exposure in logs

**Best practices:**

- Use encrypted storage for secrets at rest
- Limit secret access with RBAC
- Rotate secrets regularly

**Common errors:**

- **secret not found**: Verify secret exists and is in same namespace

## Advanced Operations

Logging, debugging, resource management, and advanced queries

### Logging and Debugging

Collect and analyze logs for troubleshooting

**Keywords:** logs, debug, troubleshoot, events, tracing

#### Advanced logging and filtering

```bash
# Get logs from all containers in pod
kubectl logs pod-name --all-containers=true

# Get logs from previous pod instance
kubectl logs pod-name --previous

# Stream logs with timestamps
kubectl logs pod-name --timestamps=true -f

# Get logs from specific time range
kubectl logs pod-name --since=1h
kubectl logs pod-name --since-time='2025-02-28T10:00:00Z'

# Get logs from multiple pods
kubectl logs -f -l app=web --max-log-requests=10

# Tail specific number of lines
kubectl logs pod-name --tail=100
```

_exec_
```bash
kubectl logs -f pod-name --tail=50
```

_output_
```bash
2025-02-28T10:30:01.123Z INFO Starting application
2025-02-28T10:30:02.456Z INFO Connected to database
```

Gets detailed logs with filtering and streaming

- -f flag streams logs in real-time
- --previous useful for crashed containers

#### Describe and inspect resources for debugging

```bash
# Get full resource details
kubectl describe pod pod-name

# Get resource events
kubectl get events

# Watch resource for changes
kubectl get pods --watch

# Get events for specific resource
kubectl get events --field-selector involvedObject.name=pod-name

# Describe deployment to see replica status
kubectl describe deployment web-deployment

# Check resource conditions
kubectl get pod pod-name -o jsonpath='{.status.conditions}' | jq .
```

_exec_
```bash
kubectl describe pod pod-name
```

_output_
```bash
Name:         pod-name
Status:       Running
Conditions:
  Type    Status  Reason
  Ready   True    ContainersReady
```

Examines resource details and troubleshoots issues

- Events show resource state changes
- Conditions show readiness and health status

#### Advanced debugging with temporary containers

```bash
# Create debug container in running pod
kubectl debug pod-name -it --image=busybox

# Debug specific container
kubectl debug pod-name -c container-name -it --image=busybox

# Debug with node access
kubectl debug node/node-name -it --image=ubuntu

# Create copy of pod for debugging
kubectl debug pod-name -it --copy-to=debug-pod

# Share process namespace for debugging
kubectl debug pod-name --target=container-name
```

_exec_
```bash
kubectl debug pod-name -it --image=busybox
```

_output_
```bash
Debugger started, running in pod-name ephemeral-debug-xyz
/ #
```

Creates temporary debugging containers

- Debug containers have tools for troubleshooting
- Copy-to creates standalone pod for destructive testing

**Best practices:**

- Check logs first when diagnosing pod issues
- Use describe to view pod events and conditions
- Create debug containers instead of modifying production pods

**Common errors:**

- **not found**: Verify pod you're debugging still exists

### JSONPath Queries and Output Formatting

Extract specific data with JSONPath queries

**Keywords:** jsonpath, query, extract, formatting, filter

#### Extract data with JSONPath

```bash
# Get pod names
kubectl get pods -o jsonpath='{.items[*].metadata.name}'

# Get pod IPs
kubectl get pods -o jsonpath='{.items[*].status.podIP}'

# Get image names from deployment
kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[*].image}'

# Get container names and images
kubectl get pods -o jsonpath='{.items[*].spec.containers[*].name}'

# Format output with custom columns
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\n"}{end}'
```

_exec_
```bash
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
```

_output_
```bash
pod1 pod2 pod3
```

Extracts specific fields using JSONPath syntax

- jsonpath is powerful for extracting nested data
- Can combine with other tools like awk

#### Custom columns and wide output

```bash
# Define custom columns
kubectl get pods \
  -o custom-columns=NAME:.metadata.name,READY:.status.conditions[?(@.type=="Ready")].status,IMAGE:.spec.containers[0].image,IP:.status.podIP

# Format with custom columns shorthand
kubectl get pods --sort-by=.metadata.creationTimestamp

# Get pods with sorted output
kubectl get pods --sort-by='{.status.phase}'

# Wide format (standard custom columns)
kubectl get pods -o wide
```

_exec_
```bash
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,IP:.status.podIP
```

_output_
```bash
NAME        STATUS    IP
pod1        Running   10.244.0.1
pod2        Running   10.244.0.2
```

Creates custom output columns for better readability

- Custom columns can format complex nested data
- Sorting by specific fields helps organize output

#### Complex JSONPath queries with filters

```bash
# Get pods that are currently running
kubectl get pods -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}'

# Get pods with specific label
kubectl get pods -o jsonpath='{.items[?(@.metadata.labels.tier=="web")].metadata.name}'

# Get containers with specific resource requests
kubectl get pods -o jsonpath='{.items[?(@.spec.containers[0].resources.requests.cpu)].metadata.name}'

# Format with line breaks for readability
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.phase}{"\t"}{.status.podIP}{"\n"}{end}'
```

_exec_
```bash
kubectl get pods -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}'
```

_output_
```bash
pod1 pod3
```

Filters resources based on conditions in JSONPath

- Filter expressions use @.field syntax
- Complex queries can extract specific information

**Best practices:**

- Use JSONPath for scripting and automation
- Custom columns improve readability of output
- Combine with grep/awk for further filtering

**Common errors:**

- **unable to parse query**: Check JSONPath syntax and verify field paths exist

### Dry-Run and Testing Patterns

Test changes before applying with dry-run

**Keywords:** dry-run, test, validation, preview, simulation

#### Preview changes with dry-run

```bash
# Preview pod creation
kubectl run test-pod --image=nginx --dry-run=client -o yaml

# Preview deployment creation
kubectl create deployment web --image=nginx --dry-run=server -o yaml

# Preview manifest application
kubectl apply -f deployment.yaml --dry-run=client

# Apply with server-side validation
kubectl apply -f deployment.yaml --dry-run=server

# Save dry-run output for review
kubectl apply -f - --dry-run=client -o yaml > deployment-preview.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:latest
EOF
```

_exec_
```bash
kubectl apply -f deployment.yaml --dry-run=client
```

_output_
```bash
deployment.apps/web created (dry run)
```

Tests manifest application without creating resources

- client: validates locally, server: validates on server
- Useful for checking YAML syntax before applying

#### Validate resources and configurations

```bash
# Validate YAML syntax
kubectl apply -f deployment.yaml --dry-run=server

# Check if resource would be created
kubectl create deployment test --image=alpine --dry-run=client

# Validate all manifests in directory
kubectl apply -f ./manifests/ --dry-run=server

# Test with specific namespace
kubectl apply -f deployment.yaml --namespace=test --dry-run=client

# Get validation details
kubectl apply -f deployment.yaml --dry-run=server -o yaml
```

_exec_
```bash
kubectl apply -f deployment.yaml --dry-run=server -o jsonpath='{.metadata.name}'
```

_output_
```bash
web
```

Validates manifests before actual deployment

- Server-side dry-run catches API errors
- Good for CI/CD pipeline validation

#### Test resource limits and constraints

```bash
# Create pod with resource limits to test
kubectl apply -f - --dry-run=server <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: resource-test
spec:
  containers:
  - name: app
    image: myapp
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 500m
        memory: 512Mi
EOF

# Check if quota allows creation
kubectl apply -f deployment.yaml --dry-run=server --validate=strict

# Test PVC binding
kubectl apply -f pvc.yaml --dry-run=server
```

_exec_
```bash
echo '{"apiVersion":"v1","kind":"Pod","metadata":{"name":"test"},"spec":{"containers":[{"name":"app","image":"nginx"}]}}' | kubectl apply -f - --dry-run=server --validate=strict
```
