自動DevOpsのためのPostgreSQLのアップグレード

Auto DevOpsは、クラスター内のPostgreSQLデータベースをアプリケーションに提供します。

PostgreSQLのプロビジョニングに使用したChartのバージョン:

  • GitLab 12.8以前では0.7.1です。
  • GitLab 12.9以降では0.7.1から8.2.1まで設定可能です。

GitLabでは、データベースを新しいPostgreSQLチャートに移行することを推奨しています。

このガイドでは、PostgreSQLデータベースの移行方法を説明します:

  1. データベースのデータをダンプします。
  2. Chartの新しいバージョン8.2.1を使用して新しいPostgreSQLデータベースをインストールし、古いPostgreSQLのインストールを削除します。
  3. データベースのダンプを新しいPostgreSQLにリストアします。

前提条件

  1. インストールkubectl.
  2. kubectlを使用してKubernetesクラスタにアクセスできることを確認します。 これはKubernetesプロバイダによって異なります。
  3. ダウンタイムの準備 以下の手順には、データベース・ダンプの作成後にクラスター内のデータベースが変更されないように、アプリケーションを オフラインにすることも含まれます。
  4. POSTGRES_ENABLEDfalseに設定していないことを確認してください。この設定により、既存のチャネル1データベースが削除されます。詳細については、既存のPostgreSQLデータベースの検出を参照してください。
ヒント:ステージングを持つようにAuto DevOpsを構成した場合、最初にステージングでバックアップとリストアの手順を試すか、レビュアーアプリで試すことを検討してください。

アプリケーションのオフライン化

必要であれば、データベース・ダンプの作成後にデータベースが変更されないように、アプリケーションをオフラインにしてください。

  1. 環境のKubernetes名前空間を取得します。 通常は<project-name>-<project-id>-<environment>のようになります。 この例では、名前空間はminimal-ruby-app-4349298-productionと呼ばれます。

    $ kubectl get ns
    
    NAME                                                  STATUS   AGE
    minimal-ruby-app-4349298-production                   Active   7d14h
    
  2. 使いやすくするために、名前空間名をエクスポートします:

    export APP_NAMESPACE=minimal-ruby-app-4349298-production
    
  3. 次のコマンドを使用して、アプリケーションのデプロイメント名を取得します。 この例では、デプロイメント名はproductionです。

    $ kubectl get deployment --namespace "$APP_NAMESPACE"
    NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
    production            2/2     2            2           7d21h
    production-postgres   1/1     1            1           7d21h
    
  4. データベースが変更されないようにするには、次のコマンドでデプロイのレプリカを 0 に設定します。 前の手順で使用したデプロイメント名 (deployments/<DEPLOYMENT_NAME>) を使用します。

    $ kubectl scale --replicas=0 deployments/production --namespace "$APP_NAMESPACE"
    deployment.extensions/production scaled
    
  5. また、ワーカーのレプリカをゼロに設定する必要があります。

バックアップ

  1. PostgreSQLのサービス名を取得します。 サービス名は-postgresで終わる必要があります。 この例では、サービス名はproduction-postgresです。

    $ kubectl get svc --namespace "$APP_NAMESPACE"
    NAME                     TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    production-auto-deploy   ClusterIP   10.30.13.90   <none>        5000/TCP   7d14h
    production-postgres      ClusterIP   10.30.4.57    <none>        5432/TCP   7d14h
    
  2. 以下のコマンドでPostgreSQLのポッド名を取得します。 この例では、ポッド名はproduction-postgres-5db86568d7-qxlxvです。

    $ kubectl get pod --namespace "$APP_NAMESPACE" -l app=production-postgres
    NAME                                   READY   STATUS    RESTARTS   AGE
    production-postgres-5db86568d7-qxlxv   1/1     Running   0          7d14h
    
  3. でポッドに接続します:

    kubectl exec -it production-postgres-5db86568d7-qxlxv --namespace "$APP_NAMESPACE" bash
    
  4. 接続したら、以下のコマンドでダンプ・ファイルを作成します。

    • SERVICE_NAME は前のステップで取得したサービス名です。
    • USERNAME は PostgreSQL 用に設定したユーザ名です。 デフォルトはuserです。
    • DATABASE_NAME は通常環境名です。

    • データベースパスワードの入力を求められますが、デフォルトはtesting-passwordです。
    ## Format is:
    # pg_dump -h SERVICE_NAME -U USERNAME DATABASE_NAME > /tmp/backup.sql
    
    pg_dump -h production-postgres -U user production > /tmp/backup.sql
    
  5. バックアップダンプが完了したら、Control-D またはexitでKubernetes execプロセスを終了します。

  6. 以下のコマンドでダンプ・ファイルをダウンロードします:

    kubectl cp --namespace "$APP_NAMESPACE" production-postgres-5db86568d7-qxlxv:/tmp/backup.sql backup.sql
    

永続ボリュームの保持

