In this Blog I am going to show how we can quickly get an Oracle 18c Express Edition (XE) database up and running on Kubernetes for testing purposes on a laptop.
This blog post covers:
- Configuring Minikube for Kubernetes
- Building the Oracle 18c XE Docker image
- Running Oracle 18x XE in Kubernetes
- The Kubernetes Dashboard
- Connecting from a laptop
- Kubernetes management with Minikube
Configuring Minikube
Before we start, if you have not already have VirtualBox and Minikube installed you can get Minikube here, and VirtualBox using this link.
In this blog I will using Oracle VirtualBox 6.0.1 and Minikube version 1.11.0, you can your check your local versions with:
$ vboxmanage --version 6.0.16r135674
$ minikube version minikube version: v1.11.0 commit: 57e2f55f47effe9ce396cea42a1e0eb4f611ebbd
Ok, let’s increase the default Minikube VM memory size from 2GB to 10GB, this is required to give my Oracle 18xe database a bit more memory, I will also set the MiniKube vm driver to use VirtualBox this can be done by changing the Minikube configuration e.g.
$ minikube config set memory 10240 $ minikube config set vm-driver virtualbox ⚠️ These changes will take effect upon a minikube delete and then a minikube start
$ minikube config view - disk-size: 40GB - vm-driver: virtualbox - memory: 10240
I will also enable the minikube metrics server to provide a CPU and Memory Usage graphs.
$ minikube addons enable metrics-server
To check what add-ons are enabled use minikube addons list
$ minikube addons list |-----------------------------|----------|--------------| | ADDON NAME | PROFILE | STATUS | |-----------------------------|----------|--------------| | ambassador | minikube | disabled | | dashboard | minikube | enabled ✅ | | default-storageclass | minikube | enabled ✅ | | efk | minikube | disabled | | freshpod | minikube | disabled | | gvisor | minikube | disabled | | helm-tiller | minikube | disabled | | ingress | minikube | disabled | | ingress-dns | minikube | disabled | | istio | minikube | disabled | | istio-provisioner | minikube | disabled | | logviewer | minikube | disabled | | metallb | minikube | disabled | | metrics-server | minikube | enabled ✅ | | nvidia-driver-installer | minikube | disabled | | nvidia-gpu-device-plugin | minikube | disabled | | olm | minikube | disabled | | registry | minikube | disabled | | registry-aliases | minikube | disabled | | registry-creds | minikube | disabled | | storage-provisioner | minikube | enabled ✅ | | storage-provisioner-gluster | minikube | disabled | |-----------------------------|----------|--------------|
Start Minikube
$ minikube start 😄 minikube v1.11.0 on Darwin 10.14.6 ✨ Using the virtualbox driver based on user configuration 👍 Starting control plane node minikube in cluster minikube 🔥 Creating virtualbox VM (CPUs=2, Memory=10240MB, Disk=40960MB) ... 🐳 Preparing Kubernetes v1.18.3 on Docker 19.03.8 ... 🔎 Verifying Kubernetes components... 🌟 Enabled addons: dashboard, default-storageclass, metrics-server, storage-provisioner 🏄 Done! kubectl is now configured to use "minikube"
Building our Oracle Docker Image
The Oracle 18c Express Edition (XE) Docker build scripts now automatically ‘pulls’ the database RPM from OTN for you. This means you no longer any need to pre-download the Oracle 18xe image for this build.
Please Note: this still required for all other non-free versions.
Let’s start by cloning the Oracle maintained Docker files from GitHub.
$ git clone https://github.com/oracle/docker-images.git
Navigate to the SingleInstance dockerfiles directory e.g.
$ cd docker-images/OracleDatabase/SingleInstance/dockerfiles
The script installs the Oracle Database software, but it does not create and configure a database. When the build has been complete, you can verify the image has been created by listing the available Docker images.
The eval command will force the Docker image to be built in our Kubernetes minikube VM rather than on our laptop.
$ eval $(minikube docker-env) $ ./buildDockerImage.sh -v 18.4.0 -x
If we perform a docker images command you will notice that we don’t have a database image, don’t worry that’s expected.
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE oraclelinux 7-slim 7442ca158991 7 days ago 120MB
However, if we shell into our minikube VM we should see our 18c XE database image.
$ minikube ssh
_ _
_ _ ( ) ( )
___ ___ (_) ___ (_)| |/') _ _ | |_ __
/' _ ` _ `\| |/' _ `\| || , < ( ) ( )| '_`\ /'__`\
| ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )( ___/
(_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
oracle/database 18.4.0-xe e1df47b35fce 2 minutes ago 5.87GB
oraclelinux 7-slim 7442ca158991 7 days ago 120MB
k8s.gcr.io/kube-proxy v1.18.3 3439b7546f29 4 weeks ago 117MB
k8s.gcr.io/kube-controller-manager v1.18.3 da26705ccb4b 4 weeks ago 162MB
k8s.gcr.io/kube-apiserver v1.18.3 7e28efa976bd 4 weeks ago 173MB
k8s.gcr.io/kube-scheduler v1.18.3 76216c34ed0c 4 weeks ago 95.3MB
kubernetesui/dashboard v2.0.0 8b32422733b3 8 weeks ago 222MB
k8s.gcr.io/pause 3.2 80d28bedfe5d 4 months ago 683kB
k8s.gcr.io/coredns 1.6.7 67da37a9a360 4 months ago 43.8MB
k8s.gcr.io/etcd 3.4.3-0 303ce5db0e90 7 months ago 288MB
kubernetesui/metrics-scraper v1.0.2 3b08661dc379 7 months ago 40.1MB
gcr.io/k8s-minikube/storage-provisioner v1.8.1 4689081edb10 2 years ago 80.8MB
Getting Started with Kubernetes
Kubernetes Namespace
For this blog I use a new Kubernetes namespace called oracle-namespace.
I can create a new namespace with kubectl create namespace.
$ kubectl create namespace oracle-namespace namespace/oracle-namespace created
Or if you prefer via a YAML file.
$ cat namespace.yaml apiVersion: v1 kind: Namespace metadata: name: oracle-namespace $ kubectl apply -f namespace.yaml
Either way we should be able to use the kubectl get namespace to return the status.
$ kubectl get namespace oracle-namespace NAME STATUS AGE oracle-namespace Active 34s
Kubernetes ConfigMap
For my Kubernetes build I will be using a ConfigMap to pass variables to my Oracle 18c Express Edition (XE) deployment.
I have created a file called oracle.properties which I will be used to create the configmap, this common file will be used to support multiple versions of Oracle so includes variable not needed for Oracle 18c XE.
$ kubectl create configmap oradb --from-env-file=oracle.properties -n oracle-namespace configmap/oradb created
We can check the key pair vales using kubectl get configmaps with an output of yaml, our Oracle 18c XE database will only use ORACLE_CHARACTER_SET & ORACLE_PWD.
$ kubectl get configmaps/oradb -o yaml -n oracle-namespace apiVersion: v1 data: DB_BUNDLE: basic DB_DOMAIN: localdomain DB_MEMORY: 4g DB_PASSWD: Kube#2020 DB_PDB: PSTGPDB1 DB_SID: PSTG ORACLE_CHARACTERSET: AL32UTF8 ORACLE_PDB: ORCLPDB1 ORACLE_PWD: Kube#2020 ORACLE_SID: ORCL kind: ConfigMap metadata: creationTimestamp: "2020-06-18T10:07:57Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:DB_BUNDLE: {} f:DB_DOMAIN: {} f:DB_MEMORY: {} f:DB_PASSWD: {} f:DB_PDB: {} f:DB_SID: {} f:ORACLE_CHARACTERSET: {} f:ORACLE_PDB: {} f:ORACLE_PWD: {} f:ORACLE_SID: {} manager: kubectl operation: Update time: "2020-06-18T10:07:57Z" name: oradb namespace: oracle-namespace resourceVersion: "2630" selfLink: /api/v1/namespaces/oracle-namespace/configmaps/oradb uid: 1910d0c2-1de3-4a23-9462-0785ca3bd3f4
Running Oracle18c XE
We can create our Oracle 18xe database Kubernetes pod with kubectl apply
$ kubectl apply -f database_18xe.yaml -n oracle-namespace deployment.apps/oracle18xe created service/oracle18xe created
Use kubectl get(s) to check status e.g.
$ kubectl get deployments -n oracle-namespace NAME READY UP-TO-DATE AVAILABLE AGE oracle18xe 1/1 1 1 27s
$ kubectl get pods -n oracle-namespace
NAME READY STATUS RESTARTS AGE
oracle18xe-5d565cbfdf-cns6s 1/1 Running 0 15s
Now we know the pod name we can view the log output during the build.
$ kubectl logs oracle18xe-5d565cbfdf-cns6s -n oracle-namespace Setup Oracle Database ORACLE PASSWORD FOR SYS AND SYSTEM: Kube#2020 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 XE. 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 31% complete 34% complete 38% complete 41% complete 43% complete Completing Database Creation 47% complete 50% complete Creating Pluggable Databases 54% complete 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/XE. Database Information: Global Database Name:XE System Identifier(SID):XE Look at the log file "/opt/oracle/cfgtoollogs/dbca/XE/XE.log" for further details. Connect to Oracle Database using one of the connect strings: Pluggable database: oracle18xe-5d565cbfdf-cns6s/XEPDB1 Multitenant container database: oracle18xe-5d565cbfdf-cns6s Use https://localhost:5500/em to access Oracle Enterprise Manager for Oracle Database XE The Oracle base remains unchanged with value /opt/oracle ######################### DATABASE IS READY TO USE! #########################
We can use kubectl describe(s) to provide detailed information e.g.
$ kubectl describe deployments -n oracle-namespace $ kubectl describe pods -n oracle-namespace $ kubectl describe secrets -n oracle-namespace $ kubectl describe services -n oracle-namespace
MiniKube Dashboard
The MiniKube dashboard provides a GUI interface to manage your Kubernetes environment, this can be started using the minikube dashboard command, this will start a browser tab ready and your ready to go.
$ minikube dashboard 🤔 Verifying dashboard health ... 🚀 Launching proxy ... 🤔 Verifying proxy health ... 🎉 Opening http://127.0.0.1:50795/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser.
From the MiniKube Dashboard we can navigate to the Pod logs and see what database logging has been written to the standard output, we can also see our database has been renamed as per our configmap.
Review log output from our Pod e.g. Workloads > Pods > POD > Logs
Minikube also provides a Shell into our Pod e.g. Workloads > Pods > POD > Shell
Connection from Laptop
To connect to our newly created Oracle database from our laptop we need to first identify the exposed IP address and port, we can do this with minikube ip & kubectl get service
$ minikube ip
192.168.99.104
$ kubectl get services -n oracle-namespace NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE oracle18xe NodePort 10.99.225.175 <none> 1521:32255/TCP,5500:31620/TCP 2m42s
We can also see the ports using minkube service
$ minikube service oracle18xe -n oracle-namespace --url http://192.168.99.104:32255 http://192.168.99.104:31620
As I have sqlplus installed on my laptop I will use that to connect using the detail above.
$ sqlplus system/Kube#2020@192.168.99.104:32255/XEPDB1 SQL*Plus: Release 19.0.0.0.0 - Production on Fri Jun 19 09:53:11 2020 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle. All rights reserved. Last Successful login time: Fri Jun 19 2020 09:52:56 +01:00 Connected to: Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production Version 18.4.0.0.0 SQL> show con_name; CON_NAME ------------------------------ XEPDB1 SQL> col INSTANCE_NAME heading 'Instance Name' format a8 SQL> col HOST_NAME heading 'Host Name' format a30 SQL> col VERSION heading 'Version' format a25 SQL> select INSTANCE_NAME, HOST_NAME, VERSION from v$instance; Instance Host Name Version -------- ------------------------------ ------------------------- XE oracle18xe-5d565cbfdf-cns6s 18.0.0.0.0
As you can above, my Oracle database is reporting the host name is the same as the Kubernetes Pod name.
Using Oracle SQL Developer
Now we have IP & Port details we can also use these to connect with Oracle SQL Developer.
Kubernetes management with Minikube
Minikube status
$ minikube status minikube type: Control Plane host: Running kubelet: Running apiserver: Running kubeconfig: Configured
Stop local Minikube Cluster
This will stop our VirtualBox minikube VM.
Please note as our database is not using persistent storage we will loose all data and our database will be rebuilt.
$ minikube stop ✋ Stopping "minikube" in virtualbox ... 🛑 Node "minikube" stopped.
Start local Minikube Cluster
$ minikube start 😄 minikube v1.11.0 on Darwin 10.14.6 ✨ Using the virtualbox driver based on existing profile 👍 Starting control plane node minikube in cluster minikube 🔄 Restarting existing virtualbox VM for "minikube" ... 🐳 Preparing Kubernetes v1.18.3 on Docker 19.03.8 ... 🔎 Verifying Kubernetes components... 🌟 Enabled addons: dashboard, default-storageclass, metrics-server, storage-provisioner 🏄 Done! kubectl is now configured to use "minikube"
Pause namespace
$ minikube pause -n oracle-namespace ⏯️ Paused kubelet and 2 containers in: oracle-namespace
Unpause Namespace
$ minikube unpause -n oracle-namespace ⏸️ Unpaused kubelet and 2 containers in: oracle-namespace
Delete local Minikube Cluster
This will delete the VirtualBox minikube VM and all our data.
$ minikube delete 🔥 Deleting "minikube" in virtualbox ... 💀 Removed all traces of the "minikube" cluster.
If you want to try and recreate any of the above, I have uploaded all code above to my GitHub repo.
However if you require your database to be persistent you may want to check-out the following blog posts:
The the blog posts above introduce the Kubernetes Container Storage Interface (CSI) and discuss running Oracle 19c on a multi-node Kubernetes Cluster.
[twitter-follow screen_name=’RonEkins’ show_count=’yes’]