# Workloads

Source: https://docs.ops0.com/docs/kubernetes/workloads

Manage all Kubernetes workload types: StatefulSets, DaemonSets, Jobs, CronJobs, and ReplicaSets.

## Workload Types

StatefulSets

Ordered, stable pods with persistent identities (databases, queues)

DaemonSets

Run one pod per node (monitoring agents, log collectors)

Jobs

Run pods to completion (batch processing, migrations)

CronJobs

Scheduled jobs (backups, reports, cleanup tasks)

---

## StatefulSets

Manage stateful applications with ordered pod creation and stable network identities.

### StatefulSet Features

| Feature | Description |
|---------|-------------|
| **Ordered Deployment** | Pods created sequentially (pod-0, pod-1, pod-2) |
| **Stable Network IDs** | Each pod gets predictable DNS name |
| **Persistent Storage** | PVCs follow pod across reschedules |
| **Ordered Scaling** | Scale up/down maintains order |

### Viewing StatefulSets

| Column | Description |
|--------|-------------|
| **Name** | StatefulSet name |
| **Namespace** | Kubernetes namespace |
| **Replicas** | Desired / Current / Ready |
| **Age** | Time since creation |

### StatefulSet Details

- Pod list showing ordered names (pod-0, pod-1, pod-2)
- PVC bindings per pod
- Service association
- Update strategy (RollingUpdate or OnDelete)

### Scaling StatefulSets

1. Open StatefulSet detail
2. Adjust replica count
3. Click "Scale"
4. Pods added/removed in reverse order

**Scaling Behavior**:
- Scale up: Creates pod-N, waits for Ready, creates pod-N+1
- Scale down: Deletes pod-N, waits for termination, deletes pod-N-1

### Restarting StatefulSets

Perform rolling restart:
1. Click "Restart"
2. Pods restart in reverse order (highest to lowest)
3. Each pod must be Ready before next restarts

---

## DaemonSets

Run exactly one pod on every node (or subset of nodes with selectors).

### DaemonSet Features

| Feature | Description |
|---------|-------------|
| **Node Coverage** | One pod per node automatically |
| **Automatic Scheduling** | New nodes get pod automatically |
| **Node Selectors** | Target specific node labels |
| **Tolerate Taints** | Run on tainted nodes (e.g., master) |

### Viewing DaemonSets

| Column | Description |
|--------|-------------|
| **Name** | DaemonSet name |
| **Namespace** | Kubernetes namespace |
| **Desired** | Pods that should exist |
| **Current** | Pods currently running |
| **Ready** | Pods passing readiness checks |
| **Nodes** | Nodes covered |

### DaemonSet Details

- Pod distribution across nodes
- Node selector rules
- Update strategy (RollingUpdate or OnDelete)
- Tolerations configured

### Common DaemonSet Uses

| Use Case | Example |
|----------|---------|
| **Log Collection** | Fluentd, Filebeat running on every node |
| **Monitoring** | Node exporter, metrics collectors |
| **Networking** | CNI plugins, kube-proxy |
| **Security** | Security agents, compliance scanners |

### Restarting DaemonSets

Rolling restart across all nodes:
1. Click "Restart"
2. Pods restart node-by-node
3. Max unavailable controls rollout speed

---

## Jobs

Run pods to completion for batch processing tasks.

### Job Features

| Feature | Description |
|---------|-------------|
| **Completions** | Number of successful pod completions required |
| **Parallelism** | Number of pods running concurrently |
| **Retries** | Automatic restart on failure (backoffLimit) |
| **TTL After Finished** | Auto-delete completed jobs |

### Viewing Jobs

| Column | Description |
|--------|-------------|
| **Name** | Job name |
| **Namespace** | Kubernetes namespace |
| **Completions** | Successful / Desired |
| **Duration** | Time since start or completion time |
| **Age** | Time since creation |

### Job Details

- Pod list (completed and failed pods)
- Completion status
- Active pods
- Failed pod count
- Conditions (Complete, Failed)

### Job Status

| Status | Meaning |
|--------|---------|
| **Running** | Pods actively executing |
| **Complete** | Required completions reached |
| **Failed** | Exceeded backoff limit |

### Deleting Jobs

1. Click "Delete" on job
2. Confirm deletion
3. Job and all pods removed

**Note**: Completed job pods remain until job is deleted (for log inspection).

---

## CronJobs

Schedule recurring jobs using cron syntax.

### CronJob Features

| Feature | Description |
|---------|-------------|
| **Cron Schedule** | Standard cron syntax (0 2 * * *) |
| **Concurrency Policy** | Allow, Forbid, or Replace concurrent jobs |
| **Suspend** | Pause scheduling without deleting |
| **Job History** | Keeps last N successful and failed jobs |

