部署自行管理的 Oracle 資料庫

本指南說明如何在 Google Distributed Cloud (GDC) 實體隔離標準叢集上,部署自行管理的 Oracle Database Enterprise 執行個體。您可以在無網路連線的環境中執行 Oracle 工作負載,並運用 GDC 現有的儲存空間和網路功能。

這項服務使用官方的 Oracle Database Operator for Kubernetes,可自動管理資料庫的生命週期。

架構

這個架構說明由 Oracle Database Operator 在 GDC 標準叢集中管理的單一執行個體 Oracle 資料庫部署項目。本指南示範如何部署單一資料庫執行個體,但您可以根據叢集的容量 (RAM、CPU、磁碟空間) 部署任意數量的執行個體。

單一執行個體 Oracle 資料庫部署架構圖。

此架構包含下列主要元件:

  • GDC 專案:資源的專案容器。
  • 標準 Kubernetes 叢集:提供運算資源的標準叢集
  • Oracle Database 運算子:Kubernetes 運算子,可自動佈建、管理生命週期及監控 Oracle 資料庫。這項服務可簡化修補、備份及復原等複雜工作,讓您在容器化環境中更輕鬆地執行具狀態的 Oracle 工作負載。
  • 資料庫執行個體:容器化的 Oracle 單一執行個體資料庫 (SIDB),具有永久性儲存空間。
  • Harbor:私有容器登錄檔,用於在無網路連線環境中代管資料庫、運算子和用戶端映像檔。
  • Cert-manager:這個運算子會依賴 cert-manager 管理 Webhook 憑證。cert-manager 已預先安裝在 GDC 標準叢集。

在本指南中,您會在專屬命名空間 (oracle-database-operator-system) 中部署運算子,並在另一個命名空間 (oracle-db) 中部署資料庫執行個體。架構圖中以虛線框表示這些命名空間。

建議您分開管理,為求明確且容易管理。不過,資料庫的整理方式完全由您決定。舉例來說,您可能會將特定資料庫分組到不同命名空間,根據工作負載需求、團隊擁有權或安全性規格,管理精細的存取權控管 (RBAC)。

事前準備

開始部署前,請務必確認您的環境符合下列需求:

  • 建立專案,做為本指南中產生所有資源的持有者。
  • 為專案中的使用者授予叢集管理員和標準叢集管理員角色。這樣一來,您就能建立標準 Kubernetes 叢集並管理其資源:

    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-admin
    
  • 建立 Harbor 執行個體Harbor 專案,用於存放本指南所需的容器映像檔。

  • 授予使用者 Harbor 執行個體管理員角色,即可將映像檔上傳至 Harbor 執行個體:

    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=harbor-instance-admin
    
  • 在 Harbor 專案中建立 Harbor 機器人帳戶。本指南稍後會將機器人帳戶的憑證儲存在 Kubernetes 密鑰中,讓叢集在例項化容器時,能夠從 Harbor 提取映像檔。

  • 建立標準 Kubernetes 叢集,其中包含兩個工作站節點,每個節點至少要有 16 GB 的記憶體。例如:

    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
    EOF
    
  • 設定環境變數。本指南會使用這些項目來建立及參照資源:

    # 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"
    

    網路注意事項:本指南假設是從可存取 GDC API 的堡壘節點執行,且可存取網際網路,以便下載 Oracle 運算子的資訊清單和容器映像檔。如果是在無法存取網際網路的電腦上執行這項作業,您必須另外取得這些資產 (例如使用 docker save 從連線電腦匯出圖片,然後使用 docker load 匯入圖片),並先將這些資產安全地上傳至您的環境,再繼續進行。

  • container-registry.oracle.com 建立帳戶並取得 API 權杖,然後接受 Oracle Database Enterprise EditionOracle Instant Client 映像檔的授權協議,再繼續操作。

將映像檔載入 Harbor

由於 Google Distributed Cloud 實體隔離方案中的叢集無法存取外部登錄檔,您必須將所需映像檔鏡像到私人 Harbor 執行個體。

登入 Oracle Container Registry

您必須先向 Oracle 官方登錄檔進行驗證,才能提取基礎映像檔:

