DUICUO

Kubernetesのデータ永続性管理についてお話しましょう


ステートフル アプリケーションのデータ ストレージをより適切にサポートするために、Kubernetes は、HostPath と EmptyDir によって提供される基本的なデータ永続化ソリューションに加えて、ストレージ管理用の PV、PVC、および StorageClass リソース オブジェクトを提供します。

PVはPersistent Volume(永続ボリューム)の略で、基盤となるデータストレージを抽象化したものです。PVは管理者によって作成、保守、構成されます。PVはCeph、NFS、ClusterFSといった基盤となるデータストレージ実装方法と関連しており、共有ストレージとのインターフェースとなるプラグインメカニズムによって完結します。

PVCはPersistent Volume Claim(永続ボリューム要求)の略です。PVは、基盤となるデータストレージをカプセル化するインターフェースと考えることができます。PVCはインターフェースを呼び出してデータストレージ操作を実行します。PVCはPVのリソースを消費します。

StorageClassは、高速ストレージや低速ストレージなど、ストレージデバイスの様々なニーズに対応するように設計されています。StorageClassを定義することで、管理者はストレージデバイスを特定のリソースタイプとして定義できます。ユーザーはStorageClassの記述に基づいて、様々なストレージリソースの具体的な特性を直感的に理解できるため、アプリケーションの特性に応じて適切なリソースを適用できます。

ストレージシステムのインストール

NFS、Ceph、GlusterFS、FastDFSなど、様々なストレージシステムから選択できます。どのシステムを使用するかは、企業のニーズによって異なります。ここではNFSを使用し、そのインストール方法について簡単に説明します。

1. 設置サービス

 $ yum install nfs - utils rpcbind - y

2.共有ディレクトリを作成する

 $ mkdir /data/k8s -p

3. NFS設定ファイルを構成する

 $ vim /etc/exports
/data/k8s *(rw、同期、ルートスカッシュなし)

4. サービスを開始する

 $ systemctl rpcbind を起動します
$ systemctl nfs を起動する
$ systemctl rpcbind を有効にする
$ systemctl nfs を有効にする

5. テスト

 $ ショーマウント -e 192.168.205.128
192.168.205.128 のエクスポート リスト:
/データ/k8s *

PS: すべてのノードに NFS クライアントがインストールされている必要があります。

PV

PV (永続ボリューム) は、管理者が事前に構成することも、StorageClass を通じて動的にプロビジョニングすることもできる Kubernetes ストレージ デバイスです。

PVはクラスターリソースです。`kubectl explain pv`コマンドを使用すると、PVの構成を確認できます。構成には、主にストレージ容量、アクセスモード、ストレージタイプ、リサイクル情報などの重要な情報が含まれます。例えば、以下のようになります。

 apiバージョン: v1
種類: 永続ボリューム
メタデータ
名前my - pv01
ラベル:
ストレージPV
仕様:
アクセスモード:
- 一度だけ読み書き可能
容量
ストレージ: 1 Gi
persistentVolumeReclaimPolicy : リサイクル
NFS :
パス: / data / k8s
サーバー: 192.168.205.128

パラメータの説明:

1. accessMode: アクセスモード(ReadWriteOnce、ReadOnlyMany、ReadWriteMany など)。

  • ReadWriteOnce: 読み取りおよび書き込み権限があるが、ノードによってマウントできるのは 1 回だけであることを示します。
  • ReadOnlyMany: デバイスに読み取り専用権限があり、複数のノードによって複数回マウントできることを示します。
  • ReadWriteMany: 読み取りおよび書き込み権限があり、複数のノードによって複数回マウントできることを示します。

2. 容量: 永続ボリュームのリソースと容量の説明。設定または要求できるリソースはストレージサイズのみです。

