GCP GKE Deployment Guide

Step-by-step guide to deploy a production-ready Google Kubernetes Engine (GKE) cluster

Deploying a GCP GKE Cluster

Google Kubernetes Engine (GKE) is a managed, production-ready environment for running containerized applications on Google Cloud. GKE offers a fully managed Kubernetes service with advanced features like auto-scaling, auto-upgrading, and high availability.

This guide walks you through the process of setting up a production-ready GKE cluster using best practices.

Prerequisites

Before you begin, ensure you have the following:

  • Google Cloud account with billing enabled
  • Google Cloud SDK installed and configured
  • kubectl installed
  • A Google Cloud Project with the Kubernetes Engine API enabled
  • (Optional) Helm for deploying applications

Setting Up Your Environment

1. Install the Google Cloud SDK

Follow the official installation guide for your operating system.

2. Initialize the Google Cloud SDK

gcloud init

This will guide you through authenticating with Google Cloud and selecting your default project.

3. Enable the Required APIs

gcloud services enable container.googleapis.com

4. Set Your Default Project and Zone/Region

# Set default project
gcloud config set project YOUR_PROJECT_ID

# Set default compute zone (or use a region with --region)
gcloud config set compute/zone us-central1-a

Creating a GKE Cluster

The simplest way to create a GKE cluster is using the gcloud command line tool.

Standard Cluster (Regional, Production-Ready)

gcloud container clusters create my-gke-cluster \
    --region us-central1 \
    --node-locations us-central1-a,us-central1-b,us-central1-c \
    --num-nodes 1 \
    --machine-type e2-standard-4 \
    --disk-size 100 \
    --enable-autoscaling --min-nodes 1 --max-nodes 5 \
    --enable-ip-alias \
    --enable-autorepair \
    --enable-autoupgrade \
    --enable-shielded-nodes \
    --release-channel regular

This creates a regional cluster across three zones for high availability, with 1 node (n1-standard-2) per zone initially, autoscaling enabled up to 5 nodes per zone.

Autopilot Cluster (Fully Managed)

GKE Autopilot is a fully managed Kubernetes service that handles node provisioning and management automatically:

gcloud container clusters create-auto my-autopilot-cluster \
    --region us-central1 \
    --release-channel regular

Option 2: Using the Google Cloud Console

If you prefer a visual interface:

  1. Go to the Google Cloud Console
  2. Navigate to Kubernetes Engine > Clusters
  3. Click "Create Cluster"
  4. Choose either "Standard" or "Autopilot"
  5. For Standard clusters:
    • Configure the cluster basics (name, location, version)
    • Configure the default node pool (machine type, size, autoscaling)
    • Configure Networking, Security, and Features as needed
  6. Review and create

Configuring kubectl to Connect to Your GKE Cluster

Once your cluster is created, configure kubectl:

gcloud container clusters get-credentials my-gke-cluster --region us-central1

Or for a zonal cluster:

gcloud container clusters get-credentials my-gke-cluster --zone us-central1-a

Verify your connection:

kubectl get nodes

Setting Up Core Add-ons

GKE comes with many features pre-installed, but you might want to set up a few additional components:

1. Google Cloud Load Balancer (Already Integrated)

GKE has built-in support for Google Cloud Load Balancers. Create a LoadBalancer type service:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer

2. Setting Up Ingress with Google Cloud Load Balancer

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

Create an ingress resource:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

3. Storage Classes (Already Available)

GKE provides several storage classes by default:

kubectl get storageclass

Use standard storage class for most workloads:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard

Setting Up Monitoring and Logging

Google Cloud's Operations suite (formerly Stackdriver) is automatically integrated with GKE.

Access Cloud Monitoring and Logging

  1. Go to the Google Cloud Console
  2. Navigate to "Monitoring" or "Logging" sections
  3. Create dashboards and alerts in Monitoring
  4. Use Logging to search and analyze logs

Deploying Custom Prometheus and Grafana (Optional)