docker --config=./docker-oracle login container-registry.oracle.com

成功登入後,憑證會儲存在 ./docker-oracle/config.json 中。

將映像檔載入 Harbor

使用私人 Harbor 執行個體進行驗證:

docker --config=./docker-harbor login ${HARBOR_INSTANCE_URL} \
  -u ${HARBOR_ROBOT_ACCOUNT} \
  -p ${HARBOR_ROBOT_SECRET}

成功登入後,機器人帳戶的憑證會儲存在 ./docker-harbor/config.json 中。

提取、標記及推送映像檔

從官方 Oracle Container Registry 下載映像檔,然後推送至內部 Harbor 專案。您將複製運算子、企業資料庫和即時用戶端,以進行測試。

  1. 鏡像 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. 鏡像 Oracle 資料庫企業版映像檔:

    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. 鏡像 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
    

設定叢集存取權

部署資源前,請先擷取標準叢集的憑證,並建立方便使用的別名:

  1. 擷取標準叢集的 kubeconfig:

    KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \
      get-credentials ${CLUSTER_NAME} \
      --standard \
      --project ${PROJECT_ID} \
      --zone ${ZONE}
    
  2. 建立 kk 別名,簡化後續指令:

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

建立密鑰

建立 Kubernetes 密鑰,讓叢集使用儲存在本機 ./docker-harbor/config.json 中的憑證,從 Harbor 提取映像檔。您需要在運算子的命名空間 (用於提取運算子映像檔) 和資料庫的命名空間 (用於提取資料庫映像檔) 中,使用這個密碼。

  1. 為運算子建立命名空間:

    kk create ns ${ORACLE_OPERATOR_NAMESPACE}
    
  2. 為運算子建立提取密鑰:

    kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ${ORACLE_OPERATOR_NAMESPACE}
    
  3. 為資料庫建立命名空間:

    kk create ns ${DB_NAMESPACE}
    
  4. 建立資料庫的提取密鑰:

    kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ${DB_NAMESPACE}
    

安裝 Oracle Database Operator

現在,請套用三個資訊清單,將 Oracle Database Operator 安裝到叢集:

  1. 叢集角色繫結:為運算子設定必要權限,以便在整個叢集運作。

    kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/cluster-role-binding.yaml
    
  2. 節點 RBAC:授予讀取節點拓撲的權限,這對正確排定 Pod 至關重要。

    kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/node-rbac.yaml
    
  3. 運算子部署:部署運算子 Pod 和自訂資源定義 (CRD)。這項指令會下載正式資訊清單、將映像檔路徑替換為 Harbor 網址、插入 imagePullSecrets 設定,讓 Kubernetes 可以向 Harbor 驗證,並套用結果:

    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 -
    

    等待運算子 Pod 執行:

    kk get pods -n ${ORACLE_OPERATOR_NAMESPACE} --watch
    

    輸出內容應如下所示:

    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
    

部署新的資料庫執行個體

執行運算子後,您現在可以部署單一執行個體的 Oracle 資料庫。本指南會建立適合開發或測試的基本 Enterprise Edition 執行個體。

  1. 建立 Kubernetes 密鑰,以儲存資料庫管理密碼:

    kk create secret generic oracle-db-password \
      --from-literal=password=${ADMIN_PASSWORD} \
      -n ${DB_NAMESPACE}
    
  2. 套用 SingleInstanceDatabase 資訊清單來建立資料庫:

    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
    

    重要設定參數:

    • sid / pdbName:定義系統 ID (SID) 和可插入式資料庫 (PDB) 名稱。
    • edition:指定資料庫版本 (本例為 enterprise)。
    • image:指向您的私人 Harbor 登錄檔映像檔。
    • persistence:使用 standard-rwo StorageClass 要求 50Gi 的永久磁碟區,這會在 GDC 中建立區域永久磁碟。
    • replicas:將 Pod 數量設為 1。雖然 1 是單一執行個體的典型做法,但您可以針對特定用途增加此值,例如進行滾動更新 (在舊 Pod 終止前建立新 Pod),或是使用支援並行存取的共用儲存空間後端。對於基本單一執行個體部署作業,1 是標準做法。

    如需完整的設定選項清單,包括自訂初始化參數和資源限制,請參閱官方說明文件

    建立資料庫需要大量資源,可能需要 10 到 20 分鐘。

  3. 等待資料庫 Pod Running

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

    輸出內容應如下所示:

    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. 然後查看記錄,等待 DATABASE IS READY TO USE! 訊息:

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

    輸出會包含下列內容:

    #########################
    DATABASE IS READY TO USE!
    #########################
    
  5. 確認狀態為 Healthy

    kk get singleinstancedatabase -n ${DB_NAMESPACE}
    

    輸出內容應如下所示:

    NAME    EDITION      STATUS    ROLE
    my-db   Enterprise   Healthy   PRIMARY
    

