Liferayの開発・検証環境において、データ不整合によるエラー(liveGroup is null などの NullPointerException)が発生した際、環境を切り分けて原因特定するために「データベースを一度完全にまっさらな初期状態に戻したい」というケースがあります。
しかし、厳格なセキュリティポリシー(PodSecurity restricted)が適用されたKubernetesクラスタや、**SSL接続・アクセス制限が厳しいAWS RDS(PostgreSQL)**が相手の場合、単純な kubectl run --rm -it ... コマンドでは様々なエラーに阻まれます。
本記事では、Windows(PowerShell)環境などからこれらのセキュリティの壁をすべて突破し、安全にLiferayのデータベースを完全初期化するノウハウをまとめました。
🛑 直面した課題とブレイクスルーのポイント
手順の前に、今回突破した3つのポイントを共有します。同じエラーで引っかかった方の参考になれば幸いです。
-
Kubernetesのセキュリティポリシー(
restricted:latest)によるブロック-
問題: 公式の
postgres:16イメージをkubectl runしようとすると、ルート権限(root)実行やセキュリティコンテキスト未設定を理由に拒否される。 -
解決: 構築用のYAMLを定義し、最初から一般ユーザーで動くように設計されている Bitnami製イメージ(
bitnami/postgresql:16) を採用。
-
問題: 公式の
-
AWS RDSへの接続拒否(
no pg_hba.conf entry/no encryption)-
問題: RDSへの接続時にSSL暗号化が強制されているため弾かれる。また管理用DB(
postgres)への接続権限がない。 -
解決: 接続先を最初から
lportalに絞り、環境変数PGSSLMODE=requireをインジェクション。コピペのタイポを防ぐためPGPASSWORDもコマンド内に埋め込んで自動入力化。
-
問題: RDSへの接続時にSSL暗号化が強制されているため弾かれる。また管理用DB(
-
AWS RDSで
DROP DATABASEができない- 問題: アプリ用ユーザーからはデータベース自体の削除権限がない。
-
解決: データベースを削除するのではなく、中に入って
DROP SCHEMA public CASCADEを実行することで、テーブル構造とデータを一瞬で完全消去。
🛠️ Liferay完全初期化・5つのステップ
前提の環境情報(プレースホルダーをご自身の環境に書き換えてください)
-
対象ネームスペース:
<YOUR_NAMESPACE> -
対象StatefulSet名:
<YOUR_STATEFULSET_NAME> -
対象データベース名:
lportal -
DB管理者ユーザー:
liferay_database_admin -
DBパスワード:
<YOUR_DB_PASSWORD> -
DBエンドポイント:
<YOUR_DB_ENDPOINT>
Step 1. Liferay サーバーの停止
データの一貫性を保ち、データベースへの既存のコネクション(接続セッション)をすべて確実に切断するため、Liferayのレプリカ数を 0 にスケールダウンします。
# StatefulSetの場合
kubectl scale sts <YOUR_STATEFULSET_NAME> --replicas=0 -n <YOUR_NAMESPACE>
💡 確認:
kubectl get pod -n <YOUR_NAMESPACE>を実行し、LiferayのPodが完全に消滅したことを確認します。
Step 2. デバッグ用Podのデプロイ
セキュリティ制限(非root実行必須、ケイパビリティのドロップなど)をクリアした、使い捨てのPostgreSQLクライアント用Podを起動します。
- 任意の場所に
psql-debug.yamlという名前で以下のファイルを保存します。
apiVersion: v1
kind: Pod
metadata:
name: psql-debug
namespace: <YOUR_NAMESPACE>
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1001 # Bitnamiイメージの一般ユーザーUID
seccompProfile:
type: RuntimeDefault
containers:
- name: psql-client
image: bitnami/postgresql:16
command: ["sleep", "3600"] # 1時間だけ維持
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
- 以下のコマンドでPodをクラスタ上に作成します。
kubectl apply -f psql-debug.yaml
💡 確認:
kubectl get pod psql-debug -n <YOUR_NAMESPACE>で STATUS がRunningになるのを待ちます。
Step 3. スキーマ(データ・テーブル群)の完全消去
パスワード自動入力、およびSSL強制(require)の環境変数をコンテナへ渡しながらログインし、Liferayが生成した何百ものテーブルをスキーマごと一撃で消去します。
- 以下のコマンドを実行し、DBに自動ログインします。
kubectl exec -it psql-debug -n <YOUR_NAMESPACE> -- sh -c 'export PGPASSWORD="<YOUR_DB_PASSWORD>"; export PGSSLMODE="require"; psql -h <YOUR_DB_ENDPOINT> -U liferay_database_admin -d lportal'
- 無事に
lportal=>というプロンプトが表示されたら、以下のSQLを1行ずつ順番に実行します。
-- 1. 既存のテーブルやデータをすべて巻き込んで public スキーマを削除
DROP SCHEMA public CASCADE;
-- 2. まっさらの空の public スキーマを再作成
CREATE SCHEMA public;
-- 3. Liferayが起動時にテーブルを再自動生成できるよう、必要な権限を再付与
GRANT ALL ON SCHEMA public TO liferay_database_admin;
GRANT ALL ON SCHEMA public TO public;
- 実行が完了したら、
\qを入力してEnterを押し、データベースからログアウトします。
Step 4. Liferay の再起動と自動セットアップ
Liferayのレプリカ数を 1 に戻します。
kubectl scale sts <YOUR_STATEFULSET_NAME> --replicas=1 -n <YOUR_NAMESPACE>
Liferayは、接続先データベース(lportal)のスキーマ内が空(テーブルが1つもない状態)であることを検知すると、起動処理の中で自動的にすべてのテーブルおよび初期デフォルトデータを再構築する仕様を持っています。
⚠️ 注意:
何百ものテーブルを一から新規生成するため、完全な起動には 5〜10 分ほどかかります。
以下のコマンドでログを監視し、気長に待ちましょう。
kubectl logs -f <YOUR_STATEFULSET_NAME>-0 -n <YOUR_NAMESPACE>
大量の DDL(SQL)が流れた後、最終的に Liferay Portal started in ... とログに出力されれば初期化再起動は成功です!
Step 5. 後片付け
役割を終えた一時的なデバッグ用Podを削除し、クラスタのリソースを解放します。
kubectl delete -f psql-debug.yaml
📝 まとめ
Liferayのように内部で複雑なデータや検索インデックスの同期を行っている製品では、予期せぬ不整合で動作が不安定になることがあります。環境そのものを一度クリアにしたい場合、上記のように「StatefulSetの停止 ➔ スキーマのCASCADE削除 ➔ レプリカ数復旧」を行うことで、クリーンな初期状態を安全に作り出すことができます。
KubernetesのセキュリティポリシーやクラウドDBのネットワーク制限で同様の事象に悩まされている方の参考になれば幸いです。