If you prefer a self-managed monitoring stack:

# Add Helm repo
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# Create namespace
kubectl create namespace monitoring

# Install Prometheus Stack with Grafana
helm install prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring

Access Grafana:

kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80

Then visit http://localhost:3000 (default credentials: admin/prom-operator)

Implementing Security Best Practices

Enabling Workload Identity

Workload Identity allows your GKE applications to access Google Cloud services securely:

# Enable Workload Identity on an existing cluster
gcloud container clusters update my-gke-cluster \
    --region us-central1 \
    --workload-pool=PROJECT_ID.svc.id.goog

# Update the node pool to use workload identity
gcloud container node-pools update default-pool \
    --cluster=my-gke-cluster \
    --region us-central1 \
    --workload-metadata=GKE_METADATA

Create a service account and grant permissions:

# Create a Google service account
gcloud iam service-accounts create gke-sa

# Grant permissions
gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:gke-sa@PROJECT_ID.iam.gserviceaccount.com" \
    --role="roles/storage.objectViewer"

# Bind the K8s service account to the Google service account
gcloud iam service-accounts add-iam-policy-binding \
    --role roles/iam.workloadIdentityUser \
    --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]" \
    gke-sa@PROJECT_ID.iam.gserviceaccount.com

Using Binary Authorization

Enable Binary Authorization to ensure only trusted container images are deployed:

gcloud container clusters update my-gke-cluster \
    --region us-central1 \
    --enable-binauthz

Enabling Network Policy

To enforce network security policies between pods:

# For new clusters
gcloud container clusters create my-gke-cluster \
    --enable-network-policy \
    [other flags...]

# For existing clusters
gcloud container clusters update my-gke-cluster \
    --region us-central1 \
    --update-addons=NetworkPolicy=ENABLED \
    --enable-network-policy

Create a default deny policy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

Setting Up CI/CD with Google Cloud Build and Cloud Deploy (Optional)

  1. Create a Cloud Source Repository or connect to GitHub/Bitbucket
  2. Create a cloudbuild.yaml file in your repo:
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA']
- name: 'gcr.io/cloud-builders/kubectl'
  args: [
    'set', 'image', 
    'deployment/my-app', 
    'my-app=gcr.io/$PROJECT_ID/my-app:$COMMIT_SHA'
  ]
  env:
  - 'CLOUDSDK_COMPUTE_REGION=us-central1'
  - 'CLOUDSDK_CONTAINER_CLUSTER=my-gke-cluster'
  1. Connect your repository to Cloud Build:
gcloud builds triggers create github \
    --repo=YOUR_GITHUB_REPO \
    --branch-pattern=main \
    --build-config=cloudbuild.yaml

Node and Cluster Upgrades

GKE handles node and cluster upgrades automatically when you create clusters with auto-upgrade enabled. For manual control:

# Upgrade the control plane
gcloud container clusters upgrade my-gke-cluster \
    --region us-central1 \
    --master

# Upgrade nodes
gcloud container clusters upgrade my-gke-cluster \
    --region us-central1

Cleaning Up

When you're done with your cluster:

# Delete the cluster
gcloud container clusters delete my-gke-cluster --region us-central1

# Optional: Clean up other resources
gcloud compute disks list  # List any orphaned disks
gcloud compute disks delete DISK_NAME  # Delete orphaned disks

Troubleshooting

Common Issues

  1. Node allocation failure: Check project quotas and limits
  2. Unable to access APIs: Verify API services are enabled
  3. Pod networking issues: Check network policies and VPC settings

Getting Logs

# Check cluster events
kubectl get events --sort-by='.lastTimestamp'

# View logs for specific pods
kubectl logs pod-name -n namespace

# Use Google Cloud Logging for comprehensive logs
gcloud logging read "resource.type=k8s_container" --limit=10

Additional Resources


This guide provides a foundation for deploying a production-ready GKE cluster. For specific use cases or additional configuration, refer to the official Google Cloud documentation.