In dieser Anleitung wird die Bereitstellung einer selbstverwalteten Oracle Database Enterprise-Instanz in einem GDC-Standardcluster (Google Distributed Cloud) ohne Internetverbindung beschrieben. Mit dieser Bereitstellung können Sie Oracle-Arbeitslasten in der Air-Gap-Umgebung ausführen und die vorhandenen Speicher- und Netzwerkfunktionen von GDC nutzen.
Dazu wird der offizielle Oracle Database Operator for Kubernetes verwendet, der die Verwaltung des Lebenszyklus der Datenbank automatisiert.
Architektur
Die Architektur beschreibt eine Oracle-Datenbankbereitstellung mit einer einzelnen Instanz, die vom Oracle Database Operator in einem GDC-Standardcluster verwaltet wird. In diesem Leitfaden wird die Bereitstellung einer einzelnen Datenbankinstanz beschrieben. Sie können jedoch so viele Instanzen bereitstellen, wie die Kapazität Ihres Clusters (RAM, CPU, Speicherplatz) zulässt.

Die Architektur umfasst die folgenden Schlüsselkomponenten:
- GDC-Projekt: Der Projektcontainer für Ihre Ressourcen.
- Standard-Kubernetes-Cluster: Ein Standardcluster, der die Rechenressourcen bereitstellt.
- Oracle Database Operator: Ein Kubernetes-Operator, der die Bereitstellung, die Verwaltung des Lebenszyklus und die Beobachtbarkeit von Oracle-Datenbanken automatisiert. Es vereinfacht komplexe Aufgaben wie das Patchen, Sichern und Wiederherstellen und erleichtert so die Ausführung zustandsorientierter Oracle-Arbeitslasten in einer containerisierten Umgebung.
- Datenbankinstanz: Die containerisierte Oracle Single Instance Database (SIDB) mit nichtflüchtigem Speicher.
- Harbor: Die private Container-Registry, die zum Hosten der Datenbank-, Operator- und Client-Images in der Air-Gap-Umgebung verwendet wird.
- Cert-manager: Der Operator verwendet
cert-managerzum Verwalten von Webhook-Zertifikaten.cert-managerist in GDC-Standardclustern vorinstalliert.
In dieser Anleitung stellen Sie den Operator in einem eigenen Namespace (oracle-database-operator-system) und die Datenbankinstanz in einem separaten Namespace (oracle-db) bereit. Diese Namespaces werden im Architekturdiagramm mit gestrichelten Linien dargestellt.
Diese Trennung wird aus Gründen der Übersichtlichkeit und Verwaltbarkeit empfohlen. Es liegt jedoch an Ihnen, wie Sie Ihre Datenbanken organisieren. Sie können beispielsweise bestimmte Datenbanken in verschiedenen Namespaces gruppieren, um die detaillierte Zugriffssteuerung (RBAC) basierend auf den Anforderungen der Arbeitslast, der Teamzugehörigkeit oder den Sicherheitsanforderungen zu verwalten.
Hinweis
Bevor Sie mit der Bereitstellung beginnen, müssen Sie dafür sorgen, dass Ihre Umgebung die folgenden Anforderungen erfüllt:
- Erstellen Sie ein Projekt, das als Container für alle Ressourcen dient, die in diesem Leitfaden generiert werden.
Weisen Sie dem Nutzer die Rollen „Cluster Admin“ und „Standard Cluster Admin“ für Ihr Projekt zu. So können Sie einen Standard-Kubernetes-Cluster erstellen und seine Ressourcen verwalten:
export PROJECT_ID=PROJECT_ID export USER_NAME=USER_NAME gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=cluster-admin gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=standard-cluster-adminErstellen Sie eine Harbor-Instanz und ein Harbor-Projekt, um die für diese Anleitung erforderlichen Container-Images zu hosten.
Weisen Sie Ihrem Nutzer die Rolle „Harbor Instance Admin“ zu, damit Sie Bilder in Ihre Harbor-Instanz hochladen können:
gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=harbor-instance-adminErstellen Sie ein Harbor-Roboterkonto in Ihrem Harbor-Projekt. Später in diesem Leitfaden werden die Anmeldedaten des Robot-Kontos in Kubernetes-Secrets gespeichert, sodass der Cluster beim Instanziieren von Containern Images aus Harbor abrufen kann.
Erstellen Sie einen Standard-Kubernetes-Cluster mit zwei Worker-Knoten, die jeweils mindestens 16 GB Arbeitsspeicher haben. Beispiel:
kubectl --kubeconfig MGMT_API_KUBECONFIG create -f - <<EOF apiVersion: cluster.gdc.goog/v1 kind: Cluster metadata: name: ${CLUSTER_NAME} namespace: ${PROJECT_ID} spec: nodePools: - machineTypeName: n3-standard-8-gdc nodeCount: 2 name: ${CLUSTER_NAME}-node-pool EOFRichten Sie die Umgebungsvariablen ein. Diese werden im gesamten Leitfaden zum Erstellen und Referenzieren von Ressourcen verwendet:
# General info export PROJECT_ID="PROJECT_ID" export ZONE="ZONE" export ORG_NAME="ORG_NAME" export CLUSTER_NAME="CLUSTER_NAME" # Oracle operator settings export ORACLE_OPERATOR_VERSION="2.1.0" export ORACLE_DB_VERSION="23.26.1.0" export ORACLE_OPERATOR_NAMESPACE="ORACLE_DBS_OPERATOR-SYSTEM # Harbor config export HARBOR_INSTANCE_PROJECT_ID="HARBOR_PROJECT_ID" export HARBOR_INSTANCE_NAME="HARBOR_INSTANCE_NAME" export HARBOR_INSTANCE_URL="HARBOR_INSTANCE_URL" export HARBOR_PROJECT="HARBOR_PROJECT" export HARBOR_PULL_SECRET_NAME="HARBOR_PULL_SECRET_NAME" export HARBOR_ROBOT_ACCOUNT="robot\$HARBOR_PROJECT+ROBOT_NAME" export HARBOR_ROBOT_SECRET="HARBOR_ROBOT_SECRET" # Oracle database config export ADMIN_PASSWORD="ADMIN_PASSWORD" export DB_NAMESPACE="DB_NAMESPACE" export DB_NAME="DB_NAME"Hinweis zum Netzwerk:In dieser Anleitung wird davon ausgegangen, dass sie von einem Bastion-Knoten aus ausgeführt wird, der Zugriff auf die GDC-APIs und auf das Internet hat, um die Manifeste und Container-Images des Oracle-Operators herunterzuladen. Wenn Sie diese Anleitung auf einem Computer ohne Internetzugriff ausführen, müssen Sie diese Assets separat abrufen (z. B. mit
docker save, um Bilder von einem verbundenen Computer zu exportieren, und mitdocker load, um sie zu importieren) und sie sicher in Ihre Umgebung hochladen, bevor Sie fortfahren.Erstellen Sie ein Konto und rufen Sie ein API-Token unter container-registry.oracle.com ab. Akzeptieren Sie dann die Lizenzvereinbarung für die Images Oracle Database Enterprise Edition und Oracle Instant Client, bevor Sie fortfahren.
Bilder in Harbor laden
Da Cluster in Google Distributed Cloud mit Air Gap nicht auf externe Registries zugreifen können, müssen Sie die erforderlichen Images auf Ihre private Harbor-Instanz spiegeln.
Bei Oracle Container Registry anmelden
Sie müssen sich zuerst bei der offiziellen Oracle-Registry authentifizieren, um die Basis-Images abzurufen:
docker --config=./docker-oracle login container-registry.oracle.com
Nach einer erfolgreichen Anmeldung werden die Anmeldedaten in ./docker-oracle/config.json gespeichert.
Bilder in Harbor laden
Authentifizieren Sie sich bei Ihrer privaten Harbor-Instanz:
docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
-u ${HARBOR_ROBOT_ACCOUNT} \
-p ${HARBOR_ROBOT_SECRET}
Nach einer erfolgreichen Anmeldung werden die Anmeldedaten des Roboter-Kontos in ./docker-harbor/config.json gespeichert.
Images herunterladen, taggen und per Push übertragen
Laden Sie die Images aus der offiziellen Oracle Container Registry herunter und übertragen Sie sie per Push in Ihr internes Harbor-Projekt. Sie spiegeln den Operator, die Unternehmensdatenbank und den Instant Client für Tests.
Spiegeln Sie das Oracle Database Operator-Image:
docker --config=./docker-oracle pull \ container-registry.oracle.com/database/operator:${ORACLE_OPERATOR_VERSION} \ --platform linux/amd64 docker tag container-registry.oracle.com/database/operator:${ORACLE_OPERATOR_VERSION} \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-operator:${ORACLE_OPERATOR_VERSION} docker --config=./docker-harbor push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-operator:${ORACLE_OPERATOR_VERSION}Spiegeln Sie das Oracle-Datenbank-Enterprise-Image:
docker --config=./docker-oracle pull \ container-registry.oracle.com/database/enterprise:${ORACLE_DB_VERSION} \ --platform linux/amd64 docker tag container-registry.oracle.com/database/enterprise:${ORACLE_DB_VERSION} \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION} docker --config=./docker-harbor push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION}Spiegeln Sie das Oracle Instant Client-Image:
docker --config=./docker-oracle pull container-registry.oracle.com/database/instantclient:latest \ --platform linux/amd64 docker tag container-registry.oracle.com/database/instantclient:latest \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-instantclient:latest docker --config=./docker-harbor push ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-instantclient:latest
Clusterzugriff konfigurieren
Bevor Sie Ressourcen bereitstellen, rufen Sie die Anmeldedaten für Ihren Standardcluster ab und erstellen Sie einen Alias:
Rufen Sie die kubeconfig-Datei für Ihren Standardcluster ab:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \ get-credentials ${CLUSTER_NAME} \ --standard \ --project ${PROJECT_ID} \ --zone ${ZONE}Erstellen Sie den Alias
kk, um nachfolgende Befehle zu vereinfachen:alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"
Secrets erstellen
Erstellen Sie ein Kubernetes-Secret, damit der Cluster Images aus Harbor mit den in Ihrer lokalen ./docker-harbor/config.json gespeicherten Anmeldedaten abrufen kann. Sie benötigen dieses Secret sowohl im Namespace des Operators (zum Pullen des Operator-Images) als auch im Namespace der Datenbank (zum Pullen des Datenbank-Images).
Erstellen Sie den Namespace für den Operator:
kk create ns ${ORACLE_OPERATOR_NAMESPACE}Erstellen Sie das Pull-Secret für den Operator:
kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker-harbor/config.json \ -n ${ORACLE_OPERATOR_NAMESPACE}Erstellen Sie den Namespace für die Datenbank:
kk create ns ${DB_NAMESPACE}Erstellen Sie das Pull-Secret für die Datenbank:
kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker-harbor/config.json \ -n ${DB_NAMESPACE}
Oracle Database Operator installieren
Installieren Sie den Oracle Database Operator in Ihrem Cluster, indem Sie drei Manifeste anwenden:
ClusterRoleBinding: Richtet die erforderlichen Berechtigungen für den Operator ein, damit er clusterweit funktioniert.
kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/cluster-role-binding.yamlKnoten-RBAC: Gewährt Berechtigungen zum Lesen der Knotentopologie, was für die korrekte Pod-Planung entscheidend ist.
kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/node-rbac.yamlOperatorbereitstellung: Stellt die Operator-Pods und benutzerdefinierten Ressourcendefinitionen (CRDs) bereit. Mit diesem Befehl wird das offizielle Manifest heruntergeladen, der Bildpfad durch Ihre Harbor-URL ersetzt, die
imagePullSecrets-Konfiguration eingefügt, damit Kubernetes sich bei Harbor authentifizieren kann, und das Ergebnis angewendet:curl -L https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/oracle-database-operator.yaml \ | sed "s|container-registry.oracle.com/database/operator:latest|${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-operator:${ORACLE_OPERATOR_VERSION}|g" \ | awk "/terminationGracePeriodSeconds: 10/{print; print \" imagePullSecrets:\n - name: ${HARBOR_PULL_SECRET_NAME}\"; next}1" \ | kk apply -f -Warten Sie, bis die Operator-Pods ausgeführt werden:
kk get pods -n ${ORACLE_OPERATOR_NAMESPACE} --watchDie Ausgabe sollte so aussehen:
NAME READY STATUS RESTARTS AGE oracle-database-operator-controller-manager-5f7b56874d-k9v4z 1/1 Running 0 45s oracle-database-operator-controller-manager-5f7b56874d-n2x8m 1/1 Running 0 45s oracle-database-operator-controller-manager-5f7b56874d-r6z7q 1/1 Running 0 45s
Neue Datenbankinstanz bereitstellen
Nachdem der Operator ausgeführt wird, können Sie eine Oracle-Datenbank mit einer einzelnen Instanz bereitstellen. In dieser Anleitung wird eine einfache Enterprise Edition-Instanz erstellt, die sich für die Entwicklung oder das Testen eignet.
Erstellen Sie ein Kubernetes-Secret zum Speichern des administrativen Datenbankpassworts:
kk create secret generic oracle-db-password \ --from-literal=password=${ADMIN_PASSWORD} \ -n ${DB_NAMESPACE}Wenden Sie das
SingleInstanceDatabase-Manifest an, um die Datenbank zu erstellen:apiVersion: database.oracle.com/v4 kind: SingleInstanceDatabase metadata: name: ${DB_NAME} namespace: ${DB_NAMESPACE} spec: sid: ORCLCDB pdbName: ORCLPDB1 edition: enterprise replicas: 1 image: pullFrom: ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION} pullSecrets: ${HARBOR_PULL_SECRET_NAME} prebuiltDB: true persistence: size: 50Gi storageClass: standard-rwo accessMode: ReadWriteOnce adminPassword: secretName: oracle-db-password secretKey: passwordWichtige Konfigurationsparameter:
sid/pdbName: Definiert die System-ID (SID) und den Namen der einsteckbaren Datenbank (Pluggable Database, PDB).edition: Gibt die Datenbankedition an (in diesem Fallenterprise).image: Verweist auf Ihr privates Harbor-Registry-Image.persistence: Fordert ein nichtflüchtiges Volume mit 50 GiB mit der StorageClassstandard-rwoan, wodurch ein zonaler nichtflüchtiger Speicher in GDC erstellt wird.replicas: Legt die Anzahl der Pods auf1fest.1ist typisch für eine einzelne Instanz. Sie können diesen Wert jedoch für bestimmte Anwendungsfälle wie Rolling Updates (bei denen ein neuer Pod erstellt wird, bevor der alte beendet wird) oder bei Verwendung eines gemeinsamen Speicher-Back-Ends, das gleichzeitigen Zugriff unterstützt, erhöhen. Bei einfachen Bereitstellungen mit einer einzelnen Instanz ist1der Standard.
Eine vollständige Liste der Konfigurationsoptionen, einschließlich benutzerdefinierter Initialisierungsparameter und Ressourcenlimits, finden Sie in der offiziellen Dokumentation.
Die Erstellung der Datenbank ist ressourcenintensiv und kann 10 bis 20 Minuten dauern.
Warten Sie, bis der Datenbank-Pod den Status
Runninghat:kk get po -n ${DB_NAMESPACE} -l app=${DB_NAME} -wDie Ausgabe sollte so aussehen:
NAME READY STATUS RESTARTS AGE my-db-i5xdj 0/1 Pending 0 0s my-db-i5xdj 0/1 Pending 0 0s my-db-i5xdj 0/1 Pending 0 1s my-db-i5xdj 0/1 Init:0/1 0 1s my-db-i5xdj 0/1 PodInitializing 0 98s my-db-i5xdj 0/1 Running 0 99s my-db-i5xdj 1/1 Running 0 99sBeobachten Sie dann die Logs und warten Sie auf die Meldung
DATABASE IS READY TO USE!:kk logs -n ${DB_NAMESPACE} -l app=${DB_NAME} -fDie Ausgabe sollte Folgendes enthalten:
######################### DATABASE IS READY TO USE! #########################Prüfen Sie, ob der Status
Healthylautet:kk get singleinstancedatabase -n ${DB_NAMESPACE}Die Ausgabe sollte so aussehen:
NAME EDITION STATUS ROLE my-db Enterprise Healthy PRIMARY
Auf die Datenbank zugreifen und sie verfügbar machen
Standardmäßig erstellt der Operator zwei Dienste für die Datenbank:
${DB_NAME}(ClusterIP): für internen Traffic innerhalb des Clusters. Verwenden Sie diesen stabilen DNS-Namen für Anwendungen, die im selben Cluster ausgeführt werden.${DB_NAME}-ext(NodePort): für externen Zugriff. Standardmäßig wird die Datenbank dadurch auf einem hohen Port auf jedem Knoten verfügbar gemacht. Sie können ein Upgrade auf einen Load-Balancer-Dienst durchführen, indem SieloadBalancer: truein derSingleInstanceDatabase-Spezifikation festlegen.
Weitere Informationen zum Anpassen dieser Dienste, z. B. zum Definieren bestimmter NodePorts, finden Sie in der GitHub-Dokumentation.
Wählen Sie je nach Bedarf eine der folgenden Methoden aus, um auf Ihre Datenbank zuzugreifen. Weitere Informationen zu GDC-Diensttypen finden Sie unter Dienste bereitstellen.
Zugriff innerhalb des Clusters (ClusterIP)
Wenn Sie von anderen Pods, die im selben Kubernetes-Cluster ausgeführt werden, auf die Datenbank zugreifen möchten, verwenden Sie den ClusterIP-Dienst.
- Um dies sicher zu überprüfen, stellen Sie eine direkte Verbindung über einen temporären Client-Pod her.
- Prüfen Sie die verfügbaren Dienste in Ihrem Namespace. Notieren Sie sich den Dienst
ClusterIPmit dem Namen${DB_NAME}(z. B.my-db). Dieser Name dient als Hostname für interne Verbindungen. Stellen Sie einen temporären Pod mit dem SQL*Plus-Client bereit. Sie verwenden das
instantclient-Image, das in Ihrer Harbor-Registry gespiegelt wird:kk run sqlplus-client -n ${DB_NAMESPACE} --rm -it --restart=Never \ --image=${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-instantclient:latest \ --image-pull-policy=Always \ --overrides='{"spec": {"imagePullSecrets": [{"name": "'${HARBOR_PULL_SECRET_NAME}'"}]}}' \ -- sqlplus sys/${ADMIN_PASSWORD}@${DB_NAME}:1521/ORCLPDB1 as sysdbaSie sollten die SQL-Eingabeaufforderung sehen, die auf eine erfolgreiche Verbindung hinweist.
Erstellen Sie eine Beispielstabelle, um den Schreibzugriff zu prüfen:
CREATE TABLE employees (id NUMBER, name VARCHAR2(50)); INSERT INTO employees VALUES (1, 'John Doe'); COMMIT; SELECT * FROM employees;Die Ausgabe sollte so aussehen:
ID NAME ---------- -------------------------------------------------- 1 John DoeBeenden Sie die Sitzung:
exit
Zugriff innerhalb der VPC (interner Load Balancer)
Wenn Sie die Datenbank für andere Ressourcen (z. B. VMs) verfügbar machen möchten, die sich im selben GDC-Projekt oder in derselben VPC, aber außerhalb des Kubernetes-Clusters befinden, verwenden Sie einen internen Load-Balancer. So bleibt der Traffic in Ihrer isolierten Netzwerkumgebung privat. Weitere Informationen finden Sie in der Dokumentation zum internen Load-Balancer von GDC.
Da der Operator das Hinzufügen von Annotationen zum generierten Dienst nicht automatisch unterstützt, müssen Sie eine separate Dienstressource erstellen. Beachten Sie die Annotation networking.gke.io/load-balancer-type: internal, die zum Bereitstellen eines internen Load Balancers erforderlich ist.
Internen Load-Balancer-Dienst erstellen:
apiVersion: v1 kind: Service metadata: name: ${DB_NAME}-internal namespace: ${DB_NAMESPACE} annotations: networking.gke.io/load-balancer-type: internal spec: type: LoadBalancer selector: app: ${DB_NAME} ports: - name: sqlnet port: 1521 targetPort: 1521Rufen Sie die interne IP-Adresse ab:
export DB_INT_IP=$(kk get svc ${DB_NAME}-internal -n ${DB_NAMESPACE} \ -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo "Database Internal IP: ${DB_INT_IP}"
Zugriff von außerhalb der VPC (externer Load Balancer)
Wenn Sie die Datenbank für Clients außerhalb der GDC-Umgebung oder VPC (z. B. aus einem Unternehmensnetzwerk oder von einem externen Client) verfügbar machen möchten, können Sie einen externen Load Balancer verwenden. Dadurch wird eine IP-Adresse zugewiesen, die von außerhalb der isolierten VPC-Grenze erreichbar ist. Weitere Informationen finden Sie in der Dokumentation zum externen Load Balancer von GDC.
Wenn Sie einen externen Load Balancer erstellen möchten, aktualisieren Sie die SingleInstanceDatabase-Spezifikation, um loadBalancer: true festzulegen. Dadurch wird der vorhandene ${DB_NAME}-ext-Diensttyp von NodePort in LoadBalancer geändert.
Aktualisieren Sie die Spezifikation:
kk patch sidb ${DB_NAME} -n ${DB_NAMESPACE} --type='merge' \ -p '{"spec":{"loadBalancer":true}}'Rufen Sie die externe IP-Adresse ab:
export DB_EXT_IP=$(kk get svc ${DB_NAME}-ext -n ${DB_NAMESPACE} \ -o jsonpath='{.status.loadBalancer.ingress[0].ip}') echo "Database External IP: ${DB_EXT_IP}"
Nächste Schritte
- Referenzarchitektur für selbstverwaltete Oracle-Datenbanken
- Hochverfügbare selbstverwaltete Oracle-Datenbanken bereitstellen