Keycloak

Keycloakデータのバックアップとリストア

Verrazzanoは、ユーザーのログイン情報をKeycloakに保存します。また、Keycloakは、すべての永続データを格納するためにMySQLをバック・エンドとして使用します。このドキュメントでは、MySQLに格納されている永続データを元のクラスタからバックアップし、新しいクラスタにリストアする方法を示します。データを同じクラスタにリストアする場合、元のクラスタと新しいクラスタという用語は同じクラスタを指しています。

ノート: アップグレード時には、アップグレード先のバージョンではなく、既存のVerrazzanoバージョンのバックアップ・ドキュメントに従ってください。

MySQL Operatorの前提条件

MySQLは、MySQL Operator for Kubernetesを使用してデプロイされます。MySQL Operatorは、MySQLインスタンスのライフ・サイクルを管理する以外に、Amazon S3互換のオブジェクト・ストレージを使用してデータをバックアップおよびリストアする機能を提供します。

MySQLのバックアップまたはリストア操作に進む前に、次の詳細を参考にしてください:

  • オブジェクト・ストレージのバケット名。
    • Amazon S3互換のオブジェクト・ストレージ・バケット。これには、Oracle Cloudテナンシの任意のコンパートメント内のOracle Cloud Object Storageバケットを使用できます。
      • 参照できるように、バケット名とテナンシ名を書き留めておきます。
      • オブジェクト・ストレージを使用したバケットの作成の詳細は、「バケットの管理」を参照してください。
    • プライベート・クラウド、エンタープライズ・ネットワークまたはエアギャップ環境では、MinIOまたは同等のオブジェクト・ストレージ・ソリューションを使用できます。
  • オブジェクト・ストレージの接頭辞名。これは、バックアップ・コンポーネントによって作成されるバケット内の子フォルダになります。
  • オブジェクト・ストレージのリージョン名。
  • オブジェクト・ストレージの署名キー。
    • Amazon S3互換オブジェクト・ストレージでの認証に必要な署名キー。これはアクセス・キー/秘密キーのペアです。
    • Oracle Cloud Infrastructure (OCI)では、ユーザーまたは管理者が顧客秘密キーを作成します。
      • 関連するアクセス・キーが秘密キーに対して生成されます。
      • 顧客秘密キーを作成するには、顧客秘密キーに関する項を参照してください。

次の例では、ネームスペースkeycloakにシークレットmysql-backup-secretを作成します。このドキュメントの手順では、MySQLからOracle Cloud Object Storageバケットにデータをバックアップし、そこからリストアします。

  1. MySQL Operatorでは、S3互換オブジェクト・ストレージと通信するためにシークレットが必要であるため、オブジェクト・ストレージ資格証明を保持するbackup-secret.txtファイルを作成します。

    [default]
    aws_access_key_id=<object storage access key>
    aws_secret_access_key=<object storage secret key>
    
  2. MySQL Operatorにはバケットが作成されるリージョン名が必要なため、リージョン情報を含むbackup-region.txtファイルを作成します。オブジェクト・ストレージがリージョンus-phoenix-1に作成されることを示すbackup-region.txtファイルの例を次に示します:

    [default]
    region=us-phoenix-1
    

  3. ネームスペースkeycloakで、mysql-backup-secretなどのKubernetesシークレットを作成します。

    $ kubectl create secret generic --namespace <backup-namespace> <secret-name> --from-file=<key>=<full_path_to_creds_file> --from-file=<key>=<full_path_to_config_file>
    

    OCIオブジェクト・ストレージに接続するための資格証明で構成されるKubernetesシークレットの作成例を次に示します。

    $ kubectl create secret generic --namespace keycloak mysql-backup-secret --from-file=credentials=backup-secret.txt --from-file=config=backup-region.txt
    

