Tech ONTAP Blogs

NetApp Trident Orchestrates Google Cloud NetApp Volumes Block for Kubernetes

DianePatton
NetApp
702 Views

Authors: Zach Ward & Diane Patton, NetApp

 

Exciting update for container developers and operators!  If your applications need high-performance block storage, Google Cloud NetApp Volumes (GCNV) now has you covered. With the general availability of Enterprise block (iSCSI) with Flex Unified storage pools in GCNV and the latest NetApp® Trident CSI Provisioner (v26.02), you can now easily provision and manage iSCSI block volumes directly for your container workloads.

 

This article will discuss Trident, advantages of using Trident with GCNV Block storage, and how to set it up to get your stateful containerized applications up and running in no time!

 

What is NetApp Trident?

 

NetApp Trident is an open-source dynamic storage orchestrator for Kubernetes that allows developers and application owners to provision storage on-demand from various NetApp storage systems. When paired with Google Cloud NetApp Volumes Flex Unified block storage—a type of storage ideal for applications that require low-latency, high-performance, and direct access to raw volumes (such as self-managed databases)—Trident automates the entire provisioning lifecycle, bringing enterprise-grade capabilities to containerized workloads.

 

Why use Trident with GCNV Block Storage?

 

Integrating Trident with your GCNV block storage provides several crucial benefits for modern container environments running applications that need block storage:

  • Dynamic Provisioning: Trident eliminates the manual process of creating volumes. When a PersistentVolumeClaim (PVC) is created in Kubernetes, Trident automatically provisions the corresponding block storage volume according to the storage class and can place the volume in a pool that delivers your performance requirements.
  • Storage Efficiency: Trident manages the underlying GCNV storage pools intelligently, ensuring efficient use of capacity.
  • Simplified Operations: It abstracts the complexity of the storage infrastructure from the application developer. Developers focus on their applications, while Trident ensures they have the right type of block storage when and where they need it. 
  • Advanced Data Services: By integrating with Google Cloud NetApp Volumes, Trident allows Kubernetes users to leverage enterprise-grade data services directly including:  
    • Snapshots: Trident and/or GCNV can create instant, space-efficient volume snapshots.
    • Volume Resizing: Dynamically resize your PV using Trident.
    • Backups and Replication: You can leverage Google Cloud Run to create a GCNV backup policy when Trident creates a new volume or to create replication.

                    As well as others.

  • Simplified Operations: It abstracts the complexity of the storage infrastructure from the application developer. Developers focus on their applications, while Trident ensures they have the right type of block storage when and where they need it.

Common Use Cases

 

The combination of Trident and GCNV block storage is particularly powerful for:

  • Stateful Databases: High-performance databases like MySQL, PostgreSQL, or MongoDB that require low-latency I/O benefit greatly from dedicated block volumes. Trident ensures these GCNV volumes are provisioned and managed seamlessly within the Kubernetes cluster.
  • Virtual Desktop Infrastructure (VDI): Environments requiring dedicated, persistent storage for user profiles and operating systems.
  • Development, Testing and Reporting: Rapidly cloning production volumes using GCNV, and quickly importing the clone into Trident speeds up CI/CD workflows and reduces time-to-market.
  • High-Performance Computing (HPC): Applications demanding the fastest possible access to storage for intensive data processing.

How do I deploy NetApp Trident with GCNV iSCSI volumes? 

 

Setting up Trident with GCNV block storage is very similar to Trident with file storage and you can be up and running in just a few steps!

 

Step 1: Create your Flex Unified storage pool on Google Cloud NetApp Volumes

 

Create a storage pool using the Flex service level and Unified type. Be sure to use a regional pool which replicates your data to another zone for disaster recovery purposes. Zonal pools will be available with Trident soon.

 

We will direct Trident to place all new volumes in this pool. You may also create multiple storage pools to be used by Trident, and specify the ones for Trident to use. Alternatively, you may just specify criteria and Trident will select a pool in that region that matches that criteria. The choice is yours. 

