Implantar bancos de dados Oracle autogerenciados altamente disponíveis

Este guia descreve a implantação de uma configuração do Oracle Data Guard altamente disponível e multizonal em um cluster padrão isolado do Google Distributed Cloud (GDC). Essa configuração usa o Oracle Database Enterprise Edition e aproveita os recursos atuais do GDC para armazenamento e rede.

Essa implantação usa o Oracle Database Operator oficial para Kubernetes, que automatiza o gerenciamento do ciclo de vida do banco de dados.

Arquitetura

A arquitetura descreve uma implantação do Oracle Database de alta disponibilidade gerenciada pelo Oracle Database Operator em um cluster padrão do GDC. Uma implantação de alta disponibilidade consiste em um banco de dados principal e um banco de dados de espera configurado com o Data Guard para replicação e failover.

Implantação de banco de dados Oracle altamente disponível com diagrama de arquitetura do Data Guard.

Os principais componentes são os seguintes:

  • Projeto do GDC: o contêiner do projeto para seus recursos.
  • Cluster padrão do Kubernetes: um cluster padrão que fornece os recursos de computação.
  • Oracle Database Operator: um operador do Kubernetes que automatiza o provisionamento, o gerenciamento do ciclo de vida e a observabilidade dos bancos de dados Oracle. Ele simplifica tarefas complexas, como aplicação de patches, backup e recuperação, facilitando a execução de cargas de trabalho com estado do Oracle em um ambiente em contêiner.
  • Banco de dados principal: a instância de banco de dados em contêiner ativa de leitura/gravação.
  • Banco de dados de espera: a instância de banco de dados somente leitura (ou leitura/gravação durante o failover) da réplica.
  • Agente do Data Guard: orquestra a configuração e as transições de papéis (alternância/failover) entre os bancos de dados.
  • Harbor: o registro de contêiner particular usado para hospedar o banco de dados, o operador e as imagens do cliente no ambiente isolado.
  • Cert-manager: o operador depende de cert-manager para gerenciar certificados de webhook. O cert-manager vem pré-instalado em clusters padrão do GDC.

Neste guia, você implanta o operador no próprio namespace (oracle-database-operator-system) e a instância do banco de dados em um namespace separado (oracle-dbs). Esses namespaces são ilustrados com caixas de borda tracejada no diagrama de arquitetura.

Essa separação é recomendada para fins de esclarecimento e capacidade de gerenciamento. No entanto, cabe a você decidir como organizar seus bancos de dados. Por exemplo, você pode agrupar determinados bancos de dados em namespaces diferentes para gerenciar o controle de acesso granular (RBAC) com base nas necessidades da carga de trabalho, na propriedade da equipe ou nas especificações de segurança.

Antes de começar

