Install and operate
GCP HyperShift Setup & Operation
Complete guide for setting up and managing Sentinel HyperShift clusters on Google Cloud Platform.
WARNING: UNVERIFIED DRAFT. GCP HyperShift is tech preview upstream, requires a GKE Autopilot management cluster and Workload Identity (not service-account JSON keys). Steps, IAM roles, quotas, costs and links below were written before verification and must not be followed as-is. See "GCP Verification" in
docs/_internal/superpowers/specs/2026-10-11-multicloud-hypershift-design.md.Status: Not implemented (Phase 3 blocked)
Timeline: See Design Spec
Prerequisites#
Tools Required#
| Tool | Version | Purpose |
|---|---|---|
| gcloud CLI | Latest | GCP resource management |
| kubectl | 1.28+ | Kubernetes cluster interaction |
| jq | Latest | JSON processing |
| Bash | 3.2+ | Script execution |
| Python | 3.11+ | E2E tests |
macOS Installation#
# gcloud CLI
curl https://sdk.cloud.google.com | bash
exec -l $SHELL # Restart shell
# Other tools
brew install kubectl jq python@3.11
Linux (Ubuntu/Debian)#
# gcloud CLI
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | \
sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | \
sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
sudo apt-get update
sudo apt-get install -y google-cloud-sdk kubectl jq python3.11
GCP Project Requirements#
- GCP Project with billing enabled
- Compute quota (default usually sufficient): - Compute Engine VMs: 10+ - vCPUs: 50+ - Persistent Disks: 50+ - In-use IP addresses: 10+ - Load balancers: 10+
- Cloud DNS zone (for cluster API endpoints)
- Service account (for HyperShift)
One-Time Setup (GCP Admin)#
These steps run once to prepare your GCP project. You need admin access only for this phase.
Step 1: Authenticate with gcloud#
# Login to GCP
gcloud auth login
# Set your project
export GCP_PROJECT_ID="my-project-id"
gcloud config set project $GCP_PROJECT_ID
# Verify
gcloud auth list
gcloud config get-value project
Step 2: Enable Required APIs#
# Enable necessary APIs
gcloud services enable \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com \
dns.googleapis.com \
container.googleapis.com \
containerregistry.googleapis.com
Step 3: Create Cloud DNS Zone#
HyperShift needs a delegated DNS zone for cluster APIs:
# Create Cloud DNS zone
gcloud dns managed-zones create sentinel-hcp \
--dns-name=sentinel-dev.example.com \
--description="HyperShift clusters"
# Get nameservers
gcloud dns managed-zones describe sentinel-hcp --format='value(nameServers)'
# Output: [ns-123.googledomains.com., ns-456.googledomains.com., ...]
# Delegate from your domain registrar:
# Update your domain's nameservers to point to the above
Verify delegation (may take a few minutes):
dig ns sentinel-dev.example.com
# Should show Google nameservers
Step 4: Create Service Account#
HyperShift needs a service account with permissions to create resources:
# Create service account
gcloud iam service-accounts create sentinel-hcp \
--display-name="Sentinel HyperShift Service Account"
# Get service account email
export SERVICE_ACCOUNT_EMAIL="sentinel-hcp@${GCP_PROJECT_ID}.iam.gserviceaccount.com"
# Grant required roles
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
--role=roles/compute.admin
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
--role=roles/dns.admin
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
--role=roles/iam.securityAdmin
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member=serviceAccount:$SERVICE_ACCOUNT_EMAIL \
--role=roles/resourcemanager.projectIamAdmin
Step 5: Create Service Account Key#
# Create key (JSON format)
gcloud iam service-accounts keys create \
~/gcp-sentinel-hcp-key.json \
--iam-account=$SERVICE_ACCOUNT_EMAIL
# Keep this file secure (git-ignored)
ls -la ~/gcp-sentinel-hcp-key.json
# Base64 encode it (for GitHub Actions)
cat ~/gcp-sentinel-hcp-key.json | base64 -w0
Step 6: Login to Management Cluster#
You need cluster-admin access to the existing HyperShift management cluster:
# Get management cluster kubeconfig (from whoever set it up)
export KUBECONFIG=~/.kube/hypershift_mgmt
# Verify access
kubectl cluster-info
kubectl get ns | grep hypershift
Step 7: Create Scoped Credentials#
This creates GCP IAM bindings for HyperShift:
# Run the credential setup script
./.github/scripts/hypershift/cloud/gcp/setup-credentials.sh
# This:
# 1. Creates service account bindings
# 2. Creates GCP IAM roles for hosted control planes
# 3. Creates OpenShift service account
# 4. Outputs: .env.sentinel-hypershift-gcp
Output: .env.sentinel-hypershift-gcp (git-ignored)
# Contents:
export CLOUD_PLATFORM=gcp
export GCP_PROJECT_ID=my-project-id
export GCP_REGION=us-central1
export GCP_SERVICE_ACCOUNT_JSON=$(cat ~/gcp-sentinel-hcp-key.json | base64 -w0)
export HYPERSHIFT_MGMT_KUBECONFIG=~/.kube/hypershift_mgmt
export PULL_SECRET=$(cat ~/.docker/config.json)
export BASE_DOMAIN=sentinel-dev.example.com
export MANAGED_BY_TAG=sentinel-hypershift-custom
export GCP_HCP_ROLE_NAME=sentinel-hypershift-custom-hcp-role
Step 8: Verify Setup#
# Load the new GCP credentials
source .env.sentinel-hypershift-gcp
# Run preflight check
./.github/scripts/hypershift/cloud/gcp/preflight-check.sh
# Output should show:
# ✓ GCP credentials valid
# ✓ Management cluster accessible
# ✓ Cloud DNS zone exists
# ✓ Quotas sufficient
# ✓ Pull secret present
✅ One-time setup complete! You now have GCP credentials for daily development.
Daily Usage (Scoped Credentials)#
After one-time setup, use these credentials for all cluster operations.
Quick Start#
# 1. Load your GCP credentials
source .env.sentinel-hypershift-gcp
# 2. Create a cluster
./.github/scripts/hypershift/create-cluster.sh
# Wait 15-20 minutes...
# ✓ Cluster created on GCP
# ✓ Kubeconfig saved to ~/.clusters/hcp/<cluster-name>/
# 3. Use the cluster
export KUBECONFIG=~/.clusters/hcp/sentinel-hypershift-custom-gcp-<suffix>/auth/kubeconfig
kubectl get nodes
# 4. Run tests
uv run pytest sentinel/tests/e2e/ -v
# 5. Cleanup
./.github/scripts/hypershift/destroy-cluster.sh <suffix>
Cluster Naming#
Clusters are named: sentinel-hypershift-custom-gcp-${SUFFIX}
Suffix options:
# Default: Your username (automatically sanitized)
./.github/scripts/hypershift/create-cluster.sh
# → sentinel-hypershift-custom-gcp-ladas
# Custom suffix
./.github/scripts/hypershift/create-cluster.sh pr529
# → sentinel-hypershift-custom-gcp-pr529
# Random suffix
CLUSTER_SUFFIX="" ./.github/scripts/hypershift/create-cluster.sh
# → sentinel-hypershift-custom-gcp-abc123
Accessing the Cluster#
# List available kubeconfigs
ls ~/.clusters/hcp/
# Set kubeconfig for your cluster
export KUBECONFIG=~/.clusters/hcp/sentinel-hypershift-custom-gcp-pr529/auth/kubeconfig
# Verify access
kubectl cluster-info
kubectl get nodes
kubectl get pods -A
Destroying Clusters#
# Destroy specific cluster
./.github/scripts/hypershift/destroy-cluster.sh pr529
# Or by full name
./.github/scripts/hypershift/destroy-cluster.sh sentinel-hypershift-custom-gcp-pr529
Important: Always destroy test clusters to avoid GCP costs!
Configuration#
Cluster Parameters#
Control cluster characteristics via environment variables:
# Number of worker nodes (default: 2)
export REPLICAS=3
./.github/scripts/hypershift/create-cluster.sh
# Machine type (default: n1-standard-4)
export MACHINE_TYPE=n1-standard-8
./.github/scripts/hypershift/create-cluster.sh
# OpenShift version (default: 4.20.11)
export OCP_VERSION=4.19.12
./.github/scripts/hypershift/create-cluster.sh
# Autoscaling (default: min=2, max=5)
export AUTOSCALE_MIN=1
export AUTOSCALE_MAX=10
./.github/scripts/hypershift/create-cluster.sh
# Disable autoscaling
export AUTOSCALE_MIN=""
export AUTOSCALE_MAX=""
./.github/scripts/hypershift/create-cluster.sh
GCP Region#
# Create cluster in different region
export GCP_REGION=europe-west1
./.github/scripts/hypershift/create-cluster.sh
Supported regions: Any GCP region in your project
CI/CD Integration#
GitHub Actions Matrix#
Both AWS and GCP run simultaneously:
strategy:
matrix:
cloud: [aws, gcp]
max-parallel: 2
Each cloud gets its own secrets and creates clusters independently.
Secrets Configuration#
- Go to Repository Settings → Secrets and variables → Actions
-
Add these secrets (same names as
.envfile): -GCP_PROJECT_ID-GCP_REGION-GCP_SERVICE_ACCOUNT_JSON(base64) -HYPERSHIFT_MGMT_KUBECONFIG(base64) -PULL_SECRET(JSON) -BASE_DOMAIN-MANAGED_BY_TAG-GCP_HCP_ROLE_NAME -
Create Environments for
e2e-awsande2e-gcpwith separate secret sets
Trigger E2E Tests#
# Automatic: Push to main or open PR
# Manual: GitHub Actions → e2e-hypershift → Run workflow
# Or via gh CLI
gh workflow run e2e-hypershift.yaml -f cluster_name=pr529
Troubleshooting#
Cluster Creation Fails#
Error: "ERROR: Quota exceeded"
Solution:
# Check your quotas
gcloud compute project-info describe --project=$GCP_PROJECT_ID | grep QUOTA
# View quota details
gcloud compute project-info describe --project=$GCP_PROJECT_ID \
--format="value(commonInstanceMetadata.items.compute-max-cpu-instances)" \
--format="value(quota.*)"
# Request quota increase in GCP Console
# IAM & Admin → Quotas → select resource → Edit Quotas → Request increase
Error: "ERROR: Cannot connect to management cluster"
Solution:
# Verify kubeconfig is set
echo $KUBECONFIG
# Verify it points to valid file
ls -la $KUBECONFIG
# Verify you can connect
kubectl cluster-info
Cluster Won't Delete#
Error: "ERROR: Timeout waiting for cluster deletion"
Solution:
# Check if control plane namespace is stuck
kubectl get ns clusters-sentinel-hypershift-custom-gcp-<suffix>
# Force delete if stuck
kubectl delete ns clusters-sentinel-hypershift-custom-gcp-<suffix> --grace-period=0 --force
# Check for orphaned GCP resources
./.github/scripts/hypershift/cloud/gcp/find-orphaned-resources.sh
# Manually delete via GCP Console if necessary
gcloud compute instances list --filter='labels.kubernetes_io_cluster_sentinel-hypershift-custom-gcp_*=owned'
Access Denied Errors#
Error: "Permission denied: 'compute.instances.create'"
Solution:
# Verify service account has permissions
gcloud projects get-iam-policy $GCP_PROJECT_ID \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:sentinel-hcp@*"
# Should show: roles/compute.admin, roles/dns.admin, roles/iam.securityAdmin
# If missing, re-run setup-credentials.sh
DNS Issues#
Error: "Could not resolve
Solution:
# Verify BASE_DOMAIN is correct
echo $BASE_DOMAIN
# Verify Cloud DNS zone exists
gcloud dns managed-zones list | grep sentinel
# Check created DNS records
gcloud dns record-sets list --zone=sentinel-hcp
# Verify nameserver delegation (may take propagation time)
dig ns sentinel-dev.example.com
Cost Management#
Monitoring Costs#
# GCP Console → Billing → Cost Management
# Filter by label: sentinel.io/managed-by = sentinel-hypershift-custom
# Or via gcloud CLI
gcloud billing accounts list
gcloud billing accounts describe <account-id> --format=json
Cost Breakdown#
Per cluster (typical): - Compute Engine: $25-45/month - Cloud Load Balancer: $15/month - VPC/Network: $5/month - Cloud DNS: <$1/month - Total: ~$45-65/month
Cost Optimization#
- Destroy unused clusters (biggest cost driver)
- Use smaller machines for non-critical tests (n1-standard-2 instead of n1-standard-4)
- Reduce node count (1 node instead of 2 if possible)
- Schedule tests to run only during business hours
- Use sustained use discounts (longer-running clusters)
Debugging#
Cluster Status#
# Check if cluster is ready
kubectl get hostedcluster -n clusters
# Check control plane pod status
kubectl get pods -n clusters-<cluster-name>
# View cluster events
kubectl describe hostedcluster -n clusters <cluster-name>
Logs#
# HyperShift operator logs
kubectl logs -n hypershift-system deployment/hypershift-operator -f
# Control plane pod logs
kubectl logs -n clusters-<cluster-name> <pod-name>
# GCP resource creation logs
gcloud logging read --limit=50 --format=json | jq '.[] | select(.resource.type=="gce_instance")'
GCP Resources#
# View all Compute Engine instances with sentinel labels
gcloud compute instances list \
--filter='labels.sentinel_io_managed_by=sentinel-hypershift-custom'
# View all Cloud DNS records
gcloud dns record-sets list --zone=sentinel-hcp
# View all network resources
gcloud compute networks list --filter='name~sentinel-hypershift'
# View firewall rules
gcloud compute firewall-rules list --filter='labels.sentinel_io_managed_by=sentinel-hypershift-custom'
Advanced: Custom VPC Configuration#
By default, HyperShift creates a new VPC for each cluster. To use existing VPC:
# Edit GCP Terraform to use existing VPC
# File: .github/scripts/hypershift/cloud/gcp/terraform/variables.tf
# Set network and subnet
export NETWORK="projects/<project>/global/networks/existing-vpc"
export SUBNET="projects/<project>/regions/<region>/subnetworks/existing-subnet"
./.github/scripts/hypershift/create-cluster.sh
Frequently Asked Questions#
Q: How long does cluster creation take?
A: 15-20 minutes typically. Monitor in CI logs or management cluster.
Q: Can I access the cluster while tests run?
A: Yes, kubeconfig is created immediately. Tests run concurrently.
Q: What happens to cluster after E2E tests?
A: It's automatically destroyed to save costs (unless you set skip_destroy=true).
Q: Can I use a different GCP region?
A: Yes, set GCP_REGION before creation.
Q: How much does a test cluster cost?
A: ~$2-3 per day (if running continuously). Always destroy when done.
Q: Can I modify a running cluster?
A: Yes, you have full kubectl access. Changes persist during test run.
Q: What if service account key expires?
A: Create a new key: gcloud iam service-accounts keys create ...
Related Documentation#
- ARCHITECTURE.md - Multi-cloud overview
- AWS.md - Amazon Web Services setup
- Troubleshooting - Common issues for both clouds
- Rotating HyperShift CI credentials - Secrets management details
Support#
- HyperShift Docs: https://hypershift-docs.readthedocs.io/
- GCP HyperShift: https://hypershift-docs.readthedocs.io/en/latest/how-to/gcp/
- GCP Docs: https://cloud.google.com/docs
- OpenShift Docs: https://docs.openshift.com/