本指南說明如何在 Google Distributed Cloud (GDC) 無網路連線的標準叢集上,部署自行管理的 Oracle Database Enterprise 執行個體。部署完成後,您就能在無網路連線的環境中執行 Oracle 工作負載,並運用 GDC 現有的儲存空間和網路功能。
這項服務使用官方的 Oracle Database Operator for Kubernetes,可自動管理資料庫的生命週期。
架構
這個架構說明由 GDC 標準叢集中的 Oracle Database Operator 管理的單一執行個體 Oracle 資料庫部署。本指南示範如何部署單一資料庫執行個體,但您可以根據叢集的容量 (RAM、CPU、磁碟空間) 部署任意數量的執行個體。

此架構包含下列主要元件:
- 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 Edition 和 Oracle 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 專案。您將複製運算子、企業資料庫和即時用戶端,以進行測試。
鏡像 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}鏡像 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}鏡像 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
設定叢集存取權
部署資源前,請先擷取標準叢集的憑證,並建立方便使用的別名:
擷取標準叢集的 kubeconfig:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \ get-credentials ${CLUSTER_NAME} \ --standard \ --project ${PROJECT_ID} \ --zone ${ZONE}建立
kk別名,簡化後續指令:alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"
建立密鑰
建立 Kubernetes 密鑰,讓叢集使用儲存在本機 ./docker-harbor/config.json 中的憑證,從 Harbor 提取映像檔。您需要在運算子的命名空間 (用於提取運算子映像檔) 和資料庫的命名空間 (用於提取資料庫映像檔) 中,使用這個密碼。
為運算子建立命名空間:
kk create ns ${ORACLE_OPERATOR_NAMESPACE}為運算子建立提取密鑰:
kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker-harbor/config.json \ -n ${ORACLE_OPERATOR_NAMESPACE}為資料庫建立命名空間:
kk create ns ${DB_NAMESPACE}建立資料庫的提取密鑰:
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 安裝到叢集:
叢集角色繫結:為運算子設定必要權限,以便在整個叢集運作。
kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/cluster-role-binding.yaml節點 RBAC:授予讀取節點拓撲的權限,這對正確排定 Pod 至關重要。
kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/node-rbac.yaml運算子部署:部署運算子 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 執行個體。
建立 Kubernetes 密鑰,以儲存資料庫管理密碼:
kk create secret generic oracle-db-password \ --from-literal=password=${ADMIN_PASSWORD} \ -n ${DB_NAMESPACE}套用
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-rwoStorageClass 要求 50Gi 的永久磁碟區,這會在 GDC 中建立區域永久磁碟。replicas:將 Pod 數量設為1。雖然1是單一執行個體的典型做法,但您可以針對特定用途增加這個值,例如進行滾動更新 (在舊 Pod 終止前建立新 Pod),或是使用支援並行存取的共用儲存空間後端。對於基本單一執行個體部署作業,1是標準做法。
如需完整的設定選項清單,包括自訂初始化參數和資源限制,請參閱官方說明文件。
建立資料庫需要大量資源,可能需要 10 到 20 分鐘。
等待資料庫 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然後查看記錄,等待
DATABASE IS READY TO USE!訊息:kk logs -n ${DB_NAMESPACE} -l app=${DB_NAME} -f輸出會包含下列內容:
######################### DATABASE IS READY TO USE! #########################確認狀態為
Healthy:kk get singleinstancedatabase -n ${DB_NAMESPACE}輸出內容應如下所示:
NAME EDITION STATUS ROLE my-db Enterprise Healthy PRIMARY
存取及公開資料庫
根據預設,運算子會為資料庫建立兩項服務:
${DB_NAME}(ClusterIP):適用於叢集內的內部流量。在相同叢集內執行的應用程式,可以使用這個穩定的 DNS 名稱。${DB_NAME}-ext(NodePort):用於外部存取。根據預設,這會在每個節點的高通訊埠上公開資料庫。只要在SingleInstanceDatabase規格中設定loadBalancer: true,即可將其升級為負載平衡器服務。
如要進一步瞭解如何自訂這些服務 (例如定義特定 NodePort),請參閱 GitHub 說明文件。
視需求選擇下列其中一種方法來存取資料庫。如要進一步瞭解 GDC 服務類型,請參閱「公開服務」。
叢集內存取 (ClusterIP)
如要從相同 Kubernetes 叢集中執行的其他 Pod 存取資料庫,請使用 ClusterIP 服務。
- 如要安全地驗證,請直接從臨時用戶端 Pod 連線。
- 檢查命名空間中的可用服務。請注意名為
${DB_NAME}的ClusterIP服務 (例如my-db)。這個名稱會做為內部連線的主機名稱。 部署含有 SQL*Plus 用戶端的臨時 Pod。您使用鏡像到 Harbor 登錄檔的映像檔:
instantclientkk 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 提示,表示連線成功。
建立範例資料表,驗證寫入存取權:
CREATE TABLE employees (id NUMBER, name VARCHAR2(50)); INSERT INTO employees VALUES (1, 'John Doe'); COMMIT; SELECT * FROM employees;輸出內容應如下所示:
ID NAME ---------- -------------------------------------------------- 1 John Doe結束工作階段:
exit
在 VPC 內存取 (內部負載平衡器)
如要將資料庫公開給位於相同 GDC 專案或 VPC 內,但 Kubernetes 叢集外的其他資源 (例如 VM),請使用內部負載平衡器。這樣一來,流量就會在隔離的網路環境中保持私密。詳情請參閱 GDC 內部負載平衡器說明文件。
由於運算子不會自動支援將註解新增至產生的服務,您必須建立個別的服務資源。請注意 networking.gke.io/load-balancer-type: 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擷取內部 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 設為 LoadBalancer。這會將現有的 ${DB_NAME}-ext 服務類型從 NodePort 變更為 LoadBalancer。
更新規格:
kk patch sidb ${DB_NAME} -n ${DB_NAMESPACE} --type='merge' \ -p '{"spec":{"loadBalancer":true}}'擷取外部 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}"