存取及公開資料庫

根據預設,運算子會為資料庫建立兩項服務:

  1. ${DB_NAME} (ClusterIP):適用於叢集內的內部流量。在相同叢集內執行的應用程式,可以使用這個穩定的 DNS 名稱。
  2. ${DB_NAME}-ext (NodePort):用於外部存取。根據預設,這會在每個節點的高通訊埠上公開資料庫。只要在 SingleInstanceDatabase 規格中設定 loadBalancer: true,即可將其升級為負載平衡器服務。

如要進一步瞭解如何自訂這些服務 (例如定義特定 NodePort),請參閱 GitHub 說明文件

視需求選擇下列其中一種方式存取資料庫。如要進一步瞭解 GDC 服務類型,請參閱「公開服務」。

叢集內的存取權 (ClusterIP)

如要從同一個 Kubernetes 叢集中執行的其他 Pod 存取資料庫,請使用 ClusterIP 服務。

  1. 如要安全地驗證這項設定,請直接從臨時用戶端 Pod 連線。
  2. 檢查命名空間中的可用服務。請注意名為 ${DB_NAME}ClusterIP 服務 (例如 my-db)。這個名稱會做為內部連線的主機名稱。
  3. 部署含有 SQL*Plus 用戶端的臨時 Pod。您使用鏡像到 Harbor 登錄檔的 instantclient映像檔:

    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
    

    畫面上應該會顯示 SQL 提示,表示連線成功。

  4. 建立範例資料表,驗證寫入存取權:

    CREATE TABLE employees (id NUMBER, name VARCHAR2(50));
    INSERT INTO employees VALUES (1, 'John Doe');
    COMMIT;
    SELECT * FROM employees;
    

    輸出內容應如下所示:

            ID NAME
    ---------- --------------------------------------------------
            1 John Doe
    
  5. 結束工作階段:

    exit
    

在 VPC 內存取 (內部負載平衡器)

如要將資料庫公開給位於相同 GDC 專案或 VPC 內,但 Kubernetes 叢集外的其他資源 (例如 VM),請使用內部負載平衡器。這樣一來,流量就會在隔離的網路環境中保持私密。詳情請參閱 GDC 內部負載平衡器說明文件

由於運算子不會自動支援將註解新增至產生的服務,您必須建立個別的服務資源。請注意 networking.gke.io/load-balancer-type: internal 註解,這是佈建內部負載平衡器時的必要條件。

  1. 建立內部負載平衡器服務:

    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. 擷取內部 IP 位址:

    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}"
    

從虛擬私有雲外部存取 (外部負載平衡器)

如要向 GDC 環境或 VPC 以外的用戶端 (例如公司網路或外部用戶端) 公開資料庫,可以使用外部負載平衡器。這會指派可從隔離虛擬私有雲邊界外部連線的 IP 位址。詳情請參閱 GDC 外部負載平衡器說明文件

如要建立外部負載平衡器,請更新 SingleInstanceDatabase 規格,將 loadBalancer: true 設為 這會將現有的 ${DB_NAME}-ext 服務類型從 NodePort 變更為 LoadBalancer

  1. 更新規格:

    kk patch sidb ${DB_NAME} -n ${DB_NAMESPACE} --type='merge' \
      -p '{"spec":{"loadBalancer":true}}'
    
  2. 擷取外部 IP 位址:

    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}"
    

後續步驟