MySQL Operatorバックアップ

  1. 元のクラスタでMySQLバックアップを開始するには、OCIオブジェクト・ストレージをバック・エンドとして使用する次のサンプル・カスタム・リソースYAMLファイルを作成します。オペレータは、spec.backupProfile.dumpInstance.storage.s3.configで参照されるシークレットを使用して、OCIオブジェクト・ストレージで認証します。

    $ kubectl apply -f - <<EOF
        apiVersion: mysql.oracle.com/v2
        kind: MySQLBackup
        metadata:
          name: <backup name>
          namespace: keycloak
        spec:
          clusterName: mysql
          backupProfile:
            name: <backupProfileName>
            dumpInstance:
              storage:
                s3:
                  bucketName: <The Object Storage bucket. See the MySQL Operator prerequisites section.>
                  config: <Kubernetes secret name. See the MySQL Operator prerequisites section.>
                  endpoint: < OCI S3 Object Storage endpoint.>
                  prefix: <The prefix name. This folder will be automatically created.>
                  profile: default
    EOF
    

    MySQLバックアップを開始するためのMySQLBackupリソースの例を次に示します:

    $ kubectl apply -f - <<EOF
        apiVersion: mysql.oracle.com/v2
        kind: MySQLBackup
        metadata:
          name: mysql-backup
          namespace: keycloak
        spec:
          clusterName: mysql
          backupProfile:
            name: mysqlOneTime
            dumpInstance:
              storage:
                s3:
                  bucketName: mysql-bucket
                  config: mysql-backup-secret
                  endpoint: https://mytenancy.compat.objectstorage.us-phoenix-1.oraclecloud.com
                  prefix: mysql-test
                  profile: default
    EOF
    
  2. バックアップ操作が完了したことを確認します。元のクラスタで次のコマンドを実行し、STATUSCompletedであることを確認します。

    $ kubectl get MySQLBackup --namespace keycloak
    
    # Sample output
    NAME           CLUSTER   STATUS      OUTPUT                         AGE
    mysql-backup   mysql     Completed   mysql-backup-20221025-180836   119s
    

  3. MySQLが正常にバックアップされると、オブジェクト・ストレージにバックアップ・フォルダが作成されます。元のクラスタでのMySQLバックアップで作成されたバックアップ・フォルダ接頭辞名をメモします。

    $ kubectl get mysqlbackup --namespace keycloak <mysql-backup-name> -o jsonpath={.status.output}
    

    次に、例を示します。

    $ kubectl get mysqlbackup --namespace keycloak mysql-backup -o jsonpath={.status.output}
    mysql-backup-20221025-180836
    
  4. MySQL Helmチャートおよび値をバックアップします。

    元のクラスタのMySQL Helmチャートの値をファイルmysql-values.yamlにバックアップします。

    $ helm get values --namespace keycloak mysql > mysql-values.yaml
    

    MySQL Helmチャートは、Verrazzanoプラットフォーム・オペレータ内に存在します。元のクラスタからローカル・ディレクトリにチャートを取得します。

    次の例では、MySQLチャートを現在のディレクトリの下のディレクトリmysql-chartsに取得します。データ破損を回避するために、ディレクトリmysql-chartsが現在のディレクトリの下にまだ存在していないことを確認してください。

    $ kubectl cp --namespace verrazzano-install \
        $(kubectl get pod --namespace verrazzano-install -l app=verrazzano-platform-operator \
        -o custom-columns=:metadata.name --no-headers):platform-operator/thirdparty/charts/mysql \
        -c verrazzano-platform-operator mysql-charts/
    

スケジュール済バックアップ

MYSQLバックアップを実行するスケジュールを実装することもできます。詳細は、「Handling MySQL Backups」の項の「A PersistentVolumeClaim Scheduled Backup Example」を参照してください。

MySQL Operatorリストア

開始する前に、「MySQL Operatorの前提条件」を参照してください。また、リストア操作を開始する前に、1つ以上の正常なバックアップが必要です。