The example below shows creating a regional storage pool on the console. You may also create a storage pool using the gcloud CLI or the API. We will call the pool flex-unified-pool.

 

 

Screenshot 2026-03-01 at 7.28.49 PM.png

 

 

 

 

Step 2: Install iSCSI tools on the worker nodes

 

Be sure to  install iscsi tools on the worker nodes if not already installed by default. . Please see the Trident documentation for the exact tools and commands.

 

Kubernetes nodes must meet the following requirements to attach block volumes provisioned from Google Cloud NetApp Volumes:

  1. iSCSI initiator installed and running
  2. Multipath enabled and configured properly
  3. Network connectivity to the Google Cloud NetApp Volumes iSCSI endpoints 

 

Step 3: Install Trident version 26.02 or later on your Kubernetes Cluster

 

The various methods to install Trident 26.02 are independent of your Kubernetes distribution. You have a choice of one of 3 methods.: tridentctl, trident operator or Helm. We will use Helm as an example here.

 

Install the helm repo:

 

helm repo add netapp-trident https://netapp.github.io/trident-helm-chart

 

Next install Trident using Helm:

 

helm install trident netapp-trident/trident-operator --version 100.2602.0 --create-namespace --namespace trident

 

Step 4: Create the Trident backend

 

Now, you’re ready to  create a Trident backend for your iSCSI volumes. 

 

First, create a secret for authentication into Google Cloud NetApp Volumes. As a quick example, you can use your service account credentials to create a secret:

 

apiVersion: v1
kind: Secret
metadata:
  name: gcnv-sa-secret
  namespace: trident
type: Opaque
stringData:
  private_key_id: "..."
  private_key: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"

$ k apply -f gcnv-secret.yaml -n trident

 

Use this secret in your backend config.  Be sure to use the storageDriverName google-cloud-netapp-volumes-san and apply the backend file: 

 

apiVersion: trident.netapp.io/v1
kind: TridentBackendConfig
metadata:
 name: gcnv-iscsi
 namespace: trident
spec:
 version: 1
 storageDriverName: google-cloud-netapp-volumes-san
 projectNumber: "<yourprojnumhere>"
 location: <location of your pool like us-east4>
 sdkTimeout: "600"
 apiKey:
  type: service_account
  project_id: <YOUR project ID here>
  private_key_id: "" # Leave empty - comes from Secret
  private_key: ""   # Leave empty - comes from Secret
  client_email: <your client email here>
  client_id: <your client id here>
  auth_uri: "https://accounts.google.com/o/oauth2/auth"
  token_uri: "https://oauth2.googleapis.com/token"
  auth_provider_x509_cert_url: <get from your SA credentials>
  client_x509_cert_url: <get from your SA credentials>
 credentials:
  name: <your secret name>
  type: secret
 storage:
 - labels:
   cloud: gcp
   performance: flex
  network: <insert vpc network here>
  serviceLevel: Flex
  storagePools:
    - flex-unified-pool

$ k apply -f backend.yaml -n trident

 

Flex-unified-pool is the name of your new storage pool created in step 1.

 

If all is configured correctly, your backend should become bound successfully:

 

$ k get tbc -n trident
NAME         BACKEND NAME    BACKEND UUID   PHASE   STATUS
gcnv-iscsi   gcnv-iscsi      ...            Bound   Success

 

More information can be found at Configure Google Cloud NetApp Volumes for SAN workloads.

 

Step 5: Create the Storage Class for ISCSI volumes

 

An example storage class is shown below. Be sure to use google-cloud-netapp-volumes-san as the backendType.

 

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: gcnv-san
provisioner: csi.trident.netapp.io
parameters:
 backendType: "google-cloud-netapp-volumes-san"
 fsType: "ext4"
allowVolumeExpansion: true


