自動DevOpsのためのPostgreSQLのアップグレード
POSTGRES_ENABLED がtrue の場合、Auto DevOps はアプリケーションのためにクラスタ内の PostgreSQL データベースを提供します。
PostgreSQLのプロビジョニングに使用したChartのバージョンです:
- GitLab 12.8以前では0.7.1です。
- GitLab 12.9以降では0.7.1から8.2.1まで設定可能。
GitLabはユーザーに対し、データベースを新しいPostgreSQL Chartにマイグレーションすることを推奨しています。
このガイドでは、PostgreSQLデータベースのマイグレーション方法を説明します:
- データのデータベースダンプを取ります。
- Chartの新しいバージョン8.2.1を使用して新しいPostgreSQLデータベースをインストールし、古いPostgreSQLのインストールを削除します。
- データベースのダンプを新しいPostgreSQLにリストアします。
前提条件
-
kubectlをインストールします。 -
kubectlを使用してKubernetesクラスターにアクセスできることを確認します。これはKubernetesプロバイダによって異なります。 - ダウンタイムの準備。以下の手順には、データベースダンプの作成後にクラスター内のデータベースが変更されないように、アプリケーションをオフラインにすることも含まれます。
- 既存のチャネル1データベースが削除されるため、
POSTGRES_ENABLEDをfalseに設定していないことを確認してください。詳細については、既存の PostgreSQL データベースの検出を参照してください。
アプリケーションをオフラインにします
必要に応じて、アプリケーションをオフラインにして、データベース・ダンプの作成後にデータベースが変更されないようにします。
-
環境のKubernetes名前空間を取得します。通常は
<project-name>-<project-id>-<environment>のようになります。この例では、名前空間はminimal-ruby-app-4349298-productionと呼ばれています。$ kubectl get ns NAME STATUS AGE minimal-ruby-app-4349298-production Active 7d14h -
使いやすくするために、名前空間名をエクスポートします:
export APP_NAMESPACE=minimal-ruby-app-4349298-production -
以下のコマンドを使用して、アプリケーションのデプロイメント名を取得します。この例では、デプロイ名は
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 -
データベースが変更されないようにするには、次のコマンドでデプロイのレプリカを 0 に設定します。前の手順(
deployments/<DEPLOYMENT_NAME>)のデプロイメント名を使用します。$ kubectl scale --replicas=0 deployments/production --namespace "$APP_NAMESPACE" deployment.extensions/production scaled -
ワーカーがある場合は、ワーカーのレプリカも 0 に設定する必要があります。
バックアップ
-
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 -
以下のコマンドで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 -
でポッドに接続します:
kubectl exec -it production-postgres-5db86568d7-qxlxv --namespace "$APP_NAMESPACE" -- bash -
接続したら、以下のコマンドでダンプ・ファイルを作成します。
-
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
-
-
バックアップダンプが完了したら、
Control-DまたはexitでKubernetes execプロセスを終了します。 -
以下のコマンドでダンプファイルをダウンロードします:
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-42010a8e0096 とpvc-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 をインストールします。
AUTO_DEVOPS_POSTGRES_CHANNEL 、AUTO_DEVOPS_POSTGRES_DELETE_V1 、POSTGRES_VERSION 変数を特定の環境、例えば、stagingにスコープすることもできます。-
AUTO_DEVOPS_POSTGRES_CHANNEL2これは、より新しい8.2.1ベースのPostgreSQLの使用を選択し、古い0.7.1ベースのPostgreSQLを削除します。 -
AUTO_DEVOPS_POSTGRES_DELETE_V1に空でない値を設定します。このフラグは、データベースが誤って削除されるのを防ぐための安全策です。 -
POSTGRES_VERSIONが設定されている場合は、9.6.16以降に設定されていることを確認してください。これは Auto DevOps がサポートする PostgreSQL の最小バージョンです。利用可能なタグのリストも参照してください。 -
PRODUCTION_REPLICASを0に設定してください。その他の環境では、環境スコープを指定してREPLICASを使用してください。 -
DB_INITIALIZEまたはDB_MIGRATE変数を設定している場合は、その変数を削除するか、一時的に変数名をXDB_INITIALIZEまたはXDB_MIGRATEに変更して、効果的に無効にします。 - ブランチに対して新しいCIパイプラインを実行します。この場合、
mainに対して新しい CI パイプラインを実行します。 - パイプラインが成功すると、アプリケーションは新しいPostgreSQLをインストールしてアップグレードされます。この時点ではレプリカは存在しないので、アプリケーションのトラフィックは提供されません(新しいデータが入ってくるのを防ぐため)。
復元
-
新しい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 -
バックアップステップのダンプファイルをポッドにコピーします:
kubectl cp --namespace "$APP_NAMESPACE" backup.sql production-postgresql-0:/tmp/backup.sql -
ポッドに接続します:
kubectl exec -it production-postgresql-0 --namespace "$APP_NAMESPACE" -- bash -
ポッドに接続したら、以下のコマンドを実行してデータベースをリストアします。
- データベースパスワードの入力を求められた場合、デフォルトは
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 - データベースパスワードの入力を求められた場合、デフォルトは
-
リストア完了後、データが正しくリストアされたことを確認できます。
psqlを使用して、データの抜き取りチェックを実行できます。
アプリケーションの再インストール
データベースがリストアされたことを確認したら、以下の手順を実行してアプリケーションを再起動します:
-
DB_INITIALIZEおよびDB_MIGRATE変数が削除または無効になっている場合は、これをリストアします。 -
PRODUCTION_REPLICASまたはREPLICAS変数を元の値に戻します。 - ブランチに対して新しいCIパイプラインを実行します。この場合、
mainに対して新しい CI パイプラインを実行します。パイプラインが成功すると、アプリケーションは以前のようにトラフィックを提供するはずです。