Antes de iniciar a implantação, verifique se o ambiente atende aos seguintes requisitos:

  • Crie um projeto que sirva como detentor de todos os recursos gerados neste guia.
  • Conceda ao usuário os papéis de administrador do cluster e administrador do cluster padrão para o projeto. Isso permite criar um cluster padrão do Kubernetes e gerenciar os recursos dele:

    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
    
  • Crie uma instância e um projeto do Harbor para hospedar as imagens de contêiner necessárias para este guia.

  • Conceda ao usuário o papel de administrador da instância do Harbor para que você possa fazer upload de imagens para a instância do Harbor:

    gdcloud projects add-iam-policy-binding ${PROJECT_ID} \
      --member="user:${USER_NAME}" \
      --role=harbor-instance-admin
    
  • Crie uma conta de robô do Harbor no projeto do Harbor. Mais adiante neste guia, as credenciais da conta de robô serão armazenadas em secrets do Kubernetes, permitindo que o cluster extraia imagens do Harbor ao instanciar contêineres.

  • Crie um cluster padrão do Kubernetes com pelo menos dois nós de trabalho, cada um com um mínimo de 16 GB de memória. Exemplo:

    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
    
  • Configure as variáveis de ambiente. Elas serão usadas em todo o guia para criar e referenciar recursos:

    Observações:

    • As duas instâncias de banco de dados são arbitrariamente nomeadas blue e green neste guia. Inicialmente, a instância blue é a principal e green é a de espera.
    # General info
    export PROJECT_ID="PROJECT_ID"
    export ZONE="ZONE"
    export ORG_NAME="ORG_NAME"
    export CLUSTER_NAME="CLUSTER_NAME"
    
    # Software versions
    export ORACLE_OPERATOR_VERSION="2.1.0"
    export ORACLE_DB_VERSION="21.3.0.0"
    
    # Namespaces
    export ORACLE_OPERATOR_NAMESPACE="ORACLE_OPERATOR_NAMESPACE"
    export DB_NAMESPACE="DATABASE_NAMESPACE"
    
    # 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 ADMIN_PASSWORD_SECRET_NAME="ADMIN_PASSWORD_SECRET_NAME"
    
    # Database names
    export DB_NAME_BLUE="database-blue"
    export DB_NAME_GREEN="database-green"
    
  • Observação de rede:este guia pressupõe que ele está sendo executado em um nó de bastion que tem acesso às APIs do GDC e também à Internet para fazer o download dos manifestos e das imagens de contêiner do operador do Oracle. Se você estiver executando isso em uma máquina sem acesso à Internet, será necessário adquirir esses recursos separadamente (por exemplo, usando docker save para exportar imagens de uma máquina conectada e docker load para importá-las) e fazer upload delas com segurança para o ambiente antes de continuar.

  • Antes de continuar, crie uma conta e receba um token de API em container-registry.oracle.com, e aceite o contrato de licença para as imagens do Oracle Database Enterprise Edition e do Oracle Instant Client.

Carregar imagens no Harbor

Como os clusters no Google Distributed Cloud com isolamento físico não podem acessar registros externos, é necessário espelhar as imagens necessárias na instância particular do Harbor.

Fazer login no Oracle Container Registry

Primeiro, autentique-se com o registro oficial do Oracle para extrair as imagens de base:

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

Após um login bem-sucedido, as credenciais serão salvas em ./docker-oracle/config.json.

Fazer login no Harbor

Autentique-se com a instância particular do Harbor:

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

Após um login bem-sucedido, as credenciais da conta de robô serão salvas em ./docker-harbor/config.json.

Extrair, marcar e enviar imagens

Faça o download das imagens do registro de contêiner oficial do Oracle e envie-as para o projeto interno do Harbor. Você vai espelhar o operador, o banco de dados corporativo e o cliente instantâneo para testes.

  1. Espelhe a imagem do operador do banco de dados Oracle:

    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. Espelhe a imagem do 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. Espelhe a imagem do cliente instantâneo do Oracle:

    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
    

Configurar o acesso ao cluster

Antes de implantar recursos, recupere as credenciais do cluster padrão e crie um alias conveniente:

  1. Recupere o arquivo kubeconfig do cluster padrão:

    KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \
      get-credentials ${CLUSTER_NAME} \
      --standard \
      --project ${PROJECT_ID} \
      --zone ${ZONE}
    
  2. Crie o alias kk para simplificar os comandos subsequentes:

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

Criar Secrets

Crie um secret do Kubernetes para permitir que o cluster extraia imagens do Harbor usando as credenciais salvas no arquivo ./docker-harbor/config.json local. Você precisa desse secret no namespace do operador (para extrair a imagem do operador) e no namespace do banco de dados (para extrair a imagem do banco de dados).

  1. Crie o namespace para o operador:

    kk create ns ${ORACLE_OPERATOR_NAMESPACE}
    
  2. Crie o secret de extração para o operador:

    kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ${ORACLE_OPERATOR_NAMESPACE}
    
  3. Crie o namespace para os bancos de dados:

    kk create ns ${DB_NAMESPACE}
    
  4. Crie o secret de extração de imagem para os contêineres de banco de dados:

    kk create secret docker-registry ${HARBOR_PULL_SECRET_NAME} \
      --from-file=.dockerconfigjson=./docker-harbor/config.json \
      -n ${DB_NAMESPACE}
    
  5. Crie o secret para a senha administrativa dos bancos de dados:

    kk create secret generic ${ADMIN_PASSWORD_SECRET_NAME} \
      --from-literal=password=${ADMIN_PASSWORD} \
      -n ${DB_NAMESPACE}
    