デフォルトでは、PostgreSQLの基礎データを格納するために使用される永続ボリュームは、そのボリュームを使用するポッドとポッドクレームが削除されるとDelete

新しい8.2.1のPostgreSQLに移行すると、古い0.7.1のPostgreSQLが削除され、永続ボリュームも削除されるためです。

以下のコマンドで確認できます:

$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                     STORAGECLASS   REASON   AGE
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Delete           Bound    minimal-ruby-app-4349298-staging/staging-postgres         standard                7d22h
pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Delete           Bound    minimal-ruby-app-4349298-production/production-postgres   standard                7d22h

古い0.7.1のPostgreSQLが削除されても永続ボリュームを保持するために、保持ポリシーをRetainに変更します。 この例では、クレーム名から永続ボリューム名を探します。minimal-ruby-app-4349298 アプリケーションのステージング用と本番用のボリュームを保持することに関心があるので、ここでのボリューム名はpvc-0da80c08-5239-11ea-9c8d-42010a8e0096pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096です:

$ kubectl patch pv  pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
persistentvolume/pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 patched
$ kubectl patch pv  pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
persistentvolume/pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 patched
$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                                     STORAGECLASS   REASON   AGE
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Retain           Bound    minimal-ruby-app-4349298-staging/staging-postgres         standard                7d22h
pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096   8Gi        RWO            Retain           Bound    minimal-ruby-app-4349298-production/production-postgres   standard                7d22h

新しいPostgreSQLのインストール

注意:新しいバージョンのPostgreSQLを使用すると、古い0.7.1のPostgreSQLが削除されます。 基礎となるデータが削除されるのを防ぐために、永続ボリュームを保持することを選択できます。
ヒント:AUTO_DEVOPS_POSTGRES_CHANNEL,AUTO_DEVOPS_POSTGRES_DELETE_V1,POSTGRES_VERSION 変数を特定の環境にスコープすることもできます(例:staging.
  1. AUTO_DEVOPS_POSTGRES_CHANNEL 2これは、新しい8.2.1ベースのPostgreSQLを使用することを選択し、古い0.7.1ベースのPostgreSQLを削除します。
  2. AUTO_DEVOPS_POSTGRES_DELETE_V1 に空でない値を設定します。 このフラグは、データベースを誤って削除しないための安全策です。
  3. POSTGRES_VERSION11.7に設定してください。 これはサポートされる PostgreSQL の最小バージョンです。
  4. PRODUCTION_REPLICAS0に設定してください。その他の環境では、REPLICAS環境スコープ付きで使用してください。
  5. DB_INITIALIZE またはDB_MIGRATE 変数を設定している場合は、その変数を削除するか、一時的にXDB_INITIALIZE またはXDB_MIGRATE に名前を変更して、効果的に無効にします。
  6. ブランチに対して新しいCIパイプラインを実行します。この例では、masterに対して新しいCIパイプラインを実行します。
  7. パイプラインが成功すると、アプリケーションは新しいPostgreSQLがインストールされた状態でアップグレードされます。 また、レプリカはゼロになり、アプリケーションにトラフィックが提供されなくなります(新しいデータが入ってくるのを防ぐため)。

復元

  1. 新しいPostgreSQLのポッド名を取得します。この例では、ポッド名はproduction-postgresql-0です:

    $ kubectl get pod --namespace "$APP_NAMESPACE" -l app=postgresql
    NAME                      READY   STATUS    RESTARTS   AGE
    production-postgresql-0   1/1     Running   0          19m
    
  2. バックアップ・ステップのダンプ・ファイルをポッドにコピーします:

    kubectl cp --namespace "$APP_NAMESPACE" backup.sql production-postgresql-0:/tmp/backup.sql
    
  3. ポッドに接続します:

    kubectl exec -it production-postgresql-0 --namespace "$APP_NAMESPACE" bash
    
  4. ポッドに接続したら、以下のコマンドを実行してデータベースをリストアします。

    • データベースパスワードの入力を求められますが、デフォルトはtesting-passwordです。
    • USERNAME は PostgreSQL 用に設定したユーザ名です。 デフォルトはuserです。
    • DATABASE_NAME は通常環境名です。
    ## Format is:
    # psql -U USERNAME -d DATABASE_NAME < /tmp/backup.sql
    
    psql -U user -d production < /tmp/backup.sql
    
  5. リストア完了後、データが正しくリストアされたことを確認できます。psqlを使用して、データの抜き取りチェックを実行できます。

お申し込みの再開

データベースがリストアされたことを確認したら、以下の手順を実行してアプリケーションを復活させます:

  1. DB_INITIALIZE およびDB_MIGRATE 変数が削除または無効化されている場合は、復元します。
  2. PRODUCTION_REPLICAS またはREPLICAS 変数を元の値に戻します。
  3. ブランチに対して新しいCIパイプラインを実行します。この例では、masterに対して新しいCIパイプラインを実行します。パイプラインが成功すると、アプリケーションは以前と同じようにトラフィックを提供するようになるはずです。