OpenShift での高可用性のベスト プラクティス


このドキュメントでは、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 のリソースを管理するをご覧ください。また、HorizontalPodAutoscaler を使用して、CPU、メモリ、またはカスタム指標に基づいてレプリカを自動的にスケールアップまたはスケールダウンすることもできます。

次のロード バランシング サービスを使用することをおすすめします。

  • OpenShift Ingress オペレーター。Ingress オペレーターは、HAProxy ベースの Ingress コントローラをデプロイして、Pod へのルーティングを処理します。特に、Ingress コントローラにグローバル アクセスを構成することをおすすめします。これにより、ロードバランサと同じ VPC ネットワークとリージョン内の任意のリージョンのクライアントが、クラスタで実行されているワークロードにアクセスできるようになります。また、Ingress コントローラ ヘルスチェックを実装して、Pod の状態をモニタリングし、失敗した Pod を再起動することをおすすめします。
  • Google Cloud ロード バランシング。ロード バランシングは、Google Cloud ゾーンにトラフィックを分散します。アプリケーションのニーズを満たすロードバランサを選択します。

Pod Disruption Budget を定義する

停止予算を定義して、メンテナンス イベントや更新などの停止中にアプリケーションで使用可能にする必要がある 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 とデータ レプリケーションをサポートするストレージを使用する

コンテナの外部に永続データ ストレージが必要なステートフル ワークロードの場合は、次のベスト プラクティスをおすすめします。

ディスクのベスト プラクティス

ディスク ストレージが必要な場合は、次のいずれかを使用します。

ストレージ オプションを選択したら、そのドライバをクラスタにインストールします。

CSI Persistent Disk オペレーターは、Persistent Volume Claim(PVC)の作成に使用できるストレージ クラスを提供します。Filestore の場合は、Filestore ストレージ クラスを作成する必要があります。

データベースのベスト プラクティス

データベースが必要な場合は、次のいずれかを使用します。

  • フルマネージド データベース: Cloud SQL または AlloyDB for PostgreSQL を使用して、データベース HA を管理することをおすすめします。Cloud SQL を使用している場合は、Cloud SQL Proxy Operator を使用して、アプリケーションとデータベース間の接続管理を簡素化できます。
  • セルフマネージド データベース: HA をサポートするデータベースを使用し、そのオペレーターをデプロイして HA を有効にすることをおすすめします。詳細については、データベース オペレーター(Redis Enterprise for KubernetesMariaDB OperatorCloudNative 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 Disruption Budget を定義する
  • HA データ レプリケーション機能を使用する
  • アプリケーションの状態を外部化する

次のステップ