Instalar o Oracle Database Operator

Agora, instale o Oracle Database Operator no cluster aplicando três manifestos:

  1. Vinculação de papel do cluster: configura as permissões necessárias para que o operador funcione em todo o 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 do nó: concede permissões para ler a topologia do nó, que é fundamental para o agendamento correto do pod.

    kk apply -f https://raw.githubusercontent.com/oracle/oracle-database-operator/refs/tags/v${ORACLE_OPERATOR_VERSION}/rbac/node-rbac.yaml
    
  3. Implantação do operador: implanta os pods do operador e as definições de recursos personalizados. Esse comando faz o download do manifesto oficial, substitui o caminho da imagem pelo URL do Harbor, injeta a configuração imagePullSecrets para que o Kubernetes possa se autenticar com o Harbor e aplica o resultado:

    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 -
    

    Aguarde a execução dos pods do operador:

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

    A saída será semelhante a esta:

    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
    

Implantar bancos de dados principal e de espera

Agora, implante duas instâncias de banco de dados no mesmo namespace sequencialmente.

Implantar a instância principal

  1. Execute o seguinte comando para criar a instância principal do banco de dados:

    apiVersion: database.oracle.com/v4
    kind: SingleInstanceDatabase
    metadata:
      name: ${DB_NAME_BLUE}
      namespace: ${DB_NAMESPACE}
    spec:
      replicas: 1
      edition: enterprise
      image:
        pullFrom: "${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION}"
        pullSecrets: ${HARBOR_PULL_SECRET_NAME}
        prebuiltDB: true
      sid: ORCLBLUE
      pdbName: ORCLPDB1
      archiveLog: true
      flashBack: true
      forceLog: true
      adminPassword:
        secretName: "${ADMIN_PASSWORD_SECRET_NAME}"
        secretKey: "password"
      persistence:
        size: "50Gi"
        storageClass: "standard-rwo"
        accessMode: "ReadWriteOnce"
      resources:
        requests:
          memory: "4Gi"
    

    Principais parâmetros de configuração:

    • sid / pdbName: define o identificador do sistema (SID) e o nome do banco de dados conectável (PDB).
    • edition: especifica a edição do banco de dados (enterprise neste caso).
    • image: aponta para a imagem do registro particular do Harbor.
    • persistence: solicita um volume permanente de 50 Gi usando o StorageClass standard-rwo, que cria um disco permanente zonal no GDC.
    • replicas: define o número de pods como 1 para a instância.
    • archiveLog: ativa o modo de registro de arquivo, que é necessário para o Data Guard.
    • flashBack: ativa o banco de dados Flashback, permitindo que você retorne o banco de dados a um ponto anterior no tempo.
    • forceLog: ativa o registro forçado, garantindo que todas as mudanças sejam registradas, mesmo para operações que normalmente ignoram o registro.

    Para uma lista completa de opções de configuração, incluindo parâmetros de inicialização personalizados e limites de recursos, consulte a documentação oficial.

    A criação do banco de dados consome muitos recursos e pode levar de 10 a 20 minutos.

    Aguarde até que o banco de dados esteja totalmente pronto antes de continuar. Isso é fundamental porque o banco de dados de espera exige que o principal esteja acessível para estabelecer a replicação.

    Aguarde até que o pod do banco de dados esteja Running:

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

    A saída será semelhante a esta:

    NAME                   READY   STATUS    RESTARTS   AGE
    database-blue-i5xdj   0/1     Pending   0          0s
    database-blue-i5xdj   0/1     Pending   0          0s
    database-blue-i5xdj   0/1     Pending   0          1s
    database-blue-i5xdj   0/1     Init:0/1   0          1s
    database-blue-i5xdj   0/1     PodInitializing   0          98s
    database-blue-i5xdj   0/1     Running           0          99s
    database-blue-i5xdj   1/1     Running           0          99s
    

    Em seguida, assista aos registros e aguarde a mensagem DATABASE IS READY TO USE!:

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

    A saída precisa conter o seguinte:

    #########################
    DATABASE IS READY TO USE!
    #########################
    
  2. Verifique se o status é Healthy e o papel é PRIMARY:

    kk get sidb -n ${DB_NAMESPACE} ${DB_NAME_BLUE}
    

    A saída será semelhante a esta:

    NAME            EDITION      STATUS    ROLE
    database-blue   Enterprise   Healthy   PRIMARY
    

