第5章 チュートリアル

5.1. ワークフローの例: OpenShift イメージバージョン用に新規 Red Hat Single Sign-On に移行する既存データベースの更新

重要
  • 以前のバージョンの Red Hat Single Sign-On for OpenShift からバージョン 7.4.10.GA へのローリングアップデートは、データベースおよびキャッシュが後方互換性がないためです。
  • アップグレードの前に、OpenShift の以前のバージョンの Red Hat Single Sign-On を実行するすべてのインスタンスを停止します。同じデータベースに対して同時に実行することはできません。
  • 事前に生成されたスクリプトは利用できず、データベースに応じて動的に生成されます。

Red Hat Single Sign-On 7.4.10.GA は、データベーススキーマを自動的に移行 するか、手動 で行うこともできます。

注記

デフォルトでは、Red Hat Single Sign-On 7.4.10.GA を初めて起動すると、データベースは自動的に移行されます。

5.1.1. データベースの自動移行

このプロセスは、PostgreSQL データベース (一時的または永続的モードでデプロイ) がサポートする Red Hat Single Sign-On for OpenShift イメージの以前のバージョンを別の Pod で 実行 することを前提としています。

重要

Red Hat Single Sign-On 7.4.10.GA にアップグレードする前に、以前のバージョンの Red Hat Single Sign-On for OpenShift イメージを実行するすべての Pod を停止します。これは、同じデータベースに対して同時に実行できないためです。

データベーススキーマを自動的に移行するには、以下の手順に従います。

  1. Red Hat Single Sign-On for OpenShift イメージの以前のバージョンを実行して、コンテナーをデプロイするために使用されるデプロイメント設定を特定します。

    $ oc get dc -o name --selector=application=sso
    deploymentconfig/sso
    deploymentconfig/sso-postgresql
  2. 現在の名前空間で、以前のバージョンの Red Hat Single Sign-On for OpenShift イメージを実行するすべての Pod を停止します。

    $ oc scale --replicas=0 dc/sso
    deploymentconfig "sso" scaled
  3. 既存のデプロイメント設定のイメージ変更トリガーを更新して、Red Hat Single Sign-On 7.4.10.GA イメージを参照します。

    $ oc patch dc/sso --type=json -p '[{"op": "replace", "path": "/spec/triggers/0/imageChangeParams/from/name", "value": "sso74-openshift-rhel8:7.4"}]'
    "sso" patched
  4. イメージ変更トリガーで定義した最新のイメージをもとに、新しい Red Hat Single Sign-On 7.4.10.GA イメージのロールアウトを開始します。

    $ oc rollout latest dc/sso
    deploymentconfig "sso" rolled out
  5. 変更したデプロイメント設定を使用して、Red Hat Single Sign-On 7.4.10.GA コンテナーをデプロイします。

    $ oc scale --replicas=1 dc/sso
    deploymentconfig "sso" scaled
  6. (必要に応じて) データベースが正常に更新されたことを確認します。

    $ oc get pods --selector=application=sso
    NAME                     READY     STATUS    RESTARTS   AGE
    sso-4-vg21r              1/1       Running   0          1h
    sso-postgresql-1-t871r   1/1       Running   0          2h
    $ oc logs sso-4-vg21r | grep 'Updating'
    11:23:45,160 INFO  [org.keycloak.connections.jpa.updater.liquibase.LiquibaseJpaUpdaterProvider] (ServerService Thread Pool -- 58) Updating database. Using changelog META-INF/jpa-changelog-master.xml

5.1.2. データベースの手動移行

重要

事前に生成されたスクリプトは利用できません。それらはデータベースに応じて動的に生成されます。Red Hat Single Sign-On 7.4.10.GA を使用すると、後でデータベースに手動で適用できる SQL ファイルにこれらのファイルを生成およびエクスポートできます。データベースの SQL 移行ファイルを動的に生成するには、以下を実行します。

  1. Red Hat Single Sign-On 7.4.10.GA を正しいデータソースで設定します。
  2. standalone-openshift.xml ファイルに以下の設定オプションを設定します。

    1. initializeEmpty=false
    2. migrationStrategy=manual
    3. migrationExport は、出力 SQL 移行ファイルが保存される Pod のファイルシステム上の場所に移行します (例: migrationExport="${jboss.home.dir}/keycloak-database-update.sql")。