3. persistentVolumeReclaimPolicy: これは再利用ポリシー、つまり永続ボリュームの解放ポリシーです。以下の内容が含まれます。

  • 保持:データを保持します。データをクリーンアップする必要がある場合は、手動で行う必要があります。これがデフォルトの戦略です。
  • 削除: これにより、Kubernetes から PV オブジェクトが削除され、AWS EBS、GCE PD、Azure ディスク、Cinder ボリュームなどの外部インフラストラクチャ内の関連ストレージ アセットも削除されます。
  • リサイクル: PV 内のすべてのデータを回収してクリアします。これは、「rm -rf /pv-volume/*」を実行するのと同じです。

作成後の PV のステータスは次のようになります。

 $ kubectl でPV を取得
名前容量アクセスモード回収ポリシーステータス請求ストレージクラス理由年齢
my - pv01 1 Gi RWO リサイクル可能5

$ kubectl pv01 記述します
名前my - pv01
ラベル: ストレージ= pv
注釈: <なし>
ファイナライザー: [ kubernetes . io / pv - protection ]
ストレージクラス:
ステータス: 利用可能
請求
回収ポリシーリサイクル
アクセスモード: RWO
ボリュームモード: ファイルシステム
容量1 ギガ
ノードアフィニティ: <なし>
メッセージ
ソース
タイプ: NFS (ポッド存続期間持続するNFS マウント)
サーバー: 192.168.205.128
パス: / data / k8s
読み取り専用: false
イベント: <なし>

現在のPVステータスは「利用可能」で、いつでも使用可能です。PVには合計4つのステータスがあります。

  • 使用可能: デバイスが使用可能であり、まだどの PVC にもバインドされていないことを示します。
  • バインド: PVC が別の PVC にバインドされていることを示します。
  • 解放済み: PVC は削除されましたが、リソースはまだクラスターによって再宣言されていません。
  • 失敗: この PV の自動リサイクルが失敗したことを示します。

PV を作成しただけでは直接使用することはできません。要求を行うには PVC (Persistent Volume Claim) を使用する必要があります。

PVC

PVC(Persistent Volume Claim)は、ユーザーのストレージニーズを表現するために使用されます。PVCを要求すると、PVリソースが消費されます。ヘルプドキュメントは、kubectl explain pvc でご覧いただけます。

前のセクションではPVを作成しました。次に、以下のようにPVCを宣言する必要があります。

 apiバージョン: v1
種類: PersistentVolumeClaim
メタデータ
名前: PVC - テスト
仕様:
アクセスモード:
- 一度だけ読み書き可能
リソース
リクエスト:
ストレージ: 1 Gi

仕様パラメータの説明:

1. accessModes: 主にボリュームのアクセス モードを定義します。

2. リソース: 主にボリュームに必要な最小限のリソースを定義します。

3. dataSource: プロバイダーがボリューム スナップショット機能を持っている場合にボリュームを作成し、そこにデータを復元するかどうかを定義します。そうでない場合は、ボリュームを作成しません。

4. セレクター: バインドされたボリュームのタグ クエリを定義します。

5. storageClassName: 定義されたストレージクラスの名前

6. volumeMode: ボリュームの種類を定義します。

7. volumeName: バインドする PV の名前とリンク。

作成後、以下に示すように PV と PVC のステータスを確認します。

 $ kubectl でPVC を取得する
名前ステータスボリューム容量アクセスモードストレージクラス 年齢
pvc - テストバウンドマイ- pv01 1 Gi RWO 2 s
$ kubectl でPV を取得
名前容量アクセスモード回収ポリシーステータス請求ストレージクラス理由年齢
my - pv01 1 Gi RWO リサイクルバウンドデフォルト/ pvc - テスト20 m

上記のように、PVCはBound状態にあり、BoundされたVOLUMEはmy-pv01です。その後、PVの状態がAvailableからBoundに変わり、CLAIMはdefault/pvc-testになります(defaultは名前空間名です)。

上記では、作成したPVにバインドされたPVCを作成しました。ここで別のPVCを作成するとどうなるでしょうか?上記のPVCファイルをコピーし、以下のように名前を変更してみましょう。

 apiバージョン: v1
種類: PersistentVolumeClaim
メタデータ
名前: pvc - test2
仕様:
アクセスモード:
- 一度だけ読み書き可能
リソース
リクエスト:
ストレージ: 1 Gi

次に、次のように PVC のステータスを確認します。

 $ kubectl でPVC を取得する
名前ステータスボリューム容量アクセスモードストレージクラス年齢
pvc - テストバウンドマイ- pv01 1 Gi RWO 3 m57s
PVC - テスト2 4 保留

先ほど作成した pvc-test2 のステータスが Pending 状態になっていることがわかります。これは、クラスター内で宣言されたすべての PV が使い果たされ、PVC が要求時に適切な PV を見つけられなかったため、この状態になっているためです。要件を満たす新しい PV を作成すると、この PVC は Bound 状態になります。以下を参照してください。

 $ kubectl でPV を取得
名前容量アクセスモード回収ポリシーステータス請求ストレージクラス理由年齢
my - pv01 1 Gi RWO リサイクルバウンドデフォルト/ pvc - テスト27 m
my - pv02 1 Gi RWO リサイクル可能5
$ kubectl でPVC を取得する
名前ステータスボリューム容量アクセスモードストレージクラス 年齢
pvc - テストバウンドマイ- pv01 1 Gi RWO 6 m50s
pvc - test2 バウンドマイ- pv02 1 Gi RWO 2 m57s

PVCはPVに任意に適用することはできません。以下の要件を満たす必要があります。(1) PVC適用モードはPVの適用モードと一致している必要があります。例えば、PVCモードがReadWriteOnceでPVモードがReadWriteManyの場合、適用は成功しません。(2) PVC適用容量はPVの容量以下である必要があります。そうでない場合、適用は成功しません。(3) PVは1つのPVCにのみバインドできます。

さらに、PVC 容量要件が利用可能な PV 容量より少ない場合、バンドルされた容量が利用可能な PV 容量になります。

ストレージクラス

前述のPVモードとPVCモードでは、まず運用担当者がPVを作成し、次に開発者が1対1のボンディングを行うためのPVCを定義する必要があります。しかし、PVCリクエストが数万件に達すると、数万個のPVを作成する必要があり、運用担当者にとって非常に大きなコストがかかります。Kubernetesは、PV作成のテンプレートとして機能するStorageClassと呼ばれるPVを自動作成する仕組みを提供しています。

具体的には、StorageClass は次の 2 つの部分を定義します。

  1. ストレージのサイズやタイプなどの PV 属性。
  2. このような PV を作成するには、Ceph などのストレージ プラグインが必要です。

これら 2 つの情報を使用して、Kubernetes はユーザーが送信した PVC に基づいて対応する StorageClass を見つけ、StorageClass によって宣言されたストレージ プラグインを呼び出して必要な PV を作成します。

ここではNFSを例に挙げます。NFSを使用するには、nfs-client用のオートローダー(ここではProvisionerと呼びます)が必要です。このプログラムは、既に設定済みのNFSサーバーを使用して永続ボリューム(PV)を自動的に作成します。つまり、PVを自動的に作成してくれるのです。注:

  • 自動的に作成された PV は、NFS サーバー上のディレクトリ形式 {pvcName}-${pvName} に配置されます。
  • この PV がリサイクルされると、NFS サーバーに archieved-{pvcName}-${pvName} の形式で保存されます。

NFSプロビジョナーをインストールする

1. ServiceAccount を作成し、NFS Provisioner を承認します。

 ---
apiバージョン: v1
種類: サービスアカウント
メタデータ
名前: nfs - クライアント- プロビジョナー

---
api バージョン: rbac.authorization.k8s.io/v1
種類: ClusterRole
メタデータ
名前: nfs - クライアント- プロビジョナー- クラスタロール
ルール
- apiグループ: [ "" ]
リソース: [ "persistentvolumes" ]
動詞: [ 「取得」「一覧表示」「監視」「作成」「削除」 ]
- apiグループ: [ "" ]
リソース: [ "persistentvolumeclaims" ]
動詞: [ 「取得する」「一覧表示する」「監視する」「更新する」 ]
- apiGroups : [ "storage.k8s.io" ]
リソース: [ "ストレージクラス" ]
動詞:[ 「取得する」「リストする」「見る」 ]
- apiグループ: [ "" ]
リソース: [ "イベント" ]
動詞: [ 「リスト」「ウォッチ」「作成」「更新」「パッチ」 ]
- apiグループ: [ "" ]
リソース: [ "エンドポイント" ]
動詞: [ 「作成」「削除」「取得」「一覧表示」「監視」「パッチ」「更新」 ]
---
api バージョン: rbac.authorization.k8s.io/v1
種類: ClusterRoleBinding
メタデータ
名前: nfs - クライアント- プロビジョナー- クラスターロールバインディング
科目
- 種類: サービスアカウント
名前: nfs - クライアント- プロビジョナー
名前空間: デフォルト
ロールリファレンス:
種類: ClusterRole
名前: nfs - クライアント- プロビジョナー- クラスタロール
apiGroup : rbac.authorization.k8s.io

2. NFSプロビジョナーを作成する

 ---
apiバージョン: アプリ/ v1
種類: デプロイメント
メタデータ
名前: nfs - クライアント- プロセッサー
仕様:
レプリカ1
戦略
タイプ: 再作成
セレクター:
マッチラベル
アプリ: nfs - クライアント- プロセッサー
テンプレート
メタデータ
ラベル:
アプリ: nfs - クライアント- プロセッサー
仕様:
serviceAccountName : nfs - クライアント- プロビジョナー
コンテナ
- 名前: nfs - クライアント- プロセッサー
イメージ: registry . cn - hangzhou . aliyuncs . com / rookieops / nfs - client - provisioner : 4.0
imagePullPolicy : IfNotPresent
ボリュームマウント:
- 名前: nfs - クライアント- ルート
マウントパス: / data / pv
環境:
- 名前: PROVISIONER_NAME
価値ルーキーオプス/ NFS
- 名前: NFS_SERVER
: 192.168 .205 .128
- 名前: NFS_PATH
: / データ/ k8s
巻数:
- 名前: nfs - クライアント- ルート
NFS :
サーバー: 192.168.205.128
パス: / data / k8s

実行後、次のように NFS プロビジョナーのステータスを確認します。

 $ kubectl でpo を取得
名前準備完了ステータス再起動年齢
nfs - クライアント- プロセッサー- 54 d64dfc85 - b4ht4 1 / 1 実行中0 10

StorageClassを使用する

NFSプロビジョナーはすでに作成されています。これで、以下のようにStorageClassを直接作成できます。

 api バージョン: storage.k8s.io/v1  
種類: ストレージクラス
メタデータ
名前: nfs
プロビジョナールーキーオプス/ NFS

各 StorageClass には、StorageClass が PersistentVolume を動的に割り当てる必要があるときに使用される provisioner、parameters、および reclaimPolicy フィールドが含まれています。

StorageClass を設定する際に reclaimPolicy が指定されていない場合、デフォルトは Delete です。また、Retain もあります。

StorageClassオブジェクトの命名は重要です。ユーザーはこの名前を使用して、特定のクラスの生成を要求します。StorageClassオブジェクトが作成されると、管理者はその名前とその他のパラメータを設定します。一度作成されると、オブジェクトは更新できません。

`kubectl apply -f sc.yaml` を使用して StorageClass を作成します。結果は次のようになります。

 $ kubectl でsc を取得する
名前プロビジョナーRECLAIMPOLICY ボリュームバインドモードALLOWVOLUMEEXPANSION 年齢
nfs rookieops / nfs 即時削除false 9 分 41 秒

次のように、動的ストレージを使用して PVC を要求できるようになりました。

 apiバージョン: v1
種類: PersistentVolumeClaim
メタデータ
名前: pvc - from - sc
仕様:
アクセスモード:
- 一度だけ読み書き可能
ストレージクラス名: nfs
リソース
リクエスト:
ストレージ: 1 Gi

以下に示すように、`kubectl apply -f pvc-from-sc.yaml` を使用して PVC の作成ステータスを確認します。

 $ kubectl でPVC を取得する
名前ステータスボリューム容量アクセスモードストレージクラス年齢
pvc - from - sc バウンドpvc - a4a71b8c - 5664 - 4 d1a - b286 - 9e4 adcf6f96a 1 Gi RWO nfs 8 s
$ kubectl でPV を取得
名前容量アクセスモード回収ポリシーステータス請求ストレージクラス理由年齢
pvc - a4a71b8c - 5664 - 4 d1a - b286 - 9e4 adcf6f96a 1 Gi RWO 削除バインドされたデフォルト/ pvc - from - sc nfs 86 s

PV が自動的に作成され、PVC にバインドされたことがわかります。

使いやすさを考慮して、クラスターにデフォルトのStorageClassが設定されている場合があります。これにより、必要に応じてデフォルトの動的ストレージを使用できるようになり、宣言する必要はありません。設定方法は次のとおりです。

 $ kubectl patch ストレージクラスnfs - p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

`@storageclass.kubernetes.io/is-default-class` アノテーションを追加することで、特定の StorageClass をデフォルトとしてマークできます。クラスター内にデフォルトの StorageClass が存在し、ユーザーが storageClassName を指定せずに PersistentVolumeClaim を作成すると、DefaultStorageClass アドミッションコントローラは、デフォルトのストレージクラスを指す storageClassName フィールドを自動的に追加します。

クラスター上に存在できるデフォルトのストレージ クラスは 1 つだけであることに注意してください。そうでない場合、storageClassName を明示的に指定しないと PersistentVolumeClaim を作成することはできません。

デフォルトの StorageClass を無効にするには、次のようにアノテーションを false に設定するだけです。

 $ kubectl patch ストレージクラスnfs - p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

Pod で PVC を使用する場合は、次のように直接宣言できます。

 apiバージョン: v1
種類: ポッド
メタデータ
名前: nginx
仕様:
コンテナ
- 名前: nginx
画像: nginx
imagePullPolicy : IfNotPresent
ボリュームマウント:
- 名前: nfs - pvc
マウントパス: / mnt
再起動ポリシー: なし
巻数:
- 名前: nfs - pvc
永続ボリュームクレーム:
クレーム名: pvc - from - sc

コンテナに入り、マウント ディレクトリに出力できます。次に例を示します。

 $ kubectl exec -it nginx -- / bin / bash
ルート@nginx : / mnt # echo "test" > / mnt / text .txt

次に、対応する NFS ディレクトリをチェックして、一致しているかどうかを確認します。

 $ cd / data / k8s / default - pvc - from - sc - pvc - a4a71b8c - 5664-4d1a - b286-9e4 adcf6f96a
$ cat テキスト. txt
テスト

これは、ポッドが永続性を正常に使用したことを示します。

要約

Kubernetesではステートレスアプリケーションの使用を推奨していますが、一部の特殊なアプリケーションではデータの永続性が依然として不可欠です。データの永続性確保の難しさは、少数のPVやPVCを作成することではなく、Cephなどのバックエンドストレージシステムにあります。バックエンドストレージとしてCephを使用する場合は、問題発生時のトラブルシューティングを容易にするために、Cephに精通している必要があります。これらのストレージシステムに精通していない場合、使用時に多くの問題が発生する可能性があります。