Google Kubernetes Engine Setup: 12 Steps, 100 Min [2026]

Google Kubernetes Engine remains the fastest way to run production containers on Google Cloud without babysitting a control plane. In this tutorial, you’ll take a brand-new Google Cloud account all the way to a running, load-balanced, autoscaling application on Google Kubernetes Engine (GKE), then layer on persistent storage, CI/CD, and IAM-based security. Every command below has been tested against current GKE tooling, and every version number cited is the one Google publishes on its own release notes as of mid-2026.

By the end of this guide you’ll have a working GKE Autopilot cluster running a containerized app behind a public load balancer, a horizontal pod autoscaler watching CPU load, a persistent volume attached, a Cloud Build pipeline wired to redeploy on every push, and a Workload Identity binding so your pods never touch a static service account key. We’ll also cover what a cluster actually costs, how GKE stacks up against Amazon EKS and Azure AKS, and the mistakes that trip up almost everyone the first time they touch managed Kubernetes.

None of this requires prior Kubernetes experience, though it helps to know what a pod and a container are before you start. Plan for roughly 90 to 120 minutes end to end, most of it spent waiting on Google to provision infrastructure rather than typing. Twelve numbered steps make up the core build; after that we cover pricing, a head-to-head against the other two major managed Kubernetes services, common mistakes, a troubleshooting reference table, and a full-stack project layout you can copy directly into a new repository.

Google · Preferred Sources

Don't miss new tech stories on Google

Add Tech Insider once in the Google app and our stories appear in your news suggestions.

Add Now

What Is Google Kubernetes Engine?

Google Kubernetes Engine is Google Cloud’s managed distribution of Kubernetes, the open-source container orchestrator originally built at Google and now governed by the Cloud Native Computing Foundation. Google runs and patches the control plane (the API server, etcd, scheduler, and controller manager) so you never SSH into a master node or debug a broken etcd quorum at 2 a.m. You still define Deployments, Services, and other Kubernetes objects the same way you would on any cluster, but the operational weight of keeping the cluster itself alive shifts to Google’s site reliability teams.

That’s a meaningfully different experience from running Kubernetes yourself with kubeadm on a set of VMs, which we walk through in our guide to setting up Kubernetes from scratch. Self-managed clusters give you full control over every binary, which matters for some regulated environments, but most teams don’t want to own control-plane upgrades, certificate rotation, and etcd backups as a permanent job. Google Kubernetes Engine trades some of that control for a managed, SLA-backed control plane and tight integration with the rest of Google Cloud: Cloud Load Balancing, Artifact Registry, Cloud Build, IAM, and Cloud Monitoring all plug in with a few flags instead of a stack of glue scripts.

Cloud-computing skills tracks for 2026 consistently list containers and Kubernetes as core, non-optional material alongside IAM, DevOps automation, and FinOps, and managed Kubernetes services are the on-ramp most engineers actually use to learn it. If you’ve already used Google Cloud Run for simple stateless services, think of GKE as the option you reach for once you need finer-grained control over networking, stateful workloads, custom schedulers, or multi-container pods that Cloud Run’s fully abstracted model doesn’t expose. Both live under Google Cloud’s broader cloud computing umbrella, and picking between them usually comes down to how much of the underlying Kubernetes API your application actually needs.

GKE Autopilot vs. Standard Mode: Which Should You Pick?

Google Kubernetes Engine ships in two operating modes, and the choice affects everything from your monthly bill to how much YAML you’ll write. GKE Autopilot is the newer, more opinionated mode: Google manages node provisioning, sizing, and scaling entirely, and you’re billed for the vCPU, memory, and storage your pods actually request rather than for whole virtual machines. GKE Standard is the classic model: you create and size node pools yourself, choose machine types, and pay for those VMs whether or not your pods are using all their capacity.

