このドキュメントでは、Compute Engine で Red Hat OpenShift Container Platform ワークロードを使用して高可用性(HA)を実現するためのベスト プラクティスについて説明します。このドキュメントでは、障害が発生してもワークロードの高可用性を維持するためのアプリケーション レベルの戦略について説明します。これらの戦略は、単一障害点を排除し、自動フェイルオーバーと復元のメカニズムを実装するのに役立ちます。
このドキュメントは、プラットフォーム アーキテクトとアプリケーション アーキテクトを対象としており、OpenShift のデプロイに関する経験があることを前提としています。OpenShift のデプロイ方法の詳細については、Red Hat のドキュメントをご覧ください。
デプロイを複数のゾーンに分散する
OpenShift は、Google Cloud リージョン内の複数のゾーンにデプロイすることをおすすめします。このアプローチにより、ゾーンで停止が発生した場合でも、クラスタのコントロール プレーンノードは、デプロイが分散されている他のゾーンで引き続き機能します。OpenShift を複数のゾーンにデプロイするには、install-config.yaml
ファイルで同じリージョンのゾーンのリストを指定します。 Google Cloud
ノードのデプロイ場所をきめ細かく制御するには、VM が同じゾーンの異なる障害発生ドメインに分散されるように VM プレースメント ポリシーを定義することをおすすめします。クラスタノードにスプレッド プレースメント ポリシーを適用すると、ロケーション固有の中断によって同時に影響を受けるノードの数を減らすことができます。既存のクラスタにスプレッド ポリシーを作成する方法については、スプレッド プレースメント ポリシーを作成して VM に適用するをご覧ください。
同様に、複数の Pod が同じノードにスケジュールされないようにするには、Pod の反アフィニティ ルールを使用することをおすすめします。これらのルールにより、アプリケーションのレプリカが複数のゾーンに分散されます。次の例は、Pod アンチアフィニティ ルールを実装する方法を示しています。
apiVersion: apps/v1 kind: Deployment metadata: name: my-app namespace: my-app-namespace spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: # Pod Anti-Affinity: Prefer to schedule new pods on nodes in different zones. affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app: my-app topologyKey: topology.kubernetes.io/zone containers: - name: my-app-container image: quay.io/myorg/my-app:latest ports: - containerPort: 8080
ウェブ フロントエンドや REST API などのステートレス サービスの場合は、サービスまたはルートごとに複数の Pod レプリカを実行することをおすすめします。このアプローチにより、トラフィックが利用可能なゾーンの Pod に自動的にルーティングされます。
リソースの過剰コミットメントを防ぐために負荷を事前に管理する
リソースの過剰コミットメントを防ぐため、アプリケーションの負荷を事前に管理することをおすすめします。過剰なコミットメントは、負荷がかかったときにサービスのパフォーマンスが低下する可能性があります。リソース リクエストの上限を設定することで、オーバーコミットメントを防ぐことができます。詳細については、Pod のリソースを管理するをご覧ください。また、水平 Pod オートスケーラーを使用して、CPU、メモリ、カスタム指標に基づいてレプリカを自動的にスケールアップまたはスケールダウンすることもできます。
また、次のロード バランシング サービスを使用することをおすすめします。
- OpenShift Ingress オペレーター。Ingress オペレーターは、HAProxy ベースの Ingress コントローラをデプロイして、Pod へのルーティングを処理します。特に、Ingress コントローラにグローバル アクセスを構成することをおすすめします。これにより、ロードバランサと同じ VPC ネットワークとリージョン内の任意のリージョンのクライアントが、クラスタで実行されているワークロードにアクセスできるようになります。また、Ingress コントローラ ヘルスチェックを実装して、Pod の状態をモニタリングし、失敗した Pod を再起動することをおすすめします。
- Google Cloud ロード バランシング。ロード バランシングは、Google Cloud ゾーンにトラフィックを分散します。アプリケーションのニーズを満たすロードバランサを選択します。
Pod 停止予算を定義する
停止予算を定義して、メンテナンス イベントや更新などの停止中にアプリケーションで使用可能にする必要がある Pod の最小数を指定することをおすすめします。次の例は、中断予算を定義する方法を示しています。
apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: my-app-pdb namespace: my-app-namespace spec: # Define how many pods need to remain available during a disruption. # At least one of "minAvailable" or "maxUnavailable" must be specified. minAvailable: 2 selector: matchLabels: app: my-app
詳細については、アプリケーションの停止予算を指定するをご覧ください。
HA とデータ レプリケーションをサポートするストレージを使用する
コンテナの外部に永続データ ストレージが必要なステートフル ワークロードの場合は、次のベスト プラクティスをおすすめします。
ディスクのベスト プラクティス
ディスク ストレージが必要な場合は、次のいずれかを使用します。
- ブロック ストレージ: 同期レプリケーションを備えた Compute Engine リージョン Persistent Disk
- 共有ファイル ストレージ: スナップショットとバックアップが有効な Filestore
ストレージ オプションを選択したら、そのドライバをクラスタにインストールします。
最後に、ディスクの StorageClass
を設定します。
次の例は、StorageClass を設定する方法を示しています。
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: regionalpd-balanced provisioner: PROVISIONER parameters: type: DISK-TYPE replication-type: REPLICATION-TYPE volumeBindingMode: WaitForFirstConsumer reclaimPolicy: Delete allowVolumeExpansion: true allowedTopologies: - matchLabelExpressions: - key: topology.kubernetes.io/zone values: - europe-west1-b - europe-west1-a
データベースのベスト プラクティス
データベースが必要な場合は、次のいずれかを使用します。
- フルマネージド データベース: Cloud SQL または AlloyDB for PostgreSQL を使用して、データベース HA を管理することをおすすめします。Cloud SQL を使用している場合は、Cloud SQL Proxy Operator を使用して、アプリケーションとデータベース間の接続管理を簡素化できます。
- セルフマネージド データベース: HA をサポートするデータベースを使用し、そのオペレータをデプロイして HA を有効にすることをおすすめします。詳細については、データベース オペレーター(Redis Enterprise for Kubernetes、MariaDB Operator、CloudNative PostgreSQL Operator など)に関するドキュメントをご覧ください。
データベース オペレータをインストールしたら、複数のインスタンスでクラスタを構成します。次の例は、次の属性を持つクラスタの構成を示しています。
- 高可用性のために 3 つのインスタンスを持つ
my-postgres-cluster
という名前の PostgreSQL クラスタが作成されます。 - クラスタは、ゾーン間で耐久性のある複製ストレージに
regionalpd-balanced
ストレージ クラスを使用します。 mydatabase
という名前のデータベースは、ユーザーmyuser
で初期化されます。このユーザーの認証情報は、my-database-secret
という Kubernetes Secret に保存されます。- セキュリティを強化するため、スーパーユーザーのアクセスは無効になっています。
- クラスタでモニタリングが有効になっている。
apiVersion: postgresql.cnpg.io/v1 kind: Cluster metadata: name: my-postgres-cluster namespace: postgres-namespace spec: instances: 3 storage: size: 10Gi storageClass: regionalpd-balanced bootstrap: initdb: database: mydatabase owner: myuser secret: name: my-database-secret enableSuperuserAccess: false monitoring: enabled: true --- apiVersion: 1 kind: Secret metadata: name: my-database-secret namespace: postgres-namespace type: Opaque data: username: bXl1c2Vy # Base64-encoded value of "myuser" password: c2VjdXJlcGFzc3dvcmQ= # Base64-encoded value of "securepassword"
アプリケーションの状態を外部化する
セッション状態またはキャッシュは、HA モードで実行するように構成された共有インメモリ ストア(Redis など)または永続データストア(Postgres、MySQL など)に移動することをおすすめします。
ベスト プラクティスの概要
要約すると、OpenShift で高可用性を実現するには、次のベスト プラクティスを実装します。
- デプロイを複数のゾーンに分散する
- リソースの過剰コミットメントを防ぐために負荷を事前に管理する
- Pod 停止予算を定義する
- HA データ レプリケーション機能を使用する
- アプリケーションの状態を外部化する