### Viewing CronJobs

| Column | Description |
|--------|-------------|
| **Name** | CronJob name |
| **Namespace** | Kubernetes namespace |
| **Schedule** | Cron expression |
| **Suspend** | Whether scheduling is paused |
| **Last Schedule** | Time of last job creation |
| **Active Jobs** | Currently running jobs |

### CronJob Details

- Schedule and next run time
- Job history (last 5 runs)
- Active jobs
- Concurrency policy
- Suspend status

### Triggering CronJobs Manually

Run job immediately without waiting for schedule:
1. Click "Trigger Now"
2. New job created with timestamp suffix
3. Job runs like scheduled execution

### Suspending CronJobs

Pause scheduling temporarily:
1. Click "Suspend"
2. No new jobs created
3. Active jobs continue running
4. Click "Resume" to restart scheduling

### Common CronJob Schedules

| Schedule | Description |
|----------|-------------|
| `0 2 * * *` | Daily at 2:00 AM |
| `0 */6 * * *` | Every 6 hours |
| `0 0 * * 0` | Weekly on Sunday at midnight |
| `0 0 1 * *` | Monthly on the 1st |
| `*/15 * * * *` | Every 15 minutes |

---

## ReplicaSets

Manage identical pod replicas (usually controlled by Deployments).

### ReplicaSet Features

| Feature | Description |
|---------|-------------|
| **Pod Replicas** | Maintains desired number of pod copies |
| **Label Selector** | Identifies pods to manage |
| **Owner References** | Usually owned by Deployment |

### Viewing ReplicaSets

| Column | Description |
|--------|-------------|
| **Name** | ReplicaSet name (usually deployment-hash) |
| **Namespace** | Kubernetes namespace |
| **Replicas** | Desired / Current / Ready |
| **Deployment** | Parent deployment (if any) |
| **Age** | Time since creation |

### When to Use

**Deployments create ReplicaSets automatically** - you rarely manage ReplicaSets directly.

**Direct ReplicaSet use cases**:
- Custom controllers
- Advanced deployment strategies
- Legacy applications migrating from ReplicationControllers

### Scaling ReplicaSets

1. Open ReplicaSet detail
2. Adjust replica count
3. Click "Scale"

**Warning**: If owned by Deployment, Deployment will override this change.

---

## HorizontalPodAutoscalers (HPA)

HPAs automatically scale workloads up or down based on CPU, memory, or custom metrics.

### Viewing HPAs

Navigate to **Kubernetes → [cluster] → Workloads → HPAs** to see all HPAs in the cluster.

| Column | Description |
|--------|-------------|
| **Name** | HPA name |
| **Namespace** | Kubernetes namespace |
| **Target** | The Deployment or StatefulSet being scaled |
| **Min Replicas** | Minimum pod count |
| **Max Replicas** | Maximum pod count |
| **Current Replicas** | Current live pod count |
| **Current Metrics** | Live CPU/memory utilization vs target |

### HPA Detail

Click an HPA to see the current scaling conditions and event history — useful for understanding why the HPA is not scaling when expected.

| Field | Description |
|-------|-------------|
| **Scale target** | Workload being autoscaled |
| **Min / Max** | Pod count bounds |
| **Target utilization** | CPU or memory threshold that triggers scaling |
| **Current utilization** | Real-time metric value |
| **Last scale time** | When scaling last occurred |
| **Conditions** | HPA controller conditions (AbleToScale, ScalingActive, etc.) |

**HPA requires metrics-server**

HPAs that scale on CPU or memory need the Kubernetes metrics-server installed in the cluster. Without it the HPA will show `ScalingActive: False` due to missing metrics.

---

## PodDisruptionBudgets (PDB)

PDBs protect workloads during voluntary disruptions — node drains, cluster upgrades, rolling restarts — by limiting how many pods of a workload can be unavailable at once.

### Viewing PDBs

Navigate to **Kubernetes → [cluster] → Workloads → PDBs**.

| Column | Description |
|--------|-------------|
| **Name** | PDB name |
| **Namespace** | Kubernetes namespace |
| **Selector** | Which pods this PDB applies to |
| **Min Available** | Minimum pods that must stay running |
| **Max Unavailable** | Maximum pods that may be disrupted |
| **Current Healthy** | Currently healthy pods matching the selector |
| **Desired Healthy** | Minimum required healthy pods |
| **Disruptions Allowed** | How many more pods can be disrupted right now |

### Why PDBs Matter

If a drain or upgrade would violate a PDB, Kubernetes will block the eviction until the constraint can be satisfied. This prevents accidental total outage during maintenance — but it also means drains can get stuck if a PDB is misconfigured (e.g. `minAvailable: 100%` on a single-replica workload).