Implantar a instância em espera

Depois que o principal estiver íntegro, implante a instância em espera. Os parâmetros do Data Guard (archiveLog, flashBack, forceLog) são herdados do principal e não podem ser especificados no manifesto de espera:

  1. Implante a instância em espera:

    apiVersion: database.oracle.com/v4
    kind: SingleInstanceDatabase
    metadata:
      name: ${DB_NAME_GREEN}
      namespace: ${DB_NAMESPACE}
    spec:
      replicas: 1
      edition: enterprise
      image:
        pullFrom: "${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/oracle-enterprise:${ORACLE_DB_VERSION}"
        pullSecrets: ${HARBOR_PULL_SECRET_NAME}
        prebuiltDB: true
      sid: ORCLGREEN
      pdbName: ORCLPDB1
      adminPassword:
        secretName: "${ADMIN_PASSWORD_SECRET_NAME}"
        secretKey: "password"
      createAs: standby
      primaryDatabaseRef: ${DB_NAME_BLUE}
      persistence:
        size: "50Gi"
        storageClass: "standard-rwo"
        accessMode: "ReadWriteOnce"
      resources:
        requests:
          memory: "4Gi"
    

    Aguarde até que o pod do banco de dados esteja Running:

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

    A saída será semelhante a esta:

    NAME                   READY   STATUS    RESTARTS   AGE
    database-green-q1gur   0/1     Pending   0          0s
    database-green-q1gur   0/1     Pending   0          0s
    database-green-q1gur   0/1     Pending   0          1s
    database-green-q1gur   0/1     Init:0/1   0          1s
    database-green-q1gur   0/1     PodInitializing   0          98s
    database-green-q1gur   0/1     Running           0          99s
    database-green-q1gur   1/1     Running           0          99s
    

    Em seguida, assista aos registros e aguarde a mensagem DATABASE IS READY TO USE!:

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

    A saída precisa conter o seguinte:

    #########################
    DATABASE IS READY TO USE!
    #########################
    
  2. Verifique se o status é Healthy e o papel é PHYSICAL_STANDBY:

    kk get sidb -n ${DB_NAMESPACE}
    

    A saída será semelhante a esta:

    NAME             EDITION      STATUS    ROLE
    database-blue    Enterprise   Healthy   PRIMARY
    database-green                Healthy   PHYSICAL_STANDBY
    

Configurar o agente do Data Guard

  1. Implante o DataguardBroker para gerenciar a configuração do Data Guard:

    apiVersion: database.oracle.com/v4
    kind: DataguardBroker
    metadata:
      name: broker-blue-green
      namespace: ${DB_NAMESPACE}
    spec:
      primaryDatabaseRef: ${DB_NAME_BLUE}
      standbyDatabaseRefs:
        - ${DB_NAME_GREEN}
      protectionMode: MaxAvailability
      fastStartFailover: false
      loadBalancer: true
    

    Principais parâmetros de configuração:

    • protectionMode: defina como MaxAvailability para garantir que não haja perda de dados se pelo menos um modo de espera estiver disponível, fazendo a transição para o modo assíncrono se pelo menos um modo de espera estiver acessível.
    • fastStartFailover: defina como false para desativar o failover automático. Quando ativado, um processo de observador pode acionar automaticamente um failover se o banco de dados principal ficar indisponível.
    • loadBalancer: defina como true para criar um serviço LoadBalancer do Kubernetes para o agente, fornecendo um endereço IP externo estável que sempre é roteado para o banco de dados principal atual.
  2. Monitore o status do agente até que ele informe Healthy:

    kk get dataguardbroker -n ${DB_NAMESPACE} -w
    

    A saída será semelhante a esta:

    NAME                PRIMARY   STANDBYS   PROTECTION MODE   CONNECT STR   STATUS     FSFO
    broker-blue-green                        MaxAvailability                 Creating
    broker-blue-green                        MaxAvailability                 Creating
    broker-blue-green   ORCLBLUE   ORCLGREEN   MaxAvailability   10.0.0.25:32345/DATAGUARD   Creating   false
    broker-blue-green   ORCLBLUE   ORCLGREEN   MaxAvailability   10.0.0.25:32345/DATAGUARD   Healthy    false
    
  3. O DataguardBroker cria um serviço do Kubernetes (broker-blue-green) que encaminha automaticamente o tráfego para o banco de dados principal atual. Isso fornece um ponto de conexão estável para aplicativos. Receba esse serviço:

    kk get svc -n ${DB_NAMESPACE} broker-blue-green
    

    A saída será parecida com esta. Observe o provisionamento de um CLUSTER-IP para clientes no cluster e um EXTERNAL-IP para clientes externos usando um balanceador de carga:

    NAME                TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                         AGE
    broker-blue-green   LoadBalancer   10.0.19.198   100.66.38.138   1521:31116/TCP,5500:31842/TCP   8m
    
  4. Verifique os endpoints do serviço do agente. Ele precisa apontar inicialmente para o endereço IP do pod azul:

    kk get endpoints -n ${DB_NAMESPACE} broker-blue-green
    

    A saída será semelhante a esta, em que o IP do pod azul aparece em vez de BLUE_POD_IP:

    NAME                ENDPOINTS
    broker-blue-green   [BLUE_POD_IP]:5500,[BLUE_POD_IP]:1521
    
  5. Verifique os pods do banco de dados para correlacionar o IP:

    kk get pod -n ${DB_NAMESPACE} -o wide
    

