ポイント: KubernetesでPostgreSQLをStatefulSetとしてデプロイすることで、永続ストレージとユニークなポッドIDを提供し、ステートフルアプリケーションの効率的な管理が可能になります。これにより、順序付きのデプロイメント、スケーリング、およびConfigMapsを通じた環境変数の管理が簡素化されます。
- StatefulSetsは、ステートフルアプリケーションの順序付きデプロイメントとスケーリングを可能にします。
- ConfigMapsを利用することで、デプロイメントにおける環境変数の管理が簡素化されます。
アプリケーションには、単一の大きなアプリケーションからマイクロサービスベースのアプリケーションまで、さまざまな種類があります。それらのアプリケーションの状態に関しては、2つの状態があります:
- ステートレスアプリケーションは、過去のトランザクションについての知識がなく、独立して隔離して実行できます。
- ステートフルアプリケーションは、過去の情報(状態)についての完全な知識を持っています。
私たちが使用するアプリケーションのほとんどはステートフルアプリケーションであり、その状態データはユーザーの好み、最近の活動、データベーストランザクション、資格情報、設定などで構成される可能性があります。
Kubernetesは、Kubernetesクラスター内でステートフルアプリケーションを作成する際にStatefulSetsを提供します。コンテナ化された環境内で状態を管理することは、Kubernetesでデータベースクラスターをデプロイする人気が高まる中、さらに重要になっています。
この記事では、StatefulSetsを使用してKubernetesクラスター上にPostgreSQLデータベースをデプロイする方法に焦点を当てます。
Kubernetes StatefulSetsとは?
StatefulSetは、ステートフルアプリケーションを管理するために使用できるKubernetesワークロードAPIオブジェクトです。
通常のデプロイメントでは、ユーザーはポッドがどのようにスケジュールされるかを気にしませんが、デプロイされたアプリケーションに悪影響を与えなければ問題ありません。しかし、永続ストレージを持つステートフルアプリケーションでは、状態を保持するためにポッドを適切に特定する必要があります。
StatefulSetは、再スケジュールに関係なくその値に関連する永続的な識別子を持つポッドを作成することによって、この機能を提供します。このようにして、ポッドが再作成されても、ストレージボリュームに正しくマッピングされ、アプリケーションの状態が保持されます。
StatefulSetsのユースケース
StatefulSetsには、いくつかのユースケースがあります。
順序付きのデプロイとスケーリング
アプリケーションが複数のコンテナに依存する場合、順序付きのスケーリングアプローチは、デプロイメントとスケーリングシナリオで依存するコンテナが秩序正しく作成されることを保証します。
順序付きの自動ローリングアップデート
依存するアプリケーションやマイクロサービスを更新する際にも、秩序正しく更新される必要があります。さらに、更新は機能に影響を与えてはなりません。
そのため、ユーザーはStatefulSetを使用して、アプリケーションやマイクロサービスの更新順序を決定できます。
永続ストレージのマッピング
データベースを考慮する場合、永続ストレージはアプリケーションがデータを保存するために非常に重要です。StatefulSetを使用すると、ユーザーは:
- 各永続ストレージに対応するポッドを定義する
- 回復力のあるアプリケーションデプロイメントを作成する
固有のネットワーク識別子を使用して永続的なネットワーク接続を作成する
固有の識別子を使用すると、ネットワークユーザーは再スケジュール時にIP変更を気にせず特定のポッドへのトラフィックを管理およびルーティングできます。これにより、ポッド間のネットワーク通信を制御する能力が向上し、望ましいポッド用に永続的なルーティング、ポリシー、およびセキュリティ設定を構成することができます。
これらの利点があるにもかかわらず、StatefulSetsはすべての要件に対するソリューションを提供するわけではありません。たとえば、StatefulSetsはデプロイメントやReplicaSetsと交換可能ではありません。これらは代わりにステートレス構成を目指しています。
StatefulSetsの欠点
StatefulSetsには、アプリケーションをデプロイする前にユーザーが認識しておくべき制限がいくつかあります。
- StatefulSetのストレージは、ストレージクラスに基づくPersistentVolumeプロビジョナーによってプロビジョニングされる必要があるか、あらかじめプロビジョニングされる必要があります。
- ポッドをスケーリングまたは削除しても、データの安全性を確保するために基盤となる永続ストレージには影響しません。プロビジョニングされたボリュームはKubernetes内に残ります。
- ユーザーは、StatefulSetsのネットワークアイデンティティを確保するためにヘッドレスサービスを手動で作成する必要があります。
- StatefulSetが削除されるときに、現在のポッドが終了することは保証されません。したがって、ベストプラクティスとして、ユーザーはStatefulSetをゼロポッドにスケールダウンしてから削除するためのSOPを実装することをお勧めします。
- デフォルトのポッド管理ポリシーでのローリングアップデートは、ポッドが破損した場合(アプリケーション設定エラー、不良バイナリなど)にデプロイ時に問題を引き起こす可能性があります。このような場合、ユーザーは:
- 以前のデプロイメントテンプレートに手動で戻す必要があります。
- 新しい更新を再実行する前に、壊れたポッドを削除する必要があります。
KubernetesクラスターでStatefulSetを設定する
StatefulSetの基本的な理解が得られたので、サンプルのStatefulSetデプロイメントを見てみましょう。
StatefulSetsはデータベースデプロイメントに最適です。この例では、永続ストレージボリュームを持つStatefulSetとしてPostgreSQLデプロイメントを作成します。
postgresql.yaml
# PostgreSQL StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-db
spec:
serviceName: postgresql-db-service
selector:
matchLabels:
app: postgresql-db
replicas: 2
template:
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: postgresql-db
image: postgres:latest
volumeMounts:
- name: postgresql-db-disk
mountPath: /data
env:
- name: POSTGRES_PASSWORD
value: testpassword
- name: PGDATA
value: /data/pgdata
# Volume Claim
volumeClaimTemplates:
- metadata:
name: postgresql-db-disk
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 25Gi
上記のYAMLファイルでは、PostgreSQLデータベースをデプロイするためのシンプルなStatefulSetを定義しました。replicas: 2の2つのポッドを持つpostgresql-dbという名前のStatefulSetを作成しています。
さらに、volumeClaimTemplateを使用して永続ボリュームを作成し、PostgreSQLデータを格納するためにStatefulSetで使用しています。デフォルトの永続ボリュームプロビジョナーがボリュームをプロビジョニングし、次のコマンドを実行することでデプロイできます。
kubectl apply -f postgresql.yaml
結果:
これで、Kubernetesクラスターの外部に公開するためのサービスが必要なPostgreSQL StatefulSetが正常に作成されました。それは、StatefulSetを指すサービスを作成することによって行うことができます。
postgresql-service.yaml
# PostgreSQL StatefulSet Service
apiVersion: v1
kind: Service
metadata:
name: postgres-db-lb
spec:
selector:
app: postgresql-db
type: LoadBalancer
ports:
- port: 5432
targetPort: 5432
これにより、ロードバランサーが作成され、サービスは「app: postgresql-db」というセレクターを使用してPostgreSQLデータベースを公開します。以下のコマンドを実行することでサービスを作成できます。
kubectl apply -f postgresql-service.yaml
結果:
次に、以下のコマンドを実行して、StatefulSetとサービスの両方がKubernetesで正常に作成されたかどうかを確認しましょう。
kubectl get all
結果:
結果は、2つのポッドが作成され、IP 10.111.253.4を使用してポート5432でStatefulSetを公開するロードバランサーサービスが稼働していることを示しています。
接続性のテスト
PostgreSQLをデプロイしたので、問題なくアクセスできることを確認する必要があります。接続を初期化するためにpgAdmin4クライアントを使用します:
- 環境にpgAdminクライアントをダウンロードします。
- 接続して初期化を試みます。
上記のデプロイメントで、postgres-db-lbサービスの外部IP(10.111.253.4)をポート5432で使用します。PostgreSQL StatefulSetの環境変数でパスワードのみを定義したため、構成には定義したパスワードで「postgres」というデフォルトのユーザー名が含まれます。
すべての詳細が正しければ、「保存」をクリックすると接続が開始され、ユーザーは接続されたデータベースを見ることができます。
StatefulSetでのConfigMapの使用
前述の例では、StatefulSet YAMLで環境変数を定義しました。
ただし、最良のプラクティスは、環境変数をConfigMapsを使用して分離し、StatefulSetデプロイメントからConfigMapを呼び出すことです。これにより、デプロイメントの各コンポーネントを管理および維持しやすくなります。
それでは、ConfigMapを作成し、以下のようにStatefulSet YAMLを修正しましょう。
postgresql-configmap.yaml
# PostgreSQL StatefulSet ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-db-config
labels:
app: postgresql-db
data:
POSTGRES_DB: testdb
POSTGRES_USER: testdbuser
POSTGRES_PASSWORD: testdbuserpassword
PGDATA: /data/pgdata
上記のConfigMapでは、PostgreSQLデータベース、ユーザー、パスワード、データストアを指定するために環境変数を拡張しました。次に、このコマンドを使用してconfigMapを作成し、構成を表示しましょう:
kubectl apply -f .postgresql-configmap.yaml
結果:
describe関数を使用して作成されたConfigMapの情報を取得できます:
kubectl describe configmap postgres-db-config
結果:
次のステップは、ConfigMapからデータを呼び出すようにStatefulSetを修正することです。これは、envFromフィールドを使用して上記のConfigMapを指すことによって行うことができます。これにより、ConfigMapのデータを使用してStatefulSetを作成できます。
postgresql.yaml
# PostgreSQL StatefulSet - ConfigMap
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-db
spec:
serviceName: postgresql-db-service
selector:
matchLabels:
app: postgresql-db
replicas: 2
template:
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: postgresql-db
image: postgres:latest
volumeMounts:
- name: postgresql-db-disk
mountPath: /data
# Config from ConfigMap
envFrom:
- configMapRef:
name: postgres-db-config
# Volume Claim
volumeClaimTemplates:
- metadata:
name: postgresql-db-disk
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 25Gi
永続ボリュームを使用すると、基盤となるデータベースの削除は、ポッドのエラーが発生した場合でも保持されます。StatefulSetとして、ポッドの状態も保持され、再作成時に正しいボリュームに割り当てられます。
次のコマンドを使用してポッドを特定できます:
kubectl get pvc
結果:
状態の管理はアプリケーション機能にとって重要
Kubernetes StatefulSetsは、ユーザーがKubernetesクラスター内でステートフルアプリケーションやサービスを簡単に作成および管理できるようにします。しかし、これらのStatefulSets構成にはいくつかの複雑さが伴うため、展開を実施する前に慎重に計画する必要があります。
さらに、StatefulSetsは、データベースアプリケーション、支払いサービスなど、状態を管理することがアプリケーション機能の重要な部分である場合に最適なソリューションです。
Kubernetesガイド
- Kubernetesとは(K8s)?Kubernetes基本チュートリアル
- クラスター効率を向上させるためのKubernetesベストプラクティス
- ベストプラクティス:Kubernetes用のアプリケーションアーキテクチャ
- Kubernetes Pods:入門
- Kubernetes ReplicaSets:簡単な紹介
- Kubernetes Deploymentsの完全な説明
- Kubernetes DaemonSetsの使用と管理
- Kubernetes Servicesの仕組み
- Kubernetes Port、TargetPort、およびNodePortの使用
- KubernetesでのConfigMapsの作成と使用
- Kubernetes Secretsの紹介
- Kubernetesネットワーキングの基本
- Kubernetes Ingressの説明
- Kubernetes Helm Chartsの紹介
- Kubernetesオペレーターパターンとは?
- KubernetesでStatefulSetとしてPostgreSQLをデプロイする
- Kubernetesカスタムリソース定義(CRD)の説明
- クラウドネイティブアプリケーションのための3つのKubernetesパターン
- Kubernetesコンピュートリソースの説明
- DevOpsパイプラインのためのKubernetesセキュリティ
- 継続的デリバリーのためにKubernetesでSpinnakerを使用する
- Kubernetesマルチクラスター:使用方法と理由
- Kubernetesモニタリング:包括的ガイド
- Kubernetes vs Docker:簡単な比較
- Kubernetes vs Docker Swarm:コンテナオーケストレーションツールの比較
- Kubernetes vs OpenShift:違いは何ですか?
- Kubernetes認定:取得方法と理由
これらの投稿は私自身のものであり、必ずしもBMCの立場、戦略、または意見を表すものではありません。