---

## Example: Managing a StatefulSet

### StatefulSet Overview

```
StatefulSet: postgresql
Namespace:   production
Replicas:    3/3
Strategy:    RollingUpdate
```

### Pod List

| Pod | Status | PVC | Ready | Age |
|-----|--------|-----|-------|-----|
| postgresql-0 | Running | data-postgresql-0 | True | 45d |
| postgresql-1 | Running | data-postgresql-1 | True | 45d |
| postgresql-2 | Running | data-postgresql-2 | True | 30d |

### Scaling from 3 to 5

**Scale-Up Process**:
```
10:30:00  Scaling postgresql from 3 to 5 replicas
10:30:01  Creating pod postgresql-3
10:30:02  Creating PVC data-postgresql-3
10:30:15  Pod postgresql-3 Running and Ready
10:30:16  Creating pod postgresql-4
10:30:17  Creating PVC data-postgresql-4
10:30:30  Pod postgresql-4 Running and Ready
10:30:30  StatefulSet successfully scaled to 5 replicas
```

### After Scaling

```
StatefulSet: postgresql
Namespace:   production
Replicas:    5/5
Pods:        postgresql-0 (Running)
             postgresql-1 (Running)
             postgresql-2 (Running)
             postgresql-3 (Running)
             postgresql-4 (Running)
```

---

## Example: DaemonSet Monitoring

### DaemonSet Overview

```
DaemonSet: node-exporter
Namespace: monitoring
Nodes:     12
Desired:   12
Current:   12
Ready:     12
```

### Node Distribution

| Node | Pod | Status | Ready | CPU | Memory |
|------|-----|--------|-------|-----|--------|
| node-1 | node-exporter-abc12 | Running | True | 50m | 100Mi |
| node-2 | node-exporter-def34 | Running | True | 48m | 98Mi |
| node-3 | node-exporter-ghi56 | Running | True | 52m | 102Mi |
| ... | ... | ... | ... | ... | ... |

### Rolling Restart

**Restart Process**:
```
10:45:00  Restarting DaemonSet node-exporter
10:45:01  Terminating pod on node-1
10:45:15  New pod on node-1 Running and Ready
10:45:16  Terminating pod on node-2
10:45:30  New pod on node-2 Running and Ready
...
10:50:00  All 12 pods restarted successfully
```

---

## Example: CronJob Backup

### CronJob Configuration

```
CronJob:     database-backup
Namespace:   production
Schedule:    0 2 * * *  (Daily at 2:00 AM)
Suspend:     False
Concurrency: Forbid
```

### Job History

| Job | Start Time | Completion | Duration | Status |
|-----|------------|------------|----------|--------|
| database-backup-20240115 | 2024-01-15 02:00:00 | 2024-01-15 02:15:00 | 15m | Complete |
| database-backup-20240114 | 2024-01-14 02:00:00 | 2024-01-14 02:12:00 | 12m | Complete |
| database-backup-20240113 | 2024-01-13 02:00:00 | 2024-01-13 02:18:00 | 18m | Complete |
| database-backup-20240112 | 2024-01-12 02:00:00 | - | - | Failed |

### Manual Trigger

Trigger backup immediately for testing:
1. Click "Trigger Now" on database-backup
2. New job created: database-backup-manual-20240115-103000
3. Job runs with same configuration as scheduled execution

**Result**:
```
Job: database-backup-manual-20240115-103000
Status: Running
Active Pods: 1
Duration: 5m 30s
```

---

## Troubleshooting

StatefulSet Pod Stuck

Check PVC binding status. StatefulSets wait for PVCs to bind before creating pods. Verify StorageClass exists and has available capacity.

DaemonSet Not Scheduling

Check node taints and DaemonSet tolerations. Verify node selectors match actual node labels. Review pod events for scheduling failures.

Job Failed

Check pod logs for failure reason. Verify backoffLimit is appropriate. Review pod events for resource constraints or image pull issues.

CronJob Not Running

Verify CronJob is not suspended. Check cron schedule syntax is valid. Review CronJob events for scheduling errors or concurrency policy conflicts.

Best Practices

• **StatefulSets** - Use headless services for stable network identities, set appropriate update strategies

• **DaemonSets** - Configure resource limits to prevent node exhaustion, use update strategies carefully

• **Jobs** - Set appropriate backoffLimit and activeDeadlineSeconds to prevent infinite retries

• **CronJobs** - Use Forbid concurrency policy for tasks that shouldn't overlap, set job history limits

• **ReplicaSets** - Use Deployments instead for most use cases, only manage directly for advanced scenarios
