This guide provides instructions for running the free version of Oracle Database 23c (23.3.0.0
) and 23ai (23.4.0.0
) on OpenShift 4.14. It also includes instructions on using the 23ai lite (23.4.0.0-lite
) image as well if required.
Oracle make a free version of their database available for download in RPM, VM or container form factors. The container version includes instructions for running locally using Podman, but it does not include instructions for running on OpenShift which is where this guide comes in. There are also several documented restrictions on the usable memory, storage and compute when using the free version which make it most suitable for development or test scenarios.
Running Oracle Database on OpenShift is not straightforward due to the security requirements and this guide documents the process by providing the definitions to create the components needed. Be aware that this is designed to be used in a PoC, demo, development or test environment and not in production.
First, create a new project (namespace) in which to run everything:
oc new-project oracle-db
Now using project "oracle-db" on server "https://example.cloud.com:32226".
You can add applications to this project with the 'new-app' command. For example, try:
oc new-app rails-postgresql-example
to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:
kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname
Next, you create a Service Account which you will use to run the database:
oc create sa oracle-sa
serviceaccount/oracle-sa created
As Oracle runs with the user and group id 54321
, you now need to add the anyuid
Security Context Constraint (SCC) to the Service Account. This allows the database to run under its required user and group IDs:
oc adm policy add-scc-to-user anyuid -z oracle-sa
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "oracle-sa"
To see the effect of this, you can run the following command to observe that the Service Account has permissions to use the anyuid
SCC:
oc adm policy who-can use scc anyuid
resourceaccessreviewresponse.authorization.openshift.io/<unknown>
Namespace: oracle-db
Verb: use
Resource: securitycontextconstraints.security.openshift.io
Users: ...
system:serviceaccount:oracle-db:oracle-sa
...
Now you create a secret to store the default password for Oracle to use by replacing [your_password_here]
in the command below with the password of your choice:
oc create secret generic oracle-db-pass --from-literal=password=[your_password_here]
secret/oracle-db-pass created
By default the most recently published Oracle container (latest
) will be deployed. At the time of writing this is 23ai (23.4.0.0
). If you want to deploy 23c (23.3.0.0
) instead change the image on line 69 of the ./config/deploy-oracle23-db-free.yaml
file from:
image: container-registry.oracle.com/database/free:latest
to image: container-registry.oracle.com/database/free:23.3.0.0
. If you wish you can use the lite version of the 23ai image by using image: container-registry.oracle.com/database/free:23.4.0.0-lite
instead. The lite image is significantly (~80%) smaller and faster to start if you can live with the limitations.
Now you can apply the yaml file in the config
folder in this repo to deploy Oracle. Note that this file assumes a storageClassName
of ocs-storagecluster-ceph-rbd
by default to provide ReadWriteOncePod
(RWOP) storage. If your RWOP storage class has a different name, please change the storageClassName
to the one for your environment.
oc apply -f ./config/deploy-oracle23-db-free.yaml
service/oracle-db-svc created
persistentvolumeclaim/oracle-db-pvc created
statefulset.apps/oracle-db created
It will take several minutes before Oracle is ready to use, but any subsequent restarts will be much faster. The first time it runs it takes time to pull the Oracle container images and then more time to copy the database files into the dynamically allocated storage. You can watch the logs by running oc logs oracle-db-0 -c oracle-db -f
to view the progress. If all goes well you should see output similar to this abbreviated output from running the 23c image:
Specify a password to be used for database accounts. Oracle recommends that the password entered
should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case
character and 1 digit [0-9]. Note that the same password will be used for SYS, SYSTEM and PDBADMIN accounts:
Confirm the password:
Configuring Oracle Listener.
Listener configuration succeeded.
Configuring Oracle Database FREE.
Enter SYS user password:
*******
Enter SYSTEM user password:
******
Enter PDBADMIN User Password:
******
Prepare for db operation
7% complete
Copying database files
29% complete
Creating and starting Oracle instance
30% complete
43% complete
Completing Database Creation
47% complete
Creating Pluggable Databases
71% complete
Executing Post Configuration Actions
93% complete
Running Custom Scripts
100% complete
Database creation complete. For details check the logfiles at:
/opt/oracle/cfgtoollogs/dbca/FREE.
Database Information:
Global Database Name:FREE
System Identifier(SID):FREE
Look at the log file "/opt/oracle/cfgtoollogs/dbca/FREE/FREE.log" for further details.
Connect to Oracle Database using one of the connect strings:
Pluggable database: oracle-db-0/FREEPDB1
Multitenant container database: oracle-db-0
SQL*Plus: Release 23.0.0.0.0 - Production on Sat Mar 23 14:22:14 2024
Version 23.3.0.23.09
Copyright (c) 1982, 2023, Oracle. All rights reserved.
Connected to:
Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.3.0.23.09
SQL>
System altered.
SQL>
Pluggable database altered.
SQL>
PL/SQL procedure successfully completed.
SQL> SQL>
Session altered.
SQL>
User created.
SQL>
Grant succeeded.
SQL>
User altered.
SQL> SQL> Disconnected from Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.3.0.23.09
The Oracle base remains unchanged with value /opt/oracle
The Oracle base remains unchanged with value /opt/oracle
#########################
DATABASE IS READY TO USE!
#########################
The following output is now a tail of the alert.log:
...
Press ctrl-c
to quit following the logs.
Once Oracle is running you can connect to it using the steps below.
Firstly, if you have a file of SQL commands that you want to run to configure Oracle you can copy them into the pod like this, assuming the file is called oracle.sql
:
oc cp oracle.sql oracle-db-0:/opt/oracle/oradata/oracle.sql -c oracle-db
Next you will rsh
into the Oracle pod so you can run SQL*Plus
commands:
oc rsh -c oracle-db oracle-db-0
sh-4.4$
At the new rsh
prompt enter the command below. In this command, the $ORACLE_PWD
environment variable has been populated from the secret you created earlier:
sh-4.4$ sqlplus sys/$ORACLE_PWD as sysdba
SQL*Plus: Release 23.0.0.0.0 - Production on Sat Mar 23 14:31:46 2024
Version 23.3.0.23.09
Copyright (c) 1982, 2023, Oracle. All rights reserved.
Connected to:
Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.3.0.23.09
SQL>
Next, you can make sure that the FREEDPB1
DB is open:
SQL> alter pluggable database FREEPDB1 OPEN;
Session altered.
Note
This may give a harmless error if FREEPDB1
is already open, which you can ignore:
alter pluggable database FREEPDB1 OPEN
*
ERROR at line 1:
ORA-65019: pluggable database FREEPDB1 already open
Help: https://docs.oracle.com/error-help/db/ora-65019/
Now at the SQL prompt you can switch the session to FREEPBD1
:
SQL> alter session set container = FREEPDB1;
Session altered.
If you uploaded a file of SQL commands earlier, you can execute them now:
SQL> @ /opt/oracle/oradata/oracle.sql
We can also execute other SQL commands, for example:
SQL> SELECT SYSDATE;
SYSDATE
---------
23-MAR-24
When you are done you can leave the SQL prompt by entering exit
. In order to leave the rsh
prompt as well, enter exit
a second time.
From the rsh
prompt you can also access Oracle via the Service that was created earlier:
sh-4.4$ sqlplus sys/$ORACLE_PWD@oracle-db-svc.oracle-db.svc.cluster.local:1521/FREEPDB1 as sysdba
This shows that other pods on the same cluster can connect to the Oracle instance via the Service. This address would also be the one to use to connect from a client application running elsewhere in the cluster.
To delete the database and clean up the namespace you can run the following commands.
Caution
This will delete all the data in the Database:
oc delete -f ./config/deploy-oracle23-db-free.yaml
service "oracle-db-svc" deleted
persistentvolumeclaim "oracle-db-pvc" deleted
statefulset.apps "oracle-db" deleted
followed by:
oc delete secret oracle-db-pass
secret "oracle-db-pass" deleted
finally:
oc delete sa oracle-sa
serviceaccount "oracle-sa" deleted
The deploy-oracle23-db-free.yaml
file in the config
folder creates the following components:
- a
Service
to provide network access to the database. - a
PersistentVolumeClaim
to provide the storage for the database. - a
StatefulSet
which creates a single instance of aPod
that has two containers.- an
initContainer
for initialisation which is explained below. - a regular container which hosts the Oracle DB. These containers run under the
oracle-sa
Service Account you created above. This is specified in theserviceAccountName
section which ties the Pod to theanyuid
SCC, via the Service Account.
- an
The first problem you hit when trying to run Oracle on OpenShift for the first time is that Oracle wants to run with the UID and GID 54321
. This is easily overcome by applying the built in anyuid
SCC as you do above. However, this is not enough to make it work. Although the Oracle container will start, it will crash after a few seconds when it starts copying the database files to the persistent volume and the logs will look something like this:
Specify a password to be used for database accounts. Oracle recommends that the password entered
should be at least 8 characters in length, contain at least 1 uppercase character, 1 lower case
character and 1 digit [0-9]. Note that the same password will be used for SYS, SYSTEM and PDBADMIN accounts:
Confirm the password:
Configuring Oracle Listener.
Listener configuration succeeded.
Configuring Oracle Database FREE.
Enter SYS user password:
***********
Enter SYSTEM user password:
***********
Enter PDBADMIN User Password:
***********
Prepare for db operation
Cannot create directory "/opt/oracle/oradata/FREE".
7% complete
100% complete
[FATAL] Prepare Operation has failed.
0% complete
Look at the log file "/opt/oracle/cfgtoollogs/dbca/FREE/FREE.log" for further details
This is because of a conflict that happens between the SCC and the persistent volume when anyuid
is specified. This is documented in this RedHat Knowledgebase article: Resolving Linux permission issues within OpenShift persistent volumes.
The solution to this is to run the workaround provided in the article as an initContainer
in the pod. This allows the correct ownership to be applied to the mounted storage before the Oracle container tries to access it. If you look at the yaml definition for the StatefulSet
you can see the script that is run when the initContainer
is started. You can also see the logs it outputs with this command:
oc logs oracle-db-0 -c init-oracle
starting permissions check on /opt/oracle/oradata/
total 20
drwxr-xr-x. 3 root root 4096 Mar 23 15:11 .
drwxr-xr-x. 1 root root 4096 Mar 23 15:11 ..
drwxr-xr-x. 3 root root 4096 Mar 23 15:11 oradata
total 20
drwxr-xr-x. 3 root root 4096 Mar 23 15:11 .
drwxr-xr-x. 1 root root 4096 Mar 23 15:11 ..
drwxr-xr-x. 3 54321 54321 4096 Mar 23 15:11 oradata
permissions set
finished
Here you can see that the initial permissions on the /opt/oracle/oradata
folder are set to be owned by root:root
and the initContainer
changes this to be the 54321:54321
that Oracle requires.
Although this has only been tested on OCP 4.14, it should work on earlier versions. However, if this is used on OCP 4.13 or earlier, then the accessModes:
in the PVC will need to be changed:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: oracle-db-pvc
labels:
app: oracle-db
spec:
accessModes:
- ReadWriteOncePod
In the above snippet ReadWriteOncePod
(RWOP) should be changed to ReadWriteOnce
, as RWOP was first introduced in OCP 4.14.
This screenshot shows the Oracle 23c Free Database running on OpenShift:
These files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the LICENSE file.
I hope you found this information useful. If you have any suggestions for improvements, please raise issues and suggestions on GitHub.