このガイドでは、Google Distributed Cloud(GDC)エアギャップ標準クラスタにセルフマネージド Oracle Database Enterprise インスタンスをデプロイする方法について説明します。このデプロイにより、エアギャップ環境内で Oracle ワークロードを実行し、GDC の既存のストレージ機能とネットワーク機能を活用できます。
データベースのライフサイクル管理を自動化する、Kubernetes 向け公式 Oracle Database オペレーター を使用します。
アーキテクチャ
このアーキテクチャは、GDC 標準クラスタ内の Oracle Database オペレーターによって管理される単一インスタンスの Oracle データベース デプロイについて説明しています。このガイドでは、単一のデータベース インスタンスのデプロイについて説明しますが、クラスタの容量(RAM、CPU、ディスク容量)に応じて、必要な数のインスタンスをデプロイできます。

このアーキテクチャは、次の主要なコンポーネントで構成されています。
- GDC プロジェクト: リソースの プロジェクト コンテナ。
- 標準 Kubernetes クラスタ: コンピューティング リソースを提供する標準クラスタ 。
- Oracle Database オペレーター: Oracle データベースの プロビジョニング、ライフサイクル管理、オブザーバビリティを自動化する Kubernetes オペレーター。 パッチ適用、バックアップ、復元などの複雑なタスクを簡素化し、コンテナ化された環境でステートフル Oracle ワークロードを簡単に実行できるようにします。
- データベース インスタンス: 永続ストレージを備えたコンテナ化された Oracle Single Instance Database (SIDB)。
- Harbor: エアギャップ環境内でデータベース、 オペレーター、クライアント イメージをホストするために使用される非公開コンテナ レジストリ。
- Cert-manager: オペレーターは、ウェブフック証明書の管理に
cert-managerを使用します。cert-managerは、GDC 標準クラスタにプリインストールされています。
このガイドでは、オペレーターを独自の Namespace(oracle-database-operator-system)にデプロイし、データベース インスタンスを別の Namespace(oracle-db)にデプロイします。これらの Namespace は、アーキテクチャ図で破線の枠で示されています。
明確さと管理のしやすさから、この分離をおすすめします。ただし、データベースの構成方法はユーザーが決定します。たとえば、ワークロードのニーズ、チームの所有権、セキュリティ仕様に基づいて、特定のデータベースを異なる Namespace にグループ化して、きめ細かいアクセス制御(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-adminHarbor プロジェクトに Harbor ロボット アカウント を作成します。このガイドの後半で、ロボット アカウントの認証情報が Kubernetes Secret に保存され、クラスタがコンテナのインスタンス化時に Harbor からイメージを pull できるようになります。
それぞれに 16 GB 以上のメモリを持つ 2 つのワーカーノードで標準 Kubernetes クラスタを作成します。次に例を示します。
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 レジストリで認証して、ベースイメージを pull する必要があります。
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 に保存されます。
イメージを pull、タグ付け、push する
公式の Oracle Container Registry からイメージをダウンロードし、内部の Harbor プロジェクトに push します。テスト用に、オペレーター、エンタープライズ データベース、インスタント クライアントをミラーリングします。
Oracle Database オペレーター イメージをミラーリングします。
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 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}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"
Secret を作成する
Kubernetes Secret を作成して、ローカルの ./docker-harbor/config.json に保存されている認証情報を使用して、クラスタが Harbor からイメージを pull できるようにします。この Secret は、オペレーターの Namespace(オペレーター イメージを pull するため)とデータベースの Namespace(データベース イメージを pull するため)の両方に必要です。
オペレーターの Namespace を作成します。
kk create ns ${ORACLE_OPERATOR_NAMESPACE}オペレーターの pull Secret を作成します。
kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker-harbor/config.json \ -n ${ORACLE_OPERATOR_NAMESPACE}データベースの Namespace を作成します。
kk create ns ${DB_NAMESPACE}データベースの pull Secret を作成します。
kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker-harbor/config.json \ -n ${DB_NAMESPACE}
Oracle Database オペレーターをインストールする
3 つのマニフェストを適用して、Oracle Database オペレーターをクラスタにインストールします。
クラスタロール バインディング: オペレーターがクラスタ全体で機能するために必要な権限を設定します。
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 URL に置き換え、Kubernetes が Harbor で認証できるように
imagePullSecrets構成を挿入して、結果を適用します。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 Secret を作成します。
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: passwordsid/pdbName: システム ID(SID)とプラガブル データベース(PDB)名を定義します。edition: データベース エディション(この場合はenterprise)を指定します。image: 非公開の Harbor レジストリ イメージを指します。persistence:standard-rwoStorageClass を使用して 50 Gi の永続ボリュームをリクエストします。これにより、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
データベースにアクセスして公開する
デフォルトでは、オペレーターはデータベース用に 2 つのサービスを作成します。
${DB_NAME}(ClusterIP): クラスタ内の内部トラフィック用。同じクラスタ内で実行されているアプリケーションには、この安定した DNS 名を使用します。${DB_NAME}-ext(NodePort): 外部アクセス用。デフォルトでは、これにより、すべてのノードの高ポートでデータベースが公開されます。SingleInstanceDatabase仕様でloadBalancer: trueを設定すると、ロードバランサ サービスにアップグレードできます。
特定の NodePort の定義など、これらのサービスをカスタマイズする方法については、GitHub のドキュメントをご覧ください。
ニーズに応じて、次のいずれかの方法でデータベースにアクセスします。GDC サービスタイプの詳細については、サービスの公開をご覧ください。
クラスタ内でのアクセス(ClusterIP)
同じ Kubernetes クラスタ内で実行されている他の Pod からデータベースにアクセスするには、ClusterIP サービスを使用します。
- これを安全に確認するには、一時的なクライアント Pod から直接接続します。
- Namespace で利用可能なサービスを確認します。
${DB_NAME}という名前のClusterIPサービス(my-dbなど)をメモします。この名前は、内部接続のホスト名として機能します。 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 sysdbaSQL プロンプトが表示され、接続が成功したことを示します。
書き込みアクセスを確認するサンプル テーブルを作成します。
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}"
VPC の外部からのアクセス(外部ロードバランサ)
GDC 環境または VPC の外部にあるクライアント(企業ネットワークや外部クライアントなど)にデータベースを公開するには、外部ロードバランサを使用します。これにより、分離された VPC 境界の外部から到達可能な IP アドレスが割り当てられます。詳細については、 GDC 外部ロードバランサ のドキュメントをご覧ください。
外部ロードバランサを作成するには、SingleInstanceDatabase 仕様を更新して loadBalancer: true を設定します。これにより、既存の ${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}"