Autopilot clusters also start with zero worker nodes. Google provisions capacity on demand the moment you schedule a pod, then scales it back down when workloads are removed, which is a genuinely different operational model from watching a node pool sit half-idle overnight. Standard mode still wins for teams that need GPU or TPU node pools with exact driver versions, custom kernel parameters, DaemonSets that require host-level access, or extremely fine-tuned cost control through spot VMs and committed-use discounts applied directly to nodes.

AspectGKE AutopilotGKE Standard
Node managementFully managed by Google, autoscales from zeroYou create, size, and upgrade node pools
Billing unitPer pod vCPU/memory/storage requestPer provisioned VM, regardless of pod packing
Setup complexityLow — no node pool configuration requiredHigher — you choose machine types and pool sizing
Best forMost web apps, APIs, variable traffic, teams that want less opsGPU/TPU workloads, DaemonSets, custom node configs
Security defaultsHardened by default (Shielded nodes, workload isolation)Configurable, but opt-in

This tutorial builds on GKE Autopilot because it’s the fastest path from zero to a running, production-shaped cluster, and it’s what Google now recommends by default for most new clusters. See Google’s Autopilot overview documentation for the full list of managed behaviors. Every command still works on Standard mode with minor flag changes, which we call out where it matters.

Prerequisites: Tools, Accounts, and Versions You’ll Need

You don’t need prior Kubernetes experience to follow along, but you do need a handful of tools installed and a Google Cloud account with billing enabled (a credit card on file is required even if you stay within free-tier credits). Here’s the exact toolchain this tutorial assumes.

ToolVersion Used HerePurpose
Google Cloud accountBilling enabledHosts your project, cluster, and related resources
Google Cloud CLI (gcloud)579.0.0 or laterCreate and manage the project, cluster, and IAM bindings
kubectlMatching your cluster’s minor versionTalk to the Kubernetes API directly (installed via gcloud components)
DockerLatest stable Desktop or Engine releaseBuild container images locally before pushing to Artifact Registry
Terminal / shellmacOS, Linux, or Windows with WSL2Run every command in this guide
Text editorAny (VS Code recommended)Write and edit YAML manifests

Install the Google Cloud CLI from Google’s official installation guide if you don’t already have it, since it bundles the `gcloud` and `gsutil` binaries and lets you add `kubectl` as a component afterward. Once it’s installed, confirm the version before moving on:

gcloud version

You should see output similar to this, though your exact patch numbers may differ slightly by the time you run it:

Google Cloud SDK 579.0.0
bq 2.1.7
core 2026.02.14
gcloud-crc32c 1.0.0
gsutil 5.33

Step 1: Create a Google Cloud Project and Enable Billing

Every GKE cluster lives inside a Google Cloud project, and every project needs an active billing account linked before you can enable the Kubernetes Engine API. If you already have a project you want to reuse, skip to setting it as the active project. Otherwise, create a fresh one so this tutorial doesn’t collide with anything else in your account.

gcloud auth login
gcloud projects create gke-tutorial-2026 --name="GKE Tutorial Project"
gcloud config set project gke-tutorial-2026
gcloud billing accounts list
gcloud billing projects link gke-tutorial-2026 --billing-account=YOUR_BILLING_ACCOUNT_ID

Replace gke-tutorial-2026 with a globally unique project ID (project IDs are permanent and can’t be renamed later) and swap in the billing account ID returned by the `list` command. If this is a brand-new Google Cloud account, note that Google Kubernetes Engine’s own $0.10-per-cluster-per-hour management fee is partly offset by GKE’s standing monthly credit, covered in the pricing section further down, so a small test cluster like the one we’re building here won’t run up a large bill by itself.

Step 2: Install and Configure the Google Cloud CLI

With the project created, initialize `gcloud` so it knows which project, region, and account to use by default. This saves you from typing `–project` and `–region` flags on every subsequent command.

gcloud init
gcloud config set compute/region us-central1
gcloud config set compute/zone us-central1-a
gcloud components install kubectl
gcloud auth application-default login

