
Kubernetesは、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化し、ローリングアップグレードやスケーリングに伴う多くの手動作業を抽象化するコンテナオーケストレーションプラットフォームです。Kubernetes環境でクラウドネイティブアプリケーションを構築する場合、アプリケーションがクラスター内でその機能を活用できるように、PostgreSQLデータベースなどのデータベースアプリケーションをデプロイする必要が生じることがよくあります。
このガイドでは、KubernetesクラスターにPostgreSQLをデプロイする手順を説明し、構成可能でスケーラブルなクラウドネイティブPostgreSQL環境を構築する方法を示します。Google Kubernetes Engine、Amazon EKS、IBM Cloud Kubernetes Service、あるいはMinikubeのようなローカルソリューションのいずれを使用している場合でも、このチュートリアルを適用できます。読み進めて、テスト用にKubernetes上で単一のPostgreSQLインスタンスをデプロイする方法を学び、さらにHelm、Kubernetes Operators、Bitnami PostgreSQLなどのツールを使用した高度なデプロイメントについても確認してください。
前提条件
次の手順では以下のものが必要となります。
- Kubernetesクラスター(DigitalOcean、Amazon Web Services、Google Cloud、IBM Cloudなどのクラウドプロバイダ上、またはローカル用のKindやMinikube上)
- Kubernetes APIコマンドラインツールkubectlに関する実用的な知識
開始する前に、Kubernetes上に単一のPostgreSQLインスタンスをデプロイするための基本手順をおさらいしましょう。
シンプルなPostgreSQLのデプロイメント
PostgreSQLのDocker化
Kubernetes はレジストリからDockerイメージを取得し、設定ファイルに基づいてデプロイします。以下の手順に従って独自のPostgreSQL Dockerイメージをビルドすることもできますし、Docker Hub にある公式のオープンソースイメージを使用することもできます。本記事では、最新のPostgres 15.3 イメージを使用します。
接続設定とシークレットの作成
データベース認証情報などの機密情報を安全に保存するために、Kubernetes環境内のネイティブリソースであるKubernetes Secrets構成を使用します。
Kubernetesはデフォルトでシークレットをbase64エンコード形式で保存しますが、それだけでは安全ではありません。セキュリティを強化するには、保存時の暗号化を有効にしてください。
すべての設定が完了したら、Kubernetes Secretのための設定を作成します。Postgresのパスワードには以下の値を使用します:
❯ echo -n "postgres" | base64
cG9zdGdyZXMK
次に、Secretsの設定ファイルを作成し、クラスターに適用します。
> cat postgres-secrets.yml
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret-config
type: Opaque
data:
password: cG9zdGdyZXMK
ここでは kind を使用しました。これは、Kubernetes にシークレットプロバイダーを使ってデータを保存するよう指示する Secret です。これらの値を保存するために使用する名前は、postgres-secret-config というキーに指定されています。最後に、data セクションに、秘密に保存したいキー/値のペアを指定しました。
ここでこの設定を適用し、内容が正しく保存されていることを確認します。
❯ kubectl apply -f postgres-secrets.yml
secret/postgres-secret-config created
❯ kubectl get secret postgres-secret-config -o yaml
apiVersion: v1
data:
password: cG9zdGdyZXMK
....
PersistentVolumeとPersistentVolumeClaimの作成
Dockerインスタンスには情報を保存するための永続的ストレージが存在しない(デフォルト)ため、コンテナが存在しなくなったときのためにデータベースデータ用の永続的なファイルストレージを作成する必要があります。
解決策は、PostgreSQLデータを保存するためのファイルシステムをマウントすることです。Kubernetesではこれらの操作に異なる設定形式が採用されているため、以下の手順に従います。
- 使用するボリュームのタイプを記述するPersistentVolumeマニフェストを作成します。
- 同じストレージクラスに基づき、特定のPersistentVolumeタイプの使用を要求するPersistentVolumeClaimを作成します。
以下の例では、現在のノードファイルシステムをボリュームとして使用していますが、データベース操作に適したStorageClass(標準、gp2、またはレプリケーションとIOPS最適化をサポートするクラウドプロバイダ固有の動的プロビジョナーなど)を使用することをおすすめします。
まず、PersistentVolumeの設定を定義します。
> cat pv-volume.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
この設定では、クラスターのノード上の/mnt/dataに、5GBの読み書き可能ストレージを確保するように指示しています。
これを適用し、永続ボリュームが使用可能であることを確認します。
❯ kubectl apply -f pv-volume.yml
persistentvolume/postgres-pv-volume created
❯ kubectl get pv postgres-pv-volume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
postgres-pv-volume 5Gi RWO Retain Available manual 51s
前のマニフェストの詳細と一致するPersistentVolumeClaim設定によりフォローアップすることが求められます。
> cat pv-claim.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
この構成では、同じストレージクラス名を使用して1GBのデータに対するPersistentVolumeClaimを要求しました。これは重要なパラメータであり、Kubernetesが利用可能な5GBのストレージクラスからこの要求のために1GBを確保できるようにします。
これを適用し、永続ボリューム要求がバインドされていることを確認します。
❯ kubectl apply -f pv-claim.yml
persistentvolumeclaim/postgres-pv-claim created
❯ kubectl get pvc postgres-pv-claim
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
postgres-pv-claim Bound postgres-pv-volume 1Gi RWO manual 5m32s
PostgreSQL用のKubernetesデプロイメントの作成
Secret名Postgres-secret-configの設定を使用し、先ほど作成したPersistentVolumeとPersistentVolumeClaimを参照して、Kubernetesインスタンスのデプロイメント設定を発行します。
> cat postgres-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
volumes:
- name: postgres-pv-storage
persistentVolumeClaim:
claimName: postgres-pv-claim
containers:
- name: postgres
image: postgres:11
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5432
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret-config
key: password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-pv-storage
ここでは、先に定義したすべての設定を、Kubernetes のシークレット設定および永続ボリュームのマウントと組み合わせました。apiVersion: apps/v1 のデプロイ設定を使用しており、selector や metadata フィールドなど、かなり多くの項目を指定する必要があります。次に、コンテナイメージの詳細とイメージプルポリシーを追加しました。これらはすべて、そのコンテナで正しいボリュームとシークレットが使用されるようにするために必要です。
次にこれを適用し、デプロイメントが利用可能かつ正常であることを確認します。
❯ kubectl apply -f postgres-deployment.yml
deployment.apps/postgres created
❯ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
postgres 1/1 1 1 28s
PostgreSQLサーバーを公開するためのサービスの作成
Kubernetes Service を使用して PostgreSQL の Pod を公開します。これを行うには、別のポートを設定するか、NodePort または LoadBalancer を公開できます。簡単のため、ここでは NodePort の使い方を紹介します。NodePort は、ノードの IP 上の静的ポートでサービスを公開します。
次のサービスマニフェストが使用可能です。
> cat postgres-service.yml
apiVersion: v1
kind: Service
metadata:
name: postgres
labels:
app: postgres
spec:
type: NodePort
ports:
- port: 5432
selector:
app: postgres
次にこれを適用し、サービスが利用可能であることと、ポートが割り当てられていることを確認します。
❯ kubectl apply -f postgres-service.yml
service/postgres created
❯ kubectl get service postgres
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
Postgresデータベースへの接続テスト
次のコマンドを使用することで、内部よりPostgreSQLデータベースに接続することができるはずです。
❯ kubectl get pods
NAME READY STATUS RESTARTS AGE
postgres-57f4746d96-7z5q8 1/1 Running 0 30m
❯ kubectl exec -it postgres-57f4746d96-7z5q8 -- psql -U postgres
Kubernetesポッド名を変数に保存するための便利な方法もあります。
POD=$(kubectl get pods -l app=postgres -o jsonpath="{.items[0].metadata.name}")
また、別のDockerコンテナを使用し、psqlコマンド経由で接続することも可能です。
export POSTGRES_PASSWORD=$(kubectl get secret postgres-secret-config -o jsonpath="{.data.password}" | base64 --decode)
❯ kubectl run postgres-client --rm --tty -i --restart='Never' --image postgres:11 --env="PGPASSWORD=$POSTGRES_PASSWORD" --command -- psql -h postgres -U postgres
コマンドプロンプトが表示されない場合は、Enterキーを押してみてください。
postgres=#
これで、クエリ実行の準備が整いました。
高度なPostgreSQLデプロイメント
前の例では、開発目的で単一のPostgreSQLインスタンスのみをデプロイしました。高可用性、レプリケーション、スケーリングが求められる本番環境およびハイブリッドクラウド環境では、以下を使用できます。
- Bitnami PostgreSQL Deployment: Bitnamiは、複数のタイプのデプロイメント(KubernetesコミュニティがメンテナンスするパッケージマネージャーであるHelmを含む)をサポートし、大規模デプロイメント向けの多くの構成オプションを提供します。
- Zalando PostgreSQLオペレーター:Patroniベースの既存クラスターテンプレートを使用する高可用性Kubernetesオペレーターです。
これらのオプションは、企業対応のインフラストラクチャとクラウドネイティブコンピューティング基盤のベストプラクティスをサポートするのに役立ちます。
次のステップ
Kubernetes 上にシンプルな PostgreSQL インスタンスをデプロイしたので、次は監視とログの統合に進む準備が整いました。Sumo Logic のようなツールは高度な Kubernetes 監視をサポートし、クラスターリソースの管理、Kubernetes Pod からのログ分析、クラウドネイティブアプリケーションの可観測性の確保を支援します。デフォルトでは、クレームが削除されるとボリュームも削除される場合があります。リクレームポリシーを Retain に設定すると、PVC が削除されてもデータが保持されます。
Sumo Logic が Kubernetes 監視にどのように役立つかをぜひご確認ください。



