Background
Over the last few years I have shared a number of posts showing how we can deliver Oracle databases on Kubernetes using deployments and statefulsets, on-premises and in the Oracle Cloud.
I have also recently posted about the use of the new Oracle Database Kubernetes Operator (OraOperator), however another simple method is with Helm.
What is Helm
Helm is a Kubernetes package manager which can be used to simplify Kubernetes deployments, think yum or apt for Linux. Helm charts are the method of packaging Kubernetes application for installation and upgrades.
Prerequisites
Before we start we need to confirm we have a Kubernetes version high than 1.12, Helm version of 2.x or 3.x and a Kubernetes secret to access the Oracle Container Registry.
Kubernetes
Use kubectl version to confirm Kubernetes version is higher than 1.12, for example
# kubectl version --short | awk -Fv '/Server Version: / {print $3}' 1.21.3
Helm
And check Helm version, using helm version, thus.
# helm version version.BuildInfo{Version:"v3.7.1", GitCommit:"1d11fcb5d3f3bf00dbe6fe31b8412839a96b3dc4", GitTreeState:"clean", GoVersion:"go1.16.9"}
Oracle Container Registry
Create Kubernetes secret for Oracle Container Registry using Oracle SSO credentials, for example.
# kubectl create secret docker-registry regcred --docker-server=container-registry.oracle.com --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
Alternatively, logon to the Oracle Container Registry (OCR) using SSO credentials
# docker login container-registry.oracle.com Username: <SSO email> Password: <SSO password> Login Succeeded
And then create a Kubernetes secret using the ~/.docker/config.json file.
# kubectl create secret generic regcred --from-file=.dockerconfigjson=$HOME/.docker/config.json --type=kubernetes.io/dockerconfigjson -n oracle-namespace secret/regcred created
Default Kubernetes Namespace
To avoid having to specify our namespace with -n each time use the set-context to specify a default namespaces for example oracle-namespace.
# kubectl config set-context --current --namespace=oracle-namespace
Oracle database Helm package
The Oracle 19c database Helm chart creates a multi-tenant, single pdb Oracle Database 19c running on Oracle Linux 7.
Start by cloning the Oracle GitHub repo
# git clone https://github.com/oracle/docker-images.git Cloning into 'docker-images'... remote: Enumerating objects: 15267, done. remote: Counting objects: 100% (129/129), done. remote: Compressing objects: 100% (96/96), done. remote: Total 15267 (delta 48), reused 73 (delta 23), pack-reused 15138 Receiving objects: 100% (15267/15267), 10.23 MiB | 4.70 MiB/s, done. Resolving deltas: 100% (8973/8973), done.
The Helm chart can be found in the docker-images/OracleDatabase/SingleInstance/helm-charts/oracle-db directory.
Use helm package to generate oracle-db-1.0.0.tgz
# helm package docker-images/OracleDatabase/SingleInstance/helm-charts/oracle-db Successfully packaged chart and saved it to: /root/oracle-db-1.0.0.tgz
Create Portworx Storage Class
The Oracle Helm chart supports a number of customisation, including providing a Kubernetes Storage Class, for this post I will be using a Portworx Storage Class.
The Portworx storage class is configured to use an io_profile of db_remote, priority_io of high, and to allow volume expansions, I have also selected a replication factor of 3 as the majority of OCI regions provide 3 Availability Domains.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: px-ora-sc
provisioner: kubernetes.io/portworx-volume
parameters:
repl: "3"
io_profile: "db_remote"
priority_io: "high"
allowVolumeExpansion: true
# kubectl apply -f px-ora-sc.yaml storageclass.storage.k8s.io/px-ora-sc created
Installing Chart
Before we install the chart preform a dry-run to validate configuration
# helm install db19c -f values.yaml oracle-db-1.0.0.tgz --dry-run
If all ok, now install using helm install and a configuration yaml file.
# helm install db19c -f values.yaml oracle-db-1.0.0.tgz
Output from helm install
NAME: db19c LAST DEPLOYED: Thu Feb 10 12:36:00 2022 NAMESPACE: oracle-namespace STATUS: deployed REVISION: 1 NOTES: # # Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. # Licensed under the Universal Permissive License v 1.0 as shown at http://oss.oracle.com/licenses/upl. # # =========================================================================== # == Add below entries to your tnsnames.ora to access this database server == # ====================== from external host ================================= ORCLCDB=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=<ip-address>)(PORT=<port>)) (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=<ORACLE_SID>))) ORCLPDB1=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=<ip-address>)(PORT=<port>)) (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=<ORACLE_PDB>))) # #ip-address : IP address of any of the Kubernetes nodes #port : Service Port that is mapped to the port 1521 of the container. # Application details ==================== IP and port can be found using the following: export NODE_PORT=$(kubectl get --namespace oracle-namespace -o jsonpath="{.spec.ports[0].nodePort}" services db19c-oracle-db) export NODE_XDB_PORT=$(kubectl get --namespace oracle-namespace -o jsonpath="{.spec.ports[1].nodePort}" services db19c-oracle-db) export NODE_IP=$(kubectl get nodes --namespace oracle-namespace -o jsonpath="{.items[0].status.addresses[0].address}") echo listener at $NODE_IP:$NODE_PORT echo XDB at $NODE_IP:$NODE_XDB_PORT Oracle Databases SID, PDB name can be figured out by : ORACLE_SID=$(kubectl get -o jsonpath="{.spec.template.spec.containers[?(.name == 'oracle-db')].env[?(.name == 'ORACLE_SID')].value }" deploy db19c-oracle-db) ORACLE_PDB=$(kubectl get -o jsonpath="{.spec.template.spec.containers[?(.name == 'oracle-db')].env[?(.name == 'ORACLE_PDB')].value }" deploy db19c-oracle-db)
List Charts
# helm list NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION db19c oracle-namespace 1 2022-02-10 12:36:00.0585055 +0000 UTC deployed oracle-db-1.0.0
Kubernetes Deployment
Using the details provide in from helm install output, we can check the $ORACLE_SID, for example
# ORACLE_SID=$(kubectl get -o jsonpath="{.spec.template.spec.containers[?(.name == 'oracle-db')].env[?(.name == 'ORACLE_SID')].value }" deploy db19c-oracle-db) # echo $ORACLE_SID PSTGCDB # ORACLE_PDB=$(kubectl get -o jsonpath="{.spec.template.spec.containers[?(.name == 'oracle-db')].env[?(.name == 'ORACLE_PDB')].value }" deploy db19c-oracle-db) # echo $ORACLE_PDB PSTGPDB1
Deployments
# kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE db19c-oracle-db 0/1 1 0 4m11s
Pods
# kubectl get pods NAME READY STATUS RESTARTS AGE db19c-oracle-db-57478b775-ngnr8 0/1 Running 0 4m2s
Pod Logs
# kubectl logs pods/db19c-oracle-db-57478b775-ngnr8 [2022:02:10 12:36:06]: Acquiring lock .PSTGCDB.create_lck with heartbeat 30 secs [2022:02:10 12:36:06]: Lock acquired [2022:02:10 12:36:06]: Starting heartbeat [2022:02:10 12:36:06]: Lock held .PSTGCDB.create_lck ORACLE EDITION: ENTERPRISE LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 10-FEB-2022 12:36:06 Copyright (c) 1991, 2019, Oracle. All rights reserved. Starting /opt/oracle/product/19c/dbhome_1/bin/tnslsnr: please wait... TNSLSNR for Linux: Version 19.0.0.0.0 - Production System parameter file is /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora Log messages written to /opt/oracle/diag/tnslsnr/db19c-oracle-db-57478b775-ngnr8/listener/alert/log.xml Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1))) Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521))) Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1))) STATUS of the LISTENER ------------------------ Alias LISTENER Version TNSLSNR for Linux: Version 19.0.0.0.0 - Production Start Date 10-FEB-2022 12:36:07 Uptime 0 days 0 hr. 0 min. 0 sec Trace Level off Security ON: Local OS Authentication SNMP OFF Listener Parameter File /opt/oracle/product/19c/dbhome_1/network/admin/listener.ora Listener Log File /opt/oracle/diag/tnslsnr/db19c-oracle-db-57478b775-ngnr8/listener/alert/log.xml Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521))) The listener supports no services The command completed successfully Prepare for db operation 8% complete Copying database files 31% complete Creating and starting Oracle instance 32% complete 36% complete 40% complete 43% complete 46% complete Completing Database Creation 51% complete 54% complete Creating Pluggable Databases 58% complete 77% complete Executing Post Configuration Actions 100% complete Database creation complete. For details check the logfiles at: /opt/oracle/cfgtoollogs/dbca/PSTGCDB. Database Information: Global Database Name:PSTGCDB System Identifier(SID):PSTGCDB Look at the log file "/opt/oracle/cfgtoollogs/dbca/PSTGCDB/PSTGCDB.log" for further details. SQL*Plus: Release 19.0.0.0.0 - Production on Thu Feb 10 12:59:54 2022 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle. All rights reserved. ... The Oracle base remains unchanged with value /opt/oracle ######################### DATABASE IS READY TO USE! ######################### ...
Persistent Volume Claims
# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE db19c-oracle-db Bound pvc-329c205a-42ea-4d68-bb3a-3a0de59fb262 20Gi RWX px-ora-sc 2m2s
Services
# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db19c-oracle-db NodePort 10.105.52.239 <none> 1521:30067/TCP,5500:30396/TCP 8m27s
Test Connection
Using the above details and SQLplus we can connect to our pdb.
% sqlplus system/Kube#2020@10.225.115.150:30067/PSTGPDB1 @database_details SQL*Plus: Release 19.0.0.0.0 - Production on Thu Feb 10 14:30:07 2022 Version 19.3.0.0.0 Copyright (c) 1982, 2019, Oracle. All rights reserved. Last Successful login time: Thu Feb 10 2022 14:29:59 +00:00 Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.3.0.0.0 Current Time : 10/02/22 14:30:08 Database Details =============================================== Hostname : db19c-oracle-db-57478b775-ngnr8 Database Name : PSTGCDB Date Created : 10/02/22 12:38:47 Date Started : 10/02/22 12:59:10 Resetlogs Date : 10/02/22 12:38:49 DB Status : OPEN Space Allocated: .69 GB Space Used : .56 GB SQL> show con_name; PSTGPDB1 SQL> select banner_full from v$version; Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.3.0.0.0
Uninstalling the Chart
To delete the dbc19c deployment, use helm uninstall, for example
# helm uninstall db19c release "db19c" uninstalled
The helm uninstall command removes all the Kubernetes components associated with the chart, including the Persistent Volume Claim (PVC) and deletes the release.
If we repeat helm list we can see that the package has been removed.
# helm list NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
Summary
In this post I have shared how we can use a Helm chart to deploy an Oracle 19c database on Kubernetes, configure the chart to use a StorageClass, connect remotely and tidy-up the deployment.
[twitter-follow screen_name=’RonEkins’ show_count=’yes’]
Leave a Reply