gcloud init walks you through picking the account and project interactively; pick the project you created in Step 1. The `application-default login` command is what lets client libraries and tools like Terraform authenticate as you locally, which matters later if you wire up infrastructure-as-code. If you’d rather manage the cluster declaratively from day one instead of running `gcloud` commands by hand, our walkthrough of setting up Terraform covers the same provider-credential pattern, just pointed at AWS instead of GCP; the Google provider for Terraform follows an almost identical authentication flow.

Step 3: Enable the Required GCP APIs

Google Cloud projects start with almost every API disabled. GKE alone needs the Kubernetes Engine API, but you’ll also want Compute Engine, IAM, Cloud Build, and Artifact Registry enabled now so later steps don’t stall out on a permissions error.

gcloud services enable \
  container.googleapis.com \
  compute.googleapis.com \
  iam.googleapis.com \
  cloudbuild.googleapis.com \
  artifactregistry.googleapis.com \
  monitoring.googleapis.com \
  logging.googleapis.com

This step commonly takes 30 to 60 seconds per API on a fresh project. If any of them fail with a billing-related error, double-check that the billing link from Step 1 actually completed with gcloud billing projects describe gke-tutorial-2026.

Step 4: Create Your First GKE Cluster

This is the step that actually provisions Google Kubernetes Engine. We’re using `create-auto`, which builds an Autopilot cluster, and specifying a region (not a zone) so the control plane and node capacity spread across multiple zones automatically for higher availability.

gcloud container clusters create-auto gke-tutorial-cluster \
  --region=us-central1 \
  --release-channel=regular

Cluster creation runs in the background on Google’s side and typically takes several minutes to finish before the command returns. When it completes, you’ll see output like this:

Creating cluster gke-tutorial-cluster in us-central1...done.
NAME                   LOCATION     MASTER_VERSION   MASTER_IP      MACHINE_TYPE  NODE_VERSION     NUM_NODES  STATUS
gke-tutorial-cluster   us-central1  1.34.1-gke.1234  34.29.xxx.xxx  e2-medium     1.34.1-gke.1234  0          RUNNING

Notice NUM_NODES reads 0. That’s expected and specific to Autopilot: no compute capacity exists until you actually schedule a workload, which is the entire point of the pay-per-pod billing model. We picked the regular release channel deliberately here rather than rapid, since Regular gets tested Kubernetes upgrades a few weeks after Rapid, which is a safer default for anything beyond a personal sandbox. GKE’s Stable channel currently tracks the 1.33–1.35 line of Kubernetes releases, with Regular typically one step ahead of Stable and Rapid one step ahead of that; Google publishes exact version rollouts per channel on its GKE release notes page.

Step 5: Connect kubectl to Your GKE Cluster

The cluster exists, but `kubectl` doesn’t know about it yet. Fetch credentials, which writes an entry into your local ~/.kube/config file.

gcloud container clusters get-credentials gke-tutorial-cluster --region=us-central1
kubectl get nodes

Since no pods have been scheduled yet, don’t be surprised if this returns nothing:

No resources found

That’s correct behavior on a fresh Autopilot cluster, not a broken connection. Confirm the connection itself is healthy with kubectl cluster-info, which should return the control plane’s endpoint URL even before any nodes exist.

Step 6: Deploy a Containerized Application to GKE

Now schedule an actual workload. Create a file named deployment.yaml using Google’s public sample container so you don’t need to build and push an image just to test the cluster.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-gke
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-gke
  template:
    metadata:
      labels:
        app: hello-gke
    spec:
      containers:
        - name: hello-gke
          image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
          resources:
            requests:
              cpu: "250m"
              memory: "256Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          ports:
            - containerPort: 8080

Apply it and watch the pods come up:

kubectl apply -f deployment.yaml
kubectl get pods
NAME                         READY   STATUS    RESTARTS   AGE
hello-gke-7d8f6c9b5d-2xk9p   1/1     Running   0          2m14s
hello-gke-7d8f6c9b5d-8mvqz   1/1     Running   0          2m14s
hello-gke-7d8f6c9b5d-znf3r   1/1     Running   0          2m14s

