Running Oracle 12c in Kubernetes with Minikube and VirtualBox

MiniKube

Before we start I will increase the default Minikube VM memory size from 2GB to 10GB, this is required to accommodate my Oracle 12c database, I will also set the MiniKube vm driver to use VirtualBox this can be done by changing the Minikube configuration.

If you have not already got MiniKube installed you get it following the instructions here, also for VirtualBox follow this link.

$ 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
- vm-driver: virtualbox
- memory: 10240

I will also enable the minikube metrics server to provide a CPU and Memory Usage graphs, these can be done after minikube has started.

$ minikube addons enable metrics-server

To check what add-ons are enabled use minikube addons list

$ minikube addons list
|-----------------------------|----------|--------------|
|         ADDON NAME          | PROFILE  |    STATUS    |
|-----------------------------|----------|--------------|
| 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     |
| metrics-server              | minikube | enabled ✅   |
| nvidia-driver-installer     | minikube | disabled     |
| nvidia-gpu-device-plugin    | minikube | disabled     |
| registry                    | minikube | disabled     |
| registry-creds              | minikube | disabled     |
| storage-provisioner         | minikube | enabled ✅   |
| storage-provisioner-gluster | minikube | disabled     |
|-----------------------------|----------|--------------|
$ minikube start
😄  minikube v1.7.3 on Darwin 10.14.6
✨  Using the virtualbox driver based on user configuration
🔥  Creating virtualbox VM (CPUs=2, Memory=10240MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.17.3 on Docker 19.03.6 ...
🚀  Launching Kubernetes ... 
🌟  Enabling addons: default-storageclass, metrics-server, storage-provisioner
⌛  Waiting for cluster to come online ...
🏄  Done! kubectl is now configured to use "minikube"

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

ConfigMap

For my Kubernetes build I will be using a ConfigMap to pass variables to my Oracle 12 deployment.

$ cat oracle.properties
DB_SID=PSTG
DB_PDB=PSTGPDB1
DB_PASSWD=Kube#2020
DB_DOMAIN=localdomain
DB_BUNDLE=basic
DB_MEMORY=8g

I have created a file called oracle.properties which I will be used to create the configmap.

$ 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.

$ kubectl get configmaps/oradb -o yaml -n oracle-namespace
apiVersion: v1
data:
  DB_BUNDLE: basic
  DB_DOMAIN: local domain
  DB_MEMORY: 8g
  DB_PASSWD: Kube2020
  DB_PDB: PSTGPDB1
  DB_SID: PSTG
kind: ConfigMap
metadata:
  creationTimestamp: "2020-02-26T13:54:08Z"
  name: oradb
  namespace: oracle-namespace
  resourceVersion: "29967"
  selfLink: /api/v1/namespaces/oracle-namespace/configmaps/oradb
  uid: 8816ad3c-83a5-4e3b-bd93-b5f95d09b33a

Secrets

For this Blog post I will be using the official Oracle 12c Docker image which is available from DockerHub. You will need therefore need a Docker account and also agree to the Oracle licence usage agreement. Alternatively you can use your Oracle account at the Oracle Container Registry.

If you want to familiarise yourself on how to get Oracle images from the DockerHub you can find out more here.

$ kubectl create secret docker-registry oracle \
--docker-server=docker.io \
--docker-username=<docker username> \
--docker-password=<docker password> \
--docker-email=<docker password> \
-n oracle-namespace
secret/oracle created
$ kubectl get secrets -n oracle-namespace
NAME                  TYPE                                  DATA   AGE
default-token-qdmw9   kubernetes.io/service-account-token   3      2m58s
oracle                kubernetes.io/dockerconfigjson        1      111s

Running Oracle12

We can create our Oracle 12c database Kubernetes pod with kubectl apply

$ kubectl apply -f database_12c.yaml -n oracle-namespace
deployment.apps/oracle12c created
service/oracle12c created

Use kubectl get(s) to check status e.g.

$ kubectl get deployments -n oracle-namespace
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
oracle12c   1/1     1            1           27s
$ kubectl get pods -n oracle-namespace
NAME                         READY   STATUS    RESTARTS   AGE
oracle12c-5d7bdf7855-6tz7b   1/1     Running   0          62s

Now we know the pod name we can view the log output during the build.

$ kubectl logs oracle12c-5d7bdf7855-6tz7b -n oracle-namespace
Setup Oracle Database
Oracle Database 12.2.0.1 Setup
...
$ kubectl get services -n oracle-namespace
NAME        TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
oracle12c   NodePort   10.103.179.200   <none>        1521:32317/TCP   25h

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

We can easily check to see if our Oracle Docker image has been downloaded into our VirtualBox MiniKube VM by ssh’ing on to VM and performing docker images.

$ minikube ssh
MiniKube Docker Images

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
MiniKube Dashboard – Config Map

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.

MiniKube also provide a Shell into our Pod e.g. Workloads > Pods > POD > Logs

Database renamed as per our ConfigMap

MiniKube provide a Shell into our Pod e.g. Workloads > Pods > POD > Shell

From here we can navigate the Linux environment and connect to our database.

PDB named from our ConfigMap

Connection from Laptop

Connecting to our database via MiniKube Dashboard is great, but connecting directly to the Oracle database from our laptop is going to be more useful, to do this we need to first identify the exposed IP address and port.

$ minikube service oracle12c -n oracle-namespace --url
http://192.168.99.102:32317

As I have sqlplus installed on my laptop I will use that to connect using the detail above.

$ sqlplus system/<password>@192.168.99.102:32317/PSTG.localdomain
SQL*Plus: Release 19.0.0.0.0 - Production on Sat Mar 14 13:40:43 2020
Version 19.3.0.0.0

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

Last Successful login time: Sat Mar 14 2020 13:37:56 +00:00

Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

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
-------- ------------------------------ -------------------------
PSTG     oracle12c-5d7bdf7855-6tz7b     12.2.0.1.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 use these with Oracle SQL Developer.

Create a connection
Using Oracle SQL Developer

In my next Blog I will share how to present persistent storage to your Kubernets pod and look at using a different Docker images and also provide a link to my GitHub code.

6 comments

Leave a Reply to goryszewskig Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s