既存のバックアップからMySQLリストア操作を開始するには、MySQLクラスタを再作成する必要があります。MySQLリストア操作を正常に実行するには、次のステップを使用します:

  1. 新しいクラスタ上のシステムからMySQLポッドおよびPersistentVolumeClaimを削除します。

    $ helm delete mysql --namespace keycloak
    $ kubectl delete pvc --namespace keycloak -l tier=mysql
    

  2. 元のクラスタのチャートを使用してHelmチャートをインストールし、MySQLリストア操作を開始します。

     $ helm install mysql <path to directory mysql-charts, where original charts are extracted> \
             --namespace keycloak \
             --set initDB.dump.name=<dump-name> \
             --set initDB.dumpOptions.loadUsers=true \
             --set initDB.dump.s3.profile=default \
             --set initDB.dump.s3.prefix=<prefixName/backup folder name> \
             --set initDB.dump.s3.bucketName=<OCI bucket name> \
             --set initDB.dump.s3.config=<Kubernetes secret name, see MySQL Operator prerequisites section.> \
             --set initDB.dump.s3.endpoint=<OCI S3 endpoint> \
             --values <mysql values file>
    

    次に、例を示します。

     $ helm install mysql mysql-charts \
             --namespace keycloak \
             --set initDB.dump.name=alpha \
             --set initDB.dump.s3.profile=default \
             --set initDB.dump.s3.prefix=mysql-test/mysql-backup-20221025-180836 \
             --set initDB.dump.s3.bucketName=mysql-bucket \
             --set initDB.dump.s3.config=mysql-backup-secret \
             --set initDB.dump.s3.endpoint=https://mytenancy.compat.objectstorage.us-phoenix-1.oraclecloud.com \
             --values mysql-values.yaml
    
  3. リストア・コマンドを実行した後、MySQLクラスタがオンラインになるまで待ちます。STATUSONLINEで、ONLINEの下の件数がINSTANCESと一致することを確認します。

    $ kubectl get innodbclusters --namespace keycloak mysql
    
    # Sample output
    NAME    STATUS   ONLINE   INSTANCES   ROUTERS   AGE
    mysql   ONLINE   3        3           3         2m23s
    
  4. すべてのMySQLポッドがRUNNING状態になるまで待ちます。

    $ kubectl wait --namespace keycloak --for=condition=ready pod -l tier=mysql --timeout=600s
    
    # Sample output
    pod/mysql-0 condition met
    pod/mysql-1 condition met
    pod/mysql-2 condition met
    pod/mysql-router-746d9d75c7-6pc5p condition met
    pod/mysql-router-746d9d75c7-bhrkw condition met
    pod/mysql-router-746d9d75c7-t8bhb condition met
    

    この時点で、MySQLクラスタは、以前に削除されたPersistentVolumeClaimとともに、バックアップから正常にリストアされています。

  5. 新しいクラスタにKeycloakをリストアする場合は、Keycloakシークレットを更新します。

    元のクラスタで、新しいクラスタにKeycloakをリストアする場合は、keycloakネームスペースのkeycloak-httpシークレットに対して次のコマンドを実行します:

     $ kubectl get secret --namespace keycloak keycloak-http -o jsonpath={.data.password}; echo
    

    新しいクラスタで、既存のパスワード値を前のコマンドによって表示された値に置き換えます。

     kubectl patch secret keycloak-http --namespace keycloak -p '{"data": {"password": "<password displayed in the step above>"}}'
    

  6. Keycloakポッドを再起動します。

    リストア操作中はMySQLがオフラインになるため、MySQLクラスタの削除と再作成により、Keycloakポッドが停止する可能性があります。次のコマンドを実行して、Keycloakポッドを再起動します:

     KEYCLOAK_REPLICAS=$(kubectl get sts --namespace keycloak keycloak -o custom-columns=:status.replicas --no-headers)
     kubectl scale sts --namespace keycloak keycloak --replicas=0
     kubectl scale sts --namespace keycloak keycloak --replicas=${KEYCLOAK_REPLICAS}
     kubectl wait --namespace keycloak --for=condition=ready pod -l app.kubernetes.io/instance=keycloak --timeout=600s
    

新しいクラスタ内のVerrazzanoシークレットの更新

次の手順は、新しいクラスタにKeycloakをリストアする場合にのみ適用できます。

MySQLリストア操作を完了した後、verrazzano-systemネームスペースの次のシークレットのパスワードを新しいクラスタ内で更新する必要があります:

  • verrazzano
  • verrazzano-es-internal
  • verrazzano-prom-internal
  1. 元のクラスタで、verrazzanoシークレットに対して次のコマンドを実行します:

     $ kubectl get secret --namespace verrazzano-system verrazzano -o jsonpath={.data.password}; echo
    

  2. 新しいクラスタで、既存のパスワード値をステップ1で表示された値に置き換えます。

     kubectl patch secret verrazzano --namespace verrazzano-system -p '{"data": {"password": "<password displayed in step 1>"}}'
    

  3. verrazzano-es-internalおよびverrazzano-prom-internalシークレットに対してステップ1および2を繰り返します。

  4. 新しいクラスタでfluentdポッドを再起動して、元のクラスタ・パスワードを使用してOpenSearchに接続します。

     $ kubectl delete pod -l app=fluentd --namespace verrazzano-system