Creating EKS clusters with eksctl is a breeze, but replicating that streamlined experience with Google Kubernetes Engine (GKE) and gcloud requires understanding a few key concepts. The most surprising thing about gcloud for GKE cluster creation is that it doesn’t have a single, idempotent command that spins up a fully production-ready cluster with networking, node pools, and IAM all configured in one go like eksctl create cluster. Instead, gcloud focuses on building blocks, giving you immense flexibility but demanding more explicit configuration.
Let’s see gcloud in action, building a cluster piece by piece. Imagine we want a basic cluster for development, similar to what eksctl might default to.
First, we need to enable the GKE API if you haven’t already:
gcloud services enable container.googleapis.com
Next, we create the cluster itself. This command initiates the control plane and defines basic networking.
gcloud container clusters create my-gke-cluster \
--zone us-central1-a \
--num-nodes 1 \
--machine-type e2-medium \
--enable-ip-alias \
--network default \
--subnetwork default
This gcloud container clusters create command is where the magic starts, but it’s a different kind of magic than eksctl.
--zone us-central1-a: Specifies the Google Cloud zone for the control plane and nodes. This is analogous to EKS’s region selection but at a finer granularity.--num-nodes 1: Sets the initial size of the default node pool.--machine-type e2-medium: Defines the VM instance type for your nodes.--enable-ip-alias: This is crucial for GKE. It enables VPC-native GKE, meaning pods get IP addresses directly from your VPC network, which is essential for robust networking and security. This is somewhat analogous to how EKS integrates with AWS VPC networking but is managed differently.--network defaultand--subnetwork default: Specifies the VPC network and subnetwork where the cluster will reside. For production, you’d typically create dedicated networks and subnetworks.
Once the cluster is created, gcloud automatically configures your kubectl context to point to it. You can verify this:
kubectl get nodes
You’ll see your single node listed.
The mental model for gcloud cluster creation is one of explicit infrastructure definition. Unlike eksctl, which abstracts away much of the underlying AWS resource provisioning (VPC, subnets, security groups, IAM roles), gcloud requires you to think about these components more directly, even if you’re using defaults.
When you create a GKE cluster, you’re essentially provisioning:
- The Control Plane: This is a managed Google-owned Kubernetes API server, scheduler, and controller manager. You don’t manage its underlying infrastructure.
- Node Pools: These are groups of Compute Engine VMs that run your Kubernetes workloads. You define their machine type, size, disk configuration, and more.
- Networking: GKE integrates tightly with Google Cloud VPC.
--enable-ip-aliasis the key to VPC-native networking, where pods receive IPs from the VPC subnet, enabling direct pod-to-pod communication and easier integration with other VPC resources.
The difference from eksctl is that gcloud commands are often single-purpose. gcloud container clusters create only creates the cluster control plane and a default node pool. Adding more nodes, creating separate node pools with different configurations, or setting up advanced networking features requires additional gcloud commands.
For instance, to add a new node pool with GPU-enabled machines:
gcloud container node-pools create gpu-pool \
--cluster my-gke-cluster \
--zone us-central1-a \
--num-nodes 2 \
--machine-type n1-standard-4 \
--accelerator type=nvidia-tesla-t4,count=1
This command explicitly creates another set of nodes, separate from the initial default pool, with GPU hardware. eksctl might allow specifying machine types and instance types with GPUs directly in its initial create cluster command, but gcloud separates the cluster infrastructure from its compute resources more distinctly.
The one thing most people don’t realize about GKE’s networking is how deeply integrated it is with VPC-native mode and IP aliasing. When --enable-ip-alias is used, pods get secondary IP addresses from the same subnet as your nodes. This isn’t just for show; it means pods can be directly accessed by other resources in your VPC without NAT, and network policies can be applied directly to pod IP ranges. This contrasts with older, non-VPC-native modes or some other cloud provider setups where pod traffic might be NATted through node IPs, making direct access and fine-grained network policy enforcement more complex.
The next thing you’ll likely want to configure is private clusters for enhanced security.