Appearance
GKE Workloads Guide
Complete guide to deploying and managing workloads in Google Kubernetes Engine (GKE), covering Deployments, StatefulSets, DaemonSets, Jobs, and CronJobs.
Workload Types Overview
Workload Selection Guide
| Workload Type | Use Case | Examples |
|---|---|---|
| Deployment | Stateless apps, web servers, APIs | nginx, REST APIs, microservices |
| StatefulSet | Databases, queues, stateful apps | PostgreSQL, Redis, Kafka |
| DaemonSet | Node-level services, agents | Log collectors, monitoring agents |
| Job | One-time tasks, batch processing | Data migrations, reports |
| CronJob | Scheduled tasks | Backups, cleanup, reports |
Deployments
The most common way to run stateless applications.
Basic Deployment
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5Rolling Update Strategy
yaml
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Max pods over desired count
maxUnavailable: 0 # Max pods unavailable during updateUpdate Deployment
bash
# Update image
kubectl set image deployment/my-app app=my-app:2.0.0
# Check rollout status
kubectl rollout status deployment/my-app
# View history
kubectl rollout history deployment/my-app
# Rollback to previous
kubectl rollout undo deployment/my-app
# Rollback to specific revision
kubectl rollout undo deployment/my-app --to-revision=2StatefulSets
For applications requiring stable identity and persistent storage.
StatefulSet Features
| Feature | Description |
|---|---|
| Stable network ID | pod-0, pod-1, pod-2 naming |
| Ordered deployment | Pods created 0, 1, 2... |
| Ordered termination | Pods deleted ...2, 1, 0 |
| Stable storage | PVC per Pod survives rescheduling |
StatefulSet Example
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres-headless
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
ports:
- containerPort: 5432
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard-rwo
resources:
requests:
storage: 10GiHeadless Service for StatefulSet
yaml
apiVersion: v1
kind: Service
metadata:
name: postgres-headless
spec:
clusterIP: None # Headless
selector:
app: postgres
ports:
- port: 5432DNS records created:
postgres-0.postgres-headless.namespace.svc.cluster.localpostgres-1.postgres-headless.namespace.svc.cluster.localpostgres-2.postgres-headless.namespace.svc.cluster.local
DaemonSets
Run a Pod on every (or selected) nodes.
DaemonSet Use Cases
| Use Case | Example |
|---|---|
| Log collection | Fluentd, Filebeat |
| Monitoring | Node exporter, Datadog agent |
| Networking | CNI plugins, kube-proxy |
| Storage | CSI node plugins |
DaemonSet Example
yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
spec:
selector:
matchLabels:
app: log-collector
template:
metadata:
labels:
app: log-collector
spec:
tolerations:
# Run on all nodes including control plane
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd:v1.16
resources:
requests:
cpu: 100m
memory: 200Mi
limits:
cpu: 200m
memory: 400Mi
volumeMounts:
- name: varlog
mountPath: /var/log
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/logRun on Specific Nodes
yaml
spec:
template:
spec:
nodeSelector:
node-type: gpu # Only on GPU nodesJobs
Run a task to completion.
Job Types
| Pattern | completions | parallelism | Use Case |
|---|---|---|---|
| Single | 1 | 1 | One-time task |
| Parallel fixed | N | N | Process N items |
| Work queue | unset | N | Process until queue empty |
Basic Job
yaml
apiVersion: batch/v1
kind: Job
metadata:
name: data-migration
spec:
completions: 1
parallelism: 1
backoffLimit: 3
activeDeadlineSeconds: 600
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: my-migration:1.0
command: ["python", "migrate.py"]Parallel Job
yaml
apiVersion: batch/v1
kind: Job
metadata:
name: batch-processor
spec:
completions: 10 # Total completions needed
parallelism: 5 # Run 5 at a time
backoffLimit: 3
template:
spec:
restartPolicy: Never
containers:
- name: processor
image: my-processor:1.0Job Commands
bash
# View jobs
kubectl get jobs
# View job pods
kubectl get pods --selector=job-name=data-migration
# View job logs
kubectl logs job/data-migration
# Delete completed jobs
kubectl delete jobs --field-selector status.successful=1CronJobs
Run Jobs on a schedule.
Cron Schedule Format
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23)
│ │ ┌───────────── day of month (1 - 31)
│ │ │ ┌───────────── month (1 - 12)
│ │ │ │ ┌───────────── day of week (0 - 6)
│ │ │ │ │
* * * * *| Schedule | Description |
|---|---|
0 * * * * | Every hour |
0 0 * * * | Daily at midnight |
0 0 * * 0 | Weekly on Sunday |
*/15 * * * * | Every 15 minutes |
0 9-17 * * 1-5 | 9 AM-5 PM, Mon-Fri |
CronJob Example
yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-job
spec:
schedule: "0 2 * * *" # Daily at 2 AM
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: backup-tool:1.0
command: ["./backup.sh"]
env:
- name: BACKUP_BUCKET
value: gs://my-backupsConcurrency Policies
| Policy | Behavior |
|---|---|
| Allow | Multiple jobs can run concurrently |
| Forbid | Skip if previous job still running |
| Replace | Cancel running job, start new |
Pod Configuration Best Practices
Resource Requests and Limits
yaml
containers:
- name: app
resources:
requests:
cpu: 100m # 0.1 CPU cores
memory: 128Mi # 128 MiB
limits:
cpu: 500m # 0.5 CPU cores
memory: 512Mi # 512 MiBHealth Checks
yaml
containers:
- name: app
# Is the container alive?
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
# Is the container ready for traffic?
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
# Has the container started?
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30
periodSeconds: 10Pod Disruption Budgets
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 2 # Or use maxUnavailable
selector:
matchLabels:
app: my-appQuick Reference
Common Commands
bash
# Deployments
kubectl get deployments
kubectl describe deployment my-app
kubectl scale deployment my-app --replicas=5
kubectl rollout restart deployment my-app
# StatefulSets
kubectl get statefulsets
kubectl scale statefulset postgres --replicas=3
# DaemonSets
kubectl get daemonsets
kubectl rollout status daemonset log-collector
# Jobs
kubectl get jobs
kubectl delete job my-job
# CronJobs
kubectl get cronjobs
kubectl create job manual-run --from=cronjob/backup-jobWorkload Comparison
Last updated: December 2025