In this Blog Series I am going to share how to deploy the Oracle Database 23c Free Developer Release on an Oracle Cloud Infrastructure (OCI) Oracle Container Engine for Kubernetes (OKE) Cluster with Portworx storage.
In Part 1 of this blog series I shared how to create an OKE Kubernetes Cluster.
In this Part 2 I will share how to install and configure Portworx Essentials Forever Free edition into an Oracle Cloud Infrastructure (OCI) Kubernetes Cluster on Oracle Container Engine for Kubernetes (OKE).
And in Part 3 we will look at deploying an Oracle 23c database on OKE using Portworx storage.
If you followed Part 1 you should already have a running Oracle Container Engine for Kubernetes (OKE) Cluster within your home Region, looking something like this.

Before we start let’s confirm the Kubernetes Cluster topology using kubectl get nodes.
rekins@rekins--MacBookPro15 ~ % kubectl get nodes -L topology.kubernetes.io/region,topology.kubernetes.io/zone,oci.oraclecloud.com/fault-domain NAME STATUS ROLES AGE VERSION REGION ZONE FAULT-DOMAIN 10.0.10.148 Ready node 4d10h v1.25.4 uk-london-1 UK-LONDON-1-AD-1 FAULT-DOMAIN-3 10.0.10.53 Ready node 4d10h v1.25.4 uk-london-1 UK-LONDON-1-AD-3 FAULT-DOMAIN-1 10.0.10.86 Ready node 4d10h v1.25.4 uk-london-1 UK-LONDON-1-AD-2 FAULT-DOMAIN-2
And check the available Kubernetes Storage Classes withe kubectl get sc.
rekins@rekins--MacBookPro15 ~ % kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE oci oracle.com/oci Delete Immediate false 40m oci-bv (default) blockvolume.csi.oraclecloud.com Delete WaitForFirstConsumer true 40m
Install Portworx Essentials
To install Portworx, logon to Portworx Central, and from here select Portworx Enterprise.

For this post I will be using the Portworx Essentials Forever Free version as this provides all the features I require for the Oracle database 23c Free Developer release.
For use with Production Oracle databases you may want to consider Portworx Enterprise to access the additional features listed below.

The Generate Spec screen now includes support for Oracle Cloud infrastructure (OCI), select Oracle from the list of available platforms.

Confirm Kubernets Distribution

And update OKE K8s Version, Cluster Name Prefix, Storage Size and VPUs count as required performance.