詳細は、「 Red Hat Single Sign-On 7.4.10.GA のデータベース設定 」を参照してください。

データベースの移行プロセスでは、データスキーマの更新を処理し、データの操作を実行します。したがって、SQL 移行ファイルを動的に生成する前に、以前のバージョンの Red Hat Single Sign-On for OpenShift イメージを実行するすべての Pod を停止します。

このプロセスは、PostgreSQL データベース (一時的または永続的モードでデプロイ) がサポートする Red Hat Single Sign-On for OpenShift イメージの以前のバージョンを別の Pod で 実行 することを前提としています。

次のコマンドを実行して、データベースの SQL 移行ファイルを生成し、取得します。

  1. OpenShift データベース移行ジョブ のテンプレートを準備し、SQL ファイルを生成します。

    $ cat job-to-migrate-db-to-sso74.yaml.orig
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: job-to-migrate-db-to-sso74
    spec:
      autoSelector: true
      parallelism: 0
      completions: 1
      template:
        metadata:
          name: job-to-migrate-db-to-sso74
        spec:
          containers:
          - env:
            - name: DB_SERVICE_PREFIX_MAPPING
              value: <<DB_SERVICE_PREFIX_MAPPING_VALUE>>
            - name: <<PREFIX>>_JNDI
              value: <<PREFIX_JNDI_VALUE>>
            - name: <<PREFIX>>_USERNAME
              value: <<PREFIX_USERNAME_VALUE>>
            - name: <<PREFIX>>_PASSWORD
              value: <<PREFIX_PASSWORD_VALUE>>
            - name: <<PREFIX>>_DATABASE
              value: <<PREFIX_DATABASE_VALUE>>
            - name: TX_DATABASE_PREFIX_MAPPING
              value: <<TX_DATABASE_PREFIX_MAPPING_VALUE>>
            - name: <<SERVICE_HOST>>
              value: <<SERVICE_HOST_VALUE>>
            - name: <<SERVICE_PORT>>
              value: <<SERVICE_PORT_VALUE>>
            image: <<SSO_IMAGE_VALUE>>
            imagePullPolicy: Always
            name: job-to-migrate-db-to-sso74
            # Keep the pod running after the SQL migration
            # file was generated, so we can retrieve it
            command:
              - "/bin/bash"
              - "-c"
              - "/opt/eap/bin/openshift-launch.sh || sleep 600"
          restartPolicy: Never
    $ cp job-to-migrate-db-to-sso74.yaml.orig \
         job-to-migrate-db-to-sso74.yaml
  2. 以前のバージョンの Red Hat Single Sign-On for OpenShift イメージを実行するのに使用されるデプロイメント設定から、データソース定義およびデータベースアクセス認証情報をデータベース移行ジョブのテンプレートの適切な場所にコピーします。

    以下のスクリプトを使用して、sso という名前のデプロイメント設定から、job-to-migrate-db-to-sso74.yaml という名前のデータベースジョブ移行テンプレートに、DB_SERVICE_PREFIX_MAPPING 変数および TX_DATABASE_PREFIX_MAPPING 変数の値と、特定のデータソース固有の環境変数の値 (<PREFIX>_JNDI<PREFIX>_USERNAME<PREFIX>_PASSWORD、および <PREFIX>_DATABASE) をコピーします。

    注記

    DB_SERVICE_PREFIX_MAPPING 環境変数では、<name>-<database_type>=<PREFIX> トリプレットのコンマ区切りリスト を値として指定することができますが、この例のスクリプトでは、デモのために 1 つのデータソースのトリプレット定義のみを受け付けます複数のデータソース定義トリプレットを処理するスクリプトを変更できます。

    $ cat mirror_sso_dc_db_vars.sh
    #!/bin/bash
    
    # IMPORTANT:
    #
    # If the name of the SSO deployment config differs from 'sso'
    # or if the file name of the YAML definition of the migration
    # job is different, update the following two variables
    SSO_DC_NAME="sso"
    JOB_MIGRATION_YAML="job-to-migrate-db-to-sso74.yaml"
    
    # Get existing variables of the $SSO_DC_NAME deployment config
    # in an array
    declare -a SSO_DC_VARS=( \
      $(oc set env dc/${SSO_DC_NAME} --list \
      | sed '/^#/d') \
    )
    
    # Get the PREFIX used in the names of environment variables
    PREFIX=$( \
      grep -oP 'DB_SERVICE_PREFIX_MAPPING=[^ ]+' \
      <<< "${SSO_DC_VARS[@]}" \
    )
    PREFIX=${PREFIX##*=}
    
    # Substitute:
    # * <<PREFIX>> with actual $PREFIX value and
    # * <<PREFIX with "<<$PREFIX" value
    # The order in which these replacements are made is important!
    sed -i "s#<<PREFIX>>#${PREFIX}#g" ${JOB_MIGRATION_YAML}
    sed -i "s#<<PREFIX#<<${PREFIX}#g" ${JOB_MIGRATION_YAML}
    
    # Construct the array of environment variables
    # specific to the datasource
    declare -a DB_VARS=(JNDI USERNAME PASSWORD DATABASE)
    
    # Prepend $PREFIX to each item of the datasource array
    DB_VARS=( "${DB_VARS[@]/#/${PREFIX}_}" )
    
    # Add DB_SERVICE_PREFIX_MAPPING and TX_DATABASE_PREFIX_MAPPING
    # variables to datasource array
    DB_VARS=( \
      "${DB_VARS[@]}" \
      DB_SERVICE_PREFIX_MAPPING \
      TX_DATABASE_PREFIX_MAPPING \
    )
    
    # Construct the SERVICE from DB_SERVICE_PREFIX_MAPPING
    SERVICE=$( \
      grep -oP 'DB_SERVICE_PREFIX_MAPPING=[^ ]' \
      <<< "${SSO_DC_VARS[@]}" \
    )
    SERVICE=${SERVICE#*=}
    SERVICE=${SERVICE%=*}
    SERVICE=${SERVICE^^}
    SERVICE=${SERVICE//-/_}
    
    # If the deployment config contains <<SERVICE>>_SERVICE_HOST
    # and <<SERVICE>>_SERVICE_PORT variables, add them to the
    # datasource array. Their values also need to be propagated into
    # yaml definition of the migration job.
    HOST_PATTERN="${SERVICE}_SERVICE_HOST=[^ ]"
    PORT_PATTERN="${SERVICE}_SERVICE_PORT=[^ ]"
    if
      grep -Pq "${HOST_PATTERN}" <<< "${SSO_DC_VARS[@]}" &&
      grep -Pq "${PORT_PATTERN}" <<< "${SSO_DC_VARS[@]}"
    then
      DB_VARS=( \
        "${DB_VARS[@]}" \
        "${SERVICE}_SERVICE_HOST" \
        "${SERVICE}_SERVICE_PORT" \
      )
    # If they are not defined, delete their placeholder rows in
    # yaml definition file (since if not defined they are not
    # expanded which make the yaml definition invalid).
    else
      for KEY in "HOST" "PORT"
      do
        sed -i "/SERVICE_${KEY}/d" ${JOB_MIGRATION_YAML}
      done
    fi
    
    # Substitute:
    # * <<SERVICE_HOST>> with ${SERVICE}_SERVICE_HOST and
    # * <<SERVICE_HOST_VALUE>> with <<${SERVICE}_SERVICE_HOST_VALUE>>
    # The order in which replacements are made is important!
    # Do this for both "HOST" and "PORT"
    for KEY in "HOST" "PORT"
    do
      PATTERN_1="<<SERVICE_${KEY}>>"
      REPL_1="${SERVICE}_SERVICE_${KEY}"
      sed -i "s#${PATTERN_1}#${REPL_1}#g" ${JOB_MIGRATION_YAML}
      PATTERN_2="<<SERVICE_${KEY}_VALUE>>"
      REPL_2="<<${SERVICE}_SERVICE_${KEY}_VALUE>>"
      sed -i "s#${PATTERN_2}#${REPL_2}#g" ${JOB_MIGRATION_YAML}
    done
    
    # Propagate the values of the datasource array items into
    # yaml definition of the migration job
    for VAR in "${SSO_DC_VARS[@]}"
    do
      IFS=$'=' read KEY VALUE <<< $VAR
      if grep -q $KEY <<< ${DB_VARS[@]}
      then
        KEY+="_VALUE"
        # Enwrap integer port value with double quotes
        if [[ ${KEY} =~ ${SERVICE}_SERVICE_PORT_VALUE ]]
        then
          sed -i "s#<<${KEY}>>#\"${VALUE}\"#g" ${JOB_MIGRATION_YAML}
        # Character values do not need quotes
        else
          sed -i "s#<<${KEY}>>#${VALUE}#g" ${JOB_MIGRATION_YAML}
        fi
        # Verify that the value has been successfully propagated.
        if
          grep -q '(JNDI|USERNAME|PASSWORD|DATABASE)' <<< "${KEY}" &&
          grep -q "<<PREFIX${KEY#${PREFIX}}" ${JOB_MIGRATION_YAML} ||
          grep -q "<<${KEY}>>" ${JOB_MIGRATION_YAML}
        then
          echo "Failed to update value of ${KEY%_VALUE}! Aborting."
          exit 1
        else
          printf '%-60s%-40s\n' \
                 "Successfully updated ${KEY%_VALUE} to:" \
                 "$VALUE"
        fi
      fi
    done

    スクリプトを実行します。

    $ chmod +x ./mirror_sso_dc_db_vars.sh
    $ ./mirror_sso_dc_db_vars.sh
    Successfully updated DB_SERVICE_PREFIX_MAPPING to:          sso-postgresql=DB
    Successfully updated DB_JNDI to:                            java:jboss/datasources/KeycloakDS
    Successfully updated DB_USERNAME to:                        userxOp
    Successfully updated DB_PASSWORD to:                        tsWNhQHK
    Successfully updated DB_DATABASE to:                        root
    Successfully updated TX_DATABASE_PREFIX_MAPPING to:         sso-postgresql=DB
  3. 事前設定されたソース を使用して Red Hat Single Sign-On 7.4.10.GA データベース移行イメージをビルドし、ビルドが完了するまで待ちます。

    $ oc get is -n openshift | grep sso74 | cut -d ' ' -f1
    sso74-openshift-rhel8
    $ oc new-build sso74-openshift-rhel8:7.4~https://github.com/iankko/openshift-examples.git#KEYCLOAK-8500 \
      --context-dir=sso-manual-db-migration \
      --name=sso74-db-migration-image
    --> Found image bf45ac2 (7 days old) in image stream "openshift/sso74-openshift-rhel8" under tag "7.4" for "sso74-openshift-rhel8:7.4"
    
        Red Hat SSO 7.4.10.GA
        ---------------
        Platform for running Red Hat SSO
    
        Tags: sso, sso7, keycloak
    
        * A source build using source code from https://github.com/iankko/openshift-examples.git#KEYCLOAK-8500 will be created
          * The resulting image will be pushed to image stream "sso74-db-migration-image:latest"
          * Use 'start-build' to trigger a new build
    
    --> Creating resources with label build=sso74-db-migration-image ...
        imagestream "sso74-db-migration-image" created
        buildconfig "sso74-db-migration-image" created
    --> Success
        Build configuration "sso74-db-migration-image" created and build triggered.
        Run 'oc logs -f bc/sso74-db-migration-image' to stream the build progress.
    $ oc logs -f bc/sso74-db-migration-image --follow
    Cloning "https://github.com/iankko/openshift-examples.git#KEYCLOAK-8500" ...
    ...
    Push successful
  4. データベース移行ジョブのテンプレート (job-to-migrate-db-to-sso74.yaml) をビルドされた sso74-db-migration-image イメージへの参照で更新します。

    1. イメージの docker pull 参照を取得します。

      $ PULL_REF=$(oc get istag -n $(oc project -q) --no-headers | grep sso74-db-migration-image | tr -s ' ' | cut -d ' ' -f 2)
    2. ジョブテンプレートの <<SSO_IMAGE_VALUE>> フィールドを、プル仕様に置き換えます。

      $ sed -i "s#<<SSO_IMAGE_VALUE>>#$PULL_REF#g" job-to-migrate-db-to-sso74.yaml
    3. フィールドが更新されていることを確認します。
  5. ジョブテンプレートからデータベース移行ジョブをインスタンス化します。

    $ oc create -f job-to-migrate-db-to-sso74.yaml
    job "job-to-migrate-db-to-sso74" created
    重要

    データベースの移行プロセスでは、データスキーマの更新を処理し、データの操作を実行します。したがって、SQL 移行ファイルを動的に生成する前に、以前のバージョンの Red Hat Single Sign-On for OpenShift イメージを実行するすべての Pod を停止します。

  6. Red Hat Single Sign-On for OpenShift イメージの以前のバージョンを実行して、コンテナーをデプロイするために使用されるデプロイメント設定を特定します。

    $ oc get dc -o name --selector=application=sso
    deploymentconfig/sso
    deploymentconfig/sso-postgresql
  7. 現在の名前空間で、以前のバージョンの Red Hat Single Sign-On for OpenShift イメージを実行するすべての Pod を停止します。

    $ oc scale --replicas=0 dc/sso
    deploymentconfig "sso" scaled
  8. データベースの移行ジョブを実行し、Pod が正しく実行されるのを待機します。

    $ oc get jobs
    NAME                            DESIRED   SUCCESSFUL   AGE
    job-to-migrate-db-to-sso74   1         0            3m
    $ oc scale --replicas=1 job/job-to-migrate-db-to-sso74
    job "job-to-migrate-db-to-sso74" scaled
    $ oc get pods
    NAME                                  READY     STATUS      RESTARTS   AGE
    sso-postgresql-1-n5p16                1/1       Running     1          19h
    job-to-migrate-db-to-sso74-b87bb   1/1       Running     0          1m
    sso74-db-migration-image-1-build      0/1       Completed   0          27m
    注記

    デフォルトでは、データベース移行ジョブは、移行ファイルの生成後 600 秒 後に自動的に終了します。この期間を調整できます。

  9. Pod から動的に生成された SQL データベース移行ファイルを取得します。

    $ mkdir -p ./db-update
    $ oc rsync job-to-migrate-db-to-sso74-b87bb:/opt/eap/keycloak-database-update.sql ./db-update
    receiving incremental file list
    keycloak-database-update.sql
    
    sent 30 bytes  received 29,726 bytes  59,512.00 bytes/sec
    total size is 29,621  speedup is 1.00
  10. keycloak-database-update.sql ファイルを検査して、Red Hat Single Sign-On 7.4.10.GA バージョンへの手動データベース更新内で実行される変更を確認します。
  11. データベースの更新を手動で適用します。

    • PostgreSQL データベース (一時的または永続的モードでデプロイ) がサポートする Red Hat Single Sign-On for OpenShift イメージの以前のバージョンを別の Pod で実行する場合は、以下のコマンドを実行します。

      1. 生成された SQL 移行ファイルを PostgreSQL Pod にコピーします。

        $ oc rsync --no-perms=true ./db-update/ sso-postgresql-1-n5p16:/tmp
        sending incremental file list
        
        sent 77 bytes  received 11 bytes  176.00 bytes/sec
        total size is 26,333  speedup is 299.24
      2. PostgreSQL Pod へのシェルセッションを開始します。

        $ oc rsh sso-postgresql-1-n5p16
        sh-4.2$
      3. psql ツールを使用して、データベースの更新を手動で適用します。

        sh-4.2$ alias psql="/opt/rh/rh-postgresql95/root/bin/psql"
        sh-4.2$ psql --version
        psql (PostgreSQL) 9.5.4
        sh-4.2$ psql -U <PREFIX>_USERNAME -d <PREFIX>_DATABASE -W -f /tmp/keycloak-database-update.sql
        Password for user <PREFIX>_USERNAME:
        INSERT 0 1
        INSERT 0 1
        ...
        重要

        <PREFIX>_USERNAME および <PREFIX>_DATABASE を、前のセクション で取得した実際のデータベースの認証情報に置き換えます。また、プロンプトが表示されたら、データベースのパスワードとして <PREFIX>_PASSWORD の値を使用します。

      4. PostgreSQL Pod へのシェルセッションを閉じます。「イメージ変更トリガーの更新手順」に進みます。
  1. 既存のデプロイメント設定のイメージ変更トリガーを更新して、Red Hat Single Sign-On 7.4.10.GA イメージを参照します。

    $ oc patch dc/sso --type=json -p '[{"op": "replace", "path": "/spec/triggers/0/imageChangeParams/from/name", "value": "sso74-openshift-rhel8:7.4"}]'
    "sso" patched
  2. イメージ変更トリガーで定義した最新のイメージをもとに、新しい Red Hat Single Sign-On 7.4.10.GA イメージのロールアウトを開始します。

    $ oc rollout latest dc/sso
    deploymentconfig "sso" rolled out
  3. 変更したデプロイメント設定を使用して、Red Hat Single Sign-On 7.4.10.GA コンテナーをデプロイします。

    $ oc scale --replicas=1 dc/sso
    deploymentconfig "sso" scaled