永続ストレージ:ボリューム、PersistentVolume、クレーム
PVC で Pod の再起動をまたいでデータを保持し、StorageClass が各要素をどうつなぐかを理解します。
コンテナのファイルシステムは、コンテナが存続する間しか続きません。Pod が置き換えられると、それが書き込んだものはすべてなくなります。ステートレスな Web サーバーならそれで問題ありませんが、データベース、アップロードされたファイル、その他生き残る必要のあるものにとっては問題です。このガイドでは、Kubernetes が Pod に永続的なストレージをどうアタッチするかを説明します。
コンテナのストレージでは不十分な理由
コンテナは小さく使い捨てであることを意図しているため、データをその中に置くことはモデルに反します。データは、コンテナの外、Pod の外、Pod の起動時に Kubernetes がアタッチするストレージ上に存在する必要があります。そのストレージが何であるかについて、Kubernetes は関知しません。クラウドのディスク、ネットワーク共有、ローカルドライブなどです。また、データのバックアップもしてくれません。それは引き続き、あなたの仕事です。
ストレージの連鎖
4 つのオブジェクトが連携します。
- StorageClass は、ストレージの種類と、それをオンデマンドで作成する方法を記述します(たとえば「クラウドプロバイダーの高速な SSD ボリューム」)。
- PersistentVolume(PV) は、クラスター内の実際のストレージの 1 つの単位です。
- PersistentVolumeClaim(PVC) は、ユーザーまたはアプリケーションによるストレージの要求です。「1 つのノードが読み書きできる 1 GiB が必要」というものです。
- Pod は、そのクレームをボリュームとして参照し、コンテナにマウントします。
コンテナ ─ mountPath ─▶ Pod のボリューム ─▶ PVC ─ バインド ─▶ PV ─▶ 実際のストレージ
▲
StorageClass がオンデマンドで PV を作成
PVC は、正確に 1 つの PV にバインドされます。Pod は PV を決して参照せず、クレームだけを参照します。これが、アプリケーションをストレージの詳細から独立させている仕組みです。
PVC でストレージを要求する
ほとんどのクラスターには、ボリュームをオンデマンドで作成する(動的プロビジョニングと呼ばれる)デフォルトの StorageClass があり、minikube にも含まれています。お使いのものを確認します。
kubectl get storageclass
次に、ストレージを要求します。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
kubectl apply -f pvc.yaml
kubectl get pvc,pv
クレームは Bound になり、対応する PV が現れるはずです。一部のストレージクラスは、Pod が実際にクレームを使うまでボリュームの作成を待つため、この時点での Pending は、必ずしもエラーではありません。
Pod にマウントして、永続性を証明する
apiVersion: v1
kind: Pod
metadata:
name: storage-demo
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: data
ファイルを書き込み、Pod を破棄し、再作成して、ファイルが残っていることを確認します。
kubectl apply -f pod.yaml
kubectl exec storage-demo -- sh -c 'echo persisted > /data/proof.txt'
kubectl delete pod storage-demo
kubectl apply -f pod.yaml
kubectl exec storage-demo -- cat /data/proof.txt
新しい Pod はまったく別のコンテナですが、クレームと、その背後のデータが、再びアタッチされました。
アクセスモード、reclaim ポリシー、静的ボリューム
- アクセスモードは、ボリュームをどのようにマウントできるかを示します。
ReadWriteOnceは、単一のノードによる読み書きを意味するため、そのノード上の複数の Pod は、それでも共有できます。ReadOnlyManyとReadWriteManyは、ストレージがサポートしていれば、多くのノードを許可します。ReadWriteOncePodは、単一の Pod に制限します。 - reclaim ポリシーは、クレームが削除されたときにボリュームがどうなるかを決めます。動的にプロビジョニングされたボリュームは通常、デフォルトが
Deleteで、基盤のストレージとそのデータを削除します。データを保持したい場合はRetainを使います。 - 静的プロビジョニングは、管理者が PV を手作業で作成し、クレームが適合するものにバインドされることを意味します。ノード上のディレクトリを使う
hostPathの PV は、よくあるデモですが、データを 1 台のマシンに縛りつけるため、単一ノードの開発にしか適していません。
データベースと StatefulSet
Deployment の Pod に 1 つのクレームをマウントすることはできますが、Deployment のレプリカは交換可能で同一であり、ほとんどのデータベースはそのようには動作しません。StatefulSet は、ステートフルなワークロード向けに作られています。各 Pod に安定した ID(db-0、db-1)を与え、順番に起動と更新を行い、レプリカごとに別々の PVC を作成できます。
spec:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
StatefulSet が扱うのは ID とストレージであり、データのレプリケーションではありません。レプリカ同士を一貫させるのはデータベースの仕事であり、そのため、Kubernetes 上でデータベースを実行することは、ステートレスなサービスの実行より難しくなります。多くのチームは、マネージドデータベースやデータベース operator を使い、ステートレスなアプリケーションをクラスターに置いています。
人気のガイド
-
Kubernetes とは何か、そしてそれが解決する問題 コンテナだけではスケールしなくなる理由と、Kubernetes がマシンの集まりを 1 つのプラットフォームに変える方法。 -
Kubernetes クラスターの仕組み:コントロールプレーンとノード クラスターを動かすコンポーネントと、kubectl apply から実行中のコンテナまでの間に何が起きるか。 -
Deployment:スケーリング、自己修復、ローリングアップデート Pod のレプリカを実行し、ダウンタイムなしで更新し、リリースがうまくいかなかったときにロールバックします。 -
Service:短命な Pod のための安定したネットワーキング Pod に安定したアドレスを与え、クラスターの内外に公開し、誰が誰と通信できるかを制限します。 -
失敗する Pod をデバッグする:describe、logs、exec、port-forward Pod が Pending のまま、クラッシュする、応答しない原因を突き止めるための、繰り返し使えるチェックリスト。