Is it possible to run an Oracle database in a container? And if so, is it supported for use in production?
The answer is “yes.” Surprised? Read on to learn how to rapidly deploy an Oracle 19c database on Kubernetes with Portworx® persistent storage.
Oracle Images
Oracle maintains 12.1, 12.2, and 19.3 database container images in the Oracle Container Registry (OCR). For this post, I’ll use the official Oracle 19.3 image. It’s also possible to build your own images for different versions using the Docker build scripts Oracle provides on GitHub.
Note: You’ll need an Oracle account to log in to the OCR and you’ll have to accept the Oracle licensing agreement before using the images.
GitHub Repository
Access the files I’ve referenced in this post from a public GitHub repository using git clone:
1 2 |
$ git clone https://github.com/PureStorage-OpenConnect/Oracle-on-Kubernetes-with-Portworx.git Cloning into ‘Oracle-on-Kubernetes’... |
Kubernetes Namespace
Start by creating a dedicated namespace for our containerized Oracle 19c database using the kubectl create namespace <namespace> command:
1 2 |
$ kubectl create namespace oracle–namespace —save–config namespace/oracle–namespace created |
To avoid having to specify the namespace each time with -n, you can use the set-context to default the namespace:
1 2 |
$ kubectl config set–context —current —namespace=oracle–namespace Context “kubernetes-admin@kubernetes” modified. |
Kubernetes Secret
Next, we need to create a Kubernetes Secret. You can do this by logging in to the Oracle Container Registry using docker login and providing your Oracle credentials.
1 2 3 4 |
$ docker login container–registry.oracle.com Username: Password: Login Succeeded |
This will create a file ~/.docker/config.json. We can then use this file to create a secret.
1 2 3 4 |
$ kubectl create secret generic regcred —from–file=.dockerconfigjson=$HOME/.docker/config.json —type=kubernetes.io/dockerconfigjson secret/regcred created |
Confirm the secret was created with kubectl get secret.
1 2 3 4 |
$ kubectl get secret –n oracle–namespace NAME TYPE DATA AGE default–token–gvrgv kubernetes.io/service–account–token 3 23s regcred kubernetes.io/dockerconfigjson 1 8s |
Kubernetes ConfigMap
For my Kubernetes build, I’ll use a ConfigMap to pass variables to the Oracle 19.3 container. This is an easy way to localize the database name and passwords.
1 2 3 |
$ kubectl create configmap oradb —from–env–file=oracle.properties –n oracle–namespace configmap/oradb created |
Kubernetes Statefulset
We can now create an Oracle 19.3.0 database Kubernetes statefulset with kubectl apply.
1 2 3 4 5 |
$ kubectl apply –f 19c_statefulset_PX.yaml storageclass.storage.k8.io/px–ora–sc created namespace/oracle–namespace configured statefulset.apps/oracle19c created service/oracle19c created |
The stateful set will create a Kubernetes pod for the database, a service for the database listener, a Portworx storage class, and three persistent volume claims (PVCs) for the Oracle database and startup and setup mount points.
Persistent Volume Claims
Before we attempt to connect to the database, let’s use kubectl get persistentvolumeclaims or pvc to list the volumes we’ll be using.
1 2 3 4 5 |
$ kubectl get pvc –n oracle–namespace NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE ora–data193–oracle19c–0 Bound pvc–ed1fc84f–ff70–41d6–a91e–84bd7aeb215c 10Gi RWO px–ora–sc 11s ora–setup193–oracle19c–0 Bound pvc–67e63172–1e15–4d83–9c3b–730eb8d343cf 1Gi RWO px–ora–sc 11s ora–startup193–oracle19c–0 Bound pvc–a92d9f16–64e9–448f–a627–b29436abf2ae 1Gi RWO px–ora–sc 11s |
Portworx Volumes
We can also see the three Portworx-managed volumes by using pxctl volume list.
1 2 3 4 5 |
$ pxctl volume list ID NAME SIZE HA SHARED ENCRYPTED PROXY–VOLUME IO_PRIORITY STATUS SNAP–ENABLED 695158833353700139 pvc–67e63172–1e15–4d83–9c3b–730eb8d343cf 1 GiB 3 no no no HIGH up – attached on 10.225.115.75 no 786606804354248227 pvc–a92d9f16–64e9–448f–a627–b29436abf2ae 1 GiB 3 no no no HIGH up – attached on 10.225.115.75 no 126169195279415360 pvc–ed1fc84f–ff70–41d6–a91e–84bd7aeb215c 10 GiB 3 no no no HIGH up – attached on 10.225.115.75 no |
Connecting Remotely
To connect to our Oracle database remotely, we need to identify the service port that is mapped to the database listener. We can use kubectl get service or svc for this.
1 2 3 |
$ kubectl get svc –n oracle–namespace NAME TYPE CLUSTER–IP EXTERNAL–IP PORT(S) AGE oracle19c NodePort 10.96.97.12 <none> 1521:30937/TCP,5500:32185/TCP 63s |
By using the command above, we can see that our Oracle listener (1521) is available externally on Port 30937 and Enterprise Manager (5500) is available on 32185.
Using the details provided in the ConfigMap and external service port, we can connect to our database remotely.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
% sqlplus system/Kube#2020@//master-1:30937/ORCL SQL*Plus: Release 19.0.0.0.0 – Production on Mon May 10 14:55:02 2021 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle. All rights reserved. Last Successful login time: Mon May 10 2021 14:52:18 +01:00 Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 – Production Version 19.3.0.0.0 SQL> select instance_name, host_name, to_char(startup_time,‘dd/mm/yy hh24:mi:ss’) as Startup, status from v$instance; INSTANCE_NAME HOST_NAME STARTUP STATUS ——————— —————– ————————– ——— ORCL oracle19c–0 10/05/21 13:40:05 OPEN |
Summary
In this blog post, I’ve shared how you can deploy an Oracle 19c database on a Kubernetes cluster with Portworx persistent storage. I’ve also shown how to connect to the database remotely.
You can learn more about running Oracle on Kubernetes on my blog.
Finally, before you deploy any Oracle software on Kubernetes I suggest you consult the Running and Licensing Oracle Programs in Containers and Kubernetes guide to fully understand any licensing implications.
Uncomplicate Oracle Data Storage
Written By:
Attend the Webinar
Learn more about building a containerized Oracle database environment.