Copy and apply the Portworx Kubernetes Operator Deployment, or alternatively either Download .yaml or Save Spec for later use.
Create OCI Secret
Create a Kubernetes Secret named ociapikey
in the Kubernetes namespace where you will installed Portworx, as below. This is required to allow Portworx Cloud Drives to create OCI Block Volumes.
kubectl create secret generic ociapikey --namespace <namespace> --from-file=oci_api_key.pem=oci_api_key.pem --from-literal=PX_ORACLE_user_ocid="<ocid>" --from-literal=PX_ORACLE_fingerprint="<fingerprint>"
Deploy Portworx Operator
Using the details copied from the Portworx Central Wizard paste the Portworx Operator kubectl apply command to deploy the Operator.
rekins@rekins--MacBookPro15 ~ % kubectl apply -f 'https://install.portworx.com/2.13?comp=pxoperator&kbver=1.25.4&ns=portworx' namespace/portworx created serviceaccount/portworx-operator created clusterrole.rbac.authorization.k8s.io/portworx-operator created clusterrolebinding.rbac.authorization.k8s.io/portworx-operator created deployment.apps/portworx-operator created
Deploy Portworx Specification
And paste the Portworx provided kubectl apply command to deploy the Specification.
rekins@rekins--MacBookPro15 ~ % kubectl apply -f 'https://install.portworx.com/2.13?operator=true&mc=false&kbver=1.25.4&ns=portworx&oem=esse&user=6ff09697-f8f7-11ea-a2c5-c24e499c7467&b=true&kd=type%3Dpv-10%2Csize%3D150&cp=oracle&s=%22type%3Dpv-10%2Csize%3D150%22&c=px-cluster-e86d8cdb-7e21-41d2-a2f4-c6820d1fe203&oke=true&stork=true&csi=true&mon=true&tel=true&st=k8s&promop=true' storagecluster.core.libopenstorage.org/px-cluster-e86d8cdb-7e21-41d2-a2f4-c6820d1fe203 created secret/px-essential created
If we repeat the list available Kubernetes Storage Classes kubectl sc, we can see a Portworx has created a number of new Kubernetes Storage Classes.
rekins@rekins--MacBookPro15 ~ % kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE oci oracle.com/oci Delete Immediate false 41h oci-bv (default) blockvolume.csi.oraclecloud.com Delete WaitForFirstConsumer true 41h px-csi-db pxd.portworx.com Delete Immediate true 71s px-csi-db-cloud-snapshot pxd.portworx.com Delete Immediate true 70s px-csi-db-cloud-snapshot-encrypted pxd.portworx.com Delete Immediate true 70s px-csi-db-encrypted pxd.portworx.com Delete Immediate true 71s px-csi-db-local-snapshot pxd.portworx.com Delete Immediate true 71s px-csi-db-local-snapshot-encrypted pxd.portworx.com Delete Immediate true 70s px-csi-replicated pxd.portworx.com Delete Immediate true 71s px-csi-replicated-encrypted pxd.portworx.com Delete Immediate true 71s px-db kubernetes.io/portworx-volume Delete Immediate true 71s px-db-cloud-snapshot kubernetes.io/portworx-volume Delete Immediate true 71s px-db-cloud-snapshot-encrypted kubernetes.io/portworx-volume Delete Immediate true 71s px-db-encrypted kubernetes.io/portworx-volume Delete Immediate true 71s px-db-local-snapshot kubernetes.io/portworx-volume Delete Immediate true 71s px-db-local-snapshot-encrypted kubernetes.io/portworx-volume Delete Immediate true 71s px-replicated kubernetes.io/portworx-volume Delete Immediate true 71s px-replicated-encrypted kubernetes.io/portworx-volume Delete Immediate true 71s stork-snapshot-sc stork-snapshot Delete Immediate true 77s
Use kubectl get pods to list the Portworx pods.
rekins@rekins--MacBookPro15 % kubectl get pods -n portworx -l name=portworx NAME READY STATUS RESTARTS AGE px-cluster-e86d8cdb-7e21-41d2-a2f4-c6820d1fe203-5qjvt 2/2 Running 0 34m px-cluster-e86d8cdb-7e21-41d2-a2f4-c6820d1fe203-qj7mz 2/2 Running 0 34m px-cluster-e86d8cdb-7e21-41d2-a2f4-c6820d1fe203-qmx47 2/2 Running 0 34m
Using pxctl –version to check Portworx version
rekins@rekins--MacBookPro15 % PX_POD=$(kubectl get pods -l name=portworx -n portworx -o jsonpath='{.items[0].metadata.name}') rekins@rekins--MacBookPro15 ~ % kubectl exec $PX_POD -n portworx -- /opt/pwx/bin/pxctl --version Defaulted container "portworx" out of: portworx, csi-node-driver-registrar pxctl version 2.13.6-cc39334
Ands use pxctl status to check Portworx status
rekins@rekins--MacBookPro15 % kubectl exec $PX_POD -n portworx -- /opt/pwx/bin/pxctl status Defaulted container "portworx" out of: portworx, csi-node-driver-registrar Status: PX is operational Telemetry: Disabled or Unhealthy Metering: Healthy License: PX-Essential (lease renewal in 23h, 50m) Node ID: 2cbdb2e1-bd13-4bb3-9aee-fbafb17666cd IP: 10.0.10.148 Local Storage Pool: 1 pool POOL IO_PRIORITY RAID_LEVEL USABLE USED STATUS ZONE REGION 0 MEDIUM raid0 150 GiB 9.5 GiB Online UK-LONDON-1-AD-1 uk-london-1 Local Storage Devices: 1 device Device Path Media Type Size Last-Scan 0:1 /dev/sdb STORAGE_MEDIUM_MAGNETIC 150 GiB 16 Jun 23 18:57 UTC total - 150 GiB Cache Devices: * No cache devices Kvdb Device: Device Path Size /dev/sdc 150 GiB * Internal kvdb on this node is using this dedicated kvdb device to store its data. Cluster Summary Cluster ID: px-cluster-e86d8cdb-7e21-41d2-a2f4-c6820d1fe203 Cluster UUID: 08d69ff7-b5ff-4705-88e9-52e31d27017c Scheduler: kubernetes Nodes: 3 node(s) with storage (3 online) IP ID SchedulerNodeName Auth StorageNode Used Capacity Status StorageStatus Version Kernel OS 10.0.10.53 d88677ed-eb86-4e03-906a-13ce355bca0e 10.0.10.53 Disabled Yes 9.5 GiB 150 GiB Online Up 2.13.6-cc39334 5.15.0-100.96.32.el8uek.x86_64 Oracle Linux Server 8.7 10.0.10.148 2cbdb2e1-bd13-4bb3-9aee-fbafb17666cd 10.0.10.148 Disabled Yes 9.5 GiB 150 GiB Online Up (This node) 2.13.6-cc39334 5.15.0-100.96.32.el8uek.x86_64 Oracle Linux Server 8.7 10.0.10.86 1f8d5a50-1c4f-4fb6-97fa-747ee5a4eb3f 10.0.10.86 Disabled Yes 9.5 GiB 150 GiB Online Up 2.13.6-cc39334 5.15.0-100.96.32.el8uek.x86_64 Oracle Linux Server 8.7 Global Storage Pool Total Used : 29 GiB Total Capacity : 450 GiB
If you find yourself using pxctl frequently, probably a good idea to set-up an alias, for example:
rekins@rekins--MacBookPro15 ~ % PX_POD=$(kubectl get pods -l name=portworx -n portworx -o jsonpath='{.items[0].metadata.name}') rekins@rekins--MacBookPro15 ~ % alias pxctl='kubectl exec -n portworx ${PX_POD} -it -- /opt/pwx/bin/pxctl' rekins@rekins--MacBookPro15 ~ % pxctl --version Defaulted container "portworx" out of: portworx, csi-node-driver-registrar pxctl version 2.13.6-cc39334
Oracle Cloud Infrastructure
Logon to OCI and navigate to Storage -> Block Volumes, and select required Compartment.
From here we can the Portworx has provision OCI Portworx Cloud Drives using the size and performance parameters provided in the Portworx Central Wizard.

