Deploy Oracle database in Kubernetes cluster using Oracle Database Kubernetes Operator(#OraOperator): Part 1

Soma Dey
Oracle Developers
Published in
5 min readSep 13, 2023
Photo by Venti Views on Unsplash

If you are true fan of Kubernetes… you would probably like to manage your Oracle Database using Kubernetes API!

Good news for you: we can do this using OraOperator!

The current release of OraOperator supports the following databases:

  1. Oracle Autonomous Database (Shared & Dedicated)
  2. Containerized Single Instance databases (SIDB)
  3. Sharded DB
  4. OCI Base DB
  5. Oracle Multitenant Databases

To cover this topic comprehensively, we have considered following scenarios/ use cases to cover the presence of Oracle Databases in various environments.

Use case 1: Leverage OraOperator to deploy/manage a new/existing native Autonomous Shared database (ADB -S) in oracle cloud. (I will be covering this use case in this post.)

Use case 2: Leverage OraOperator to deploy/manage Oracle Single Instance Databases with dynamic persistence in on premise/multi cloud environment. (I will be covering this use case in part 2 of this series.)

Use case 3: Leverage OraOperator to deploy/manage Oracle Single Instance Databases with static persistence in on premise/multi cloud environment.(I will be covering this use case in part3 of this series.)

Let’s dive in!

Use case 1: Leverage OraOperator to deploy/manage a new/existing native Autonomous Shared database (ADB -S) in oracle cloud.

Prerequisites:

  1. An Oracle cloud account.
  2. an Oracle Kubernetes Engine (OKE) instance on the Oracle Cloud Infrastructure (Using the Console to create a Cluster with Default Settings in the ‘Quick Create’ workflow (oracle.com)).
  3. An Autonomous shared database (ADB-S) (Create an Autonomous Database (oracle.com)).

Step 1: Install OraOperator in OKE

Enable the Certificate manager and Database Operator addons in OKE from OCI cloud console.

Validate the operator from oci cloud shell:

kubectl api-resources --api-group=database.oracle.com

user1@cloudshell:~ (us-ashburn-1)$ kubectl api-resources --api-group=database.oracle.com
NAME SHORTNAMES APIVERSION NAMESPACED KIND
autonomouscontainerdatabases acd,acds database.oracle.com/v1alpha1 true AutonomousContainerDatabase
autonomousdatabasebackups adbbu,adbbus database.oracle.com/v1alpha1 true AutonomousDatabaseBackup
autonomousdatabaserestores adbr,adbrs database.oracle.com/v1alpha1 true AutonomousDatabaseRestore
autonomousdatabases adb,adbs database.oracle.com/v1alpha1 true AutonomousDatabase
cdbs database.oracle.com/v1alpha1 true CDB
dbcssystems database.oracle.com/v1alpha1 true DbcsSystem
oraclerestdataservices database.oracle.com/v1alpha1 true OracleRestDataService
pdbs database.oracle.com/v1alpha1 true PDB
shardingdatabases database.oracle.com/v1alpha1 true ShardingDatabase
singleinstancedatabases database.oracle.com/v1alpha1 true SingleInstanceDatabase

Step 2: OraOperator needs to have access to OCI services. To provide this access, instance principal authorization needs to be set up.

Create a dynamic group and define necessary policies to enable access.

Matching rules in dynamic groups-
instance.compartment.id='ocid1.compartment.oc1..***************************'
Allow dynamic-group soma_dyn_grp to manage all-resources in compartment id ocid1.compartment.oc1..*****************************

Step 3: Create a manifest file (adb_provision_new.yaml ) to setup the ADB secret and provision the autonomous database. (This is applicable for new data base provisioning.)

---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: adb-devdb-admin-password
stringData:
adb-devdb-admin-password: **********
---
apiVersion: database.oracle.com/v1alpha1
kind: AutonomousDatabase
metadata:
name: adb-devdb
spec:
hardLink: true
details:
compartmentOCID: "ocid1.compartment.oc1..**********************"
dbName: DEVDB
displayName: DEVDB
dbVersion: 19c
dbWorkload: OLTP
cpuCoreCount: 1
dataStorageSizeInTBs: 1
adminPassword:
k8sSecret:
name: adb-devdb-admin-password

Apply the YAML file.

user1@cloudshell:~ (us-ashburn-1)$ kubectl apply -f adb_provision_new.yaml
secret/adb-devdb-admin-password created
autonomousdatabase.database.oracle.com/adb-devdb created

Validate the newly provisioned database.

user1@cloudshell:~ (us-ashburn-1)$ kubectl get AutonomousDatabase
NAME DISPLAY NAME DB NAME STATE DEDICATED OCPUS STORAGE (TB) WORKLOAD TYPE CREATED
adb-devdb DEVDB DEVDB AVAILABLE false 1 1 OLTP 2023-09-08 07:06:16 UTC

DB can be terminated using same yaml file.

user1@cloudshell:~ (us-ashburn-1)$ kubectl delete -f adb_provision_new.yaml
secret "adb-devdb-admin-password" deleted
autonomousdatabase.database.oracle.com "adb-devdb" deleted

OraOpertaor can be leveraged to manage the lifecycle operations of an existing autonomous database as well.

Steps to bind the existing Autonomous database:

1. Create two secrets to store the ADB admin and wallet password using adb_secret.yaml

---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: adb-admin-password
stringData:
adb-admin-password: **********
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: adb-instance-wallet-password
stringData:
adb-instance-wallet-password: *********

2. Create a manifest file to bind the ADB along with tns details.

metadata:
name: adb-test
spec:
hardLink: false
details:
autonomousDatabaseOCID: ocid1.autonomousdatabase.oc1.iad.anuwcljtp77apcqaivt2ftczwctwj4wy4dfpvngfh6cd6t4zvdu7gy2ubsma
adminPassword:
k8sSecret:
name: adb-admin-password
wallet:
name: adb-tns-admin
password:
k8sSecret:
name: adb-instance-wallet-password
user1@cloudshell:~ (us-ashburn-1)$ kubectl apply -f adb_test.yaml
autonomousdatabase.database.oracle.com/adb-test created

user1@cloudshell:~ (us-ashburn-1)$ kubectl get AutonomousDatabase
NAME DISPLAY NAME DB NAME STATE DEDICATED STORAGE (TB) WORKLOAD TYPE CREATED
adb-test TEST TEST AVAILABLE false 1 DW 2023-09-08 07:48:50 UTC

Validate the ADB wallet secrets.

user1@cloudshell:~ (us-ashburn-1)$ kubectl get secrets
NAME TYPE DATA AGE
adb-admin-password Opaque 1 10m
adb-instance-wallet-password Opaque 1 10m
adb-tns-admin Opaque 9 4m56s

Let's check the connectivity now!

We need an instant client to check the connectivity.

Set the ORACLE_HOME and TNS _ADMIN path

export ORACLE_HOME=/home/user1/instantclient_12_2
export TNS_ADMIN=$ORACLE_HOME/network/admin
mkdir -p $ORACLE_HOME/network/admin

Extract the tns and wallet details from the secret (adb-tns-admin) created in previous step.

kubectl get secret/adb-tns-admin \
--template="{{ index .data \"tnsnames.ora\" | base64decode }}" > $ORACLE_HOME/network/admin/tnsnames.ora
kubectl get secret/adb-tns-admin \
--template="{{ index .data \"sqlnet.ora\" | base64decode }}" > $ORACLE_HOME/network/admin/sqlnet.ora
kubectl get secret/adb-tns-admin \
--template="{{ index .data \"cwallet.sso\" | base64decode }}" > $ORACLE_HOME/network/admin/cwallet.sso

Fetch ADB admin password and service details.

ADB_ADMIN_PWD=$(kubectl get secrets/adb-admin-password --template="{{index .data \"adb-admin-password\" | base64decode}}")
ADB_SERVICE=$(kubectl get adb -o json | jq -r .items[0].spec.details.dbName)_medium

Establish the connectivity!

user1@cloudshell:admin (us-ashburn-1)$ sqlplus admin/$ADB_ADMIN_PWD@$ADB_SERVICE

SQL*Plus: Release 21.0.0.0.0 - Production on Fri Sep 8 08:50:22 2023
Version 21.11.0.0.0

Copyright (c) 1982, 2022, Oracle. All rights reserved.


Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.20.0.1.0

SQL>

In a similar way we can leverage the OraOperator for other lifecycle management activities like (scale/rename/backup/restore) etc.

Useful links:

https://github.com/oracle/oracle-database-operator

https://www.oracle.com/in/database/kubernetes-for-container-database/

--

--

Soma Dey
Oracle Developers

/* Opinions expressed here are my own & do not express the views or opinions of my employer */