G-gen の佐々木です。当記事では、Google Cloud の仮想マシンサービスである Compute Engine(Google Compute Engine: GCE)に PostgreSQL サーバを構築していきます。
- 当記事の目的
- Compute Engine インスタンスの作成
- PostgreSQL のインストール
- インスタンス内部からデータベースに接続確認
- リモートクライアントからデータベースに接続確認
- バックアップの取得とインスタンスの復元
当記事の目的
当記事では、Google Cloud 上で仮想マシンを利用できるサービスである Compute Engine を利用して、PostgreSQL サーバを構築していきます。
Compute Engine についての詳細は解説は、以下の記事をご参照ください。
Google Cloud では Cloud SQL や AlloyDB for PostgreSQL などの PostgreSQL 完全互換のデータベース サービスが提供されています。また、無制限のスケーリングとマルチリージョンの展開が可能な非常に強力なデータベース サービスである Cloud Spanner でも、完全互換ではないものの、PostgreSQL との互換性があります。
したがって、Google Cloud において新規にデータベースを利用する際、データベースエンジンとして PostgreSQL を優先的に検討・採用するケースが想定されます。
上記の Google Cloud におけるマネージド データベース サービスは、本番環境向け、エンタープライズ向けの機能を多く持つことから、 個人の PostgreSQL の学習用途や、簡単なテスト用のデータベースとして利用するには性能が過剰で、またコスト(Google Cloud 利用料)が高くついてしまいます。
そこで当記事では、個人による、Google Cloud の環境を利用した PostgreSQL の学習用途を想定して、Compute Engine 仮想マシン上に PostgreSQL サーバを構築していきます。
Compute Engine インスタンスの作成
作業の概要
Google Cloud プロジェクトに Compute Engine 仮想マシン(インスタンス)を作成していきます。
インスタンスは VPC 内のサブネットに作成する必要があるため、それらのリソースを先に作成し、その中にインスタンスを作成します。
そして、インスタンスに PostgreSQL をインストールする際や、インスタンス上に構築した PostgreSQL サーバーを利用する際に VPC の外部から接続できるように、接続を許可するファイアウォールルールを設定しておきます。
当記事では gcloud コマンドを用いてリソースの作成を行っていきます。gcloud コマンドのインストールについてはこちらのドキュメントを参照してください。
また、Google Cloud コンソールから利用できる Cloud Shell(ブラウザベースのターミナル環境)には gcloud コマンドがプリインストールされているため、以降の作業をそのまま実施することができます。
シェル変数の設定
コマンドで何度か使用する値をシェル変数に格納しておきます。
SUFFIX={適当な値} PROJECT={プロジェクトID} REGION={リソースを作成するリージョン}
VPC・サブネットの作成
VPC の作成
以下のコマンドで VPC を作成します。サブネットを手動で作成するため、--subnet-mode
フラグで custom
を指定します。
# VPC を作成する $ gcloud compute networks create vpc-${SUFFIX} \ --subnet-mode=custom \ --project=${PROJECT}
サブネットの作成
作成した VPC を指定し、その中にサブネットを作成します。--range
フラグではサブネットに割り当てるプライベート IP アドレスの範囲を CIDR で指定します。当記事では 192.168.150.0/28
を割り当てています。
# サブネットを作成する $ gcloud compute networks subnets create subnet-${SUFFIX} \ --network=vpc-${SUFFIX} \ --region=${REGION} \ --range=192.168.150.0/28 \ --project=${PROJECT}
インスタンスの作成
作成した VPC とサブネットを指定し、Compute Engine インスタンスを作成します。
当記事では以下の設定値でインスタンスを作成します。
項目 | gcloud コマンドのフラグ | 値 | 備考 |
---|---|---|---|
インスタンス名 | vm-${SUFFIX} | ||
VPC | --network |
vpc-${SUFFIX} | |
サブネット | --subnet |
subnet-${SUFFIX} | |
OS イメージ | --image-family --image-project |
debian-12 debian-cloud |
以降の手順はここで指定した OS を前提とする点に注意 |
マシンタイプ | --machine-type |
e2-micro | 2 vCPU、メモリ1GB 必要に応じて変更可(参考) |
ネットワークタグ | --tags |
ssh postgres |
後で作成するファイアウォールルールをインスタンスに紐付ける際に使用 |
# Compute Engine インスタンスを作成する $ gcloud compute instances create vm-${SUFFIX} \ --network=vpc-${SUFFIX} \ --subnet=subnet-${SUFFIX} \ --zone=${REGION}-a \ --image-family=debian-12 \ --image-project=debian-cloud \ --machine-type=e2-micro \ --tags=ssh,postgres \ --project=${PROJECT}
ファイアウォールルールの設定
作成したインスタンスに SSH でアクセスできるように、VPC に内向きのファイアウォールルールを作成します。--target-tags
フラグでインスタンスに設定したものと同じタグを指定することで、このルールをインスタンスに紐付けることができます。
なお、当記事では便宜上 --source-ranges
フラグ、つまりアクセス元の IP アドレス範囲を 0.0.0.0/0(任意の IP アドレス)に設定していますが、セキュリティを考慮して自身の PC の IP アドレス等を設定することもできます。
# SSH を許可する $ gcloud compute firewall-rules create vpc-${SUFFIX}-allow-ssh \ --direction=INGRESS \ --source-ranges=0.0.0.0/0 \ --allow=tcp:22 \ --target-tags=ssh \ --network=vpc-${SUFFIX} \ --project=${PROJECT}
次に、インスタンス上に構築する PostgreSQL サーバーに外部からアクセスできるように、ファイアウォールルールを作成します。
# PostgreSQL サーバへの接続を許可する $ gcloud compute firewall-rules create vpc-${SUFFIX}-allow-postgres \ --direction=INGRESS \ --source-ranges=0.0.0.0/0 \ --allow=tcp:5432 \ --target-tags=postgres \ --network=vpc-${SUFFIX} \ --project=${PROJECT}
インスタンスに SSH 接続
コンソールからインスタンスに接続(GUI の場合)
Google Cloud コンソールからインスタンスに SSH 接続する場合、インスタンス一覧画面で「SSH」を選択します。
gcloud コマンドで SSH 接続(CLI の場合)
gcloud では、以下のコマンドを使用してインスタンスに SSH 接続できます。
# インスタンスに SSH 接続する $ gcloud compute ssh vm-${SUFFIX} \ --zone=${REGION}-a \ --project=${PROJECT}
PostgreSQL のインストール
パッケージリストの更新
以降の手順については、SSH 接続した Compute Engine VM 上でコマンドを実行してください。
PostgreSQL をインストールする前に、apt のパッケージを最新化しておきます。
# パッケージリストを最新の状態にする $ sudo apt update # パッケージの最新化(時間がかかる可能性あり) $ sudo apt upgrade -y
PostgreSQL のインストール
apt install
で PostgreSQL をインストールします。
当記事では Debian のデフォルトに設定されているバージョンをインストールします。特定のバージョンを指定したい場合は公式ウェブサイト(postgresql.org)の Linux downloads (Debian) の手順を参照してください。
# PostgreSQL をインストールする $ sudo apt install postgresql -y # PostgreSQL のバージョンを確認する $ psql -U postgres -c "SELECT version()" ---------- 出力例 ---------- version ------------------------------------------------------------------------------------------------------------------- PostgreSQL 15.8 (Debian 15.8-0+deb12u1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit (1 row)
インスタンス内部からデータベースに接続確認
apt install
で PostgreSQL をインストールした場合、初期ユーザーとして postgres
という名前のユーザーがパスワード無しで設定されています。
ユーザーを切り替えて psql コマンドでデフォルトのデータベースに接続してみます。
# ユーザーの切り替え $ sudo su - postgres # PostgreSQL に接続する $ psql
ログインしたら、試しにデータベースの一覧を確認します。
# データベースの一覧を確認する postgres=# \l ---------- 出力例 ---------- List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+---------+---------+------------+-----------------+----------------------- postgres | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc | template0 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | C.UTF-8 | C.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres (3 rows)
確認が終わったら、データベースからはログアウトします。
# データベースからログアウトする postgres=# \q
PostgreSQL の管理ツールである pg_ctl などのコマンドは /usr/lib/postgresql/15/bin/
にあるため、postges ユーザーの .bash_profile ファイルにパスを設定しておきます。
# 管理ツールがあるディレクトリにパスを設定する $ echo 'PATH=$PATH:/usr/lib/postgresql/15/bin/' >> ~/.bash_profile # 変更を反映させる $ source ~/.bash_profile
リモートクライアントからデータベースに接続確認
設定ファイルの編集
postgresql.conf
postgres ユーザーのまま作業を続けていきます。
設定ファイルである postgresql.conf を編集して、ローカル PC や Cloud Shell などのリモートクライアントからデータベースに接続できるようにします。
初期状態では、listen_addresses
の項目がコメントアウトされています。この項目では、データベース接続を受け付けるインスタンス側の IP アドレス(接続元 IP アドレスではない)を設定します。
$ cat /etc/postgresql/15/main/postgresql.conf | grep listen_addresses #listen_addresses = 'localhost' # what IP address(es) to listen on;
エディタを使用してファイルを編集していきます。
# エディタを使用して postgresql.conf を編集する $ vi /etc/postgresql/15/main/postgresql.conf
listen_address
の行のコメントアウトを外し、以下のように修正してファイルを保存します。
listen_addresses = '*' # what IP address(es) to listen on;
インターネットからデータベースに接続するためには、ここで Compute Engine インスタンスの外部 IP アドレスを設定する必要があります。
しかし、当記事ではインスタンスの外部 IP アドレスを固定していないため、インスタンスの停止・起動を行うと IP アドレスが変わってしまう可能性があります。そのため、上記のように「*」を設定することで全ての IP アドレスでデータベース接続を受け付けるようにします。
postgresql.conf の listen_addresses
項目は、設定を反映するためにデータベースの再起動が必要な項目となっているため、後の手順で再起動を実施します。
pg_hba.conf
クライアント認証に関する設定ファイルである pg_hba.conf も編集する必要があります。このファイルでは、1行のレコードでクライアントが利用できるデータベースやデータベースユーザー、アクセス元 IP アドレスなどを設定します。
# エディタを使用して pg_hba.conf を編集する $ vi /etc/postgresql/15/main/pg_hba.conf
ファイル内の # IPv4 local connections:
の下に以下のレコードを追記します。
host all all 0.0.0.0/0 trust
上記の記述では、全ての IP アドレス(4列目の 0.0.0.0/0
)から、全てのデータベース(2列めの all
)に対して、全てのデータベースユーザーを使用して(3列目の all
)、パスワード無しで(5行目の trust
)接続できるようになります。
よりセキュリティを考慮する場合は、以下のドキュメントを参考に、アクセス元 IP アドレスやパスワード認証の強制等を設定するとよいでしょう。
データベース再起動
編集した設定ファイルを反映させるため、pg_ctl restart
でデータベースの再起動を行います。
# データベースを再起動する $ pg_ctl restart -D /var/lib/postgresql/15/main/ ---------- 出力例 ---------- waiting for server to shut down.... done server stopped waiting for server to start....2024-10-26 14:34:46.636 UTC [1548] LOG: starting PostgreSQL 15.8 (Debian 15.8-0+deb12u1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit 2024-10-26 14:34:46.637 UTC [1548] LOG: listening on IPv4 address "0.0.0.0", port 5432 2024-10-26 14:34:46.637 UTC [1548] LOG: listening on IPv6 address "::", port 5432 2024-10-26 14:34:46.640 UTC [1548] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2024-10-26 14:34:46.648 UTC [1551] LOG: database system was shut down at 2024-10-26 14:34:46 UTC 2024-10-26 14:34:46.657 UTC [1548] LOG: database system is ready to accept connections done server started
データベースクラスタのパスを PGDATA
環境変数に設定しておくことで、上記コマンドのように -D
フラグでデータベースクラスタを指定しなくてもよくなります。必要に応じて環境変数を設定するとよいでしょう。
接続確認
リモートクライアントからデータベースへの接続を行います。以降の手順は全て自身の PC や Cloud Shell のターミナルからコマンドを実行してください。
psql コマンドがない場合はこちらのドキュメント を参考にインストールします。なお、Cloud Shell には psql がプリインストールされています。
まず、Compute Engine インスタンスの外部 IP アドレスをシェル変数 HOST_IP
に格納します。
# インスタンスの外部 IP アドレスをシェル変数に格納する HOST_IP=$( gcloud compute instances describe vm-${SUFFIX} \ --zone=${REGION}-a \ --project=${PROJECT} \ --format="value(networkInterfaces[0].accessConfigs[0].natIP)" )
psql コマンドでデータベース接続を行います。
# データベースに接続する $ psql -h ${HOST_IP} -U postgres
バックアップの取得とインスタンスの復元
バックアップの目的
PostgreSQL の設定が完了した状態の Compute Engine インスタンスのバックアップを作成します。
今回作成した環境は PostgreSQL の学習用のため、重要なデータなどは格納されない想定ですが、バックアップを取っておくことで以下のようなメリットがあります。
- 環境を長期間利用しない場合に削除し、必要なときにバックアップから環境を再作成することで、Google Cloud 利用料を節約する。
- 学習中に環境を壊してしまった場合に、壊れる前の環境をすぐに復元することができる。
Compute Engine のバックアップについてはスナップショット、マシンイメージ、カスタムイメージなどいくつかの方法がありますが、ここではマシンイメージを作成していきます。
それぞれの違いについては、以下の記事で詳しく説明されています。
マシンイメージの取得
以下のコマンドを使用して、PostgreSQL をインストールしたインスタンスをソースとしてマシンイメージを取得します。
いつの状態のバックアップかを明確にするため、マシンイメージを取得した時刻をイメージの名前に含めておくと便利です。
# マシンイメージの取得 $ gcloud compute machine-images create mimg-${SUFFIX}-$(date '+%Y%m%d%H%M%S') \ --source-instance=vm-${SUFFIX} \ --source-instance-zone=${REGION}-a \ --storage-location=${REGION} \ --project=${PROJECT}
マシンイメージからインスタンスを復元
古いインスタンスの削除
Compute Engine では同一のゾーンに同名のインスタンスを作成することができないため(参考)、なるべく同じ構成でバックアップからインスタンスを復元したい場合、先に古いインスタンスを削除します。
# インスタンスを削除する $ gcloud compute instances delete vm-${SUFFIX} \ --zone=${REGION}-a \ --project=${PROJECT}
マシンイメージからインスタンスを復元
マシンイメージからのインスタンスの復元は、インスタンス作成時と同じコマンドで --source-machine-image
フラグを使用します。
OS やネットワークタグなどの情報はマシンイメージに含まれているため、復元時に設定する必要はありません。
# マシンイメージからインスタンスを復元する $ gcloud compute instances create vm-${SUFFIX} \ --source-machine-image={マシンイメージの名前を指定} \ --network=vpc-${SUFFIX} \ --subnet=subnet-${SUFFIX} \ --zone=${REGION}-a \ --project=${PROJECT}
復元したインスタンスのデータベースに接続
復元したインスタンスの外部 IP アドレスを確認し、psql コマンドでデータベース接続を行います。
# インスタンスの外部 IP アドレスをシェル変数に格納する $ HOST_IP=$( gcloud compute instances describe vm-${SUFFIX} \ --zone=${REGION}-a \ --project=${PROJECT} \ --format="value(networkInterfaces[0].accessConfigs[0].natIP)" ) # データベースに接続する $ psql -h ${HOST_IP} -U postgres
PostgreSQL インストール後に設定ファイルを編集した状態がマシンイメージに保存されているため、復元したインスタンスであってもリモートクライアントから問題なく接続できます。
佐々木 駿太 (記事一覧)
G-gen最北端、北海道在住のクラウドソリューション部エンジニア
2022年6月にG-genにジョイン。Google Cloud Partner Top Engineer 2024に選出。好きなGoogle CloudプロダクトはCloud Run。
趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。
Follow @sasashun0805