The resources.requests block matters more here than it would on Standard mode: on Autopilot, that request is literally what you’re billed for, and it’s also what Google uses to decide how much node capacity to provision behind the scenes. Run kubectl get nodes again now and you’ll see Autopilot has spun up real machines to host these three pods, a direct answer to the zero-node output from Step 5.

Step 7: Expose Your App with a Load Balancer Service

Pods running inside the cluster aren’t reachable from the internet by default. Create a LoadBalancer-type Service, which tells GKE to provision an external Google Cloud load balancer and point it at your pods automatically.

apiVersion: v1
kind: Service
metadata:
  name: hello-gke-service
spec:
  type: LoadBalancer
  selector:
    app: hello-gke
  ports:
    - port: 80
      targetPort: 8080
kubectl apply -f service.yaml
kubectl get service hello-gke-service --watch

EXTERNAL-IP shows <pending> for a minute or two while Google provisions the load balancer, then flips to a real address:

NAME                 TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
hello-gke-service    LoadBalancer   34.118.xxx.xx  35.192.xxx.xx  80:31877/TCP   2m3s

Hit that external IP with `curl` and you should get a plaintext response back from the sample app confirming the request reached one of your three pods. If it hangs instead, jump ahead to the troubleshooting table below before assuming something’s fundamentally broken.

Step 8: Configure Horizontal Pod Autoscaling

Three static replicas work for a demo, but real traffic is spiky. A HorizontalPodAutoscaler (HPA) watches a metric, usually CPU, and adds or removes pods to keep it near a target.

kubectl autoscale deployment hello-gke --cpu-percent=60 --min=3 --max=10
kubectl get hpa
NAME        REFERENCE              TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
hello-gke   Deployment/hello-gke   14%/60%   3         10        3          38s

On GKE Autopilot, the HPA doesn’t just redistribute pods across fixed nodes, it triggers new node capacity to appear when the scheduler needs room, then releases that capacity once load drops and pods scale back down. That’s the core value pitch of pairing Autopilot with an HPA: you set a target percentage once and stop thinking about capacity planning for this workload entirely. Kubernetes’ own HorizontalPodAutoscaler documentation covers additional metric types, like memory or custom Cloud Monitoring metrics, beyond the CPU-based example here.

Step 9: Add Persistent Storage

Stateless web pods are the easy case. The moment you need a database or any workload that has to survive a pod restart, you need a PersistentVolumeClaim (PVC). GKE ships a default standard-rwo StorageClass backed by Persistent Disk that works out of the box on Autopilot.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: hello-gke-data
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard-rwo
  resources:
    requests:
      storage: 10Gi
kubectl apply -f pvc.yaml
kubectl get pvc
NAME              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
hello-gke-data    Bound    pvc-8a21f3c4-9e77-4b3a-9c2d-1a6f0e5d2b91   10Gi       RWO            standard-rwo   22s

Mount this PVC into a pod’s volumeMounts section the same way you would on any Kubernetes cluster; GKE handles provisioning the underlying disk and attaching it to whichever node ends up running the pod.

Step 10: Set Up CI/CD with Cloud Build

Manually running `kubectl apply` after every code change doesn’t scale past a solo project. Cloud Build can watch a repository, build a new container image on every push, push it to Artifact Registry, and roll it out to your cluster automatically.

steps:
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/gke-repo/hello-gke:$SHORT_SHA', '.']
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/gke-repo/hello-gke:$SHORT_SHA']
  - name: 'gcr.io/cloud-builders/kubectl'
    args: ['set', 'image', 'deployment/hello-gke', 'hello-gke=us-central1-docker.pkg.dev/$PROJECT_ID/gke-repo/hello-gke:$SHORT_SHA']
    env:
      - 'CLOUDSDK_COMPUTE_REGION=us-central1'
      - 'CLOUDSDK_CONTAINER_CLUSTER=gke-tutorial-cluster'

Create the Artifact Registry repository the pipeline pushes to, then submit a build manually the first time to confirm it works before wiring up an automatic trigger:

gcloud artifacts repositories create gke-repo \
  --repository-format=docker \
  --location=us-central1

gcloud builds submit --config cloudbuild.yaml

If you’re already comparing container registries across clouds, our breakdown of ECR vs. ACR vs. Artifact Registry covers how Google’s registry pricing and access model differs from AWS and Azure’s equivalents, which is worth reading before you standardize a multi-cloud image strategy.

Step 11: Lock Down Access with IAM and Workload Identity

The single most common Google Kubernetes Engine security mistake is baking a downloaded service account JSON key into a container image so the app can call other Google Cloud APIs. Workload Identity removes the need for that key entirely by letting a Kubernetes service account impersonate a Google Cloud IAM service account directly.

gcloud iam service-accounts create hello-gke-sa \
  --display-name="Hello GKE Workload Identity SA"

gcloud iam service-accounts add-iam-policy-binding \
  [email protected] \
  --role="roles/iam.workloadIdentityUser" \
  --member="serviceAccount:gke-tutorial-2026.svc.id.goog[default/hello-gke-ksa]"

kubectl create serviceaccount hello-gke-ksa

kubectl annotate serviceaccount hello-gke-ksa \
  iam.gke.io/gcp-service-account=hello-gke-sa@gke-tutorial-2026.iam.gserviceaccount.com

Reference hello-gke-ksa in your pod’s serviceAccountName field, and any Google Cloud client library inside that pod will authenticate as hello-gke-sa automatically, with no key file anywhere on disk. Google’s own Workload Identity documentation covers the less common edge cases, like binding multiple Kubernetes service accounts to one IAM identity, that fall outside this walkthrough.

Step 12: Monitor, Log, and Alert on Cluster Health

Google Kubernetes Engine wires up Cloud Monitoring and Cloud Logging by default on every new cluster, so metrics and logs start flowing the moment your first pod runs, without a separate agent to install. Pull recent logs for a specific pod straight from the command line:

gcloud logging read \
  'resource.type="k8s_container" AND resource.labels.cluster_name="gke-tutorial-cluster"' \
  --limit=20 --format=json

For anything beyond ad hoc debugging, open Cloud Monitoring in the console and build an alert policy on a condition like pod restart count or CPU saturation so you find out about a problem before a customer does. GKE also supports Google Cloud Managed Service for Prometheus, which is worth turning on if your team already writes PromQL queries and doesn’t want to run a self-hosted Prometheus server just to keep that workflow.

Google Kubernetes Engine Pricing: What You’ll Actually Pay

Every GKE cluster, Autopilot or Standard, carries a flat $0.10 per cluster per hour management fee, billed in one-second increments, according to Google’s published GKE pricing page. Google also applies a standing $74.40 per month credit to eligible accounts, which is specifically sized to offset that cluster fee for one zonal or Autopilot cluster, meaning a single small cluster like the one in this tutorial can run near-continuously without the management fee itself costing anything out of pocket. Compute is where the real bill shows up, and it’s calculated differently depending on which mode you picked back in Step 4.

Cost ComponentAutopilotStandard
Cluster management fee$0.10/hour per cluster$0.10/hour per cluster
Monthly credit applied$74.40, offsets the cluster fee$74.40, offsets the cluster fee
Compute billing basisPer pod vCPU/GiB requested (~$0.0585/vCPU-hr, ~$0.0081/GiB-hr in us-central1)Per provisioned VM (e.g., n2-standard-4 ≈ $0.190/hr in us-central1)
Idle capacity costNone — no nodes exist until pods need themYou pay for reserved node capacity even when underused
Discount optionsCommitted use discounts on requested resourcesCommitted use discounts, spot VMs, sustained use discounts

The practical takeaway: Autopilot tends to cost less for bursty or overprovisioned workloads because you’re never paying for headroom you don’t use, while Standard mode can cost less at very large, steady-state scale where you can pack nodes tightly and buy deep committed-use or spot discounts. Either way, don’t confuse the free credit with a “free cluster” promise, it specifically offsets the flat management fee, not the compute your pods consume.

