自動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_CHANNEL
2
これは、より新しい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 パイプラインを実行します。パイプラインが成功すると、アプリケーションは以前のようにトラフィックを提供するはずです。