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 のリソースを管理するをご覧ください。また、水平 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 とデータ レプリケーションをサポートするストレージを使用する

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

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

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

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

最後に、ディスクの 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 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 停止予算を定義する
  • HA データ レプリケーション機能を使用する
  • アプリケーションの状態を外部化する

次のステップ