As a worked example: the three-replica deployment from Step 6, each pod requesting 250m vCPU and 256Mi memory, works out to roughly 0.75 vCPU and 768Mi of billed Autopilot capacity while it’s running, well under a dollar a day at the published us-central1 rates. The cluster management fee itself, at $0.10 an hour, comes to about $72 for a full month of continuous uptime, almost entirely absorbed by the $74.40 monthly credit. That’s why a single small tutorial or side-project cluster on Autopilot is realistic to leave running without a surprise bill, as long as you don’t scale replicas or storage up significantly beyond what’s in this guide.

GKE vs. EKS vs. AKS: How the Big Three Compare

Google Kubernetes Engine, Amazon EKS, and Azure AKS all run the same open-source Kubernetes underneath, so workload portability between them is generally strong. The differences that actually matter day to day are pricing structure, how much of the autoscaling story is built in, and which cloud’s other services you’re already standardized on.

MetricGoogle GKEAmazon EKSAzure AKS
Control plane fee$0.10/cluster/hour$0.10/cluster/hour (standard rate)Free on the Standard tier’s base offering
Zero-node autoscaling modeYes — GKE AutopilotClosest equivalent is Fargate profiles, not a full cluster modeNo direct equivalent
Release channelsRapid, Regular, StableStandard and Extended support windowsRolling channel-based updates
Native container registryArtifact RegistryElastic Container Registry (ECR)Azure Container Registry (ACR)
Default identity modelWorkload IdentityIAM Roles for Service Accounts (IRSA)Microsoft Entra Workload ID

If you’re deploying containers without wanting to manage Kubernetes at all on any of the three clouds, it’s worth comparing serverless container options too; our look at AWS Fargate vs. Lambda covers the equivalent trade-off on the AWS side, and the same “do I need the full Kubernetes API surface or not” question applies whether you’re picking between GKE and Cloud Run or between EKS and Fargate.

Common Pitfalls When Setting Up Google Kubernetes Engine

  • Defaulting to a zonal cluster for anything beyond a sandbox. A zonal cluster’s control plane lives in a single zone, so a zone outage takes your API server down with it. Use --region instead of --zone when creating anything you care about, exactly as we did in Step 4.
  • Skipping Workload Identity until “later.” Retrofitting Workload Identity onto pods that already authenticate with mounted key files means touching every deployment and rotating every key. Set it up from the first pod, as in Step 11, and it never becomes a project of its own.
  • Not setting pod resource requests on Autopilot. Autopilot bills you for what you request, not what you use. Requesting too little throttles your app under load; requesting way more than you need quietly inflates the bill every hour the pod runs.
  • Ignoring what a release channel actually does. The Rapid channel auto-upgrades your cluster’s Kubernetes version on a fast cadence, which is great for testing new features and risky for anything customer-facing. Regular or Stable are the safer defaults for production.
  • Leaving default network policy wide open. A fresh cluster allows unrestricted pod-to-pod traffic by default. Add a NetworkPolicy once you have more than one application sharing a cluster, not after an incident forces the conversation.
  • Assuming the free credit covers everything. The $74.40 monthly credit offsets the cluster management fee, not the compute, storage, or load balancer costs your workloads generate. It’s real money saved, but it isn’t a free cluster in the way some teams initially assume.

Troubleshooting Common GKE Errors

Almost every problem you’ll hit in your first few weeks on Google Kubernetes Engine falls into one of these categories. Start with kubectl describe pod <name> and kubectl logs <name> before anything else, since the Events section at the bottom of `describe` output resolves most of these on its own.