Testar a sincronização de dados e os papéis

Agora, verifique a replicação gravando dados no principal e lendo-os no modo de espera usando um pod de cliente no cluster.

Gravar no banco de dados principal com o serviço do agente

  1. Implante um pod temporário para se conectar ao banco de dados principal usando o serviço de agente estável:

    kk run sqlplus -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}@broker-blue-green:1521/ORCLPDB1 as sysdba
    
  2. Crie uma tabela de teste:

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

    A saída será semelhante a esta:

            ID NAME
    ---------- --------------------------------------------------
            1 John Doe
    

Ler do modo de espera (acesso direto)

  1. Implante um pod temporário para se conectar diretamente ao serviço de espera:

    kk run sqlplus -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_GREEN}:1521/ORCLPDB1 as sysdba
    
  2. Verifique a replicação de dados:

    SELECT * FROM employees;
    exit;
    

    A saída será semelhante a esta:

            ID NAME
    ---------- --------------------------------------------------
            1 John Doe
    

Realizar uma alternância manual

Acione uma alternância manual para inverter os papéis, tornando o banco de dados verde o novo principal. O operador exige o SID (por exemplo, ORCLGREEN) para o destino da alternância.

  1. Execute este comando:

    kk patch dataguardbroker broker-blue-green -n ${DB_NAMESPACE} --type='merge' \
      -p "{\"spec\":{\"setAsPrimaryDatabase\":\"ORCLGREEN\"}}"
    
  2. Monitore o progresso da alternância:

    kk get sidb -n ${DB_NAMESPACE} -w
    

    A saída será semelhante a esta quando a alternância for concluída:

    NAME             EDITION      STATUS    ROLE
    database-blue    Enterprise   Healthy   PHYSICAL_STANDBY
    database-green                Healthy   PRIMARY
    
  3. Confirme se as instâncias de banco de dados trocaram de papel e se o banco de dados verde agora é o principal:

    kk get dataguardbroker -n ${DB_NAMESPACE}
    

    A saída será semelhante a esta:

    NAME                PRIMARY     STANDBYS   PROTECTION MODE
    broker-blue-green   ORCLGREEN   ORCLBLUE   MaxAvailability
    
  4. Verifique se os endpoints de serviço broker-blue-green foram atualizados para apontar para o IP do pod verde:

    kk get endpoints -n ${DB_NAMESPACE} broker-blue-green
    

    A saída será semelhante a esta, em que o IP do pod verde aparece em vez de GREEN_POD_IP:

    NAME                ENDPOINTS
    broker-blue-green   [GREEN_POD_IP]:5500,[GREEN_POD_IP]:1521
    

A seguir