自動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データベースの移行方法を説明します:
- データベースのデータをダンプします。
- Chartの新しいバージョン8.2.1を使用して新しいPostgreSQLデータベースをインストールし、古いPostgreSQLのインストールを削除します。
- データベースのダンプを新しいPostgreSQLにリストアします。
前提条件
- インストール
kubectl
. -
kubectl
を使用してKubernetesクラスタにアクセスできることを確認します。 これはKubernetesプロバイダによって異なります。 - ダウンタイムの準備 以下の手順には、データベース・ダンプの作成後にクラスター内のデータベースが変更されないように、アプリケーションを オフラインにすることも含まれます。
-
POSTGRES_ENABLED
をfalse
に設定していないことを確認してください。この設定により、既存のチャネル1データベースが削除されます。詳細については、既存の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
-
また、ワーカーのレプリカをゼロに設定する必要があります。
バックアップ
-
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
を11.7
に設定してください。 これはサポートされる PostgreSQL の最小バージョンです。 -
PRODUCTION_REPLICAS
を0
に設定してください。その他の環境では、REPLICAS
を環境スコープ付きで使用してください。 -
DB_INITIALIZE
またはDB_MIGRATE
変数を設定している場合は、その変数を削除するか、一時的にXDB_INITIALIZE
またはXDB_MIGRATE
に名前を変更して、効果的に無効にします。 - ブランチに対して新しいCIパイプラインを実行します。この例では、
master
に対して新しい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パイプラインを実行します。この例では、
master
に対して新しいCIパイプラインを実行します。パイプラインが成功すると、アプリケーションは以前と同じようにトラフィックを提供するようになるはずです。