$ k apply -f storage-class.yaml -n trident

 

Step 6: Create the PVC and containerized application

 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-data
  namespace: default
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
  storageClassName: gcnv-san

$ kubectl apply -f mysql-pvc.yaml -n trident

$ kubectl get pvc mysql-data -n trident

NAME         STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-data   Bound    pvc-...   101Gi      RWO            gcnv-san       12s

 

Trident returns a volume size of one GiB larger than the PVC requested. GCNV block volumes have a small amount of internal metadata overhead that reduces the kernel-visible device size compared to the provisioned capacity. Testing shows this overhead can be up to ~300 KiB on initial creation and up to ~107 MiB after a resize. To ensure the usable space on the device always meets or exceeds what the  PVC requested, Trident rounds the requested size up to the next  GiB to add a 1 GiB buffer. For example, a 100 GiB PVC request results in a 101 GiB volume in GCNV, guaranteeing that the usable space visible to your application is at least 100 GiB.

 

Below, we create the MySQL deployment:

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8.0
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: "my-secret-pw"
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-data
          persistentVolumeClaim:
            claimName: mysql-data

$ kubectl apply -f mysql-deployment.yaml 

$ kubectl get pods  -l app=mysql
NAME                     READY   STATUS    RESTARTS   AGE
mysql-6c4f7b8d9f-xk2pv   1/1     Running   0          45s

$ kubectl describe pod mysql-6c4f7b8d9f-xk2pv -n trident
Name:             mysql-6c4f7b8d9f-xk2pv
Namespace:        default
Priority:         0
Service Account:  default
Node:             gke-trident-gcnv-san-fle-default-pool-3c7571ea-bwhl/10.150.0.52
Start Time:       Thu, 26 Feb 2026 10:15:32 -0700
Labels:           app=mysql
                  pod-template-hash=6c4f7b8d9f
Status:           Running
IP:               10.80.0.12
Containers:
  mysql:
    Container ID:  containerd://a3d1f8e92b4c7d6a5e0f1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2
    Image:         mysql:8.0
    Port:          3306/TCP
    State:          Running
      Started:      Thu, 26 Feb 2026 10:16:04 -0700
    Ready:          True
    Restart Count:  0
    Environment:
      MYSQL_ROOT_PASSWORD:  my-secret-pw
    Mounts:
      /var/lib/mysql from mysql-data (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-r7m4k (ro)
Volumes:
  mysql-data:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  mysql-data
    ReadOnly:   false
  kube-api-access-r7m4k:
    Type:                    Projected
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
Events:
  Type    Reason                  Age   From                     Message
  ----    ------                  ----  ----                     -------
  Normal  Scheduled               38s   default-scheduler        Successfully assigned trident/mysql-6c4f7b8d9f-xk2pv to gke-trident-gcnv-san-fle-default-pool-3c7571ea-bwhl
  Normal  SuccessfulAttachVolume  31s   attachdetach-controller  AttachVolume.Attach succeeded for volume "pvc-8e0dd07f-0f1f-4848-8ea9-507da0f7a1b1"
  Normal  Pulled                  24s   kubelet                  Container image "mysql:8.0" already present on machine
  Normal  Created                 24s   kubelet                  Created container: mysql
  Normal  Started                 24s   kubelet                  Started container app

 

Now what?

 

NetApp Trident with GCNV block storage is a powerful pairing for any organization running stateful workloads on Kubernetes. It automates storage provisioning, brings GCNV’s robust data services into the container ecosystem, and simplifies the entire storage management plane. By bridging the gap between container orchestration and Google Cloud NetApp volumes, it allows you to fully harness the agility and scalability of Kubernetes without compromising on performance or data management capabilities in Google Cloud!  Now you can use Trident for both file (NFS, SMB) and block (iSCSI). Try it yourself!  More information can be found in the Trident documentation and Google Cloud NetApp Volumes documentation.

Public