GCP ACE: Deploying a GKE Autopilot Cluster, Step by Step
The previous two articles covered the theory: what containers and Kubernetes are, and how GKE’s control plane, nodes, and Autopilot/Standard modes fit together. This one is the hands-on version — creating a real Autopilot cluster and getting a container running behind a public IP.
Prerequisites
Enable the required APIs and make sure your user account has enough permissions:
gcloud services enable container.googleapis.com artifactregistry.googleapis.com
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="user:[email protected]" \
--role="roles/container.admin"
Autopilot clusters use the Compute Engine default service account for nodes unless you specify one. That account needs the node service account role:
PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)")
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:${PROJECT_NUMBER}[email protected]" \
--role="roles/container.defaultNodeServiceAccount"
Step 1 — Create the cluster
gcloud container clusters create-auto hello-cluster \
--location=europe-southwest1 \
--project=PROJECT_ID
--locationtakes a region for Autopilot (not a zone). If you haven’t set a default region/zone viagcloud config, omitting this flag fails withOne of [--zone, --region] must be supplied.- You don’t choose a Kubernetes version here on purpose — the cluster takes the default version for its release channel.
- Cluster creation takes several minutes. Behind the scenes, Google is provisioning the control plane and enrolling the cluster in the Regular release channel (the default for new clusters, unless you pass
--release-channel). Unlike Standard clusters, an Autopilot cluster can’t opt out of release channels entirely — it’s always enrolled in one.
Step 2 — Point kubectl at the cluster
gcloud container clusters get-credentials hello-cluster \
--location=europe-southwest1
This writes an entry into your local kubeconfig so every kubectl command from here on targets this cluster. Confirm Autopilot is actually on:
gcloud container clusters describe hello-cluster \
--location=europe-southwest1 \
--format="value(autopilot.enabled)"
Should return True.
Step 3 — Deploy a container
No YAML needed for a quick deployment — kubectl create deployment builds the Deployment object for you from an existing image:
kubectl create deployment hello-server \
--image=us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
This is the Google-provided sample image used across GKE’s own documentation — useful for a first test before pointing at the image you built with Cloud Build in the containers article.
Step 4 — Expose it with a Service
The Deployment is running, but nothing outside the cluster can reach it yet. A LoadBalancer-type Service provisions an actual Compute Engine load balancer with a public IP:
kubectl expose deployment hello-server \
--type=LoadBalancer \
--port=80 \
--target-port=8080
--port is what the outside world connects to; --target-port is the port the container actually listens on inside the Pod. In this sample app that’s 8080, fronted publicly on 80.
Step 5 — Verify
kubectl get pods
kubectl get service hello-server
The Service’s EXTERNAL-IP column starts as <pending> while the load balancer provisions — give it a couple of minutes and re-run the command. Once it shows a real IP, http://EXTERNAL_IP should serve the app.
Step 6 — Clean up
A LoadBalancer Service and the cluster both cost money while they exist. Always tear down what you created in a test:
kubectl delete service hello-server
gcloud container clusters delete hello-cluster --location=europe-southwest1
Deleting the Service first releases the load balancer; deleting the cluster afterward removes everything else (nodes, workloads, the control plane).
Exam Takeaways
gcloud container clusters create-autocreates an Autopilot cluster;--locationmust be a region, not a zone.- New Autopilot clusters default to the Regular release channel unless you override it with
--release-channel. - The node service account (Compute Engine default, unless overridden) needs
roles/container.defaultNodeServiceAccount— a prerequisite that’s easy to skip and causes cluster creation to fail. gcloud container clusters get-credentialsconfigureskubectlto target a specific cluster — this is the step people forget right after creating a cluster.kubectl create deployment --image=...is the imperative shortcut; it skips writing YAML.kubectl expose deployment --type=LoadBalancerprovisions a real Compute Engine load balancer — it has a cost, andEXTERNAL-IPstays<pending>until it’s ready.--portis the externally reachable port;--target-portis the container’s actual listening port — know the difference, it’s a classic exam trap.- Always delete the Service before (or along with) the cluster — an orphaned load balancer keeps billing.