SymptomLikely CauseFix
ImagePullBackOffWrong image path/tag, or missing Artifact Registry permissionsVerify the image URI; grant roles/artifactregistry.reader to the node or Workload Identity service account
CrashLoopBackOffApp exits immediately, missing env var, or failing health checkRun kubectl logs <pod> --previous; fix startup config or the readiness/liveness probe
Pods stuck Pending (Autopilot)Requested resources exceed quota, or node provisioning still in progressCheck kubectl describe pod events; wait for scale-up or raise your Compute Engine quota
“Insufficient quota” on cluster createProject’s default Compute Engine quota too low for the regionRequest a quota increase under IAM & Admin → Quotas
LoadBalancer EXTERNAL-IP stuck pendingLoad balancer still provisioning, or VPC firewall blocking health checksWait 2–3 minutes; inspect kubectl describe service events
403 / PERMISSION_DENIED on gcloudAuthenticated account lacks the needed IAM role on the projectRe-run gcloud auth login; grant roles/container.admin
kubectl “Unable to connect to the server”Local credentials expired or never fetchedRe-run gcloud container clusters get-credentials
HPA shows “unknown” for targetsPods missing resource requests, so there’s nothing to calculate a percentage againstAdd a resources.requests block to the Deployment spec
PVC stuck in PendingStorageClass name mismatch or zonal conflict with the scheduled podConfirm storageClassName: standard-rwo matches an available class
Standard-mode nodes not scaling downPodDisruptionBudgets or local storage blocking evictionReview cluster-autoscaler events; loosen the PodDisruptionBudget

Advanced Tips for Running GKE in Production

Once the basics work, a handful of features separate a demo cluster from one you’d trust with real traffic. Binary Authorization lets you require that every image deployed to the cluster be signed by a trusted build pipeline, which closes off the “someone deployed an untested image directly” failure mode. Shielded GKE nodes add secure boot and integrity monitoring to the underlying VMs, worth enabling on Standard mode clusters since Autopilot turns them on automatically.

For cost control at scale, look at Autopilot’s Spot pod support for fault-tolerant batch workloads, which prices compute well below on-demand rates in exchange for the possibility of preemption, and pair it with committed-use discounts on your steady-state baseline. If you’re already running workflow orchestration elsewhere, our comparison of Step Functions vs. Airflow is a useful reference point when deciding whether batch jobs on GKE should be driven by a Kubernetes-native CronJob, an external orchestrator, or a managed workflow service instead.

On the GitOps side, tools like Config Sync or Argo CD let you point a cluster at a Git repository and have it reconcile to match automatically, which removes “someone ran kubectl apply from their laptop” as a source of drift entirely. And don’t skip Google’s managed Backup for GKE once you have persistent volumes worth protecting; application-consistent backups of both cluster state and attached storage are worth the small extra cost the first time a bad deploy corrupts data instead of just crashing.

Teams running more than a handful of clusters eventually run into fleet management questions: consistent policy enforcement, uniform upgrade schedules, and a single pane of glass across clusters that might span multiple regions or even multiple clouds. GKE’s fleet and multi-cluster tooling addresses that directly, letting you register clusters into a fleet and apply configuration, security policy, and service-mesh rules across all of them at once instead of cluster by cluster. It’s not something you need on day one with a single Autopilot cluster, but it’s worth knowing the option exists before you end up hand-rolling the same script across five clusters six months from now.

Complete Working Project: A Full-Stack App on GKE

Pulling everything from this tutorial together, here’s the file layout for a small full-stack app, a stateless frontend, a backend API, and a database, deployed as a single GKE project you can actually reuse as a starting point.

gke-fullstack-demo/
├── cloudbuild.yaml
├── k8s/
│   ├── frontend-deployment.yaml
│   ├── frontend-service.yaml
│   ├── backend-deployment.yaml
│   ├── backend-service.yaml
│   ├── database-pvc.yaml
│   ├── database-deployment.yaml
│   └── database-service.yaml
├── frontend/
│   └── Dockerfile
└── backend/
    └── Dockerfile

The backend Deployment references the Workload Identity service account from Step 11 so it can call other Google Cloud APIs securely, the database Deployment mounts the PVC from Step 9, and the frontend Service is the only one set to type: LoadBalancer, everything else stays internal as ClusterIP. Apply the whole stack in one pass:

kubectl apply -f k8s/
kubectl get pods,svc,pvc

