New to KubeDB? Please start here.
Oracle Volume Expansion
This guide will show you how to use KubeDB Ops-manager operator to expand the volume of an Oracle database.
Before You Begin
At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using kind.
Install
KubeDBProvisioner and Ops-manager operator in your cluster following the steps here.You must have a
StorageClassthat supports volume expansion (i.e. its provisioner setsallowVolumeExpansion: true). This tutorial useslonghorn.
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 12d
longhorn driver.longhorn.io Delete Immediate true 12d
Note:
local-pathhasALLOWVOLUMEEXPANSION: false, so it cannot be used for volume expansion. Use a storage class such aslonghornthat supports it.
- To keep things isolated, this tutorial uses a separate namespace called
demo.
$ kubectl create ns demo
namespace/demo created
Note: YAML files used in this tutorial are stored in docs/examples/oracle/volume-expansion folder in GitHub repository kubedb/docs.
Oracle images are pulled from
container-registry.oracle.com. Every Oracle CR must reference an image pull secret (namedorclcredin this tutorial) throughspec.podTemplate.spec.imagePullSecrets. Create an Oracle Container Registry token, if you haven’t created one already, by following the instructions in the guide below: here
Deploy Oracle
In this section, we are going to deploy an Oracle standalone database with 10Gi of storage on the longhorn storage class. Below is the YAML of the Oracle CR,
apiVersion: kubedb.com/v1alpha2
kind: Oracle
metadata:
name: oracle-sa-sample
namespace: demo
spec:
podTemplate:
spec:
imagePullSecrets:
- name: orclcred
version: "21.3.0"
edition: enterprise
mode: Standalone
storageType: Durable
replicas: 1
storage:
storageClassName: "longhorn"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
deletionPolicy: WipeOut
Let’s create the Oracle CR and wait until it is Ready.
Once ready, let’s check the size of the PersistentVolumeClaim used by the database,
$ kubectl get pvc -n demo -l app.kubernetes.io/instance=oracle-sa-sample
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-oracle-sa-sample-0 Bound pvc-7c115ba3-ed65-4437-992c-aa8b789b0019 10Gi RWO longhorn 8m37s
Expand Volume
Here, we are going to expand the volume of the database to 12Gi.
Create OracleOpsRequest
In order to expand the volume of the database, we have to create an OracleOpsRequest CR with our desired volume size. Below is the YAML,
apiVersion: ops.kubedb.com/v1alpha1
kind: OracleOpsRequest
metadata:
name: standalone-volume-expention
namespace: demo
spec:
type: VolumeExpansion
databaseRef:
name: oracle-sa-sample
volumeExpansion:
mode: "Offline"
node: 12Gi
Here,
spec.typespecifies that we are performing aVolumeExpansionoperation.spec.databaseRef.namespecifies the databaseoracle-sa-sample.spec.volumeExpansion.nodespecifies the desired size of the database node’s PVC.spec.volumeExpansion.modespecifies the expansion mode.Offlinerecreates the pod after the PVC is resized;Onlineresizes the PVC without recreating the pod (the underlying storage class must support online expansion). For a DataGuard cluster, you can also setspec.volumeExpansion.observerto resize the observer’s PVC.
Let’s create the OracleOpsRequest,
$ kubectl create -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/oracle/volume-expansion/standalone-volume-expention.yaml
oracleopsrequest.ops.kubedb.com/standalone-volume-expention created
Verify the volume expanded
Let’s wait for the OracleOpsRequest to become Successful,
$ kubectl get oracleopsrequest -n demo standalone-volume-expention
NAME TYPE STATUS AGE
standalone-volume-expention VolumeExpansion Successful 61s
$ kubectl describe oracleopsrequest -n demo standalone-volume-expention
Name: standalone-volume-expention
Namespace: demo
...
Status:
Conditions:
Last Transition Time: 2026-06-22T20:04:52Z
Message: Oracle ops-request has started to expand volume of oracle nodes
Reason: VolumeExpansion
Status: True
Type: VolumeExpansion
Last Transition Time: 2026-06-22T20:05:14Z
Message: successfully deleted the petSets with orphan propagation policy
Reason: OrphanPetSetPods
Status: True
Type: OrphanPetSetPods
Last Transition Time: 2026-06-22T20:05:33Z
Message: successfully reconciled the Oracle resources
Reason: UpdatePetSets
Status: True
Type: UpdatePetSets
Last Transition Time: 2026-06-22T20:05:50Z
Message: Successfully completed volume expansion for Oracle
Reason: Successful
Status: True
Type: Successful
Phase: Successful
The operator has updated the Oracle spec and the PetSet volumeClaimTemplate to 12Gi,
$ kubectl get oracle -n demo oracle-sa-sample -o jsonpath='{.spec.storage.resources.requests.storage}'
12Gi
The capacity reported by the PersistentVolumeClaim changes once the storage provisioner finishes resizing the underlying volume. While the resize is in progress, the PVC carries a Resizing condition and the requested size (spec.resources.requests.storage) updates ahead of the reported capacity (status.capacity.storage),
$ kubectl get pvc data-oracle-sa-sample-0 -n demo -o jsonpath='req={.spec.resources.requests.storage} cap={.status.capacity.storage} cond={.status.conditions[*].type}'
req=12Gi cap=10Gi cond=Resizing
Note (test environment): On the single-node longhorn dev cluster used to capture this guide, the
OracleOpsRequestreached theSuccessfulphase and both theOraclespec and the PetSetvolumeClaimTemplatewere updated to12Gi, but the longhorn volume remained in theResizingstate and the PVC capacity had not yet been reflected as12Giat the time of writing. Volume expansion depends on the CSI driver fully completing the resize; on a production-grade storage class the PVC capacity updates to the new size once resizing completes. Always confirm the final size withkubectl get pvc -n demo data-oracle-sa-sample-0 -o jsonpath='{.status.capacity.storage}'.
Expanding a DataGuard cluster’s volume
The same OracleOpsRequest works for a DataGuard cluster — point spec.databaseRef.name at the DataGuard database. You can also resize the observer’s PVC through spec.volumeExpansion.observer:
apiVersion: ops.kubedb.com/v1alpha1
kind: OracleOpsRequest
metadata:
name: dataguard-volume-expention
namespace: demo
spec:
type: VolumeExpansion
databaseRef:
name: oracle-dg-sample
volumeExpansion:
mode: "Offline"
node: 12Gi
The operator expands the PVC of each DataGuard database pod (and the observer, if specified) to the requested size.
Cleaning up
To clean up the Kubernetes resources created by this tutorial, run:
kubectl delete oracleopsrequest -n demo standalone-volume-expention
kubectl patch -n demo oracle/oracle-sa-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge"
kubectl delete oracle -n demo oracle-sa-sample
kubectl delete ns demo
Next Steps
- Detail concepts of Oracle object.
- Learn how to vertically scale an Oracle database.
- Want to hack on KubeDB? Check our contribution guidelines.
⚠️ Legal Notice
Oracle® and Oracle Database® are registered trademarks of Oracle Corporation. KubeDB is not affiliated with, endorsed by, or sponsored by Oracle Corporation.
KubeDB provides only orchestration and management tooling for Kubernetes. It does not distribute, bundle, ship, or include any Oracle Database software or binaries.
Users must provide their own Oracle container images and hold valid Oracle licenses. Users are solely responsible for compliance with Oracle’s licensing terms, including all rules regarding containers, Docker, and Kubernetes environments.
KubeDB makes no representations or warranties regarding Oracle licensing compliance.































