Panduan ini menguraikan deployment instance Oracle Database Enterprise yang dikelola sendiri di cluster standar Google Distributed Cloud (GDC) dengan air gap. Deployment ini memungkinkan Anda menjalankan workload Oracle dalam lingkungan air-gapped, dengan memanfaatkan kemampuan penyimpanan dan jaringan GDC yang ada.
Solusi ini menggunakan Oracle Database Operator for Kubernetes resmi, yang mengotomatiskan pengelolaan siklus proses database.
Arsitektur
Arsitektur ini menjelaskan deployment database Oracle instance tunggal yang dikelola oleh Oracle Database Operator dalam cluster standar GDC. Meskipun panduan ini menunjukkan cara men-deploy satu instance database, Anda dapat men-deploy instance sebanyak yang diizinkan oleh kapasitas cluster (RAM, CPU, kapasitas disk).

Arsitektur ini terdiri dari komponen utama berikut:
- Project GDC: container project untuk resource Anda.
- Cluster Kubernetes standar: cluster standar yang menyediakan resource komputasi.
- Oracle Database Operator: operator Kubernetes yang mengotomatiskan penyediaan, pengelolaan siklus proses, dan kemampuan observasi database Oracle. Operator ini menyederhanakan tugas-tugas kompleks seperti patching, pencadangan, dan pemulihan, sehingga memudahkan menjalankan workload Oracle stateful di lingkungan dalam container.
- Instance database: Oracle Single Instance Database (SIDB) dalam container dengan penyimpanan persisten.
- Harbor: Container Registry pribadi yang digunakan untuk menghosting image database, operator, dan klien dalam lingkungan air-gapped.
- Cert-manager: operator mengandalkan
cert-manageruntuk mengelola sertifikat webhook.cert-managersudah diinstal sebelumnya di cluster standar GDC.
Dalam panduan ini, Anda akan men-deploy operator di namespace-nya sendiri
(oracle-database-operator-system) dan instance database di namespace
terpisah (oracle-db). Namespace ini diilustrasikan dengan kotak berbatas putus-putus
dalam diagram arsitektur.
Pemisahan ini direkomendasikan untuk kejelasan dan kemudahan pengelolaan. Namun, Anda bebas memutuskan cara mengatur database Anda. Misalnya, Anda dapat mengelompokkan database tertentu dalam namespace yang berbeda untuk mengelola kontrol akses terperinci (RBAC) berdasarkan kebutuhan workload, kepemilikan tim, atau spesifikasi keamanan.
Sebelum memulai
Sebelum memulai deployment, Anda harus memastikan bahwa lingkungan Anda memenuhi persyaratan berikut:
- Buat project yang akan berfungsi sebagai penampung untuk semua resource yang dihasilkan di sepanjang panduan ini.
Beri pengguna Anda peran Cluster Admin dan Standard Cluster Admin untuk project Anda. Dengan demikian, Anda dapat membuat cluster Kubernetes standar dan mengelola resource-nya:
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-adminBuat instance Harbor dan project Harbor untuk menghosting image container yang diperlukan untuk panduan ini.
Beri pengguna Anda peran Harbor Instance Admin agar Anda dapat mengupload image ke instance Harbor:
gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=harbor-instance-adminBuat akun robot Harbor di project Harbor Anda. Selanjutnya dalam panduan ini, kredensial akun robot akan disimpan di secret Kubernetes, sehingga cluster dapat mengambil image dari Harbor saat membuat instance container.
Buat cluster Kubernetes standar dengan dua worker node, masing-masing memiliki memori minimal 16 GB. Contoh:
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 EOFSiapkan variabel lingkungan Anda. Variabel ini akan digunakan di seluruh panduan untuk membuat dan mereferensikan resource:
# 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"Catatan jaringan: Panduan ini mengasumsikan bahwa panduan ini dijalankan dari node bastion yang memiliki akses ke GDC API dan juga memiliki akses ke internet untuk mendownload manifes dan image container Oracle Operator. Jika Anda menjalankan ini dari mesin tanpa akses internet, Anda harus mendapatkan aset ini secara terpisah (misalnya, menggunakan
docker saveuntuk mengekspor image dari mesin yang terhubung dandocker loaduntuk mengimpornya) dan menguploadnya dengan aman ke lingkungan Anda sebelum melanjutkan.Buat akun dan dapatkan token API di container-registry.oracle.com, lalu setujui perjanjian lisensi untuk image Oracle Database Enterprise Edition dan Oracle Instant Client sebelum melanjutkan.
Memuat image ke Harbor
Karena cluster dalam Google Distributed Cloud dengan air gap tidak dapat mengakses registry eksternal, Anda harus menduplikasi image yang diperlukan ke instance Harbor pribadi Anda.
Login ke Oracle Container Registry
Anda harus melakukan autentikasi terlebih dahulu dengan registry Oracle resmi untuk mengambil image dasar:
docker --config=./docker-oracle login container-registry.oracle.com
Setelah login berhasil, kredensial akan disimpan di
./docker-oracle/config.json.
Memuat image ke Harbor
Lakukan autentikasi dengan instance Harbor pribadi Anda:
docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
-u ${HARBOR_ROBOT_ACCOUNT} \
-p ${HARBOR_ROBOT_SECRET}
Setelah berhasil login, kredensial akun robot akan disimpan di
./docker-harbor/config.json.
Menarik, memberi tag, dan mengirim image
Download image dari Oracle Container Registry resmi dan kirim ke project Harbor internal Anda. Anda akan menduplikasi operator, database perusahaan, dan klien instan untuk pengujian.
Duplikasi image Oracle Database Operator:
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}Duplikasi image Oracle database Enterprise:
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}Duplikasi image Oracle Instant Client:
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
Mengonfigurasi akses cluster
Sebelum men-deploy resource, ambil kredensial untuk cluster standar Anda dan buat alias yang mudah:
Ambil kubeconfig untuk cluster standar Anda:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \ get-credentials ${CLUSTER_NAME} \ --standard \ --project ${PROJECT_ID} \ --zone ${ZONE}Buat alias
kkuntuk menyederhanakan perintah berikutnya:alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"
Membuat secret
Buat secret Kubernetes untuk mengizinkan cluster mengambil image dari Harbor menggunakan kredensial yang disimpan di ./docker-harbor/config.json lokal Anda. Anda
memerlukan secret ini di namespace operator (untuk mengambil image operator)
dan namespace database (untuk mengambil image database).
Buat namespace untuk operator:
kk create ns ${ORACLE_OPERATOR_NAMESPACE}Buat secret pull untuk operator:
kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker-harbor/config.json \ -n ${ORACLE_OPERATOR_NAMESPACE}Buat namespace untuk database:
kk create ns ${DB_NAMESPACE}Buat secret pull untuk database:
kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker-harbor/config.json \ -n ${DB_NAMESPACE}
Menginstal Oracle Database Operator
Sekarang, instal Operator Database Oracle ke cluster Anda dengan menerapkan tiga manifes:
Cluster Role Binding: Menyiapkan izin yang diperlukan agar operator dapat berfungsi di seluruh cluster.
kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/cluster-role-binding.yamlRBAC Node: Memberikan izin untuk membaca topologi node, yang sangat penting untuk penjadwalan pod yang benar.
kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/node-rbac.yamlDeployment Operator: Men-deploy pod operator dan definisi resource kustom (CRD). Perintah ini mendownload manifes resmi, mengganti jalur image dengan URL Harbor Anda, memasukkan konfigurasi
imagePullSecretsagar Kubernetes dapat melakukan autentikasi dengan Harbor, dan menerapkan hasilnya: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 -Tunggu hingga pod operator berjalan:
kk get pods -n ${ORACLE_OPERATOR_NAMESPACE} --watchOutputnya akan terlihat seperti berikut ini:
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
Men-deploy instance database baru
Dengan operator yang berjalan, Anda kini dapat men-deploy database Oracle instance tunggal. Panduan ini membuat instance Enterprise Edition dasar yang cocok untuk pengembangan atau pengujian.
Buat secret Kubernetes untuk menyimpan sandi administratif database:
kk create secret generic oracle-db-password \ --from-literal=password=${ADMIN_PASSWORD} \ -n ${DB_NAMESPACE}Terapkan manifes
SingleInstanceDatabaseuntuk membuat database: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: passwordsid/pdbName: menentukan ID Sistem (SID) dan nama database yang dapat dicolokkan (PDB).edition: menentukan edisi database (enterprisedalam hal ini).image: mengarah ke image registry Harbor pribadi Anda.persistence: meminta volume persisten 50Gi menggunakan StorageClassstandard-rwo, yang membuat persistent disk zona di GDC.replicas: menetapkan jumlah pod ke1. Meskipun1adalah nilai standar untuk satu instance, Anda dapat meningkatkan nilai ini untuk kasus penggunaan tertentu seperti update bertahap (saat pod baru dibuat sebelum pod lama dihentikan) atau jika Anda menggunakan backend penyimpanan bersama yang mendukung akses serentak. Untuk deployment dasar dengan satu instance,1adalah standarnya.
Untuk mengetahui daftar lengkap opsi konfigurasi, termasuk parameter init kustom dan batas resource, lihat dokumentasi resmi.
Pembuatan database memerlukan banyak resource dan mungkin memerlukan waktu 10 hingga 20 menit.
Tunggu hingga pod database berstatus
Running:kk get po -n ${DB_NAMESPACE} -l app=${DB_NAME} -wOutputnya akan terlihat seperti berikut ini:
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 99sKemudian, amati log dan tunggu pesan
DATABASE IS READY TO USE!:kk logs -n ${DB_NAMESPACE} -l app=${DB_NAME} -fOutput-nya harus berisi yang berikut:
######################### DATABASE IS READY TO USE! #########################Pastikan statusnya adalah
Healthy:kk get singleinstancedatabase -n ${DB_NAMESPACE}Outputnya akan terlihat seperti berikut ini:
NAME EDITION STATUS ROLE my-db Enterprise Healthy PRIMARY
Mengakses dan mengekspos database
Secara default, operator membuat dua layanan untuk database:
${DB_NAME}(ClusterIP): untuk traffic internal dalam cluster. Gunakan nama DNS yang stabil ini untuk aplikasi yang berjalan di dalam cluster yang sama.${DB_NAME}-ext(NodePort): untuk akses eksternal. Secara default, tindakan ini mengekspos database pada port tinggi di setiap node. Anda dapat mengupgradenya ke layanan load balancer dengan menetapkanloadBalancer: truedalam spesifikasiSingleInstanceDatabase.
Untuk mengetahui informasi selengkapnya tentang cara menyesuaikan layanan ini, seperti menentukan NodePort tertentu, lihat dokumentasi GitHub.
Pilih salah satu metode berikut untuk mengakses database Anda, bergantung pada kebutuhan Anda. Untuk mengetahui detail selengkapnya tentang jenis layanan GDC, lihat Mengekspos Layanan.
Akses dalam cluster (ClusterIP)
Untuk mengakses database dari pod lain yang berjalan dalam cluster Kubernetes yang sama, gunakan layanan ClusterIP.
- Untuk memverifikasi ini dengan aman, hubungkan langsung dari pod klien sementara.
- Periksa layanan yang tersedia di namespace Anda. Perhatikan layanan
ClusterIPbernama${DB_NAME}(misalnya,my-db). Nama ini berfungsi sebagai nama host untuk koneksi internal. Men-deploy pod sementara yang berisi klien SQL*Plus. Anda menggunakan image
instantclientyang diduplikasi ke registry Harbor: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 sysdbaAnda akan melihat prompt SQL yang menunjukkan koneksi berhasil.
Buat tabel contoh untuk memverifikasi akses tulis:
CREATE TABLE employees (id NUMBER, name VARCHAR2(50)); INSERT INTO employees VALUES (1, 'John Doe'); COMMIT; SELECT * FROM employees;Outputnya akan terlihat seperti berikut ini:
ID NAME ---------- -------------------------------------------------- 1 John DoeKeluar dari sesi:
exit
Akses dalam VPC (load balancer internal)
Untuk mengekspos database ke resource lain (seperti VM) yang berada dalam project atau VPC GDC yang sama, tetapi di luar cluster Kubernetes, gunakan load balancer internal. Tindakan ini menjaga kerahasiaan traffic dalam lingkungan jaringan Anda yang terisolasi. Lihat dokumentasi load balancer internal GDC untuk mengetahui detail selengkapnya.
Karena operator tidak otomatis mendukung penambahan anotasi ke layanan yang dihasilkan, Anda harus membuat resource layanan terpisah. Perhatikan anotasi networking.gke.io/load-balancer-type: internal, yang diperlukan untuk menyediakan load balancer internal.
Buat layanan load balancer internal:
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: 1521Ambil alamat IP internal:
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}"
Akses dari luar VPC (load balancer eksternal)
Untuk mengekspos database ke klien sepenuhnya di luar lingkungan GDC atau VPC (misalnya, dari jaringan perusahaan atau klien eksternal), Anda dapat menggunakan load balancer eksternal. Tindakan ini akan menetapkan alamat IP yang dapat dijangkau dari luar batas VPC yang terisolasi. Lihat dokumentasi load balancer eksternal GDC untuk mengetahui detail selengkapnya.
Untuk membuat load balancer eksternal, perbarui spesifikasi SingleInstanceDatabase
untuk menetapkan loadBalancer: true. Tindakan ini akan mengubah jenis layanan ${DB_NAME}-ext yang ada dari NodePort menjadi LoadBalancer.
Perbarui spesifikasi:
kk patch sidb ${DB_NAME} -n ${DB_NAMESPACE} --type='merge' \ -p '{"spec":{"loadBalancer":true}}'Ambil alamat IP eksternal:
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}"
Langkah berikutnya
- Arsitektur referensi database Oracle yang dikelola sendiri
- Men-deploy database Oracle yang dikelola sendiri dan sangat tersedia