Alternatively, use the oci bv volume list to get a verbose output from your terminal interface.
rekins@rekins--MacBookPro15 % oci bv volume list --compartment-id <compartment> --lifecycle-state "Available" --output json
When you list the disks via OCI you maybe surprised by the number of block devices being returned.
rekins@rekins--MacBookPro15 ~ % kubectl exec $PX_POD -n portworx -- /opt/pwx/bin/pxctl clouddrive list -j Defaulted container "portworx" out of: portworx, csi-node-driver-registrar { "1f8d5a50-1c4f-4fb6-97fa-747ee5a4eb3f": { "Configs": { "ocid1.volume.oc1.uk-london-1.abwgiljtjop7xjnwiv6hp4jdoanfzeoi3p4tsl32x6q4ayer3wduviplynkq": { "Type": "pv-10", "Size": 150, "ID": "ocid1.volume.oc1.uk-london-1.abwgiljtjop7xjnwiv6hp4jdoanfzeoi3p4tsl32x6q4ayer3wduviplynkq", "Path": "/dev/sdc", "Iops": 9000, "Vpus": 10, "PXType": "kvdb", "State": "In Use", "labels": null, "AttachOptions": null, "Provisioner": "", "EncryptionKeyInfo": "" }, "ocid1.volume.oc1.uk-london-1.abwgiljtomfogk6uxuuhmt4vvs5xic26xspnb4yldzhzwndiad5n34aepdca": { "Type": "pv-10", "Size": 150, "ID": "ocid1.volume.oc1.uk-london-1.abwgiljtomfogk6uxuuhmt4vvs5xic26xspnb4yldzhzwndiad5n34aepdca", "Path": "/dev/sdb", "Iops": 9000, "Vpus": 10, "PXType": "data", "State": "In Use", "labels": null, "AttachOptions": null, "Provisioner": "", "EncryptionKeyInfo": "" } }, "NodeID": "1f8d5a50-1c4f-4fb6-97fa-747ee5a4eb3f", "ReservedInstanceID": "", "SchedulerNodeName": "10.0.10.86", "NodeIndex": 0, "CreateTimestamp": "2023-06-16T18:56:24.184079943Z", "InstanceID": "ocid1.instance.oc1.uk-london-1.anwgiljt54aw2uacrcdt2sgcl6jhq6idb6fg5l2ehzgelflm6fie7lngltra", "Zone": "iXvO:UK-LONDON-1-AD-2", "State": "In Use", "labels": {} }, "2cbdb2e1-bd13-4bb3-9aee-fbafb17666cd": { "Configs": { "ocid1.volume.oc1.uk-london-1.abwgiljrenxwvg7joichglgad3znir2za6rse5jpkes26mzbitp7kqaqkxxq": { "Type": "pv-10", "Size": 150, "ID": "ocid1.volume.oc1.uk-london-1.abwgiljrenxwvg7joichglgad3znir2za6rse5jpkes26mzbitp7kqaqkxxq", "Path": "/dev/sdc", "Iops": 9000, "Vpus": 10, "PXType": "kvdb", "State": "Pending Add", "labels": null, "AttachOptions": null, "Provisioner": "", "EncryptionKeyInfo": "" }, "ocid1.volume.oc1.uk-london-1.abwgiljrt5vp2e6fax56xhc2ixjtju7icrn4ba5vqal7k3b3hwfpt62qvanq": { "Type": "pv-10", "Size": 150, "ID": "ocid1.volume.oc1.uk-london-1.abwgiljrt5vp2e6fax56xhc2ixjtju7icrn4ba5vqal7k3b3hwfpt62qvanq", "Path": "/dev/sdb", "Iops": 9000, "Vpus": 10, "PXType": "data", "State": "In Use", "labels": null, "AttachOptions": null, "Provisioner": "", "EncryptionKeyInfo": "" } }, "NodeID": "2cbdb2e1-bd13-4bb3-9aee-fbafb17666cd", "ReservedInstanceID": "", "SchedulerNodeName": "10.0.10.148", "NodeIndex": 2, "CreateTimestamp": "2023-06-16T18:56:21.552846171Z", "InstanceID": "ocid1.instance.oc1.uk-london-1.anwgiljr54aw2uacrkvjxxfq6avs54zg7uvjw63r256k4liujhv7ppaiwh3a", "Zone": "iXvO:UK-LONDON-1-AD-1", "State": "In Use", "labels": {} }, "d88677ed-eb86-4e03-906a-13ce355bca0e": { "Configs": { "ocid1.volume.oc1.uk-london-1.abwgiljs4kvselc7jjs2oxmstj5c2fa5onbcfdx5nav4r4lyzw3bsn2b4g5q": { "Type": "pv-10", "Size": 150, "ID": "ocid1.volume.oc1.uk-london-1.abwgiljs4kvselc7jjs2oxmstj5c2fa5onbcfdx5nav4r4lyzw3bsn2b4g5q", "Path": "/dev/sdb", "Iops": 9000, "Vpus": 10, "PXType": "data", "State": "In Use", "labels": null, "AttachOptions": null, "Provisioner": "", "EncryptionKeyInfo": "" }, "ocid1.volume.oc1.uk-london-1.abwgiljsdb532n34tt6v3gsevkc5tecjsvlkyesspy3a5qorrv6q4fjxicla": { "Type": "pv-10", "Size": 150, "ID": "ocid1.volume.oc1.uk-london-1.abwgiljsdb532n34tt6v3gsevkc5tecjsvlkyesspy3a5qorrv6q4fjxicla", "Path": "/dev/sdc", "Iops": 9000, "Vpus": 10, "PXType": "kvdb", "State": "Pending Add", "labels": null, "AttachOptions": null, "Provisioner": "", "EncryptionKeyInfo": "" } }, "NodeID": "d88677ed-eb86-4e03-906a-13ce355bca0e", "ReservedInstanceID": "", "SchedulerNodeName": "10.0.10.53", "NodeIndex": 1, "CreateTimestamp": "2023-06-16T18:56:35.450844916Z", "InstanceID": "ocid1.instance.oc1.uk-london-1.anwgiljs54aw2uaci5tjiwjrsgbnaj4zmp2eiz72dexn43hevwc7kil5sduq", "Zone": "iXvO:UK-LONDON-1-AD-3", "State": "In Use", "labels": {} } }%
Summary
In this post I have shared how to install Portworx Essentials Forever Free edition into an OCI OKE Cluster.
Read Part 3 show to see how to install Oracle 23c Free Developer Release on an OKE Kubernetes Cluster.