Skip to content

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 TypeUse CaseExamples
DeploymentStateless apps, web servers, APIsnginx, REST APIs, microservices
StatefulSetDatabases, queues, stateful appsPostgreSQL, Redis, Kafka
DaemonSetNode-level services, agentsLog collectors, monitoring agents
JobOne-time tasks, batch processingData migrations, reports
CronJobScheduled tasksBackups, 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: 5

Rolling Update Strategy

yaml
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Max pods over desired count
      maxUnavailable: 0  # Max pods unavailable during update

Update 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=2

StatefulSets

For applications requiring stable identity and persistent storage.

StatefulSet Features

FeatureDescription
Stable network IDpod-0, pod-1, pod-2 naming
Ordered deploymentPods created 0, 1, 2...
Ordered terminationPods deleted ...2, 1, 0
Stable storagePVC 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: 10Gi

Headless Service for StatefulSet

yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres-headless
spec:
  clusterIP: None  # Headless
  selector:
    app: postgres
  ports:
  - port: 5432

DNS records created:

  • postgres-0.postgres-headless.namespace.svc.cluster.local
  • postgres-1.postgres-headless.namespace.svc.cluster.local
  • postgres-2.postgres-headless.namespace.svc.cluster.local

DaemonSets

Run a Pod on every (or selected) nodes.

DaemonSet Use Cases

Use CaseExample
Log collectionFluentd, Filebeat
MonitoringNode exporter, Datadog agent
NetworkingCNI plugins, kube-proxy
StorageCSI 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/log

Run on Specific Nodes

yaml
spec:
  template:
    spec:
      nodeSelector:
        node-type: gpu  # Only on GPU nodes

Jobs

Run a task to completion.

Job Types

PatterncompletionsparallelismUse Case
Single11One-time task
Parallel fixedNNProcess N items
Work queueunsetNProcess 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.0

Job 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=1

CronJobs

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)
│ │ │ │ │
* * * * *
ScheduleDescription
0 * * * *Every hour
0 0 * * *Daily at midnight
0 0 * * 0Weekly on Sunday
*/15 * * * *Every 15 minutes
0 9-17 * * 1-59 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-backups

Concurrency Policies

PolicyBehavior
AllowMultiple jobs can run concurrently
ForbidSkip if previous job still running
ReplaceCancel 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 MiB

Health 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: 10

Pod Disruption Budgets

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-app-pdb
spec:
  minAvailable: 2  # Or use maxUnavailable
  selector:
    matchLabels:
      app: my-app

Quick 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-job

Workload Comparison


Last updated: December 2025

Built with VitePress & Mermaid diagrams