Provides step-by-step instructions for accessing the Rackspace Spot Kubernetes cluster to debug ARC runners using spotctl...
This guide provides instructions for accessing the Matchpoint ARC runners Kubernetes cluster on Rackspace Spot using spotctl. The cluster hosts GitHub Actions self-hosted runners managed by Actions Runner Controller (ARC).
| Property | Value |
|---|---|
| GCP Project | project-beta-407300 |
| Secret Name | rackspace-spot-token |
| Organization ID | org_z0ELxD9LNTjgYwjc |
| Region | us-central-dfw-1 |
| Cloudspace Name | matchpoint-runners |
| Cluster Purpose | GitHub Actions ARC runners |
roles/secretmanager.secretAccessor on project-beta-407300# Install spotctl via pip
pip install spotctl
# Verify installation
spotctl --version
Note: If pip fails, ensure Python 3.8+ is installed:
python3 --version
pip3 install spotctl
# Login to GCP
gcloud auth login
# Set project
gcloud config set project project-beta-407300
# Verify access to secret
gcloud secrets versions access latest --secret=rackspace-spot-token
# Get the API token from GCP Secret Manager
export RACKSPACE_SPOT_TOKEN=$(gcloud secrets versions access latest \
--secret=rackspace-spot-token \
--project=project-beta-407300)
# Verify token retrieved (should show non-empty string)
echo "Token retrieved: ${RACKSPACE_SPOT_TOKEN:0:20}..."
Troubleshooting:
roles/secretmanager.secretAccessor# Configure spotctl with organization and token
spotctl configure set organization org_z0ELxD9LNTjgYwjc
spotctl configure set token "$RACKSPACE_SPOT_TOKEN"
# Verify configuration
spotctl configure get organization
spotctl configure get token # Will show masked token
Alternative: Use environment variable directly
# spotctl respects SPOT_TOKEN env var
export SPOT_TOKEN="$RACKSPACE_SPOT_TOKEN"
export SPOT_ORGANIZATION="org_z0ELxD9LNTjgYwjc"
# List available cloudspaces to confirm access
spotctl cloudspace list
# Get kubeconfig for the matchpoint-runners cluster
spotctl cloudspace kubeconfig matchpoint-runners > /tmp/matchpoint-runners-kubeconfig.yaml
# Set KUBECONFIG environment variable
export KUBECONFIG=/tmp/matchpoint-runners-kubeconfig.yaml
# Verify connectivity
kubectl cluster-info
kubectl get nodes
Expected Output:
NAME STATUS ROLES AGE VERSION
matchpoint-runners-pool-abc123-node-xyz456 Ready <none> 5d v1.28.x
matchpoint-runners-pool-abc123-node-xyz789 Ready <none> 5d v1.28.x
# List all runner pods across namespaces
kubectl get pods -A -l app.kubernetes.io/component=runner
# Check specific namespace (primary runner namespace)
kubectl get pods -n arc-beta-runners-new -l app.kubernetes.io/component=runner
# Get pod details with node placement
kubectl get pods -n arc-beta-runners-new -o wide
# List AutoscalingRunnerSets
kubectl get autoscalingrunnerset -A
# Describe specific scale set
kubectl get autoscalingrunnerset arc-beta-runners -n arc-beta-runners-new -o yaml
# Check scaling status
kubectl get autoscalingrunnerset -A -o custom-columns=\
NAME:.metadata.name,\
NAMESPACE:.metadata.namespace,\
MIN:.spec.minRunners,\
MAX:.spec.maxRunners,\
CURRENT:.status.currentRunners
# Check controller pods
kubectl get pods -n arc-systems
# View controller logs
kubectl logs -n arc-systems deployment/arc-gha-rs-controller --tail=100 --follow
# Check for errors in controller
kubectl logs -n arc-systems deployment/arc-gha-rs-controller | grep -i error
# Get logs from a specific runner pod
kubectl logs -n arc-beta-runners-new <pod-name>
# Follow logs in real-time
kubectl logs -n arc-beta-runners-new <pod-name> -f
# Get logs from all containers in a pod (if using DinD sidecar)
kubectl logs -n arc-beta-runners-new <pod-name> --all-containers
# Get previous container logs (if pod restarted)
kubectl logs -n arc-beta-runners-new <pod-name> --previous
# Get recent events in runner namespace
kubectl get events -n arc-beta-runners-new --sort-by='.lastTimestamp' | tail -20
# Check for scaling events
kubectl get events -n arc-beta-runners-new --field-selector reason=ScalingReplicaSet
# Check for pod errors
kubectl get events -A --field-selector type=Warning
# List nodes with capacity
kubectl get nodes -o wide
# Check node resource usage
kubectl top nodes
# Check pod resource usage
kubectl top pods -n arc-beta-runners-new
# Describe node for detailed info
kubectl describe node <node-name>
# List secrets in runner namespace
kubectl get secrets -n arc-beta-runners-new
# Check GitHub token secret exists
kubectl get secret arc-beta-runners-gha-rs-github-secret -n arc-beta-runners-new
# List ConfigMaps
kubectl get configmaps -n arc-beta-runners-new
# Get shell in runner pod (for debugging)
kubectl exec -it -n arc-beta-runners-new <pod-name> -- /bin/bash
# Run specific command in runner
kubectl exec -n arc-beta-runners-new <pod-name> -- env | grep RUNNER
# Check Docker availability (if DinD enabled)
kubectl exec -n arc-beta-runners-new <pod-name> -- docker version
Error: pip: command not found
# Install pip
sudo apt install python3-pip # Debian/Ubuntu
brew install python3 # macOS
Error: spotctl: command not found after install
# Check if installed in user site-packages
python3 -m site --user-site
# Add to PATH
export PATH="$HOME/.local/bin:$PATH"
# Or use full path
python3 -m spotctl --version
Error: Invalid token
# Verify token from GCP Secret Manager is correct
gcloud secrets versions access latest --secret=rackspace-spot-token --project=project-beta-407300
# Re-configure spotctl
spotctl configure set token "$RACKSPACE_SPOT_TOKEN"
Error: Organization not found
# Verify organization ID
spotctl configure get organization
# Should show: org_z0ELxD9LNTjgYwjc
# Reset if wrong
spotctl configure set organization org_z0ELxD9LNTjgYwjc
Error: Unable to connect to cluster
# Verify kubeconfig is set correctly
echo $KUBECONFIG
# Should show: /tmp/matchpoint-runners-kubeconfig.yaml
# Test connectivity with verbose output
kubectl cluster-info --v=8
# Check if kubeconfig is valid YAML
cat $KUBECONFIG | kubectl config view --minify
Error: Token expired
Rackspace Spot kubeconfig tokens expire after 3 days. Regenerate:
# Get fresh kubeconfig
spotctl cloudspace kubeconfig matchpoint-runners > /tmp/matchpoint-runners-kubeconfig.yaml
export KUBECONFIG=/tmp/matchpoint-runners-kubeconfig.yaml
Alternative: Use Terraform-managed kubeconfig
The terraform state maintains a fresh kubeconfig (auto-refreshed every 2 days):
# Get GitHub token from gh CLI config
export TF_HTTP_PASSWORD=$(cat ~/.config/gh/hosts.yml | grep oauth_token | awk '{print $2}')
# Navigate to terraform directory
cd /home/pselamy/repositories/matchpoint-github-runners-helm/terraform
# Initialize terraform
terraform init -input=false
# Get kubeconfig from output
terraform output -raw kubeconfig_raw > /tmp/runners-kubeconfig.yaml
export KUBECONFIG=/tmp/runners-kubeconfig.yaml
# Test
kubectl get nodes
See the rackspace-spot-best-practices skill for more details on kubeconfig token expiration.
Error: Cloudspace not found
# List all cloudspaces in org
spotctl cloudspace list
# Verify cloudspace name matches
# Expected: matchpoint-runners
# Region: us-central-dfw-1
# If using different region, specify explicitly
spotctl configure set region us-central-dfw-1
# Complete setup in one command sequence
export RACKSPACE_SPOT_TOKEN=$(gcloud secrets versions access latest --secret=rackspace-spot-token --project=project-beta-407300) && \
spotctl configure set organization org_z0ELxD9LNTjgYwjc && \
spotctl configure set token "$RACKSPACE_SPOT_TOKEN" && \
spotctl cloudspace kubeconfig matchpoint-runners > /tmp/matchpoint-runners-kubeconfig.yaml && \
export KUBECONFIG=/tmp/matchpoint-runners-kubeconfig.yaml && \
kubectl get nodes
# Quick health check
kubectl get pods -A -l app.kubernetes.io/component=runner
kubectl get autoscalingrunnerset -A
kubectl logs -n arc-systems deployment/arc-gha-rs-controller --tail=20
kubectl get events -n arc-beta-runners-new --sort-by='.lastTimestamp' | tail -10
# Check runners registered with GitHub (requires gh CLI)
gh api /orgs/Matchpoint-AI/actions/runners --jq '.runners[] | {name, status, busy, labels: [.labels[].name]}'
# Count online runners
gh api /orgs/Matchpoint-AI/actions/runners --jq '[.runners[] | select(.status=="online")] | length'
Never commit tokens to git
Use short-lived sessions
~/.bashrc or ~/.zshrcRotate tokens regularly
Use temporary files
# Store in /tmp (cleared on reboot)
spotctl cloudspace kubeconfig matchpoint-runners > /tmp/kubeconfig.yaml
Set restrictive permissions
chmod 600 /tmp/matchpoint-runners-kubeconfig.yaml
Clean up after use
# When done debugging
unset KUBECONFIG
rm /tmp/matchpoint-runners-kubeconfig.yaml
| Issue/PR | Description |
|---|---|
| #135 | Epic: ARC runner environment limitations |
| #136 | Document troubleshooting learnings in skills |
| #137 | PR: Auto-refresh kubeconfig token workflow |
| #142 | This skill - Rackspace Spot cluster access guide |
Use this checklist to verify cluster access is working:
spotctl installed and in PATHgcloud auth list)spotctl configure set with org and tokenmatchpoint-runners visible in spotctl cloudspace list$KUBECONFIGkubectl get nodes returns nodes successfullykubectl get pods -A returns pods successfullyarc-systems namespacearc-beta-runners-new namespace