
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イメージを使用します。
接続設定とSecretの作成
データベースの資格情報などの機密情報を安全に保存するため、KubernetesのネイティブリソースであるKubernetes Secrets設定を使用します。
Kubernetesは、デフォルトではbase64エンコード形式でSecretの保存を行いますが、これだけでは安全とはいえません。セキュリティ強化のため、静止時の暗号化を有効にします。
すべての設定が完了したら、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というSecretは、KubernetesにSecretsプロバイダを使用してデータを保存するように指示します。これらの値を保存するために使用する必要がある名前は、postgres-secret-configキーの下にあります。最後に提供されているのは、データセクションにSecretとして保存する必要があるキーと値のペアです。
ここでこの設定を適用し、内容が正しく保存されていることを確認します。
❯ 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データの保存用にファイルシステムをマウントすることが、これに対する解決策となります。これらの操作を行うには、次のステップで異なる設定形式を使用します。
- 使用するボリュームのタイプを記述する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のSecrtet設定と永続ボリュームマウントに結合しています。ここで使用したapiVersion: apps/v1のデプロイメント設定では、セレクタやメタデータフィールドなど、かなり多くの行を指定することが求められます。続いて、コンテナイメージとイメージプルポリシーの詳細が追加されています。これらはすべて、コンテナに適切なボリュームとSecretが使用されていることを確認するために必要となります。
次にこれを適用し、デプロイメントが利用可能かつ正常であることを確認します。
❯ 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サーバーを公開するためのサービスの作成
PostgreSQLポッドの公開には、Kubernetesサービスを使用します。これを行うには、別のポートを設定するか、NodePortまたはLoadBalancerを公開します。わかりやすいように、ここではノードのIP上のサービスを静的ポートで公開するNodePortの使用方法を説明します。
次のサービスマニフェストが使用可能です。
> 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デプロイメント:Bitnamiは、複数タイプのデプロイメント(Kubernetesコミュニティが管理するパッケージマネージャであるHelmを含む)と、大規模デプロイメントのための設定オプションを多数サポートします。
- Zalando PostgreSQLオペレーター:Patroniベースの既存クラスターテンプレートを使用する高可用性Kubernetesオペレーターです。
これらのオプションは、企業対応のインフラストラクチャとクラウドネイティブコンピューティング基盤のベストプラクティスをサポートするのに役立ちます。
次のステップ
Kubernetes上にシンプルなPostgreSQLインスタンスをデプロイしたことで、監視とログ記録を統合する準備が整いました。Sumo Logicなどのツールは、高度なKubernetes監視をサポートすることで、クラスターリソースの管理や、Kubernetesポッドのログ分析、クラウドネイティブアプリケーションにおける可観測性の確保を支援します。デフォルトでは、要求が削除されるとボリュームも削除されます。再要求ポリシーを「保持」に設定することで、PVCの削除後もデータをそのまま保持することができるようになります。
こちらより、Sumo LogicがKubernetesの監視にどのように役立つかをご覧ください。


