Audience: Developers running Sentinel on GKE for integration testing before merging code changes.
IMPORTANT: This documentation covers running Sentinel for development and testing purposes. Production deployments are handled via hyperfleet-infra. For local development, see the Development Guide. For production deployment, see the Deployment Guide.
- GKE cluster access (use the shared cluster below or your own)
- GKE cluster must have Workload Identity enabled (required for Pub/Sub authentication; the shared dev cluster already has this enabled)
gcloudCLI configured and authenticatedkubectlconfigured for the clusterpodmanfor building imageshelmfor deploying the chart- Access to Google Container Registry (GCR) for your project
Set these variables once and use them throughout the deployment:
# GCP project ID
export GCP_PROJECT=hcm-hyperfleet
# Your namespace: hyperfleet-{env}-{username}
export NAMESPACE=hyperfleet-dev-${USER}
# Image tag: {namespace}-{git-sha-short} (follows naming convention)
export IMAGE_TAG=${NAMESPACE}-$(git rev-parse --short HEAD)
# Example: hyperfleet-dev-rafael-a1b2c3d (if USER=rafael)Note: The image tag format
{namespace}-{git-sha-short}follows the Naming Strategy convention to prevent collisions between developers.
A shared GKE cluster with Config Connector enabled is available for development and testing:
gcloud container clusters get-credentials hyperfleet-dev --zone=us-central1-a --project=${GCP_PROJECT}Usage guidelines:
- For personal work, create a namespace named after yourself to isolate resources
- For team collaboration, use a designated namespace to separate resources among members
Note: This environment is scheduled for deletion every Friday at 8:00 PM (EST). See GKE deployment docs for more details.
For pushing to your personal Quay registry:
# One-time login (required before pushing to Quay)
make quay-login
# Build and push to quay.io/${QUAY_USER}/${IMAGE_NAME}:dev-<commit>
QUAY_USER=${USER} make image-devThis will output the image tag to use in your terraform.tfvars.
For pushing to Google Container Registry:
# Build for AMD64 (required for GKE)
podman build --platform linux/amd64 -t gcr.io/${GCP_PROJECT}/sentinel:${IMAGE_TAG} .Note: If building on ARM64 Mac for AMD64 GKE, you must use
--platform linux/amd64to avoid architecture mismatch errors.
Note: If you used
make image-dev(Option A above), authentication and push are handled automatically. Skip to Helm Deployment. For Quay.io, ensure you've runmake quay-loginfirst.
gcloud auth configure-docker gcr.iopodman push gcr.io/${GCP_PROJECT}/sentinel:${IMAGE_TAG}Follow the Workload Identity for Pub/Sub instructions in the Deployment Guide. When running the gcloud command, use sentinel-test as the ServiceAccount name (matching the Helm release name in this guide).
Deploy Sentinel using the image you built:
If you used make image-dev, deploy with:
helm upgrade --install sentinel-test ./charts \
--namespace ${NAMESPACE} \
--create-namespace \
--set global.imageRegistry=quay.io \
--set image.repository=${USER}/hyperfleet-sentinel \
--set image.tag=dev-$(git rev-parse --short HEAD) \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=${GCP_PROJECT} \
--set monitoring.podMonitoring.enabled=trueIf you manually built and pushed to GCR, deploy with:
helm upgrade --install sentinel-test ./charts \
--namespace ${NAMESPACE} \
--create-namespace \
--set image.repository=gcr.io/${GCP_PROJECT}/sentinel \
--set image.tag=${IMAGE_TAG} \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=${GCP_PROJECT} \
--set monitoring.podMonitoring.enabled=true
# For Prometheus Operator environments (OpenShift, vanilla Kubernetes):
helm upgrade --install sentinel-test ./charts \
--namespace ${NAMESPACE} \
--create-namespace \
--set image.repository=gcr.io/${GCP_PROJECT}/sentinel \
--set image.tag=${IMAGE_TAG} \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=${GCP_PROJECT} \
--set monitoring.serviceMonitor.enabled=true \
--set monitoring.serviceMonitor.labels.release=prometheusTip: The default topic is
{namespace}-{resourceType}(e.g.,hyperfleet-dev-rafael-clusters). Override with--set broker.topic=custom-topic. See Naming Strategy for details.
kubectl get pods -n ${NAMESPACE} -l app.kubernetes.io/name=sentinelkubectl logs -n ${NAMESPACE} -l app.kubernetes.io/name=sentinel -fYou should see the startup messages:
2025-12-17T14:07:30.136547Z INFO [sentinel] [0.1.0] [pod-name] Loading configuration from /app/configs/sentinel.yaml
2025-12-17T14:07:30.137373Z INFO [sentinel] [0.1.0] [pod-name] Configuration loaded successfully: resource_type=clusters
2025-12-17T14:07:30.137382Z INFO [sentinel] [0.1.0] [pod-name] Starting HyperFleet Sentinel
Note: Sentinel outputs minimal logs during normal operation. Use the health endpoints (
/healthz,/readyz) and metrics to verify the service is running correctly. Configure--log-format=jsonfor production deployments.
Start port-forward in a separate terminal:
kubectl port-forward -n ${NAMESPACE} svc/sentinel-test 8080:8080 9090:9090Check health endpoints:
# Liveness
curl http://localhost:8080/healthz
# Readiness
curl http://localhost:8080/readyzCheck metrics:
curl http://localhost:9090/metrics | grep hyperfleet_sentinelFor GKE with Google Cloud Managed Prometheus (PodMonitoring):
kubectl get podmonitoring -n ${NAMESPACE}
kubectl describe podmonitoring -n ${NAMESPACE} -l app.kubernetes.io/name=sentinelFor Prometheus Operator environments (ServiceMonitor):
kubectl get servicemonitor -n ${NAMESPACE}
kubectl describe servicemonitor -n ${NAMESPACE} -l app.kubernetes.io/name=sentinel- Open the Metrics Explorer for your project
- In "Select a metric", search for
hyperfleet_sentinel - Select Prometheus Target > Hyperfleet > choose a metric (e.g.,
api_errors_total)
See Verify Workload Identity IAM Binding in the Deployment Guide.
Remove the deployment when done:
helm uninstall sentinel-test -n ${NAMESPACE}Optionally, delete the image from the registry:
gcloud container images delete gcr.io/${GCP_PROJECT}/sentinel:${IMAGE_TAG} \
--quiet --force-delete-tagsIf you configured Workload Identity, remove the IAM binding — see Remove Workload Identity IAM Binding in the Deployment Guide.
Problem: Container fails to start with exec format error
Cause: Architecture mismatch - image was built for a different CPU architecture than the target
Solution: Ensure --platform linux/amd64 is used when building:
podman build --platform linux/amd64 -t gcr.io/${GCP_PROJECT}/sentinel:${IMAGE_TAG} .Problem: Sentinel fails to start with "connection refused" errors for broker
Cause: Broker is not running or broker.yaml is configured for the wrong broker type
Solution:
- Verify the broker is running (RabbitMQ or Pub/Sub emulator)
- Ensure
broker.yamlhas the correcttype(rabbitmq or googlepubsub) - For Pub/Sub emulator, ensure
PUBSUB_EMULATOR_HOSTis set - For RabbitMQ, ensure
BROKER_RABBITMQ_URLis set or the URL inbroker.yamlis correct
Problem: Metrics are not visible in Google Cloud Metrics Explorer
Cause: PodMonitoring not configured correctly or GMP collector not scraping
Solution:
-
Verify PodMonitoring is created:
kubectl get podmonitoring -n ${NAMESPACE} -
Check GMP collector logs:
kubectl logs -n gmp-system -l app.kubernetes.io/name=collector
-
Ensure the metrics endpoint is accessible:
kubectl port-forward -n ${NAMESPACE} svc/sentinel-test 8080:8080 9090:9090 curl http://localhost:9090/metrics
Problem: Broker credentials not being picked up
Cause: Broker credentials must be set via environment variables, not ConfigMap
Solution: Use --set flags or a values file to set broker credentials:
--set broker.rabbitmq.url="amqp://user:pass@host:5672/"Problem: Sentinel cannot connect to HyperFleet API
Solution:
-
Verify the API endpoint is correct in your config
-
For local execution, ensure the API is running
-
For GKE, use the in-cluster service name:
clients: hyperfleet_api: base_url: http://hyperfleet-api.hyperfleet-system.svc.cluster.local:8080
Problem: Build fails with missing package errors
Cause: OpenAPI client was not generated
Solution: Run the generate target before building:
make generate
make build