1. ホーム
  2. docker

KubernetesのPod間でストレージを共有する方法とは?

2023-08-26 06:36:40

質問

私は、新しいアプリケーションのプラットフォームとしてKubernetesを評価しています。今のところ、すべてが非常にエキサイティングに見えます! しかし、私は問題にぶつかっています。私は GCE 上で私のクラスタをホストしており、2 つのポッド (継続的統合サーバーと私のアプリケーション サーバー) 間でストレージを共有するための何らかのメカニズムが必要なのです。kubernetesでこれを行うための最良の方法は何でしょうか?1つのポッドがディスクに書き込む必要がある場合、GCEディスクは共有できないので、ボリュームタイプはどれも私のニーズに合わないようです。NFSは完璧ですが、kubernetesクラスタのための特別なビルドオプションが必要なようです。

EDIT: ストレージの共有は、Kubernetes を使用して今までに何度も遭遇している問題のようです。1つのボリュームを持ち、それを複数のポッドにフックしたい(書き込みアクセス可能な)ユースケースが複数存在します。これは一般的なユースケースであるとしか思えませんが、違いますか?

EDIT2: 例えば このページ には Elasticsearch クラスタのセットアップ方法が書かれていますが、それを永続記憶装置で配線するのは不可能です ( にあるように で説明されているように)不可能であり、無意味なものです :(

どのように解決するのですか?

まず、あなたは 本当に は複数のリーダ/ライタが必要なのでしょうか?

Kubernetes / マイクロサービスアーキテクチャ (MSA) の私の経験では、問題はしばしばデザインパターンに関連しています。MSA の基本的なデザイン パターンの 1 つは、サービスの適切なカプセル化であり、これには各サービスが所有するデータも含まれます。

OOP と同じように、サービスはその関心領域に関連するデータの世話をし、インターフェイスを介して他のサービスにこのデータへのアクセスを許可する必要があります。このインターフェースは、API、直接または仲介サービス経由で処理されるメッセージ、またはプロトコルバッファとgRPCを使用することができます。一般に、データへのマルチサービスアクセスは、OOPやほとんどのプログラミング言語におけるグローバル変数と同様のアンチパターンです。

例として、ログを書きたい場合、各サービスがログに必要な関連データで呼び出すことができるログサービスを用意する必要があります。共有ディスクに直接書き込むことは、ログ ディレクトリ構造を変更したり、特定の種類のエラーに電子メールを送信するような追加機能を決定した場合、すべてのコンテナーを更新する必要があることを意味します。

ほとんどの場合、ファイルシステムを使用する前に、何らかの形で最小限のインターフェイスを使用する必要があります。 ハイラムの法則 の意図しない副作用を避けることができます。サービス間の適切なインターフェイスや契約がなければ、保守可能で回復力のあるサービスを構築する能力が大きく損なわれます。

OK、あなたの状況はファイル システムを使用して解決するのが最善です。多くのオプションがあります...

複数の同時書き込みを処理できるファイルシステムが、より「伝統的な」MSA 形式の通信よりも優れたソリューションを提供する場合があることは明らかです。Kubernetes は多数のボリューム タイプをサポートしており、以下のものを見つけることができます。 ここで . このリストは非常に長いのですが、これらのボリュームタイプの多くは、複数のライター(別名 ReadWriteMany Kubernetesではと呼ばれます)をサポートしていません。

をサポートしているボリュームタイプは ReadWriteMany この表 で、執筆時点では、AzureFile、CephFS、Glusterfs、Quobyte、NFS、PortworxVolumeがあります。

また、人気の高い rook.io などの演算子も強力で素晴らしい機能を提供していますが、シンプルなソリューションを求めて前進し続ける場合、このようなシステムの学習曲線は難しいものになります。

最もシンプルなアプローチ

私の経験では、最良の初期オプションは NFS です。に関する基本的な考え方を学ぶには最適な方法です。 ReadWriteMany Kubernetes ストレージに関する基本的な考え方を学ぶには最適で、ほとんどのユースケースに対応でき、実装が最も簡単です。マルチサービス パーシステンスの実用的な知識を構築した後、実装に多くの作業を必要とする、より機能豊富なオファリングを使用するための、より多くの情報に基づいた意思決定を行うことができます。

NFS を設定するための詳細は、クラスタがどのように、どこで動作しているか、また、NFS サービスの仕様によって異なりますが、私は以前、NFS を オンプレミスクラスター とAWSのNFSに相当する EKSクラスタ上のEFS . この2つの記事は、特定の状況下でどのように異なる実装が可能であるかについて、良い対比を与えてくれます。

最小限の例では、まず NFS サービスが必要です。簡単なテストを行いたい場合、または SLO の要件が低い場合は、次のようにします。 このDOの記事 は、Ubuntu上でNFSをセットアップするための素晴らしい入門書です。NFS を提供し、クラスタからアクセス可能な既存の NAS がある場合、これも同様に機能します。

NFS サービスがあれば、次のような永続ボリュームを作成することができます。

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-name
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  nfs:
    server: 255.0.255.0 # IP address of your NFS service
    path: "/desired/path/in/nfs"

ここでの注意点は、NFS を使用するためにはノードにバイナリをインストールする必要があることです。 オンプレミスクラスター の記事で詳しく説明しています。これはまた、あなたが が必要です。 を使用する理由でもあります。

永続的なボリュームを設定したら、他のボリュームと同じように使用するのは簡単なケースです。

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-name
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
        - name: p-name
          volumeMounts:
            - mountPath: /data
              name: v-name
      volumes:
        - name: v-name
          persistentVolumeClaim:
            claimName: pvc-name