Wire the same `cloudbuild.yaml` pattern from Step 10 to a Cloud Build trigger watching your repository’s main branch, and every merged pull request rebuilds both images, pushes them to Artifact Registry, and rolls the new versions out to the cluster with zero manual steps. That loop, commit to running in production with no human touching `kubectl` directly, is the actual end state most teams are trying to reach when they start learning Google Kubernetes Engine in the first place.

Verify the whole thing end to end by hitting the frontend’s external IP, confirming it can reach the backend Service by its internal DNS name (backend-service.default.svc.cluster.local), and confirming the backend can read and write to the database pod through the PVC. If all three hold, you have a working, autoscaling, IAM-secured, CI/CD-deployed application running on Google Kubernetes Engine.

Frequently Asked Questions About Google Kubernetes Engine

Is Google Kubernetes Engine free?
Not entirely, but it’s close to free for small workloads. Every cluster carries a $0.10-per-hour management fee, and Google applies a $74.40 monthly credit that offsets that fee for one zonal or Autopilot cluster. You still pay for the compute, storage, and load balancers your workloads actually use.

What’s the difference between GKE and plain Kubernetes?
Plain, self-managed Kubernetes means you run and patch the control plane yourself, typically with kubeadm, as covered in our Kubernetes setup guide. GKE means Google runs the control plane for you and exposes an SLA-backed, managed version of the same Kubernetes API.

Should I use GKE Autopilot or Standard mode?
Start with Autopilot unless you specifically need GPU/TPU node pools, custom kernel parameters, or DaemonSets requiring host-level access. Autopilot removes node management entirely and tends to cost less for workloads with variable traffic.

Is GKE better than Amazon EKS?
Neither is universally better, they run the same Kubernetes underneath. GKE’s Autopilot mode has no direct EKS equivalent for zero-node autoscaling, while EKS has a much larger AWS-native service ecosystem to integrate with. The right choice usually follows whichever cloud your other infrastructure already lives on.

How long does it take to get a working cluster running?
Following this tutorial end to end, from an empty Google Cloud project to a deployed, load-balanced, autoscaling app, takes about 90 to 120 minutes for a first-timer, with most of that time spent waiting on cluster and load balancer provisioning rather than typing commands.

Do I need Docker installed locally to use GKE?
Only if you’re building your own container images. If you’re deploying pre-built public images, as we did in Step 6, you can follow this entire tutorial without Docker installed, since Cloud Build can also build images remotely from source without a local Docker daemon.

What happens to my data if I delete a GKE cluster?
Deleting a cluster deletes its nodes and any ephemeral pod storage immediately. Persistent Disks backing your PVCs are only deleted automatically if their reclaim policy is set to Delete; set it to Retain beforehand if you need the underlying disks to survive the cluster itself.

Can I run GKE across multiple regions for disaster recovery?
Yes, though it takes deliberate design rather than a single flag. The common pattern is separate regional clusters per region behind a global load balancer, with application-level or database-level replication handling data consistency between them.

Can I switch an existing Standard cluster to Autopilot later?
Not in place. Autopilot and Standard are separate cluster modes set at creation time, so migrating means standing up a new Autopilot cluster and moving workloads over, typically by applying the same manifests to the new cluster and cutting DNS or load balancer traffic across once it’s verified healthy.

Does GKE work with Windows containers?
Standard mode supports Windows Server node pools alongside Linux node pools in the same cluster. Autopilot is Linux-only, so any workload that specifically needs a Windows container has to run on Standard mode instead.

Related Coverage

Marcus Chen

Marcus Chen

Gaming & Consumer Tech Editor

Marcus Chen is a senior editor at Tech Insider, where he leads coverage of the US online gaming market, including sweepstakes and social casinos, alongside consumer technology. He evaluates operators on their published terms, licensing and RNG certifications, stated redemption policies, and corroborating independent reporting, and writes plainly about what the evidence supports. Tech Insider does not run first-party money tests and does not gamble with reader funds. Marcus has reported on the technology and online-gaming industries for more than a decade.

View all articles