Skip to main content
This guide walks through deploying Flyte on GKE using the flyte-binary Helm chart, backed by Google Cloud Storage (GCS) and Cloud SQL PostgreSQL.

Prerequisites

Create a GKE cluster with Workload Identity enabled:
gcloud container clusters create flyte \
  --region us-central1 \
  --machine-type n2-standard-4 \
  --num-nodes 3 \
  --workload-pool=<PROJECT_ID>.svc.id.goog
gsutil mb -l us-central1 gs://my-flyte-bucket
Create a Cloud SQL PostgreSQL 13+ instance. Enable the Cloud SQL Admin API and create a database named flyteadmin. Note the private IP address (or connection string if using Cloud SQL Auth Proxy).
Flyte uses Workload Identity to let Kubernetes service accounts impersonate Google Service Accounts (GSAs) without static keys.Create two GSAs:
# Backend GSA for Flyte control-plane components
gcloud iam service-accounts create flyte-backend \
  --project=<PROJECT_ID>

# Task GSA for user task pods
gcloud iam service-accounts create flyte-tasks \
  --project=<PROJECT_ID>
Grant GCS permissions:
gsutil iam ch \
  serviceAccount:flyte-backend@<PROJECT_ID>.iam.gserviceaccount.com:objectAdmin \
  gs://my-flyte-bucket

gsutil iam ch \
  serviceAccount:flyte-tasks@<PROJECT_ID>.iam.gserviceaccount.com:objectAdmin \
  gs://my-flyte-bucket
Bind the Kubernetes service accounts to the GSAs:
# Bind the flyte-backend KSA
gcloud iam service-accounts add-iam-policy-binding \
  flyte-backend@<PROJECT_ID>.iam.gserviceaccount.com \
  --role roles/iam.workloadIdentityUser \
  --member "serviceAccount:<PROJECT_ID>.svc.id.goog[flyte/flyte-backend]"

Installation

1

Add the Flyte Helm repo

helm repo add flyteorg https://flyteorg.github.io/flyte
helm repo update
2

Download the GKE starter values

curl -sL https://raw.githubusercontent.com/flyteorg/flyte/master/charts/flyte-binary/gke-starter.yaml \
  -o values.yaml
3

Edit values.yaml

Replace all placeholder values. See the annotated reference below.
4

Install with Helm

helm install flyte-backend flyteorg/flyte-binary \
  --namespace flyte \
  --create-namespace \
  --values values.yaml

GKE values reference

configuration:
  database:
    username: postgres
    password: ""              # Set to your Cloud SQL password
    host: 127.0.0.1           # Use Cloud SQL Auth Proxy sidecar or private IP
    dbname: flyteadmin

  storage:
    metadataContainer: "my-flyte-bucket"
    userDataContainer: "my-flyte-bucket"
    provider: gcs
    providerConfig:
      gcs:
        project: "<PROJECT_ID>"

  logging:
    level: 5
    plugins:
      stackdriver:
        enabled: true
        templateUri: |
          "https://console.cloud.google.com/logs/query;query=resource.labels.namespace_name%3D%22{{.namespace}}%22%0Aresource.labels.pod_name%3D%22{{.podName}}%22%0Aresource.labels.container_name%3D%22{{.containerName}}%22?project=<PROJECT_ID>"

  auth:
    enabled: false
    oidc:
      baseUrl: ""
      clientId: ""
      clientSecret: ""
    internal:
      clientId: flytepropeller
      clientSecret: ""
      clientSecretHash: ""
    authorizedUris: []

  inline:
    # Annotate default KSA in each project namespace with the task GSA
    cluster_resources:
      customData:
        - production:
          - defaultIamServiceAccount:
              value: flyte-tasks@<PROJECT_ID>.iam.gserviceaccount.com
        - staging:
          - defaultIamServiceAccount:
              value: flyte-tasks@<PROJECT_ID>.iam.gserviceaccount.com
        - development:
          - defaultIamServiceAccount:
              value: flyte-tasks@<PROJECT_ID>.iam.gserviceaccount.com

    plugins:
      k8s:
        inject-finalizer: true
        gpu-device-node-label: cloud.google.com/gke-accelerator
        gpu-partition-size-node-label: cloud.google.com/gke-gpu-partition-size
        resource-tolerations:
          - nvidia.com/gpu:
            - key: "nvidia.com/gpu"
              operator: "Equal"
              value: "present"
              effect: "NoSchedule"

    storage:
      cache:
        max_size_mbs: 10
        target_gc_percent: 100

    tasks:
      task-plugins:
        enabled-plugins:
          - container
          - sidecar
          - K8S-ARRAY
          - connector-service
          - echo
        default-for-task-types:
          - container: container
          - container_array: K8S-ARRAY

clusterResourceTemplates:
  inline:
    001_namespace.yaml: |
      apiVersion: v1
      kind: Namespace
      metadata:
        name: '{{ namespace }}'
    # Annotate the default KSA with the task GSA for Workload Identity
    002_serviceaccount.yaml: |
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: default
        namespace: '{{ namespace }}'
        annotations:
          iam.gke.io/gcp-service-account: '{{ defaultIamServiceAccount }}'

serviceAccount:
  create: true
  annotations:
    iam.gke.io/gcp-service-account: flyte-backend@<PROJECT_ID>.iam.gserviceaccount.com

rbac:
  create: true
  extraRules:
    - apiGroups: [""]
      resources: ["serviceaccounts"]
      verbs: ["create", "get", "patch"]

GCS IAM roles reference

GSARequired roleScope
flyte-backendroles/storage.objectAdminFlyte metadata bucket
flyte-tasksroles/storage.objectAdminUser data bucket
flyte-backendroles/cloudsql.clientCloud SQL instance

Verify the installation

kubectl get pods -n flyte

# Port-forward before DNS is configured
kubectl -n flyte port-forward service/flyte-binary 8088:8088 8089:8089
Open http://localhost:8088/console.

What’s next

Build docs developers (and LLMs) love