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

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

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

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

GitLabはユーザーに対し、データベースを新しいPostgreSQL Chartにマイグレーションすることを推奨しています。

このガイドでは、PostgreSQLデータベースのマイグレーション方法を説明します:

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

前提条件

  1. kubectlをインストールします。
  2. kubectlを使用してKubernetesクラスターにアクセスできることを確認します。これはKubernetesプロバイダによって異なります。
  3. ダウンタイムの準備。以下の手順には、データベースダンプの作成後にクラスター内のデータベースが変更されないように、アプリケーションをオフラインにすることも含まれます。
  4. 既存のチャネル1データベースが削除されるため、POSTGRES_ENABLEDfalse に設定していないことを確認してください。詳細については、既存の PostgreSQL データベースの検出を参照してください。
note
ステージングを持つように 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. ワーカーがある場合は、ワーカーのレプリカも 0 に設定する必要があります。

バックアップ

  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 をインストールします。

caution
新しいバージョンのPostgreSQLを使用すると、古い0.7.1のPostgreSQLが削除されます。基礎となるデータが削除されないように、永続ボリュームを保持することを選択できます。
note
また、AUTO_DEVOPS_POSTGRES_CHANNELAUTO_DEVOPS_POSTGRES_DELETE_V1POSTGRES_VERSION 変数を特定の環境、例えば、stagingスコープすることもできます。
  1. AUTO_DEVOPS_POSTGRES_CHANNEL 2これは、より新しい8.2.1ベースのPostgreSQLの使用を選択し、古い0.7.1ベースのPostgreSQLを削除します。
  2. AUTO_DEVOPS_POSTGRES_DELETE_V1 に空でない値を設定します。このフラグは、データベースが誤って削除されるのを防ぐための安全策です。
  3. POSTGRES_VERSION が設定されている場合は、9.6.16 以降に設定されていることを確認してください。これは Auto DevOps がサポートする PostgreSQL の最小バージョンです。利用可能なタグのリストも参照してください。
  4. PRODUCTION_REPLICAS0 に設定してください。その他の環境では、環境スコープを指定してREPLICAS を使用してください。
  5. DB_INITIALIZE またはDB_MIGRATE 変数を設定している場合は、その変数を削除するか、一時的に変数名をXDB_INITIALIZE またはXDB_MIGRATE に変更して、効果的に無効にします。
  6. ブランチに対して新しいCIパイプラインを実行します。この場合、main に対して新しい 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パイプラインを実行します。この場合、main に対して新しい CI パイプラインを実行します。パイプラインが成功すると、アプリケーションは以前のようにトラフィックを提供するはずです。