Eine bereits bestehende Oracle Database Installation kann mit einer frei verfügbaren OpenSource Erweiterung, genannt OraOperator, als native Ressource in ein Kubernetes Cluster eingebunden werden. Die Datenbank wird dadurch noch besser integrierbar in moderne DevOps Prinzipien und sichtbarer Teil eines Continuous Delivery Ansatzes. Wie eine solche Einbindung funktionieren kann möchten wir in diesem Artikel aufzeigen und wir möchten kurz darstellen, welche weiteren Optionen der OraOperator bietet wie beispielsweise einen vereinfachten Betrieb der Oracle Database im Kubernetes Cluster.
Der Oracle Operator für Kubernetes, oder auch OraOperator genannt, unterstützt mehrere Ausprägungen und Betriebsformen einer Oracle Database, zum Beispiel
lassen sich damit Autonomous Databases in der Oracle Cloud erzeugen und ansprechen, Oracle Databases mit und ohne Sharding innerhalb des Kubernetes Clusters erzeugen und betreiben. Aber es können auch auf beliebige Weise installierte Oracle Databases auf gängiger Hardware und Exadata-Systeme eingebunden und referenziert werden. Da der letztere Fall das wahrscheinlich häufigste Szenario darstellen dürfte möchten wir im Folgenden diesen Weg etwas näher Beschreiben.
Die Dokumentation des OraOperator auf github.com erläutert diesen Weg im Kapitel “Oracle Multitenant Database Controller”. Wir stellen den Weg ein wenig umgestellt und anders erläutert vor und berücksichtigen dabei neuere Versionen und Features des OraOperators Version 0.2.1 und der Oracle REST Data Services (ORDS), hier in Version 23.1.
Funktionsweise des OraOperator für Multitenant Databases (funktioniert auch mit nur einem Tenant):
- Eine in YAML Format zu formulierende Kubernetes Ressource beschreibt den Zugang zu einer Container Database (CDB).
Die Kubernetes Ressource ist bezeichnenderweise vom Typ “ContainerDatabase” oder kurz “CDB“. - Bei Anlegen der Ressource (z.B. mittels “kubectl apply” Kommando) konfiguriert, verknüpft und startet der OraOperator einen Container mit enthaltenen Oracle REST Data Services (ORDS) zur Verwaltung von Pluggable Databases über eine REST API.
- Eine in YAML Format zu formulierende Kubernetes Ressource beschreibt eine einzubindende, zu clonende oder neu anzulegende Pluggable Database (PDB).
Die dafür anzusprechende Container Database (CDB) wird in der Beschreibung namentlich referenziert.
Die Kubernetes Ressource ist bezeichnenderweise vom Typ “PluggableDatabase” oder kurz “PDB“. - Bei Anlegen der Ressource (“kubectl apply”) spricht der OraOperator den ORDS Container an und ruft die zum Cloning, Anlegen, Löschen, Hoch- und Herunterfahren nötigen REST Services auf. Der Status der Kubernetes Ressource wird entsprechend aktualisiert und ist abfragbar (“kubectl get pdb <pdbname>”).
Einrichtung des OraOperators, Verknüpfung von Container und Pluggable Database in Kubernetes
1. Installation des OraOperators
2. Erzeugung und Ablage eines ORDS Container Images für den OraOperator
3. Vorbereitung der Container Database
4. “Sicherheitsvorkehrungen” für den CDB-Zugriff im Kubernetes Cluster
5. Verknüpfung des Kubernetes Clusters mit einer Container Database
6. Anlegen, Stoppen und Löschen einer Pluggable Database
7. Einbindung von Datenbank und Applikation in ein Werkzeug für Continuous Deployment
8. Ausblick: da geht doch noch mehr ?
1. Installation des OraOperators
In ein bestehendes Kubernetes Cluster läßt sich die Software des OraOperator mit zwei kurzen Kommandos installieren.
Für die Verwaltung von SSL Zertifikaten für die interne Kommunikation des OraOperator sollte zunächst die Komponente “cert-manager” installiert werden. Ist bereits eine Container Management Plattform wie Oracle Verrazzano installiert, so ist der cert-manager bereits vorhanden und muß nicht mehr berücksichtigt werden.
$ kubectl apply -f https://github.com/jetstack/cert-manager/releases/latest/download/cert-manager.yaml
Nun folgt das Kommando für Neuinstallation (und auch Update) der OraOperator-Software selbst:
$ kubectl apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/main/oracle-database-operator.yaml
Nach erfolgter Installation müßte im Kubernetes Cluster ein neuer Namespace oracle-database-operator-system angelegt sein, darin mehrere Container bzw. Pods desselben Software-Deployments oracle-database-operator-controller-manager. Dies kann wie folgt geprüft werden:
$ kubectl get pods -n oracle-database-operator-system NAME READY STATUS RESTARTS AGE oracle-database-operator-controller-manager-775bb46fd-6smq7 1/1 Running 5 (24h ago) 33d oracle-database-operator-controller-manager-775bb46fd-mkhxw 1/1 Running 6 (24h ago) 33d oracle-database-operator-controller-manager-775bb46fd-wjxdn 1/1 Running 4 (24h ago) 33d
2. Erzeugung und Ablage eines ORDS Container Images für den OraOperator
Das herunterladbare Container Image für ORDS auf container-registry.oracle.com genügt hier nicht für den Einsatz mit dem OraOperator. Die ORDS Einrichtung muß mit einigen zusätzlichen Einstellungen erfolgen, zum Beispiel der Aktivierung der REST Management API für Datenbanken, Einrichtung eines Datenbank-Administrations-Benutzers im integrierten HTTP Server, Einrichtung einer internen SSL Kommunikation. Zu diesem Zweck existiert auf den github-Seiten des OraOperators ein angepaßtes ORDS Start-Skript und ein entsprechendes Dockerfile, um das Image zu erzeugen. Bitte laden Sie die beiden Dateien z.B. auf ein Linux-System mit vorinstalliertem “docker” oder “podman” herunter:
$ wget https://raw.githubusercontent.com/oracle/oracle-database-operator/main/ords/Dockerfile $ wget https://raw.githubusercontent.com/oracle/oracle-database-operator/main/ords/runOrdsSSL.sh
Das Dockerfile verwendet als Basis ein mit Oracle Java vorinstalliertes Container Image. Wenn Sie dies verwenden möchten, brauchen Sie das Dockerfile nicht anzupassen, allerdings sollten Sie sich vorher mit einem Browser auf container-registry.oracle.com anmelden, auf den “Java” Bereich klicken und die Software-Bestimmungen für die Java Container akzeptieren. Dann melden Sie sich bitte per “docker” oder “podman” Kommando auf container-registry.oracle.com mit dem selben Benutzer an (“podman login container-registry.oracle.com”).
Ist dieser Schritt erfolgt, können Sie nun das Container Image erzeugen und dieses auf eine schreibberechtigte Container Registry Ihrer Wahl hochladen, zum Beispiel nach docker.io:
$ podman build -t docker.io/meinbenutzer/pub_ordsrestmgmt:23.1 . $ podman push docker.io/meinbenutzer/pub_ordsrestmgmt:23.1
Ein vorbereitetes Image zu reinen Testzwecken liegt aktuell in der Oracle Cloud bereit unter der Bezeichnung fra.ocir.io/frul1g8cgfam/pub_ordsrestmgmt:23.1
3. Vorbereitung der Container Database
Damit die Verwaltung von Pluggable Databases funktioniert, muß sich die ORDS Installation direkt mit der Container Database und NICHT mit einer der verwalteten Pluggable Databases verbinden. Sollte mindestens eine der Pluggable Databases eine eigene, sprich lokale Installation des ORDS Schemas ORDS_PUBLIC_USER besitzen, so wird die Einrichtung des ORDS für die Verwaltung von Pluggable Databases fehlschlagen. Bitte verwenden Sie nur eine Container Datenbank mit dort eingerichtetem ORDS_PUBLIC_USER – oder noch ganz ohne diesen. Die ORDS Installation würde das Datenbank-Schema entsprechend einrichten oder aktualisieren.
Weiterhin ist ein umfassend berechtigter Datenbank-Benutzer anzulegen, der in der Lage ist, Pluggable Databases zu bearbeiten und abzufragen. Typischerweise wird der Name C##DBAPI_DB_ADMIN verwendet. Der ORDS Container wird sich mit diesem Benutzer an der Container Database anmelden. Um den Power-User C##DBAPI_DB_ADMIN anzulegen, setzen Sie bitte folgende SQL Kommandos gegen Ihre Container Database ab:
SQL> conn /as sysdba
-- Create the below user at the database level:
ALTER SESSION SET "_oracle_script"=true;
DROP USER C##DBAPI_CDB_ADMIN cascade;
CREATE USER C##DBAPI_CDB_ADMIN IDENTIFIED BY <Password> CONTAINER=ALL ACCOUNT UNLOCK;
GRANT SYSOPER TO C##DBAPI_CDB_ADMIN CONTAINER = ALL;
GRANT SYSDBA TO C##DBAPI_CDB_ADMIN CONTAINER = ALL;
GRANT CREATE SESSION TO C##DBAPI_CDB_ADMIN CONTAINER = ALL;
-- Verify the account status of the below usernames. They should not be in locked status.
-- Missing ORDS_PUBLIC_USER is OK, will be created when running ORDS the first time.
col username for a30
col account_status for a30
select username, account_status from dba_users where username in ('ORDS_PUBLIC_USER','C##DBAPI_CDB_ADMIN','APEX_PUBLIC_USER','APEX_REST_PUBLIC_USER');
Der Datenbank-Benutzer wird später in ORDS automatisch an einen anderslautenden Benutzer des HTTP Servers gekoppelt, zum Beispiel sql_admin. Dieser muß zu diesem Zweck die Applikationsrolle SQL Administrator innehaben. Auch diese Zuordnung erfolgt später noch automatisch beim ersten Start des ORDS Containers.
4. “Sicherheitsvorkehrungen” für den CDB-Zugriff im Kubernetes Cluster
Die existierenden Benutzernamen und Kennwörter der Container Database sowie gewünschte Benutzernamen und das Kennwort des ORDS HTTP Benutzers müssen zunächst in einem Kubernetes “Secret” abgelegt werden, damit sie vom OraOperator aufgreifbar sind. Benutzernamen und Passwörter sind BASE64-encodierte Werte. Eine entsprechende YAML Datei mit Kennwörtern darin , z.B. “cdb_secret.yaml” könnte wie folgt aussehen:
apiVersion: v1 kind: Secret metadata: name: cdb19c-secret namespace: oracle-database-operator-system type: Opaque data: # pwd for ORDS_PUBLIC_USER ords_pwd: "yadayadayumyum" # pwd for SYS AS SYSDBA sysadmin_pwd: "yadayadayumyum" # CDB Admin User, e.g. C##DBAPI_CDB_ADMIN cdbadmin_user: "QyMjREJBUElfQ0RCX0FETUlO" # pwd for cdbadmin_user cdbadmin_pwd: "yadayadayumyum" # HTTP user with "SQL Administrator" role, e.g. sql_admin webserver_user: "c3FsX2FkbWlu" # pwd for HTTP user webserver_pwd: "yadayadayumyum"
Die von Ihnen noch einzutragenden Werte für die Felder erhalten Sie beispielsweise durch Codierung mit dem “base64” Werkzeug unter Linux:
$ echo -n "C##_DBAPI_CDB_ADMIN" | base64 ; echo QyMjREJBUElfQ0RCX0FETUlO
Als Namespace für das Secret und auch für die noch folgenden Ressourcen wäre ein anderer denkbar als der hier verwendete oracle-database-operator-system. Für unser Beispiel bleiben wir jedoch dabei. Bitte legen Sie nun die Ressource vom Typ “Secret” in Kubernetes an:
$ kubectl apply -f cdb_secret.yaml
Im nächsten Schritt werden für die interne Kommunikation des OraOperator mit dem ORDS Container zwei Zertifikate erzeugt und ebenfalls als Kubernetes “Secret” abgelegt. Die hier verwendeten self-signed Zertifikate dürften vollauf genügen, da ORDS nicht außerhalb des Kubernetes Clusters angesprochen wird. Die Kommunikation findet normalerweise nur zwischen dem OraOperator und dem ORDS innerhalb des Clusters statt.
Bitte beachten Sie, daß der Server-Name, für den das Zertifikat ausgestellt wird, gleich lauten muß wie die noch anzulegende ContainerDatabase-Ressource – nur mit dem Zusatz “-ords”. In unserem Beispiel wird die ContainerDatabase-Ressource den Namen “cdb19c” tragen, also muß das Zertifikat ausgestellt werden auf einen Server mit Namen cdb19c-ords. Das ist eine Besonderheit mit ORDS ab Version 22.4: Ab dieser Version prüft der Netzwerk-Stack des HTTP Servers, ob der aufgerufene Server-Name mit dem im installierten Zertifikat übereinstimmt. Wenn nicht wird eine Fehlermeldung der Art “Invalid SNI” zurückgegeben, die REST Services lassen sich nicht aufrufen.
$ genrsa -out ca.key 2048 $ openssl req -new -x509 -days 365 -key ca.key -subj "/C=CN/ST=GD/L=SZ/O=oracle, Inc./CN=oracle Root CA" -out ca.crt $ openssl req -newkey rsa:2048 -nodes -keyout tls.key -subj "/C=CN/ST=GD/L=SZ/O=oracle, Inc./CN=cdb19c-ords" -out server.csr $ /usr/bin/echo "subjectAltName=DNS:cdb19c-ords,DNS:www.example.com" > extfile.txt $ openssl x509 -req -extfile extfile.txt -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out tls.crt $ kubectl create secret tls db-tls --key="tls.key" --cert="tls.crt" -n oracle-database-operator-system $ kubectl create secret generic db-ca --from-file=ca.crt -n oracle-database-operator-system
Soweit zu den Sicherheitsvorkehrungen. Im nächsten Teil verbinden wir alles miteinander.
5. Verknüpfung des Kubernetes Clusters mit einer Container Database
Nun kommen alle bisherigen Aufgaben zusammen: wir legen eine Kubernetes Ressource vom Typ CDB an und geben darin alles an, was bisher angelegt wurde: Name des ORDS Container Images, Name der CDB Ressource, Benutzernamen und Kennwörter aus einem Kubernetes Secret und SSL Zertifikate aus einem anderen Kubernetes Secret. Die beschreibende YAML Datei cdb.yaml könnte wie nachfolgend aussehen – bitte passen Sie Ihre Servernamen, Ports, Container Image und Datenbank Service entsprechend Ihrer Umgebung an. Die Kennwörter und Benutzernamen werden dynamisch aus den Kubernetes Secrets ausgelesen, die Sie im vorigen Schritt definiert haben. Bitte beachten Sie dort die jeweiligen Namen Ihrer selbst angelegten Secrets.
apiVersion: database.oracle.com/v1alpha1
kind: CDB
metadata:
name: cdb19c
namespace: oracle-database-operator-system
spec:
cdbName: "DB19c"
dbServer: "130.61.106.99"
dbPort: 1521
replicas: 1
ordsImage: "fra.ocir.io/frul1g8cgfam/pub_ordsrestmgmt:23.1"
ordsImagePullPolicy: "Always"
# Uncomment Below Secret Format for accessing ords image from private docker registry
# ordsImagePullSecret: ""
serviceName: "DB19c_fra1gq.publicdevnet.k8snet.oraclevcn.com"
sysAdminPwd:
secret:
secretName: "cdb19c-secret"
key: "sysadmin_pwd"
ordsPwd:
secret:
secretName: "cdb19c-secret"
key: "ords_pwd"
cdbAdminUser:
secret:
secretName: "cdb19c-secret"
key: "cdbadmin_user"
cdbAdminPwd:
secret:
secretName: "cdb19c-secret"
key: "cdbadmin_pwd"
webServerUser:
secret:
secretName: "cdb19c-secret"
key: "webserver_user"
webServerPwd:
secret:
secretName: "cdb19c-secret"
key: "webserver_pwd"
cdbTlsCrt:
secret:
secretName: "db-tls"
key: "tls.crt"
cdbTlsKey:
secret:
secretName: "db-tls"
key: "tls.key"
Nun können Sie mit “kubectl apply -f cdb.yaml” die Ressource in Kubernetes anlegen und der OraOperator sollte daraufhin sein Werk tun, einen ORDS Container zu konfigurieren und zu starten. Ob dies funktioniert hat, können Sie an mehreren Stellen überprüfen. Nach etwa 20 Sekunden sollte es neben den Containern bzw. Pods für den OraOperator auch einen Pod geben mit dem Namen cdb19c-ords, wenn Sie Ihre CDB Ressource entsprechend cdb19c genannt haben:
$ kubectl get pods -n oracle-database-operator-system NAME READY STATUS RESTARTS AGE cdb19c-ords-rs-ftd7b 1/1 Running 0 43h oracle-database-operator-controller-manager-775bb46fd-6smq7 1/1 Running 5 (42h ago) 33d oracle-database-operator-controller-manager-775bb46fd-mkhxw 1/1 Running 6 (42h ago) 33d oracle-database-operator-controller-manager-775bb46fd-wjxdn 1/1 Running 4 (42h ago) 33d
Sehen Sie sich bitte auch die Log-Einträge des Containers an, der recht detailliert seine Konfiguration ausgibt und auch Infos über Datenbank-Konnektivität ausgibt.
$ kubectl logs cdb19c-ords-rs-ftd7b -n oracle-database-operator-system ... ... jdbc.InitialLimit=50 db.connectionType=basic java.class.version=64.0 standalone.access.log=/home/oracle 2023-05-22T11:31:57.453Z INFO Mapped local pools from /etc/ords/config/databases: /ords/ => default => VALID 2023-05-22T11:31:57.578Z INFO Oracle REST Data Services initialized Oracle REST Data Services version : 23.1.2.r1151944 Oracle REST Data Services server info: jetty/10.0.12 Oracle REST Data Services java info: Java HotSpot(TM) 64-Bit Server VM 20.0.1+9-29 2023-05-22T11:31:58.201Z INFO handleException /ords/_/db-api/stable/metadata-catalog/ org.eclipse.jetty.http.BadMessageException: 400: Invalid SNI
Sollten Sie ebenfalls wie in unserer Umgebung eine Fehlermeldung der Art “invalid SNI” sehen, so ist es an genau dieser Stelle kein Problem: es handelt sich dabei um einen nur teilweise fehlgeschlagenen Testaufruf an sich selbst, ob die REST Services grundsätzlich ansprechbar sind. Leider erfolgt dieser Testaufruf an einen Server mit dem Namen “localhost”, und dieser steht nicht im SSL Zertifikat.
Um den Datenbank-Zugriff zu testen und zu sehen ob der korrekte Server-Name im Zertifikat steht, schauen Sie am besten direkt in den Pod hinein. Verbinden Sie sich mit einer Shell dorthin und rufen Sie eine Test-URL auf. Die hier verwendete Test-URL sollte Ihnen eine Liste aller PDBs im JSON Format liefern, die bereits in Ihrer CDB existieren:
$ kubectl exec -n oracle-database-operator-system -it cdb19c-ords-rs-ftd7b -- /bin/bash
[oracle@cdb19c-ords-rs-ftd7b ~]$ curl --user sql_admin https://cdb19c-ords:8888/ords/_/db-api/stable/database/pdbs/ --insecure
Enter host password for user 'sql_admin':
{"items":[{"inst_id":1,"con_id":2,"dbid":3834124154,"con_uid":3834124154,"guid":"5LG5f2Oe3DvgUzABCgrhSQ==","name":"PDB$SEED","open_mode":"READ ONLY","restricted":"NO","open_time":"2023-05-22T08:52:16.037Z","create_scn":2543153,"total_size":1092616192,"block_size":8192,"recovery_status":"ENABLED","snapshot_parent_con_id":null,"application_root":"NO","application_pdb":"NO","application_seed":"NO","application_root_con_id":null,"application_root_clone":"NO","proxy_pdb":"NO","local_undo":1,"undo_scn":268,"undo_timestamp":null,"creation_time":"2022-07-26T08:02:41Z","diagnostics_size":0,"pdb_count":0,"audit_files_size":0,"max_size":0,"max_diagnostics_size":0,"max_audit_size":0,"last_changed_by":"COMMON USER","template":"NO","tenant_id":null,"upgrade_level":1,"guid_base64":"5LG5f2Oe3DvgUzABCgrhSQA=","links":[{"rel":"self","href":"https://cdb19c-ords:8888/ords/_/db-api/stable/database/pdbs/PDB%24SEED/"}]},
...usw...
Der –insecure Parameter wird benötigt, da nur self-signed Zertifikate benutzt werden. Der HTTP Benutzer sql_admin trägt den Namen, den Sie im vorigen Schritt im Kubernetes Secret abgelegt haben. Eventuell heißt dieser bei Ihnen nicht sql_admin .
Auch die Container des OraOperator sollten einiges an Log Output erzeugt haben beim Versuch, Ressource und Pod anzulegen. Recht übliche Probleme wie Fehlversuche beim Herunterladen und Starten des Container Images (Pod-Status CrashLoopBackoff, Infos über “kubectl get events -n oracle-database-operator-system”) werden hier nicht weiter beleuchtet.
Zu guter Letzt teilt Ihnen Kubernetes mit, ob die neue CDB Ressource erfolgreich angelegt und gestartet wurde. Schauen Sie bitte auf folgende Weise nach dem Rechten:
$ kubectl get cdb -n oracle-database-operator-system NAME CDB NAME DB SERVER DB PORT TNS STRING REPLICAS STATUS MESSAGE cdb19c DB19c 130.61.106.99 1521 1 Ready
Nun ist es soweit – Gratulation! Ihre Container Database ist angebunden und wir können einige Versuche mit Pluggable Databases starten.
6. Anlegen, Stoppen und Löschen einer Pluggable Database
Um eine neue Pluggable Database (PDB) zu erzeugen oder eine bestehende PDB anzubinden, müssen zunächst, ganz ähnlich wie bei der Anbindung der CDB, bestehende bzw. gewünschte Benutzernamen und Kennwörter in einem Kubernetes Secret hinterlegt werden. Hier eine Beispiel-Datei “testpdb-secret.yaml” mit BASE64-encodiertem Benutzernamen “pdbadmin” und einem von Ihnen noch einzutragendem Kennwort in BASE64 Format, ähnlich wie in Schritt 4 beschrieben (echo -n “MeinKennwort” | base64 ; echo).
apiVersion: v1 kind: Secret metadata: name: testdb-secret namespace: oracle-database-operator-system type: Opaque data: # base64 encoded String for "pdbadmin" sysadmin_user: "cGRiYWRtaW4=" # add Your own base64 encoded password here sysadmin_pwd: "yadayadayumyum"
Legen Sie das Secret nun in Ihrem Kubernetes Cluster an:
kubectl apply -f testpdb-secret.yaml
Jetzt ist es soweit – lassen wir uns nun eine neue PDB erzeugen. Es genügt eine kleine beschreibende YAML Datei “testpdb.yaml” mit Wunschnamen der PDB, Admin-Benutzer und Kennwort, Größe des Temp-Bereichs, damit auszuführender Aktion (z.B. “Create”,”Modify”, “Status”) und anderen möglichen Angaben, die unter folgendem Link in Form einer Custom Resource Definition dokumentiert sind: https://github.com/oracle/oracle-database-operator/blob/main/config/crd/bases/database.oracle.com_pdbs.yaml.
apiVersion: database.oracle.com/v1alpha1
kind: PDB
metadata:
name: testpdb
namespace: oracle-database-operator-system
labels:
cdb: cdb19c
spec:
cdbResName: "cdb19c"
cdbName: "DB19C"
pdbName: "testpdb"
adminName:
secret:
secretName: "testpdb-secret"
key: "sysadmin_user"
adminPwd:
secret:
secretName: "testpdb-secret"
key: "sysadmin_pwd"
fileNameConversions: "NONE"
totalSize: "1G"
tempSize: "100M"
action: "Create"
pdbTlsCat:
secret:
secretName: "db-ca"
key: "ca.crt"
pdbTlsCrt:
secret:
secretName: "db-tls"
key: "tls.crt"
pdbTlsKey:
secret:
secretName: "db-tls"
key: "tls.key"
Die in der YAML Datei referenzierten Zertifikate sind dieselben, die bei Anbindung der CDB erzeugt und benutzt wurden.
Nun können Sie die YAML Ressourcen-Beschreibung an Ihr Kubernetes Cluster senden:
kubectl apply -f testpdb.yaml
In recht kurzer Zeit sollte eine neue PDB angelegt sein, die entsprechende Kubernetes Ressource ihren Status von “Creating” auf “Ready” wechseln, der “PDB STATE” auf “READ WRITE” stehen.
kubectl get pdbs -n oracle-database-operator-system NAME CONNECT_STRING CDB NAME PDB NAME PDB STATE PDB SIZE STATUS MESSAGE testpdb 130.61.106.99:1521/testpdb DB19C testpdb READ WRITE 1.08G Ready Success
Auch auf dem Datenbank-Server sollte sich etwas getan haben. Zum Beispiel kennt der Datenbank-Listener nun einen weiteren Service. Eine Liste aller registrierten Datenbank-Dienste erhalten Sie direkt auf dem Datenbank-Server beispielsweise mittels “lsnrctl status” Kommando.
Möchten Sie nun die PDB stoppen, so ist der Wunsch-Zustand mit 2 zusätzlichen Parametern in die Ressourcen-Beschreibung einzutragen und an Kubernetes zu senden. Der OraOperator stellt dann den Wunsch-Zustand her. In der YAML Datei testpdb.yaml können sie nun das Feld action von Create nach Modify ändern und Parameter-Felder hinzufügen für den Wunsch-Zustand (pdbState) und einem Zusatz zur Art der Durchführung (modifyOption):
apiVersion: database.oracle.com/v1alpha1
kind: PDB
metadata:
name: testpdb
namespace: oracle-database-operator-system
labels:
cdb: cdb19c
spec:
cdbResName: "cdb19c"
cdbName: "DB19C"
pdbName: "testpdb"
adminName:
secret:
secretName: "testpdb-secret"
key: "sysadmin_user"
adminPwd:
secret:
secretName: "testpdb-secret"
key: "sysadmin_pwd"
fileNameConversions: "NONE"
totalSize: "1G"
tempSize: "100M"
action: "Modify"
pdbState: "CLOSE"
modifyOption: "IMMEDIATE"
pdbTlsCat:
secret:
secretName: "db-ca"
key: "ca.crt"
pdbTlsCrt:
secret:
secretName: "db-tls"
key: "tls.crt"
pdbTlsKey:
secret:
secretName: "db-tls"
key: "tls.key"
Ein erneuter kubectl apply gefolgt von einem kubectl get pdb sollte schnell die Änderung des Zustands der PDB von “READ WRITE” auf “MOUNTED” darstellen:
$ kubectl apply -f testpdb.yaml $ kubectl get pdb -n oracle-database-operator-system NAME CONNECT_STRING CDB NAME PDB NAME PDB STATE PDB SIZE STATUS MESSAGE testpdb 130.61.106.99:1521/testpdb DB19C testpdb MOUNTED 1.08G Ready Success
Ist die PDB erst einmal heruntergefahren, können wir sie gleich auch zum Test löschen. In unserer Datei testpdb.yaml wäre das action Feld auf den Wert Delete zu ändern. Ein Zusatz-Feld dropAction, dessen Wert festlegt ob die Datafiles mitgelöscht werden sollen, ist ebenso notwendig. Die Parameter-Felder aus der vorhergehenden Aktion dürfen bestehen bleiben, denn sie werden nur bei dem passenden Inhalt des action Feldes benutzt. Sonst werden sie ignoriert:
apiVersion: database.oracle.com/v1alpha1
kind: PDB
metadata:
name: testpdb
namespace: oracle-database-operator-system
labels:
cdb: cdb19c
spec:
cdbResName: "cdb19c"
cdbName: "DB19C"
pdbName: "testpdb"
adminName:
secret:
secretName: "testpdb-secret"
key: "sysadmin_user"
adminPwd:
secret:
secretName: "testpdb-secret"
key: "sysadmin_pwd"
fileNameConversions: "NONE"
totalSize: "1G"
tempSize: "100M"
action: "Delete"
dropAction: "INCLUDING"
pdbTlsCat:
secret:
secretName: "db-ca"
key: "ca.crt"
pdbTlsCrt:
secret:
secretName: "db-tls"
key: "tls.crt"
pdbTlsKey:
secret:
secretName: "db-tls"
key: "tls.key"
Führen Sie nun einen kubectl apply gefolgt von einem kubectl get pdb aus, so können Sie schnell erkennen daß der OraOperator nicht nur die PDB gelöscht hat. Er hat auch gleich die zugehörige Kubernetes Ressource entfernt. Hingegen würde ein kubectl delete pdb zwar die Ressource entfernen, die PDB in der Datenbank jedoch beibehalten. Dies ist ein so vorgesehenes Verhalten des OraOperator und unseres Erachtens durchaus sinnvoll:
$ kubectl apply -f testpdb.yaml pdb.database.oracle.com/testpdb configured $ kubectl get pdb -n oracle-database-operator-system No resources found in oracle-database-operator-system namespace.
So viel zum Pflichtteil unserer Darstellung. Sie und andere via sogenannter ServiceAccounts berechtigte Entwickler in Ihrem Hause sollten nun in der Lage sein, beliebig PDBs zu erzeugen, zu clonen und zu löschen. Und dies alles per Self Service und sichtbar in Kubernetes. Wir gratulieren herzlich!
Was können Sie mit diesen Möglichkeiten anfangen, was sollten Sie vielleicht noch ergänzen? Darüber einige Gedanken im nächsten Teil:
7. Einbindung von Datenbank und Applikation in ein Continuous Deployment Werkzeug
Einmal angenommen, Sie laden nun alle Ihre Applikations-beschreibenden YAML Dateien gemeinsam mit den YAML Dateien für die dazugehörige Pluggable Database in ein GIT Repository Ihrer Wahl hoch. Dann könnte ein Werkzeug für Continuous Deployment reagieren, sobald es Änderungen in der Applikations- oder Datenbank-Konfiguration gibt und diese sofort nachfahren und überwachen. Oder auch zurückfahren auf eine ältere Konfiguration, ganz wie Sie wünschen.
Möchten Sie neben der Datenbank-Größe oder einem anderen Clone als bisher die Inhalte der Datenbank feingranularer kontrollieren und versionieren, so wäre die Einbindung eines Containers mit installierter liquibase-Software und versioniertem Datenbank-Schema denkbar. Im einfacheren Fall können Sie beim Start des Anwendungscontainers ein SQL Skript referenzieren, das beim Deployment ausgeführt werden soll. Auf jeden Fall haben Sie dank des OraOperators noch mehr Automatisierung und Dokumentation beim Ausrollen von Anwendung und zugehöriger Datenbank – und auch beim Rollback auf einen älteren Stand der Anwendung.
Wir haben als Beispiel eine kleine Demo-Applikation und unsere eben erstellte PDB Beschreibung auf ein github Repository hochgeladen und zwecks Einsicht und Dokumentation in ArgoCD eingebunden, einem OpenSource Continuous Deployment Werkzeug für Kubernetes und auch Bestandteil der OpenSource Container Management Plattform “Oracle Verrazzano”. Das Repository ist zu Testzwecken öffentlich zugänglich unter der URL https://github.com/ilfur/OraOperatorDBWithApp:

Die entsprechende github-URL in ArgoCD eingebunden und einen Namen (“oraoperatordbwithapp”) für die zu pflegende Applikation gewählt, ist unser Beispiel als Kachel aufgelistet:

Dann einmal auf den Sync-Button geklickt, stellt sich die Anwendung mit allen ihren Kubernetes Ressourcen vollständig dar – nun endlich auch mit zugehöriger, nicht länger anonymer Oracle Datenbank bzw. Pluggable Database.

Die Pluggable Database Ressource ist wie jede andere Kubernetes Ressource hier einsehbar und zeigt z.B. die letzten Ereignisse rund um die Ressource an, gefüttert aus den Informationen des OraOperator.

Wir hoffen, wir konnten bislang einen kleinen Einblick in die Thematik und eine Idee dazu vermitteln, warum es sinnvoll ist eine (externe) Oracle Datenbank als Kubernetes Ressource einzubinden. Doch an dieser Stelle sind wir noch nicht ganz am Schluß angekommen.
Fazit – oder: da geht doch noch mehr ?
Oracle Datenbanken als Teil einer Microservices-basierten Anwendung zu behandeln und zu dokumentieren, sie automatisiert einbinden, clonen oder frisch erzeugen. Das ist für viele Entwickler sicher wünschenswert und dank des OraOperator auch lösbar. Kubernetes als Laufzeitumgebung für Container bietet darüberhinaus viel Komfort für den umfassenden Betrieb seiner darin verwalteten Software Komponenten. Es wurde unter anderem dabei gedacht an Skalierung (Horizontal und Vertikal), Patching, Failover, Persistenz auch im Sinne eines Backups oder eines Flashback Bereichs und ArchiveLogs. Auch der OraOperator kann diese Möglichkeiten nutzen, jedoch muß die zu verwaltende Oracle Database ebenfalls im Kubernetes Cluster betrieben werden, nicht nur extern eingebunden. Viele Betriebs-Automatisierungen funktionieren durch Definition einer Kubernetes Ressource vom Typ “SingleInstanceDatabase”, die ebenfalls dem OraOperator angehörig ist. Patches, d.h. Release Updates, können durch Tausch der Datenbank Container-Images eingespielt werden. Datenbanken lassen sich umkonfigurieren, Clonen und einiges mehr. Eine Kombination aus der lokal verwalteten “SingleInstanceDatabase” für Betrieb und der hier aufgezeigten Kombination “PluggableDatabase/ContainerDatabase” für Entwickler ist durchaus möglich und wahrscheinlich Inhalt eines weiteren Blog Eintrages.
Bis dahin – viel Spaß und Erfolg beim Testen und ausprobieren!
Einige interessante Links rund um diesen Artikel:
Zahlreiche Oracle Produkte als offizielle vorgefertigte Container Images
OraOperator Seite auf github.com
Oracle Verrazzano Seite auf github.com
Ankündigung der Verfügbarkeit von ArgoCD in Oracle Verrazzano
Blog Artikel über Kubernetes Operatoren für Oracle Datenbanken
Ankündigung des OraOperators seitens Product Management
Artikel über Verwaltung von PDBs mittels ORDS und REST management API – ohne OraOperator