Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion infrabox/local-dev/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ services:
- "5432:5432"

minio:
image: minio/minio
image: quay.io/minio/minio
command: server /data
environment:
- MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
Expand Down
2 changes: 1 addition & 1 deletion infrabox/test/api/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ services:
dockerfile: ./src/postgres/Dockerfile

minio:
image: minio/minio
image: quay.io/minio/minio
command: server /data
environment:
- MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
Expand Down
2 changes: 1 addition & 1 deletion infrabox/utils/storage/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: "3.2"

services:
minio:
image: minio/minio
image: quay.io/minio/minio
command: server /data
environment:
- MINIO_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
Expand Down
63 changes: 63 additions & 0 deletions src/services/gcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,69 @@ or using
export KUBECONFIG="/var/run/infrabox.net/services/$SERVICE_NAME/kubeconfig"
```

## Spec Reference

| Field | Type | Default | Description |
|---|---|---|---|
| `zone` | string | — | GCP zone (required) |
| `machineType` | string | — | GKE node machine type |
| `numNodes` | int | — | Number of nodes |
| `diskSize` | int | — | Boot disk size in GB |
| `clusterVersion` | string | — | Kubernetes version (e.g. `1.37`) |
| `preemptible` | bool | false | Use preemptible nodes |
| `enableAutoscaling` | bool | false | Enable cluster autoscaling |
| `minNodes` | int | — | Minimum nodes (requires `enableAutoscaling`) |
| `maxNodes` | int | — | Maximum nodes (requires `enableAutoscaling`) |
| `enableNetworkPolicy` | bool | false | Enable Kubernetes network policy |
| `disableLegacyAuthorization` | bool | false | Disable legacy ABAC authorization |
| `enablePodSecurityPolicy` | bool | false | Enable Pod Security Policy |
| `stackType` | string | — | Set to `ipv4-ipv6` for dual-stack networking |
| `enableManagedPrometheus` | bool | false | Enable Google Managed Prometheus |
| `serviceCidr` | string | `/18` | Services IPv4 CIDR |
| `clusterCidr` | string | `/18` | Pods IPv4 CIDR |
| `keepAlive` | bool | false | Keep cluster running after job ends (see below) |

## Long-Running Clusters (keepAlive)

By default, GKE clusters are deleted as soon as the InfraBox job finishes. Set `keepAlive: true` to keep the cluster running after the job ends — useful for debugging or extended testing scenarios.

```json
"services": [{
"apiVersion": "gcp.service.infrabox.net/v1alpha1",
"kind": "GKECluster",
"metadata": {
"name": "my-cluster"
},
"spec": {
"zone": "us-east1-b",
"machineType": "n1-standard-1",
"numNodes": 1,
"diskSize": 100,
"clusterVersion": "1.37",
"keepAlive": true
}
}]
```

When `keepAlive: true`:
- The cluster is tagged with the GCP label `infrabox-keep-alive=true` at creation time
- InfraBox removes its CRD record when the job ends but does **not** delete the GKE cluster
- The cluster is excluded from InfraBox's GC loop

**Finding keepAlive clusters:**
```bash
gcloud container clusters list \
--filter="labels.infrabox-keep-alive=true" \
--format="table(name,zone,status,createTime)"
```

**Deleting a keepAlive cluster:**
```bash
gcloud container clusters delete <name> --zone <zone>
```

> **Note:** keepAlive clusters are not managed by InfraBox after the job ends. You are responsible for deleting them to avoid ongoing GCP costs.

## Install
To install the service in your Kubernetes cluster you have to first create a GCP Service Account with `Kubernetes Engine Admin` and `Service Account User` roles.
Download the service account json file and save it as `service_account.json`. Then create a secret for it:
Expand Down
2 changes: 2 additions & 0 deletions src/services/gcp/infrabox-service-gcp/templates/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ spec:
type: boolean
stackType:
type: string
keepAlive:
type: boolean
status:
x-kubernetes-preserve-unknown-fields: true
names:
Expand Down
1 change: 1 addition & 0 deletions src/services/gcp/pkg/apis/gcp/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type GKEClusterSpec struct {
ServiceCidr string `json:"serviceCidr,omitempty"`
ClusterCidr string `json:"clusterCidr,omitempty"`
EnableManagedPrometheus bool `json:"enableManagedPrometheus,omitempty"`
KeepAlive bool `json:"keepAlive,omitempty"`
}

type GKEClusterStatus struct {
Expand Down
14 changes: 13 additions & 1 deletion src/services/gcp/pkg/stub/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ func createCluster(cr *v1alpha1.GKECluster, log *logrus.Entry) (*v1alpha1.GKEClu
if !cr.Spec.EnableManagedPrometheus {
args = append(args, "--no-enable-managed-prometheus")
}
if cr.Spec.KeepAlive {
args = append(args, "--labels", "infrabox-keep-alive=true")
}
master_authorized_networks := os.Getenv("ALLOW_IPS")
if master_authorized_networks == "" {
master_authorized_networks = "0.0.0.0/0"
Expand Down Expand Up @@ -546,6 +549,15 @@ func checkTimeout(cr *v1alpha1.GKECluster, log *logrus.Entry) error {
}

func deleteGKECluster(cr *v1alpha1.GKECluster, log *logrus.Entry) error {
if cr.Spec.KeepAlive {
if err := cleanUpCrd(cr, log); err != nil {
log.Errorf("Failed to remove GKECluster CRD: %v", err)
return err
}
log.Infof("GKE cluster %s kept alive (keepAlive=true)", cr.Status.ClusterName)
return nil
}

// Get the GKE Cluster
gkecluster, err := getRemoteCluster(cr.Status.ClusterName, log)
if err != nil && !errors.IsNotFound(err) {
Expand Down Expand Up @@ -895,7 +907,7 @@ func cleanUpClusters(maxAge string, log *logrus.Entry) {

func getOutdatedClusters(maxAge string, log *logrus.Entry) ([]RemoteCluster, error) {
cmd := exec.Command("gcloud", "container", "clusters", "list",
"--filter", fmt.Sprintf("createTime<-P%s AND name:ib-*", maxAge),
"--filter", fmt.Sprintf("createTime<-P%s AND name:ib-* AND NOT labels.infrabox-keep-alive=true", maxAge),
"--format", "json")

out, err := cmd.Output()
Expand Down
Loading