Men-deploy database Oracle yang dikelola sendiri

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 dengan air gap, dengan memanfaatkan kemampuan penyimpanan dan jaringan GDC yang ada.

Deployment ini menggunakan Oracle Database Operator resmi untuk Kubernetes, 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 instance database tunggal, Anda dapat men-deploy instance sebanyak kapasitas cluster Anda (RAM, CPU, ruang disk) memungkinkan.

Diagram arsitektur deployment database Oracle instance tunggal.

Arsitektur ini terdiri dari komponen utama berikut:

  • Project GDC: project container untuk resource Anda.
  • Cluster Kubernetes standar: cluster standar yang menyediakan resource komputasi.
  • Oracle Database Operator: operator Kubernetes yang mengotomatiskan penyediaan, pengelolaan siklus proses, dan observabilitas database Oracle. Operator ini menyederhanakan tugas kompleks seperti patching, pencadangan, dan pemulihan, sehingga memudahkan Anda menjalankan workload Oracle stateful di lingkungan yang dikontainerkan.
  • Instance database: Oracle Single Instance Database (SIDB) yang dikontainerkan dengan penyimpanan persisten.
  • Harbor: registry container pribadi yang digunakan untuk menghosting image database, operator, dan klien dalam lingkungan dengan air gap.
  • Cert-manager: operator bergantung pada cert-manager untuk mengelola sertifikat webhook. cert-manager sudah 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 bergaris putus-putus dalam diagram arsitektur.

Pemisahan ini direkomendasikan untuk kejelasan dan kemudahan pengelolaan. Namun, Anda dapat memutuskan cara mengatur database Anda. Misalnya, Anda dapat mengelompokkan database tertentu di 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:

Memuat image ke Harbor

Karena cluster dalam Google Distributed Cloud dengan air gap tidak dapat mengakses registry eksternal, Anda harus mencerminkan image yang diperlukan ke instance Harbor pribadi Anda.

Login ke Oracle Container Registry

Anda harus melakukan autentikasi terlebih dahulu dengan registry Oracle resmi untuk menarik 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 login berhasil, 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 mencerminkan operator, database perusahaan, dan klien instan untuk pengujian.

  1. Cerminkan 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}
    
  2. Cerminkan 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}
    
  3. Cerminkan 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 digunakan:

  1. Ambil kubeconfig untuk cluster standar Anda:

    KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \
      get-credentials ${CLUSTER_NAME} \
      --standard \
      --project ${PROJECT_ID} \
      --zone ${ZONE}
    
  2. Buat alias kk untuk menyederhanakan perintah berikutnya:

    alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"
    

Membuat secret

Buat secret Kubernetes untuk mengizinkan cluster menarik image dari Harbor menggunakan kredensial yang disimpan di ./docker-harbor/config.json lokal Anda. Anda memerlukan secret ini di namespace operator (untuk menarik image operator) dan namespace database (untuk menarik image database).

  1. Buat namespace untuk operator:

    kk create ns ${ORACLE_OPERATOR_NAMESPACE}
    
  2. 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}
    
  3. Buat namespace untuk database:

    kk create ns ${DB_NAMESPACE}
    
  4. 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 Anda akan menginstal Oracle Database Operator ke cluster Anda dengan menerapkan tiga manifes:

  1. Cluster Role Binding: Menyiapkan izin yang diperlukan agar operator 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.yaml
    
  2. RBAC Node: Memberikan izin untuk membaca topologi node, yang 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.yaml
    
  3. Deployment Operator: Men-deploy pod operator dan definisi resource kustom (CRD). Perintah ini mendownload manifes resmi, mengganti jalur image dengan URL Harbor Anda, menyisipkan konfigurasi imagePullSecrets sehingga 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} --watch
    

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

  1. Buat secret Kubernetes untuk menyimpan sandi administratif database:

    kk create secret generic oracle-db-password \
      --from-literal=password=${ADMIN_PASSWORD} \
      -n ${DB_NAMESPACE}
    
  2. Terapkan manifes SingleInstanceDatabase untuk 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: password
    

    Parameter konfigurasi utama:

    • sid / pdbName: menentukan ID Sistem (SID) dan nama database yang dapat dicocokkan (PDB).
    • edition: menentukan edisi database (enterprise dalam hal ini).
    • image: mengarah ke image registry Harbor pribadi Anda.
    • persistence: meminta volume persisten 50 Gi menggunakan standard-rwo StorageClass, yang membuat persistent disk zona di GDC.
    • replicas: menetapkan jumlah pod ke 1. Meskipun 1 biasanya digunakan untuk instance tunggal, Anda dapat meningkatkannya untuk kasus penggunaan tertentu seperti rolling update (saat pod baru dibuat sebelum pod lama dihentikan) atau jika Anda menggunakan backend penyimpanan bersama yang mendukung akses serentak. Untuk deployment instance tunggal dasar, 1 adalah standar.

    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.

  3. Tunggu hingga pod database Running:

    kk get po -n ${DB_NAMESPACE} -l app=${DB_NAME} -w
    

    Outputnya 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          99s
    
  4. Kemudian, lihat log dan tunggu pesan DATABASE IS READY TO USE!:

    kk logs -n ${DB_NAMESPACE} -l app=${DB_NAME} -f
    

    Output-nya harus berisi yang berikut:

    #########################
    DATABASE IS READY TO USE!
    #########################
    
  5. Verifikasi bahwa 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:

  1. ${DB_NAME} (ClusterIP): untuk traffic internal dalam cluster. Gunakan nama DNS stabil ini untuk aplikasi yang berjalan di dalam cluster yang sama.
  2. ${DB_NAME}-ext (NodePort): untuk akses eksternal. Secara default, hal ini mengekspos database di port tinggi pada setiap node. Anda dapat mengupgrade-nya ke layanan load balancer dengan menetapkan loadBalancer: true dalam spesifikasi SingleInstanceDatabase.

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.

  1. Untuk memverifikasi hal ini dengan aman, hubungkan langsung dari pod klien sementara.
  2. Periksa layanan yang tersedia di namespace Anda. Perhatikan layanan ClusterIP yang diberi nama ${DB_NAME} (misalnya, my-db). Nama ini berfungsi sebagai nama host untuk koneksi internal.
  3. Deploy pod sementara yang berisi klien SQL*Plus. Anda menggunakan image instantclient yang dicerminkan ke registry Harbor Anda:

    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 sysdba
    

    Anda akan melihat perintah SQL yang menunjukkan koneksi berhasil.

  4. 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 Doe
    
  5. Keluar 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. Hal ini menjaga traffic tetap bersifat pribadi dalam lingkungan jaringan terisolasi Anda. 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.

  1. 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: 1521
    
  2. Ambil 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 yang sepenuhnya berada di luar lingkungan atau VPC GDC (misalnya, dari jaringan perusahaan atau klien eksternal), Anda dapat menggunakan load balancer eksternal. Tindakan ini menetapkan alamat IP yang dapat dijangkau dari luar batas VPC 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 mengubah jenis layanan ${DB_NAME}-ext yang ada dari NodePort menjadi LoadBalancer.

  1. Perbarui spesifikasi:

    kk patch sidb ${DB_NAME} -n ${DB_NAMESPACE} --type='merge' \
      -p '{"spec":{"loadBalancer":true}}'
    
  2. 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