DevOpsil
GCP
92%
Needs Review

GKE Autopilot: Serverless Kubernetes on Google Cloud

Amara OkaforAmara Okafor6 min read

GKE Autopilot: Serverless Kubernetes on Google Cloud

GKE Standard gives you full control over nodes — and full responsibility for managing, patching, and right-sizing them. GKE Autopilot flips that model: you deploy workloads, Google manages the infrastructure. No node pools to configure, no OS patches to apply, no idle node costs.

But Autopilot isn't just Standard with managed nodes. It has meaningful differences in how billing works, what's allowed, and how you write your manifests. This guide covers what you actually need to know to run production workloads on it.

Autopilot vs Standard: The Real Differences

FeatureAutopilotStandard
Node managementGoogle-managedYou manage
BillingPer-pod resource requestsPer node
SSH to nodesNot allowedAllowed
DaemonSetsRestricted (Google-managed only)Full control
Privileged podsNot allowedAllowed
HostPath volumesNot allowedAllowed
Cluster autoscalingAlways on, automaticOptional, manual config
Node auto-provisioningAutomaticOptional
Cost for idle nodesNone (no nodes when no pods)You pay for idle nodes

The billing model is the biggest operational difference. In Autopilot, you pay for what your pods request, not what nodes are provisioned. An idle cluster costs effectively nothing.

Creating a GKE Autopilot Cluster

# Set project and region
gcloud config set project YOUR_PROJECT_ID
gcloud config set compute/region us-central1

# Create Autopilot cluster
gcloud container clusters create-auto prod-autopilot \
  --region us-central1 \
  --release-channel regular \
  --network default \
  --subnetwork default \
  --enable-private-nodes \
  --master-ipv4-cidr 172.16.0.0/28 \
  --enable-master-authorized-networks \
  --master-authorized-networks 203.0.113.0/24

# Get credentials
gcloud container clusters get-credentials prod-autopilot \
  --region us-central1

--enable-private-nodes is strongly recommended for production — nodes have no public IPs, and you control which CIDRs can reach the API server.

Writing Autopilot-Compatible Manifests

The most common Autopilot gotcha is resource requests. Every container must specify CPU and memory requests and limits. If you don't, Autopilot injects defaults, which are often wrong for your workload.

# deployment.yaml — Autopilot-ready
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-service
  template:
    metadata:
      labels:
        app: api-service
    spec:
      containers:
        - name: api
          image: gcr.io/YOUR_PROJECT/api-service:v1.2.3
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 500m
              memory: 512Mi
            limits:
              cpu: 1000m
              memory: 1Gi
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 15
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        seccompProfile:
          type: RuntimeDefault

Autopilot enforces the Restricted pod security standard by default. runAsNonRoot: true and a seccomp profile are required. Containers running as root will be rejected.

Workload Identity — The Right Way to Access GCP Services

In Autopilot, there's no node service account to abuse. Use Workload Identity to map Kubernetes service accounts to Google service accounts:

# Create a Google service account for your app
gcloud iam service-accounts create api-service-sa \
  --display-name "API Service Account"

# Grant it permissions (example: read from Cloud Storage)
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
  --member "serviceAccount:api-service-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com" \
  --role "roles/storage.objectViewer"

# Allow the Kubernetes SA to impersonate the Google SA
gcloud iam service-accounts add-iam-policy-binding \
  api-service-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:YOUR_PROJECT_ID.svc.id.goog[production/api-service]"
# kubernetes-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: api-service
  namespace: production
  annotations:
    iam.gke.io/gcp-service-account: api-service-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com

Now your pod uses serviceAccountName: api-service in its spec and automatically gets GCP credentials — no secret management required.

Horizontal Pod Autoscaling

Autopilot manages node capacity automatically, but you still configure pod-level autoscaling:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-service-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api-service
  minReplicas: 2
  maxReplicas: 50
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 70

When the HPA scales pods up, Autopilot automatically provisions more node capacity to fit them. When pods scale down, Autopilot reclaims nodes. You only pay for the pod time.

Spot Pods for Cost Savings

Autopilot supports Spot VMs at the pod level via a node selector:

spec:
  template:
    spec:
      nodeSelector:
        cloud.google.com/gke-spot: "true"
      tolerations:
        - key: cloud.google.com/gke-spot
          operator: Equal
          value: "true"
          effect: NoSchedule
      containers:
        - name: batch-worker
          image: gcr.io/YOUR_PROJECT/batch-worker:latest
          resources:
            requests:
              cpu: 2
              memory: 4Gi

Spot pods can be preempted, so use them for batch workloads, CI runners, and data processing — not for your API servers.

Persistent Storage

Autopilot supports Persistent Volume Claims with the standard GKE storage classes:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
  namespace: production
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard-rwo    # Regional SSD for HA
  resources:
    requests:
      storage: 50Gi

Available storage classes:

ClassTypeUse Case
standardHDDDev, low IOPS
standard-rwoSSD, zonalSingle-node apps
premium-rwoNVMe SSDHigh IOPS databases
filestore-*NFSReadWriteMany workloads

Monitoring and Logging

GKE Autopilot ships with Cloud Operations (Stackdriver) pre-configured:

# View cluster-level metrics in Cloud Monitoring
gcloud monitoring dashboards list

# Stream pod logs
kubectl logs -f deployment/api-service -n production

# Query logs in Cloud Logging
gcloud logging read \
  'resource.type="k8s_container" AND resource.labels.cluster_name="prod-autopilot" AND severity>=ERROR' \
  --limit 50 \
  --freshness 1h

Set up alerts for your deployment health:

# Create uptime check for your service endpoint
gcloud monitoring uptime-check-configs create \
  --display-name "API Service Health" \
  --resource-type "uptime-url" \
  --hostname "api.yourapp.com" \
  --path "/healthz" \
  --check-interval 60s

Cost Optimization Tips

StrategySavings
Use Spot pods for batch jobs60-90% off pod costs
Set accurate resource requestsAvoid over-provisioned billing
Scale to zero with KEDAZero cost when idle
Use startupProbe to avoid early restartsReduce wasted compute
Regional clusters only where HA is neededZonal is cheaper for dev

When Not to Use Autopilot

Autopilot is the right default for most teams, but there are legitimate reasons to choose Standard:

  • You need DaemonSets for custom node-level monitoring or networking
  • Your workloads require privileged containers (uncommon but valid)
  • You need specific node hardware (GPUs, local SSDs) beyond what Autopilot offers
  • You have strict compliance requirements around node access and auditing

For everything else — web APIs, background workers, data pipelines, microservices — Autopilot is simpler to operate and often cheaper than Standard once you factor in the engineering time saved not managing nodes.

Share:

Was this article helpful?

Amara Okafor
Amara Okafor

DevSecOps Lead

Security-first mindset in everything I ship. From zero-trust architectures to supply chain security, I make sure your pipeline doesn't become your weakest link.

Related Articles

Discussion