Introduction
Google Kubernetes Engine (GKE) is Google Cloud's managed service for orchestrating containers with Kubernetes. It simplifies cluster management by handling updates, scalability, and security, so you can focus on your code. Why GKE in 2026? With the rise of microservices and AI, cloud-native apps demand robust orchestration. This beginner tutorial guides you through creating a cluster, deploying a simple Nginx app, exposing it via a service, and scaling it. By the end, you'll master the basics for production-ready deployments. Think of Kubernetes as a conductor: GKE is the theater that handles the lights and sound.
Prerequisites
- A free Google Cloud Platform (GCP) account with billing enabled.
- Terminal with gcloud CLI and kubectl installed (instructions below).
- Basic knowledge of Docker and YAML.
- GCP region enabled (e.g., us-central1).
Install gcloud and kubectl
#!/bin/bash
# Download and install gcloud CLI (2026 edition)
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init
gcloud components install kubectl
gcloud components updateThis script installs the gcloud CLI and kubectl, essential for interacting with GKE. Run it once. Pitfall: Check your PATH after installation with gcloud version to avoid 'command not found' errors.
GCP Authentication
Before creating a cluster, authenticate and set up your project. This generates an OAuth token for GCP APIs.
Authenticate and configure the project
#!/bin/bash
# Interactive authentication
gcloud auth login
# List available projects
gcloud projects list
# Set the project (replace PROJECT_ID with yours)
gcloud config set project my-gke-project-2026
gcloud config listThese commands connect you to GCP and select your project. Copy the project ID from the GCP console. Warning: Without billing enabled, GKE clusters will fail silently.
Create the GKE Cluster
#!/bin/bash
# Create a standard cluster (3 nodes, e2-medium machine type)
gcloud container clusters create my-gke-cluster \
--zone=us-central1-a \
--num-nodes=3 \
--machine-type=e2-medium \
--enable-ip-alias
# Get kubectl credentials for this cluster
gcloud container clusters get-credentials my-gke-cluster --zone=us-central1-a
# Verify the connection
kubectl get nodesThis script provisions a managed cluster ready in 5-10 minutes. --enable-ip-alias enables VPC-native networking for scalability. Pitfall: Change the zone if unavailable; check with kubectl get nodes that all 3 nodes are 'Ready'.
Deploy the Application
Now, let's deploy an Nginx pod via a Kubernetes Deployment. This is the heart of orchestration: replication, rolling updates, and self-healing.
Create the Nginx Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"This YAML manifest creates 2 Nginx replicas with resource limits to prevent OOM kills. Copy it to a file and apply it. Analogy: Like a blueprint for identical clones of your container.
Apply the Deployment
#!/bin/bash
# Create the YAML file (or copy manually)
cat > nginx-deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
EOF
# Apply the Deployment
kubectl apply -f nginx-deployment.yaml
# Check the status
kubectl get deployments
kubectl get podsApplies the YAML and verifies pods are 'Running'. Pitfall: If image pull fails, check the public registry; use kubectl describe pod for debugging.
Expose the Application
To access Nginx from outside, create a LoadBalancer Service. GKE automatically provisions an external IP.
Create the LoadBalancer Service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginxThis Service routes external traffic to Nginx pods. LoadBalancer type is ideal for GKE (free for basic ingress). Tip: The IP appears after kubectl get svc.
Apply the Service and Test
#!/bin/bash
# Apply the Service
kubectl apply -f nginx-service.yaml
# Wait for the external IP (1-2 min)
kubectl get services nginx-service
# Get the IP
EXTERNAL_IP=$(kubectl get service nginx-service -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "External IP: $EXTERNAL_IP"
# Test with curl (or browser)
curl http://$EXTERNAL_IP
# Alternative port-forward for local testing
kubectl port-forward service/nginx-service 8080:80Exposes the app publicly and tests connectivity. Port-forward is great for dev without a public IP. Pitfall: GCP firewall blocks by default; allow port 80 in the console.
Scale the Application
#!/bin/bash
# Scale to 5 replicas
kubectl scale deployment nginx-deployment --replicas=5
# Watch new pods
kubectl get pods -w
# HPA autoscaling (optional, for production)
cat > hpa.yaml << EOF
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
EOF
kubectl apply -f hpa.yaml
kubectl get hpaScale manually or auto with HPA based on CPU. -w watches in real-time. GKE Advantage: Cluster autoscaling handles nodes automatically.
Best Practices
- Use namespaces:
kubectl create namespace prodto isolate environments. - Limit resources: Always set requests/limits to avoid noisy neighbors.
- Enable Workload Identity: For pod security without Service Account keys.
- Monitor with Cloud Monitoring: Built into GKE, enable via console.
- Use vulnerability-scanned images: With Artifact Registry.
Common Errors to Avoid
- Forgetting
get-credentials: kubectl can't see the cluster. - GCP quota exhausted: Check limits in console before creating.
- Pods Pending: Image not public or insufficient nodes (scale cluster).
- LoadBalancer IP not assigned: Wait 2-5 min or use Ingress.
Next Steps
Master Helm for complex charts, Istio for service mesh, or Anthos for multi-cloud. Check out our Learni Kubernetes and GKE training courses for a certified CKA/CKAD path.