これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
ストレージ
- 1: ボリューム
- 2: 永続ボリューム
- 3: 投影ボリューム
- 4: CSI Volume Cloning
- 5: VolumeSnapshotClass
- 6: ボリュームの動的プロビジョニング(Dynamic Volume Provisioning)
- 7: ストレージ容量
1 - ボリューム
コンテナ内のディスク上のファイルは一時的なものであり、コンテナ内で実行する場合、重要なアプリケーションでいくつかの問題が発生します。1つの問題は、コンテナがクラッシュしたときにファイルが失われることです。kubeletはコンテナを再起動しますが、クリーンな状態です。
2番目の問題は、Pod
で一緒に実行されているコンテナ間でファイルを共有するときに発生します。
Kubernetesボリュームの抽象化は、これらの問題の両方を解決します。
Podに精通していることをお勧めします。
背景
Dockerにはボリュームの概念がありますが、多少緩く、管理も不十分です。Dockerボリュームは、ディスク上または別のコンテナ内のディレクトリです。Dockerはボリュームドライバーを提供しますが、機能は多少制限されています。
Kubernetesは多くの種類のボリュームをサポートしています。 Podは任意の数のボリュームタイプを同時に使用できます。 エフェメラルボリュームタイプにはPodの存続期間がありますが、永続ボリュームはPodの存続期間を超えて存在します。 Podが存在しなくなると、Kubernetesはエフェメラルボリュームを破棄します。ただしKubernetesは永続ボリュームを破棄しません。 特定のPod内のあらゆる種類のボリュームについて、データはコンテナの再起動後も保持されます。
コアとなるボリュームはディレクトリであり、Pod内のコンテナからアクセスできるデータが含まれている可能性があります。 ディレクトリがどのように作成されるか、それをバックアップするメディア、およびそのコンテンツは、使用する特定のボリュームタイプによって決まります。
ボリュームを使用するには、.spec.volumes
でPodに提供するボリュームを指定し、.spec.containers[*].volumeMounts
でそれらのボリュームをコンテナにマウントする場所を宣言します。
コンテナ内のプロセスはコンテナイメージの初期コンテンツと、コンテナ内にマウントされたボリューム(定義されている場合)で構成されるファイルシステムビューを確認します。
プロセスは、コンテナイメージのコンテンツと最初に一致するルートファイルシステムを確認します。
そのファイルシステム階層内への書き込みは、もし許可されている場合、後続のファイルシステムアクセスを実行するときにそのプロセスが表示する内容に影響します。
ボリュームはイメージ内の指定されたパスへマウントされます。
Pod内で定義されたコンテナごとに、コンテナが使用する各ボリュームをマウントする場所を個別に指定する必要があります。
ボリュームは他のボリューム内にマウントできません(ただし、関連するメカニズムについては、subPathの使用を参照してください)。 またボリュームには、別のボリューム内の何かへのハードリンクを含めることはできません。
ボリュームの種類
Kubernetesはいくつかのタイプのボリュームをサポートしています。
awsElasticBlockStore
awsElasticBlockStore
ボリュームは、Amazon Web Services(AWS)EBSボリュームをPodにマウントします。
Podを削除すると消去されるemptyDir
とは異なり、EBSボリュームのコンテンツは保持されたままボリュームはアンマウントされます。
これは、EBSボリュームにデータを事前入力でき、データをPod間で共有できることを意味します。
aws ec2 create-volume
またはAWSAPIを使用してEBSボリュームを作成する必要があります。
awsElasticBlockStore
ボリュームを使用する場合、いくつかの制限があります。
- Podが実行されているノードはAWS EC2インスタンスである必要があります
- これらのインスタンスは、EBSボリュームと同じリージョンおよびアベイラビリティーゾーンにある必要があります
- EBSは、ボリュームをマウントする単一のEC2インスタンスのみをサポートします
AWS EBSボリュームの作成
PodでEBSボリュームを使用する前に作成する必要があります。
aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2
ゾーンがクラスターを立ち上げたゾーンと一致していることを確認してください。サイズとEBSボリュームタイプが使用に適していることを確認してください。
AWS EBS設定例
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-ebs
name: test-volume
volumes:
- name: test-volume
# This AWS EBS volume must already exist.
awsElasticBlockStore:
volumeID: "<volume id>"
fsType: ext4
EBSボリュームがパーティション化されている場合は、オプションのフィールドpartition: "<partition number>"
を指定して、マウントするパーティションを指定できます。
AWS EBS CSIの移行
Kubernetes v1.17 [beta]
awsElasticBlockStore
のCSIMigration
機能を有効にすると、すべてのプラグイン操作が既存のツリー内プラグインからebs.csi.aws.com
Container Storage Interface(CSI)ドライバーにリダイレクトされます。
この機能を使用するには、AWS EBS CSIドライバーがクラスターにインストールされ、CSIMigration
とCSIMigrationAWS
のbeta機能が有効になっている必要があります。
AWS EBS CSIの移行の完了
Kubernetes v1.17 [alpha]
awsElasticBlockStore
ストレージプラグインがコントローラーマネージャーとkubeletによって読み込まれないようにするには、InTreePluginAWSUnregister
フラグをtrue
に設定します。
azureDisk
azureDisk
ボリュームタイプは、MicrosoftAzureデータディスクをPodにマウントします。
詳細については、azureDisk
ボリュームプラグインを参照してください。
azureDisk CSIの移行
Kubernetes v1.19 [beta]
azureDisk
のCSIMigration
機能を有効にすると、すべてのプラグイン操作が既存のツリー内プラグインからdisk.csi.azure.com
Container Storage Interface(CSI)ドライバーにリダイレクトされます。
この機能を利用するには、クラスターにAzure Disk CSI Driverをインストールし、CSIMigration
およびCSIMigrationAzureDisk
機能を有効化する必要があります。
azureFile
azureFile
ボリュームタイプは、Microsoft Azureファイルボリューム(SMB 2.1および3.0)をPodにマウントします。
詳細についてはazureFile
volume pluginを参照してください。
azureFile CSIの移行
Kubernetes v1.21 [beta]
zureFile
のCSIMigration
機能を有効にすると、既存のツリー内プラグインからfile.csi.azure.com
Container Storage Interface(CSI)Driverへすべてのプラグイン操作がリダイレクトされます。
この機能を利用するには、クラスターにAzure File CSI Driverをインストールし、CSIMigration
およびCSIMigrationAzureFile
フィーチャーゲートを有効化する必要があります。
Azure File CSIドライバーは、異なるfsgroupで同じボリュームを使用することをサポートしていません。AzurefileCSIの移行が有効になっている場合、異なるfsgroupで同じボリュームを使用することはまったくサポートされません。
cephfs
cephfs
ボリュームを使用すると、既存のCephFSボリュームをPodにマウントすることができます。
Podを取り外すと消去されるemptyDir
とは異なり、cephfs
ボリュームは内容を保持したまま単にアンマウントされるだけです。
つまりcephfs
ボリュームにあらかじめデータを入れておき、そのデータをPod間で共有することができます。
cephfs
ボリュームは複数の書き込み元によって同時にマウントすることができます。
詳細についてはCephFSの例を参照してください。
cinder
cinder
ボリュームタイプは、PodにOpenStackのCinderのボリュームをマウントするために使用されます。
Cinderボリュームの設定例
apiVersion: v1
kind: Pod
metadata:
name: test-cinder
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-cinder-container
volumeMounts:
- mountPath: /test-cinder
name: test-volume
volumes:
- name: test-volume
# This OpenStack volume must already exist.
cinder:
volumeID: "<volume id>"
fsType: ext4
OpenStack CSIの移行
Kubernetes v1.21 [beta]
CinderのCSIMigration
機能は、Kubernetes1.21ではデフォルトで有効になっています。
既存のツリー内プラグインからのすべてのプラグイン操作をcinder.csi.openstack.org
Container Storage Interface(CSI) Driverへリダイレクトします。
OpenStack Cinder CSIドライバーをクラスターにインストールする必要があります。
CSIMigrationOpenStack
フィーチャーゲートをfalse
に設定すると、クラスターのCinder CSIマイグレーションを無効化することができます。
CSIMigrationOpenStack
機能を無効にすると、ツリー内のCinderボリュームプラグインがCinderボリュームのストレージ管理のすべての側面に責任を持つようになります。
configMap
ConfigMapは構成データをPodに挿入する方法を提供します。
ConfigMapに格納されたデータは、タイプconfigMap
のボリュームで参照され、Podで実行されているコンテナ化されたアプリケーションによって使用されます。
ConfigMapを参照するときは、ボリューム内のConfigMapの名前を指定します。
ConfigMapの特定のエントリに使用するパスをカスタマイズできます。
次の設定は、log-config
ConfigMapをconfigmap-pod
というPodにマウントする方法を示しています。
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
log-config
ConfigMapはボリュームとしてマウントされ、そのlog_level
エントリに格納されているすべてのコンテンツは、パス/etc/config/log_level
のPodにマウントされます。
このパスはボリュームのmountPath
とlog_level
をキーとするpath
から派生することに注意してください。
downwardAPI
downwardAPI
ボリュームは、アプリケーションへのdownward APIデータを利用できるようになります。ディレクトリをマウントし、要求されたデータをプレーンテキストファイルに書き込みます。
subPath
ボリュームマウントとしてdownward APIを使用するコンテナは、downward APIの更新を受け取りません。
詳細についてはdownward API exampleを参照してください。
emptyDir
emptyDir
ボリュームはPodがノードに割り当てられたときに最初に作成され、そのPodがそのノードで実行されている限り存在します。
名前が示すようにemptyDir
ボリュームは最初は空です。
Pod内のすべてのコンテナはemptyDir
ボリューム内の同じファイルを読み書きできますが、そのボリュームは各コンテナで同じパスまたは異なるパスにマウントされることがあります。
何らかの理由でPodがノードから削除されると、emptyDir
内のデータは永久に削除されます。
emptyDir
ボリューム内のデータは、コンテナのクラッシュしても安全です。
emptyDir
のいくつかの用途は次の通りです。
- ディスクベースのマージソートなどのスクラッチスペース
- クラッシュからの回復のための長い計算のチェックポイント
- Webサーバーコンテナがデータを提供している間にコンテンツマネージャコンテナがフェッチするファイルを保持する
環境に応じて、emptyDir
ボリュームは、ディスクやSSD、ネットワークストレージなど、ノードをバックアップするあらゆる媒体に保存されます。
ただし、emptyDir.medium
フィールドを"Memory"
に設定すると、Kubernetesは代わりにtmpfs(RAMベースのファイルシステム)をマウントします。
tmpfsは非常に高速ですが、ディスクと違ってノードのリブート時にクリアされ、書き込んだファイルはコンテナのメモリー制限にカウントされることに注意してください。
SizeMemoryBackedVolumes
フィーチャーゲートが有効な場合、メモリーバックアップボリュームにサイズを指定することができます。
サイズが指定されていない場合、メモリーでバックアップされたボリュームは、Linuxホストのメモリーの50%のサイズになります。
emptyDirの設定例
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
fc (fibre channel)
fc
ボリュームタイプを使用すると、既存のファイバーチャネルブロックストレージボリュームをPodにマウントできます。
targetWWNs
ボリューム構成のパラメーターを使用して、単一または複数のターゲットWorld Wide Name(WWN)を指定できます。
複数のWWNが指定されている場合、targetWWNは、それらのWWNがマルチパス接続からのものであると想定します。
詳細についてはfibre channelの例を参照してください。
flocker (非推奨)
Flockerはオープンソースのクラスター化されたコンテナデータボリュームマネージャーです。 Flockerは、さまざまなストレージバックエンドに支えられたデータボリュームの管理とオーケストレーションを提供します。
flocker
ボリュームを使用すると、FlockerデータセットをPodにマウントできます。
もしデータセットがまだFlockerに存在しない場合は、まずFlocker CLIかFlocker APIを使ってデータセットを作成する必要があります。
データセットがすでに存在する場合は、FlockerによってPodがスケジュールされているノードに再アタッチされます。
これは、必要に応じてPod間でデータを共有できることを意味します。
詳細についてはFlocker exampleを参照してください。
gcePersistentDisk
gcePersistentDisk
ボリュームは、Google Compute Engine (GCE)の永続ディスク(PD)をPodにマウントします。
Podを取り外すと消去されるemptyDir
とは異なり、PDの内容は保持されボリュームは単にアンマウントされるだけです。これはPDにあらかじめデータを入れておくことができ、そのデータをPod間で共有できることを意味します。
gcloud
を使用する前に、またはGCE APIまたはUIを使用してPDを作成する必要があります。
gcePersistentDisk
を使用する場合、いくつかの制限があります。
- Podが実行されているノードはGCE VMである必要があります
- これらのVMは、永続ディスクと同じGCEプロジェクトおよびゾーンに存在する必要があります
GCE永続ディスクの機能の1つは、永続ディスクへの同時読み取り専用アクセスです。gcePersistentDisk
ボリュームを使用すると、複数のコンシューマーが永続ディスクを読み取り専用として同時にマウントできます。
これはPDにデータセットを事前入力してから、必要な数のPodから並行して提供できることを意味します。
残念ながらPDは読み取り/書き込みモードで1つのコンシューマーのみがマウントできます。同時書き込みは許可されていません。
PDが読み取り専用であるか、レプリカ数が0または1でない限り、ReplicaSetによって制御されるPodでGCE永続ディスクを使用すると失敗します。
GCE永続ディスクの作成
PodでGCE永続ディスクを使用する前に、それを作成する必要があります。
gcloud compute disks create --size=500GB --zone=us-central1-a my-data-disk
GCE永続ディスクの設定例
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
# This GCE PD must already exist.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
リージョン永続ディスク
リージョン永続ディスク機能を使用すると、同じリージョン内の2つのゾーンで使用できる永続ディスクを作成できます。 この機能を使用するには、ボリュームをPersistentVolumeとしてプロビジョニングする必要があります。Podから直接ボリュームを参照することはサポートされていません。
リージョンPD PersistentVolumeを手動でプロビジョニングする
GCE PDのStorageClassを使用して動的プロビジョニングが可能です。 SPDPersistentVolumeを作成する前に、永続ディスクを作成する必要があります。
gcloud compute disks create --size=500GB my-data-disk
--region us-central1
--replica-zones us-central1-a,us-central1-b
リージョン永続ディスクの設定例
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-volume
spec:
capacity:
storage: 400Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
# failure-domain.beta.kubernetes.io/zone should be used prior to 1.21
- key: topology.kubernetes.io/zone
operator: In
values:
- us-central1-a
- us-central1-b
GCE CSIの移行
Kubernetes v1.17 [beta]
GCE PDのCSIMigration
機能を有効にすると、すべてのプラグイン操作が既存のツリー内プラグインからpd.csi.storage.gke.io
Container Storage Interface (CSI) Driverにリダイレクトされるようになります。
この機能を使用するには、クラスターにGCE PD CSI Driverがインストールされ、CSIMigration
とCSIMigrationGCE
のbeta機能が有効になっている必要があります。
GCE CSIの移行の完了
Kubernetes v1.21 [alpha]
gcePersistentDisk
ストレージプラグインがコントローラーマネージャーとkubeletによって読み込まれないようにするには、InTreePluginGCEUnregister
フラグをtrue
に設定します。
gitRepo(非推奨)
gitRepo
ボリュームタイプは非推奨です。gitリポジトリを使用してコンテナをプロビジョニングするには、Gitを使用してリポジトリのクローンを作成するInitContainerにEmptyDirをマウントしてから、PodのコンテナにEmptyDirをマウントします。
gitRepo
ボリュームは、ボリュームプラグインの一例です。このプラグインは空のディレクトリをマウントし、そのディレクトリにgitリポジトリをクローンしてPodで使えるようにします。
gitRepo
ボリュームの例を次に示します。
apiVersion: v1
kind: Pod
metadata:
name: server
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
glusterfs
glusterfs
ボリュームはGlusterfs(オープンソースのネットワークファイルシステム)ボリュームをPodにマウントできるようにするものです。
Podを取り外すと消去されるemptyDir
とは異なり、glusterfs
ボリュームの内容は保持され、単にアンマウントされるだけです。
これは、glusterfsボリュームにデータを事前に入力でき、データをPod間で共有できることを意味します。
GlusterFSは複数のライターが同時にマウントすることができます。
詳細についてはGlusterFSの例を参照してください。
hostPath
HostPathボリュームには多くのセキュリティリスクがあり、可能な場合はHostPathの使用を避けることがベストプラクティスです。HostPathボリュームを使用する必要がある場合は、必要なファイルまたはディレクトリのみにスコープを設定し、読み取り専用としてマウントする必要があります。
AdmissionPolicyによって特定のディレクトリへのHostPathアクセスを制限する場合、ポリシーを有効にするためにvolumeMounts
はreadOnly
マウントを使用するように要求されなければなりません。
hostPath
ボリュームは、ファイルまたはディレクトリをホストノードのファイルシステムからPodにマウントします。
これはほとんどのPodに必要なものではありませんが、一部のアプリケーションには強力なエスケープハッチを提供します。
たとえばhostPath
のいくつかの使用法は次のとおりです。
- Dockerの内部にアクセスする必要があるコンテナを実行する場合:
hostPath
に/var/lib/docker
を使用します。 - コンテナ内でcAdvisorを実行する場合:
hostPath
に/sys
を指定します。 - Podが実行される前に、与えられた
hostPath
が存在すべきかどうか、作成すべきかどうか、そして何として存在すべきかを指定できるようにします。
必須のpath
プロパティに加えて、オプションでhostPath
ボリュームにtype
を指定することができます。
フィールドtype
でサポートされている値は次のとおりです。
値 | ふるまい |
---|---|
空の文字列(デフォルト)は下位互換性のためです。つまり、hostPathボリュームをマウントする前にチェックは実行されません。 | |
DirectoryOrCreate |
指定されたパスに何も存在しない場合、必要に応じて、権限を0755に設定し、Kubeletと同じグループと所有権を持つ空のディレクトリが作成されます。 |
Directory |
指定されたパスにディレクトリが存在する必要があります。 |
FileOrCreate |
指定されたパスに何も存在しない場合、必要に応じて、権限を0644に設定し、Kubeletと同じグループと所有権を持つ空のファイルが作成されます。 |
File |
指定されたパスにファイルが存在する必要があります。 |
Socket |
UNIXソケットは、指定されたパスに存在する必要があります。 |
CharDevice |
キャラクターデバイスは、指定されたパスに存在する必要があります。 |
BlockDevice |
ブロックデバイスは、指定されたパスに存在する必要があります。 |
このタイプのボリュームを使用するときは、以下の理由のため注意してください。
- HostPath は、特権的なシステム認証情報(Kubeletなど)や特権的なAPI(コンテナランタイムソケットなど)を公開する可能性があり、コンテナのエスケープやクラスターの他の部分への攻撃に利用される可能性があります。
- 同一構成のPod(PodTemplateから作成されたものなど)は、ノード上のファイルが異なるため、ノードごとに動作が異なる場合があります。
- ホスト上に作成されたファイルやディレクトリは、rootでしか書き込みができません。特権コンテナ内でrootとしてプロセスを実行するか、ホスト上のファイルのパーミッションを変更して
hostPath
ボリュームに書き込みができるようにする必要があります。
hostPathの設定例
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /data
# this field is optional
type: Directory
FileOrCreate
モードでは、ファイルの親ディレクトリは作成されません。マウントされたファイルの親ディレクトリが存在しない場合、Podは起動に失敗します。
このモードが確実に機能するようにするには、FileOrCreate
構成に示すように、ディレクトリとファイルを別々にマウントしてみてください。
hostPath FileOrCreateの設定例
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
containers:
- name: test-webserver
image: k8s.gcr.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# Ensure the file directory is created.
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
iscsi
iscsi
ボリュームは、既存のiSCSI(SCSI over IP)ボリュームをPodにマウントすることができます。
Podを取り外すと消去されるemptyDir
とは異なり、iscsi
ボリュームの内容は保持され、単にアンマウントされるだけです。
つまり、iscsiボリュームにはあらかじめデータを入れておくことができ、そのデータをPod間で共有することができるのです。
iSCSIの特徴として、複数のコンシューマーから同時に読み取り専用としてマウントできることが挙げられます。 つまり、ボリュームにあらかじめデータセットを入れておき、必要な数のPodから並行してデータを提供することができます。 残念ながら、iSCSIボリュームは1つのコンシューマによってのみ読み書きモードでマウントすることができます。 同時に書き込みを行うことはできません。
詳細についてはiSCSIの例を参照してください。
local
local
ボリュームは、ディスク、パーティション、ディレクトリなど、マウントされたローカルストレージデバイスを表します。
ローカルボリュームは静的に作成されたPersistentVolumeとしてのみ使用できます。動的プロビジョニングはサポートされていません。
hostPath
ボリュームと比較して、local
ボリュームは手動でノードにPodをスケジューリングすることなく、耐久性と移植性に優れた方法で使用することができます。
システムはPersistentVolume上のノードアフィニティーを見ることで、ボリュームのノード制約を認識します。
ただし、local
ボリュームは、基盤となるノードの可用性に左右されるため、すべてのアプリケーションに適しているわけではありません。
ノードが異常になると、Podはlocal
ボリュームにアクセスできなくなります。
このボリュームを使用しているPodは実行できません。local
ボリュームを使用するアプリケーションは、基盤となるディスクの耐久性の特性に応じて、この可用性の低下と潜在的なデータ損失に耐えられる必要があります。
次の例では、local
ボリュームとnodeAffinity
を使用したPersistentVolumeを示しています。
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
ローカルボリュームを使用する場合は、PersistentVolume nodeAffinity
を設定する必要があります。
KubernetesのスケジューラはPersistentVolume nodeAffinity
を使用して、これらのPodを正しいノードにスケジューリングします。
PersistentVolume volumeMode
を(デフォルト値の「Filesystem」ではなく)「Block」に設定して、ローカルボリュームをrawブロックデバイスとして公開できます。
ローカルボリュームを使用する場合、volumeBindingMode
をWaitForFirstConsumer
に設定したStorageClassを作成することをお勧めします。
詳細については、local StorageClassの例を参照してください。
ボリュームバインディングを遅延させると、PersistentVolumeClaimバインディングの決定が、ノードリソース要件、ノードセレクター、Podアフィニティ、Podアンチアフィニティなど、Podが持つ可能性のある他のノード制約も含めて評価されるようになります。
ローカルボリュームのライフサイクルの管理を改善するために、外部の静的プロビジョナーを個別に実行できます。 このプロビジョナーはまだ動的プロビジョニングをサポートしていないことに注意してください。 外部ローカルプロビジョナーの実行方法の例については、ローカルボリュームプロビジョナーユーザーガイドを参照してください。
nfs
nfs
ボリュームは、既存のNFS(Network File System)共有をPodにマウントすることを可能にします。Podを取り外すと消去されるemptyDir
とは異なり、nfs
ボリュームのコンテンツは保存され、単にアンマウントされるだけです。
つまり、NFSボリュームにはあらかじめデータを入れておくことができ、そのデータをPod間で共有することができます。
NFSは複数のライターによって同時にマウントすることができます。
詳細についてはNFSの例を参照してください。
persistentVolumeClaim
PersistentVolumeClaim
ボリュームはPersistentVolumeをPodにマウントするために使用されます。
PersistentVolumeClaimは、ユーザが特定のクラウド環境の詳細を知らなくても、耐久性のあるストレージ(GCE永続ディスクやiSCSIボリュームなど)を「要求」するための方法です。
詳細についてはPersistentVolumeを参照してください。
portworxVolume
portworxVolume
は、Kubernetesとハイパーコンバージドで動作するエラスティックブロックストレージレイヤーです。
Portworxは、サーバー内のストレージをフィンガープリントを作成し、機能に応じて階層化し、複数のサーバーにまたがって容量を集約します。
Portworxは、仮想マシンまたはベアメタルのLinuxノードでゲスト内動作します。
portworxVolume
はKubernetesを通して動的に作成することができますが、事前にプロビジョニングしてPodの中で参照することもできます。
以下は、事前にプロビジョニングされたPortworxボリュームを参照するPodの例です。
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# This Portworx volume must already exist.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
pxvol
という名前の既存のPortworxVolumeがあることを確認してください。
詳細についてはPortworxボリュームの例を参照してください。
投影
投影ボリュームは、複数の既存のボリュームソースを同じディレクトリにマッピングします。 詳細については投影ボリュームを参照してください。
quobyte(非推奨)
quobyte
ボリュームは、既存のQuobyteボリュームをPodにマウントすることができます。
CSIは、Kubernetes内部でQuobyteボリュームを使用するための推奨プラグインです。 QuobyteのGitHubプロジェクトには、CSIを使用してQuobyteをデプロイするための手順と例があります
rbd
rbd
ボリュームはRados Block Device(RBD)ボリュームをPodにマウントすることを可能にします。
Podを取り外すと消去されるemptyDir
とは異なり、rbd
ボリュームの内容は保存され、ボリュームはアンマウントされます。つまり、RBDボリュームにはあらかじめデータを入れておくことができ、そのデータをPod間で共有することができるのです。
RBDの特徴として、複数のコンシューマーから同時に読み取り専用としてマウントできることが挙げられます。 つまり、ボリュームにあらかじめデータセットを入れておき、必要な数のPodから並行して提供することができるのです。 残念ながら、RBDボリュームは1つのコンシューマーによってのみ読み書きモードでマウントすることができます。 同時に書き込みを行うことはできません。
詳細についてはRBDの例を参照してください。
RBD CSIの移行
Kubernetes v1.23 [alpha]
RBD
のCSIMigration
機能を有効にすると、既存のツリー内プラグインからrbd.csi.ceph.com
CSIドライバーにすべてのプラグイン操作がリダイレクトされます。
この機能を使用するには、クラスターにCeph CSIドライバーをインストールし、CSIMigration
およびcsiMigrationRBD
フィーチャーゲートを有効にしておく必要があります。
ストレージを管理するKubernetesクラスターオペレーターとして、RBD CSIドライバーへの移行を試みる前に完了する必要のある前提条件は次のとおりです。
- Ceph CSIドライバー(
rbd.csi.ceph.com
)v3.5.0以降をKubernetesクラスターにインストールする必要があります。 - CSIドライバーの動作に必要なパラメーターとして
clusterID
フィールドがありますが、ツリー内StorageClassにはmonitors
フィールドがあるため、Kubernetesストレージ管理者はCSI config mapでモニターハッシュ(例:#echo -n '<monitors_string>' | md5sum
)に基づいたclusterIDを作成し、モニターをこのclusterID設定の下に保持しなければなりません。 - また、ツリー内Storageclassの
adminId
の値がadmin
と異なる場合、ツリー内Storageclassに記載されているadminSecretName
にadminId
パラメーター値のbase64値をパッチしなければなりませんが、それ以外はスキップすることが可能です。
secret
secret
ボリュームは、パスワードなどの機密情報をPodに渡すために使用します。
Kubernetes APIにsecretを格納し、Kubernetesに直接結合することなくPodが使用するファイルとしてマウントすることができます。
secret
ボリュームはtmpfs(RAM-backed filesystem)によってバックアップされるため、不揮発性ストレージに書き込まれることはありません。
SubPath
ボリュームマウントとしてSecretを使用しているコンテナは、Secretの更新を受け取りません。
詳細についてはSecretの設定を参照してください。
storageOS(非推奨)
storageos
ボリュームを使用すると、既存のStorageOSボリュームをPodにマウントできます。
StorageOSは、Kubernetes環境内でコンテナとして実行され、Kubernetesクラスター内の任意のノードからローカルストレージまたは接続されたストレージにアクセスできるようにします。 データを複製してノードの障害から保護することができます。シンプロビジョニングと圧縮により使用率を向上させ、コストを削減できます。
根本的にStorageOSは、コンテナにブロックストレージを提供しファイルシステムからアクセスできるようにします。
StorageOS Containerは64ビットLinuxを必要とし、追加の依存関係はありません。 無償の開発者ライセンスが利用可能です。
次の例は、StorageOSを使用したPodの設定です。
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
role: master
name: test-storageos-redis
spec:
containers:
- name: master
image: kubernetes/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: redis-data
volumes:
- name: redis-data
storageos:
# The `redis-vol01` volume must already exist within StorageOS in the `default` namespace.
volumeName: redis-vol01
fsType: ext4
StorageOS、動的プロビジョニング、およびPersistentVolumeClaimの詳細については、StorageOSの例を参照してください。
vsphereVolume
vsphereVolume
は、vSphereVMDKボリュームをPodにマウントするために使用されます。
ボリュームの内容は、マウント解除されたときに保持されます。VMFSとVSANの両方のデータストアをサポートします。
Creating a VMDK volume
次のいずれかの方法を選択して、VMDKを作成します。
最初にESXにSSHで接続し、次に以下のコマンドを使用してVMDKを作成します。
vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk
次のコマンドを使用してVMDKを作成します。
vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk
vSphere VMDKの設定例
apiVersion: v1
kind: Pod
metadata:
name: test-vmdk
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-vmdk
name: test-volume
volumes:
- name: test-volume
# This VMDK volume must already exist.
vsphereVolume:
volumePath: "[DatastoreName] volumes/myDisk"
fsType: ext4
詳細についてはvSphereボリュームの例を参照してください。
vSphere CSIの移行
Kubernetes v1.19 [beta]
vsphereVolume
のCSIMigration
機能を有効にすると、既存のツリー内プラグインからcsi.vsphere.vmware.com
CSIドライバーにすべてのプラグイン操作がリダイレクトされます。
この機能を使用するには、クラスターにvSphere CSIドライバーがインストールされ、CSIMigration
およびCSIMigrationvSphere
フィーチャーゲートが有効になっていなければなりません。
また、vSphere vCenter/ESXiのバージョンが7.0u1以上、HWのバージョンがVM version 15以上であることが条件です。
組み込みのvsphereVolume
プラグインの次のStorageClassパラメーターは、vSphere CSIドライバーでサポートされていません。
diskformat
hostfailurestotolerate
forceprovisioning
cachereservation
diskstripes
objectspacereservation
iopslimit
これらのパラメーターを使用して作成された既存のボリュームはvSphere CSIドライバーに移行されますが、vSphere CSIドライバーで作成された新しいボリュームはこれらのパラメーターに従わないことに注意してください。
vSphere CSIの移行の完了
Kubernetes v1.19 [beta]
vsphereVolume
プラグインがコントローラーマネージャーとkubeletによって読み込まれないようにするには、InTreePluginvSphereUnregister
機能フラグをtrue
に設定する必要があります。すべてのワーカーノードにcsi.vsphere.vmware.com
CSIドライバーをインストールする必要があります。
Portworx CSIの移行
Kubernetes v1.23 [alpha]
PortworxのCSIMigration
機能が追加されましたが、Kubernetes 1.23ではAlpha状態であるため、デフォルトで無効になっています。
すべてのプラグイン操作を既存のツリー内プラグインからpxd.portworx.com
Container Storage Interface(CSI)ドライバーにリダイレクトします。
Portworx CSIドライバーをクラスターにインストールする必要があります。
この機能を有効にするには、kube-controller-managerとkubeletでCSIMigrationPortworx=true
を設定します。
subPathの使用
1つのPodで複数の用途に使用するために1つのボリュームを共有すると便利な場合があります。
volumeMounts.subPath
プロパティは、ルートではなく、参照されるボリューム内のサブパスを指定します。
次の例は、単一の共有ボリュームを使用してLAMPスタック(Linux Apache MySQL PHP)でPodを構成する方法を示しています。
このサンプルのsubPath
構成は、プロダクションでの使用にはお勧めしません。
PHPアプリケーションのコードとアセットはボリュームのhtml
フォルダーにマップされ、MySQLデータベースはボリュームのmysql
フォルダーに保存されます。例えば:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
拡張された環境変数でのsubPathの使用
Kubernetes v1.17 [stable]
subPathExpr
フィールドを使用して、downwart API環境変数からsubPath
ディレクトリ名を作成します。
subPath
プロパティとsubPathExpr
プロパティは相互に排他的です。
この例では、Pod
がsubPathExpr
を使用して、hostPath
ボリューム/var/log/pods
内にpod1
というディレクトリを作成します。
hostPath
ボリュームはdownwardAPI
からPod
名を受け取ります。
ホストディレクトリ/var/log/pods/pod1
は、コンテナ内の/logs
にマウントされます。
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
# The variable expansion uses round brackets (not curly brackets).
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
リソース
emptyDir
ボリュームの記憶媒体(DiskやSSDなど)は、kubeletのルートディレクトリ(通常は/var/lib/kubelet
)を保持するファイルシステムの媒体によって決定されます。
emptyDir
またはhostPath
ボリュームが消費する容量に制限はなく、コンテナ間またはPod間で隔離されることもありません。
リソース仕様を使用したスペースの要求については、リソースの管理方法を参照してください。
ツリー外のボリュームプラグイン
ツリー外ボリュームプラグインにはContainer Storage Interface(CSI)、およびFlexVolume(非推奨)があります。 これらのプラグインによりストレージベンダーは、プラグインのソースコードをKubernetesリポジトリに追加することなく、カスタムストレージプラグインを作成することができます。
以前は、すべてのボリュームプラグインが「ツリー内」にありました。 「ツリー内」のプラグインは、Kubernetesのコアバイナリとともにビルド、リンク、コンパイルされ、出荷されていました。 つまり、Kubernetesに新しいストレージシステム(ボリュームプラグイン)を追加するには、Kubernetesのコアコードリポジトリにコードをチェックインする必要があったのです。
CSIとFlexVolumeはどちらも、ボリュームプラグインをKubernetesコードベースとは独立して開発し、拡張機能としてKubernetesクラスターにデプロイ(インストール)することを可能にします。
ツリー外のボリュームプラグインの作成を検討しているストレージベンダーについては、ボリュームプラグインのFAQを参照してください。
csi
Container Storage Interface(CSI)は、コンテナオーケストレーションシステム(Kubernetesなど)の標準インターフェイスを定義して、任意のストレージシステムをコンテナワークロードに公開します。
詳細についてはCSI design proposalを参照してください。
CSI互換のボリュームドライバーがKubernetesクラスター上に展開されると、ユーザーはcsi
ボリュームタイプを使用して、CSIドライバーによって公開されたボリュームをアタッチまたはマウントすることができます。
csi
ボリュームはPodで3つの異なる方法によって使用することができます。
- PersistentVolumeClaimの参照を通して
- 一般的なエフェメラルボリューム(alpha機能)で
- ドライバーがそれをサポートしている場合は、CSIエフェメラルボリューム(beta機能)を使って
ストレージ管理者は、CSI永続ボリュームを構成するために次のフィールドを使用できます。
driver
: 使用するボリュームドライバーの名前を指定する文字列。 この値はCSI specで定義されたCSIドライバーがGetPluginInfoResponse
で返す値に対応していなければなりません。 これはKubernetesが呼び出すCSIドライバーを識別するために使用され、CSIドライバーコンポーネントがCSIドライバーに属するPVオブジェクトを識別するために使用されます。volumeHandle
: ボリュームを一意に識別する文字列。この値は、CSI specで定義されたCSIドライバーがCreateVolumeResponse
のvolume.id
フィールドに返す値に対応していなければなりません。この値はCSIボリュームドライバーのすべての呼び出しで、ボリュームを参照する際にvolume_id
として渡されます。readOnly
: ボリュームを読み取り専用として「ControllerPublished」(添付)するかどうかを示すオプションのブール値。デフォルトはfalseです。この値は、ControllerPublishVolumeRequest
のreadonly
フィールドを介してCSIドライバーに渡されます。fsType
: PVのVolumeMode
がFilesystem
の場合、このフィールドを使用して、ボリュームのマウントに使用する必要のあるファイルシステムを指定できます。ボリュームがフォーマットされておらず、フォーマットがサポートされている場合、この値はボリュームのフォーマットに使用されます。この値は、ControllerPublishVolumeRequest
、NodeStageVolumeRequest
、およびNodePublishVolumeRequest
のVolumeCapability
フィールドを介してCSIドライバーに渡されます。volumeAttributes
: ボリュームの静的プロパティを指定する、文字列から文字列へのマップ。このマップは、CSI specで定義されているように、CSIドライバーがCreateVolumeResponse
のvolume.attributes
フィールドで返すマップと一致しなければなりません。このマップはControllerPublishVolumeRequest
,NodeStageVolumeRequest
,NodePublishVolumeRequest
のvolume_context
フィールドを介してCSIドライバーに渡されます。controllerPublishSecretRef
: CSIControllerPublishVolume
およびControllerUnpublishVolume
呼び出しを完了するためにCSIドライバーに渡す機密情報を含むsecretオブジェクトへの参照。このフィールドはオプションで、secretが必要ない場合は空にすることができます。secretに複数のsecretが含まれている場合は、すべてのsecretが渡されます。nodeStageSecretRef
: CSINodeStageVolume
呼び出しを完了するために、CSIドライバーに渡す機密情報を含むsecretオブジェクトへの参照。このフィールドはオプションで、secretが必要ない場合は空にすることができます。secretに複数のsecretが含まれている場合、すべてのsecretが渡されます。nodePublishSecretRef
: CSINodePublishVolume
呼び出しを完了するために、CSIドライバーに渡す機密情報を含むsecretオブジェクトへの参照。このフィールドはオプションで、secretが必要ない場合は空にすることができます。secretオブジェクトが複数のsecretを含んでいる場合、すべてのsecretが渡されます。
CSI rawブロックボリュームのサポート
Kubernetes v1.18 [stable]
外部のCSIドライバーを使用するベンダーは、Kubernetesワークロードでrawブロックボリュームサポートを実装できます。
CSI固有の変更を行うことなく、通常どおり、rawブロックボリュームをサポートするPersistentVolume/PersistentVolumeClaimを設定できます。
CSIエフェメラルボリューム
Kubernetes v1.16 [beta]
Pod仕様内でCSIボリュームを直接構成できます。この方法で指定されたボリュームは一時的なものであり、Podを再起動しても持続しません。詳細についてはエフェメラルボリュームを参照してください。
CSIドライバーの開発方法の詳細についてはkubernetes-csiドキュメントを参照してください。
ツリー内プラグインからCSIドライバーへの移行
Kubernetes v1.17 [beta]
CSIMigration
機能を有効にすると、既存のツリー内プラグインに対する操作が、対応するCSIプラグイン(インストールおよび構成されていることが期待されます)に転送されます。
その結果、オペレーターは、ツリー内プラグインに取って代わるCSIドライバーに移行するときに、既存のストレージクラス、PersistentVolume、またはPersistentVolumeClaim(ツリー内プラグインを参照)の構成を変更する必要がありません。
サポートされている操作と機能には、プロビジョニング/削除、アタッチ/デタッチ、マウント/アンマウント、およびボリュームのサイズ変更が含まれます。
CSIMigration
をサポートし、対応するCSIドライバーが実装されているツリー内プラグインは、ボリュームのタイプにリストされています。
flexVolume
Kubernetes v1.23 [deprecated]
FlexVolumeは、ストレージドライバーとのインターフェースにexecベースのモデルを使用するツリー外プラグインインターフェースです。FlexVolumeドライバーのバイナリは、各ノード、場合によってはコントロールプレーンノードにも、あらかじめ定義されたボリュームプラグインパスにインストールする必要があります。
PodはflexVolume
ツリー内ボリュームプラグインを通してFlexVolumeドライバーと対話します。
詳細についてはFlexVolumeのREADMEを参照してください。
FlexVolumeは非推奨です。ツリー外のCSIドライバーを使用することは、外部ストレージをKubernetesと統合するための推奨される方法です。
FlexVolumeドライバーのメンテナーは、CSIドライバーを実装し、FlexVolumeドライバーのユーザーをCSIに移行するのを支援する必要があります。FlexVolumeのユーザーは、同等のCSIドライバーを使用するようにワークロードを移動する必要があります。
マウントの伝播
マウントの伝播により、コンテナによってマウントされたボリュームを、同じPod内の他のコンテナ、または同じノード上の他のPodに共有できます。
ボリュームのマウント伝播は、Container.volumeMounts
のmountPropagation
フィールドによって制御されます。その値は次のとおりです。
-
None
- このボリュームマウントは、ホストによってこのボリュームまたはそのサブディレクトリにマウントされる後続のマウントを受け取りません。同様に、コンテナによって作成されたマウントはホストに表示されません。これがデフォルトのモードです。このモードはLinuxカーネルドキュメントで説明されている
private
マウント伝播と同じです。 -
HostToContainer
- このボリュームマウントは、このボリュームまたはそのサブディレクトリのいずれかにマウントされる後続のすべてのマウントを受け取ります。つまりホストがボリュームマウント内に何かをマウントすると、コンテナはそこにマウントされていることを確認します。
同様に同じボリュームに対して
Bidirectional
マウント伝搬を持つPodが何かをマウントすると、HostToContainer
マウント伝搬を持つコンテナはそれを見ることができます。このモードはLinuxカーネルドキュメントで説明されている
rslave
マウント伝播と同じです。 -
Bidirectional
- このボリュームマウントは、HostToContainer
マウントと同じように動作します。さらに、コンテナによって作成されたすべてのボリュームマウントは、ホストと、同じボリュームを使用するすべてのPodのすべてのコンテナに伝播されます。このモードの一般的な使用例は、FlexVolumeまたはCSIドライバーを備えたPod、または
hostPath
ボリュームを使用してホストに何かをマウントする必要があるPodです。このモードはLinuxカーネルドキュメントで説明されている
rshared
マウント伝播と同じです。警告:Bidirectional
マウント伝搬は危険です。ホストオペレーティングシステムにダメージを与える可能性があるため、特権的なコンテナでのみ許可されています。 Linuxカーネルの動作に精通していることが強く推奨されます。 また、Pod内のコンテナによって作成されたボリュームマウントは、終了時にコンテナによって破棄(アンマウント)される必要があります。
構成
一部のデプロイメント(CoreOS、RedHat/Centos、Ubuntu)でマウント伝播が正しく機能する前に、以下に示すように、Dockerでマウント共有を正しく構成する必要があります。
Dockerのsystemd
サービスファイルを編集します。以下のようにMountFlags
を設定します。
MountFlags=shared
または、MountFlags=slave
があれば削除してください。その後、Dockerデーモンを再起動します。
sudo systemctl daemon-reload
sudo systemctl restart docker
次の項目
永続ボリュームを使用してWordPressとMySQLをデプロイする例に従ってください。
2 - 永続ボリューム
このドキュメントではKubernetesの PersistentVolume について説明します。ボリュームを一読することをおすすめします。
概要
ストレージを管理することはインスタンスを管理することとは全くの別物です。PersistentVolumeサブシステムは、ストレージが何から提供されているか、どのように消費されているかをユーザーと管理者から抽象化するAPIを提供します。これを実現するためのPersistentVolumeとPersistentVolumeClaimという2つの新しいAPIリソースを紹介します。
PersistentVolume (PV)はストレージクラスを使って管理者もしくは動的にプロビジョニングされるクラスターのストレージの一部です。これはNodeと同じようにクラスターリソースの一部です。PVはVolumeのようなボリュームプラグインですが、PVを使う個別のPodとは独立したライフサイクルを持っています。このAPIオブジェクトはNFS、iSCSIやクラウドプロバイダー固有のストレージシステムの実装の詳細を捕捉します。
PersistentVolumeClaim (PVC)はユーザーによって要求されるストレージです。これはPodと似ています。PodはNodeリソースを消費し、PVCはPVリソースを消費します。Podは特定レベルのCPUとメモリーリソースを要求することができます。クレームは特定のサイズやアクセスモード(例えば、ReadWriteOnce、ReadOnlyMany、ReadWriteManyにマウントできます。詳しくはアクセスモードを参照してください)を要求することができます。
PersistentVolumeClaimはユーザーに抽象化されたストレージリソースの消費を許可する一方、ユーザーは色々な問題に対処するためにパフォーマンスといった様々なプロパティを持ったPersistentVolumeを必要とすることは一般的なことです。クラスター管理者はユーザーに様々なボリュームがどのように実装されているかを表に出すことなく、サイズやアクセスモードだけではない色々な点で異なった、様々なPersistentVolumeを提供できる必要があります。これらのニーズに応えるために StorageClass リソースがあります。
実例を含む詳細なチュートリアルを参照して下さい。
ボリュームと要求のライフサイクル
PVはクラスター内のリソースです。PVCはこれらのリソースの要求でありまた、クレームのチェックとしても機能します。PVとPVCの相互作用はこのライフサイクルに従います。
プロビジョニング
PVは静的か動的どちらかでプロビジョニングされます。
静的
クラスター管理者は多数のPVを作成します。それらはクラスターのユーザーが使うことのできる実際のストレージの詳細を保持します。それらはKubernetes APIに存在し、利用できます。
動的
ユーザーのPersistentVolumeClaimが管理者の作成したいずれの静的PVにも一致しない場合、クラスターはPVC用にボリュームを動的にプロビジョニングしようとする場合があります。 このプロビジョニングはStorageClassに基づいています。PVCはストレージクラスの要求が必要であり、管理者は動的プロビジョニングを行うためにストレージクラスの作成・設定が必要です。ストレージクラスを""にしたストレージ要求は、自身の動的プロビジョニングを事実上無効にします。
ストレージクラスに基づいたストレージの動的プロビジョニングを有効化するには、クラスター管理者がDefaultStorageClass
アドミッションコントローラーをAPIサーバーで有効化する必要があります。
これは例えば、DefaultStorageClass
がAPIサーバーコンポーネントの--enable-admission-plugins
フラグのコンマ区切りの順序付きリストの中に含まれているかで確認できます。
APIサーバーのコマンドラインフラグの詳細についてはkube-apiserverのドキュメントを参照してください。
バインディング
ユーザは、特定のサイズのストレージとアクセスモードを指定した上でPersistentVolumeClaimを作成します(動的プロビジョニングの場合は、すでに作られています)。マスター内のコントロールループは、新しく作られるPVCをウォッチして、それにマッチするPVが見つかったときに、それらを紐付けます。PVが新しいPVC用に動的プロビジョニングされた場合、コントロールループは常にPVをそのPVCに紐付けます。そうでない場合、ユーザーは常に少なくとも要求したサイズ以上のボリュームを取得しますが、ボリュームは要求されたサイズを超えている可能性があります。一度紐付けされると、どのように紐付けられたかに関係なくPersistentVolumeClaimの紐付けは排他的(決められた特定のPVとしか結びつかない状態)になります。PVCからPVへの紐付けは、PersistentVolumeとPersistentVolumeClaim間の双方向の紐付けであるClaimRefを使用した1対1のマッピングになっています。
一致するボリュームが存在しない場合、クレームはいつまでも紐付けされないままになります。一致するボリュームが利用可能になると、クレームがバインドされます。たとえば、50GiのPVがいくつもプロビジョニングされているクラスターだとしても、100Giを要求するPVCとは一致しません。100GiのPVがクラスターに追加されると、PVCを紐付けできます。
使用
Podは要求をボリュームとして使用します。クラスターは、要求を検査して紐付けられたボリュームを見つけそのボリュームをPodにマウントします。複数のアクセスモードをサポートするボリュームの場合、ユーザーはPodのボリュームとしてクレームを使う時にどのモードを希望するかを指定します。
ユーザーがクレームを取得し、そのクレームがバインドされると、バインドされたPVは必要な限りそのユーザーに属します。ユーザーはPodをスケジュールし、PodのvolumesブロックにpersistentVolumeClaim
を含めることで、バインドされたクレームのPVにアクセスします。
書式の詳細はこちらを確認して下さい。
使用中のストレージオブジェクトの保護
使用中のストレージオブジェクト保護機能の目的はデータ損失を防ぐために、Podによって実際に使用されている永続ボリュームクレーム(PVC)と、PVCにバインドされている永続ボリューム(PV)がシステムから削除されないようにすることです。
ユーザーがPodによって実際に使用されているPVCを削除しても、そのPVCはすぐには削除されません。PVCの削除は、PVCがPodで使用されなくなるまで延期されます。また、管理者がPVCに紐付けられているPVを削除しても、PVはすぐには削除されません。PVがPVCに紐付けられなくなるまで、PVの削除は延期されます。
PVCの削除が保護されているかは、PVCのステータスがTerminating
になっていて、そしてFinalizers
のリストにkubernetes.io/pvc-protection
が含まれているかで確認できます。
kubectl describe pvc hostpath
Name: hostpath
Namespace: default
StorageClass: example-hostpath
Status: Terminating
Volume:
Labels: <none>
Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath
volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [kubernetes.io/pvc-protection]
同様にPVの削除が保護されているかは、PVのステータスがTerminating
になっていて、そしてFinalizers
のリストにkubernetes.io/pv-protection
が含まれているかで確認できます。
kubectl describe pv task-pv-volume
Name: task-pv-volume
Labels: type=local
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating
Claim:
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
再クレーム
ユーザーは、ボリュームの使用が完了したら、リソースの再クレームを許可するAPIからPVCオブジェクトを削除できます。PersistentVolumeの再クレームポリシーはそのクレームが解放された後のボリュームの処理をクラスターに指示します。現在、ボリュームは保持、リサイクル、または削除できます。
保持
Retain
という再クレームポリシーはリソースを手動で再クレームすることができます。PersistentVolumeClaimが削除される時、PersistentVolumeは依然として存在はしますが、ボリュームは解放済みです。ただし、以前のクレームデータはボリューム上に残っているため、別のクレームにはまだ使用できません。管理者は次の手順でボリュームを手動で再クレームできます。
- PersistentVolumeを削除します。PVが削除された後も、外部インフラストラクチャー(AWS EBS、GCE PD、Azure Disk、Cinderボリュームなど)に関連付けられたストレージアセットは依然として残ります。
- ストレージアセットに関連するのデータを手動で適切にクリーンアップします。
- 関連するストレージアセットを手動で削除するか、同じストレージアセットを再利用したい場合、新しいストレージアセット定義と共にPersistentVolumeを作成します。
削除
Delete
再クレームポリシーをサポートするボリュームプラグインの場合、削除するとPersistentVolumeオブジェクトがKubernetesから削除されるだけでなく、AWS EBS、GCE PD、Azure Disk、Cinderボリュームなどの外部インフラストラクチャーの関連ストレージアセットも削除されます。動的にプロビジョニングされたボリュームは、StorageClassの再クレームポリシーを継承します。これはデフォルトで削除です。管理者は、ユーザーの需要に応じてStorageClassを構成する必要があります。そうでない場合、PVは作成後に編集またはパッチを適用する必要があります。PersistentVolumeの再クレームポリシーの変更を参照してください。
リサイクル
Recycle
再クレームポリシーは非推奨になりました。代わりに、動的プロビジョニングを使用することをおすすめします。
基盤となるボリュームプラグインでサポートされている場合、Recycle
再クレームポリシーはボリュームに対して基本的な削除(rm -rf /thevolume/*
)を実行し、新しいクレームに対して再び利用できるようにします。
管理者はreferenceで説明するように、Kubernetesコントローラーマネージャーのコマンドライン引数を使用して、カスタムリサイクラーPodテンプレートを構成できます。カスタムリサイクラーPodテンプレートには、次の例に示すように、volumes
仕様が含まれている必要があります。
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "k8s.gcr.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /scrub)\" || exit 1"]
volumeMounts:
- name: vol
mountPath: /scrub
ただし、カスタムリサイクラーPodテンプレートのvolumes
パート内で指定された特定のパスは、リサイクルされるボリュームの特定のパスに置き換えられます。
永続ボリュームの予約
コントロールプレーンは、永続ボリュームクレームをクラスター内の一致する永続ボリュームにバインドできます。 ただし、永続ボリュームクレームを特定の永続ボリュームにバインドする場合、それらを事前にバインドする必要があります。
永続ボリュームクレームで永続ボリュームを指定することにより、その特定の永続ボリュームと永続ボリュームクレームの間のバインディングを宣言します。
永続ボリュームが存在し、そのclaimRef
フィールドで永続ボリュームクレームを予約していない場合に永続ボリュームと永続ボリュームクレームがバインドされます。
バインディングは、ノードアフィニティを含むいくつかのボリュームの一致基準に関係なく発生します。 コントロールプレーンは、依然としてストレージクラス、アクセスモード、および要求されたストレージサイズが有効であることをチェックします。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: foo
spec:
storageClassName: "" # 空の文字列を明示的に指定する必要があります。そうしないとデフォルトのストレージクラスが設定されてしまいます。
volumeName: foo-pv
...
この方法は、永続ボリュームへのバインド特権を保証するものではありません。
他の永続ボリュームクレームが指定した永続ボリュームを使用できる場合、最初にそのストレージボリュームを予約する必要があります。
永続ボリュームのclaimRef
フィールドに関連する永続ボリュームクレームを指定して、他の永続ボリュームクレームがその永続ボリュームにバインドできないようにしてください。
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
spec:
storageClassName: ""
claimRef:
name: foo-pvc
namespace: foo
...
これは、既存の永続ボリュームを再利用する場合など、claimPolicy
がRetain
に設定されている永続ボリュームを使用する場合に役立ちます。
永続ボリュームクレームの拡大
Kubernetes v1.11 [beta]
PersistentVolumeClaim(PVC)の拡大はデフォルトで有効です。次のボリュームの種類で拡大できます。
- gcePersistentDisk
- awsElasticBlockStore
- Cinder
- glusterfs
- rbd
- Azure File
- Azure Disk
- Portworx
- FlexVolumes
- CSI
そのストレージクラスのallowVolumeExpansion
フィールドがtrueとなっている場合のみ、PVCを拡大できます。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restuser: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
PVCに対してさらに大きなボリュームを要求するには、PVCオブジェクトを編集してより大きなサイズを指定します。これによりPersistentVolumeを受け持つ基盤にボリュームの拡大がトリガーされます。クレームを満たすため新しくPersistentVolumeが作成されることはありません。代わりに既存のボリュームがリサイズされます。
CSIボリュームの拡張
Kubernetes v1.16 [beta]
CSIボリュームの拡張のサポートはデフォルトで有効になっていますが、ボリューム拡張をサポートするにはボリューム拡張を利用できるCSIドライバーも必要です。詳細については、それぞれのCSIドライバーのドキュメントを参照してください。
ファイルシステムを含むボリュームのリサイズ
ファイルシステムがXFS、Ext3、またはExt4の場合にのみ、ファイルシステムを含むボリュームのサイズを変更できます。
ボリュームにファイルシステムが含まれる場合、新しいPodがPersistentVolumeClaim
でReadWriteモードを使用している場合にのみ、ファイルシステムのサイズが変更されます。ファイルシステムの拡張は、Podの起動時、もしくはPodの実行時で基盤となるファイルシステムがオンラインの拡張をサポートする場合に行われます。
FlexVolumesでは、ドライバのRequiresFSResize
機能がtrueに設定されている場合、サイズを変更できます。
FlexVolumeは、Podの再起動時にサイズ変更できます。
使用中の永続ボリュームクレームのリサイズ
Kubernetes v1.15 [beta]
ExpandInUsePersistentVolume
機能を有効化する必要があります。これはベータ機能のため多くのクラスターで自動的に行われます。詳細については、フィーチャーゲートのドキュメントを参照してください。
この場合、既存のPVCを使用しているPodまたはDeploymentを削除して再作成する必要はありません。使用中のPVCは、ファイルシステムが拡張されるとすぐにPodで自動的に使用可能になります。この機能は、PodまたはDeploymentで使用されていないPVCには影響しません。拡張を完了する前に、PVCを使用するPodを作成する必要があります。
他のボリュームタイプと同様、FlexVolumeボリュームは、Podによって使用されている最中でも拡張できます。
ボリューム拡張時の障害からの復旧
基盤ストレージの拡張に失敗した際には、クラスターの管理者はPersistent Volume Claim (PVC)の状態を手動で復旧し、リサイズ要求をキャンセルします。それをしない限り、リサイズ要求は管理者の介入なしにコントローラーによって継続的に再試行されます。
- PersistentVolumeClaim(PVC)にバインドされているPersistentVolume(PV)を
Retain
再クレームポリシーとしてマークします。 - PVCを削除します。PVは
Retain
再クレームポリシーを持っているため、PVCを再び作成したときにいかなるデータも失うことはありません。 claimRef
エントリーをPVスペックから削除して、新しいPVCがそれにバインドできるようにします。これによりPVはAvailable
になります。- PVより小さいサイズでPVCを再作成し、PVCの
volumeName
フィールドをPVの名前に設定します。これにより新しいPVCを既存のPVにバインドします。 - PVを再クレームポリシーを復旧することを忘れずに行ってください。
永続ボリュームの種類
PersistentVolumeの種類はプラグインとして実装されます。Kubernetesは現在次のプラグインに対応しています。
awsElasticBlockStore
- AWS Elastic Block Store (EBS)azureDisk
- Azure DiskazureFile
- Azure Filecephfs
- CephFS volumecinder
- Cinder (OpenStack block storage) (非推奨)csi
- Container Storage Interface (CSI)fc
- Fibre Channel (FC) storageflexVolume
- FlexVolumeflocker
- Flocker storagegcePersistentDisk
- GCE Persistent Diskglusterfs
- Glusterfs volumehostPath
- HostPath volume (テスト用の単一ノードのみ。マルチノードクラスターでは動作しません。代わりにlocal
ボリュームを利用することを検討してください。)iscsi
- iSCSI (SCSI over IP) storagelocal
- ノードにマウントされたローカルストレージデバイスnfs
- Network File System (NFS) storagephotonPersistentDisk
- Photon controller persistent disk (対応するクラウドプロバイダーが削除されたため、このボリュームタイプは機能しなくなりました。)portworxVolume
- Portworx volumequobyte
- Quobyte volumerbd
- Rados Block Device (RBD) volumescaleIO
- ScaleIO volume (非推奨)storageos
- StorageOS volumevsphereVolume
- vSphere VMDK volume
永続ボリューム
各PVには、仕様とボリュームのステータスが含まれているspecとstatusが含まれています。 PersistentVolumeオブジェクトの名前は、有効な DNSサブドメイン名である必要があります。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
/sbin/mount.nfs
が必要になります。
容量
通常、PVには特定のストレージ容量があります。これはPVのcapacity
属性を使用して設定されます。容量によって期待される単位を理解するためには、Kubernetesのリソースモデルを参照してください。
現在、設定または要求できるのはストレージサイズのみです。将来の属性には、IOPS、スループットなどが含まれます。
ボリュームモード
Kubernetes v1.18 [stable]
KubernetesはPersistentVolumesの2つのvolumeModes
をサポートしています: Filesystem
とBlock
です。
volumeMode
は任意のAPIパラメーターです。
Filesystem
はvolumeMode
パラメーターが省略されたときに使用されるデフォルトのモードです。
volumeMode: Filesystem
であるボリュームはPodにマウントされてディレクトリになります。 ボリュームがブロックデバイスでデバイスが空の時、Kubernetesは初めてそれにマウントされる前にデバイスのファイルシステムを作成します。
volumeMode
の値をBlock
に設定してボリュームをRAWブロックデバイスとして使用します。
このようなボリュームは、ファイルシステムを持たないブロックデバイスとしてPodに提示されます。
このモードは、Podとボリュームの間のファイルシステムレイヤなしにボリュームにアクセスする可能な限り最速の方法をPodに提供するのに便利です。一方で、Pod上で実行しているアプリケーションはRAWブロックデバイスの扱い方を知っていなければなりません。
Pod内でvolumeMode: Block
とともにボリュームを使用する例としては、Raw Block Volume Supportを参照してください。
アクセスモード
PersistentVolumeは、リソースプロバイダーがサポートする方法でホストにマウントできます。次の表に示すように、プロバイダーにはさまざまな機能があり、各PVのアクセスモードは、その特定のボリュームでサポートされる特定のモードに設定されます。たとえば、NFSは複数の読み取り/書き込みクライアントをサポートできますが、特定のNFSのPVはサーバー上で読み取り専用としてエクスポートされる場合があります。各PVは、その特定のPVの機能を記述する独自のアクセスモードのセットを取得します。
アクセスモードは次の通りです。
ReadWriteOnce
- ボリュームは単一のNodeで読み取り/書き込みとしてマウントできます
ReadOnlyMany
- ボリュームは多数のNodeで読み取り専用としてマウントできます
ReadWriteMany
- ボリュームは多数のNodeで読み取り/書き込みとしてマウントできます
ReadWriteOncePod
- ボリュームは、単一のPodで読み取り/書き込みとしてマウントできます。クラスタ全体で1つのPodのみがそのPVCの読み取りまたは書き込みを行えるようにする場合は、ReadWriteOncePodアクセスモードを使用します。これは、CSIボリュームとKubernetesバージョン1.22以降でのみサポートされます。
これについてはブログIntroducing Single Pod Access Mode for PersistentVolumesに詳細が記載されています。
CLIではアクセスモードは次のように略されます。
- RWO - ReadWriteOnce
- ROX - ReadOnlyMany
- RWX - ReadWriteMany
Important! ボリュームは、多数のモードをサポートしていても、一度に1つのアクセスモードでしかマウントできません。たとえば、GCEPersistentDiskは、単一NodeではReadWriteOnceとして、または多数のNodeではReadOnlyManyとしてマウントできますが、同時にマウントすることはできません。
ボリュームプラグイン | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStore | ✓ | - | - |
AzureFile | ✓ | ✓ | ✓ |
AzureDisk | ✓ | - | - |
CephFS | ✓ | ✓ | ✓ |
Cinder | ✓ | - | - |
CSI | ドライバーに依存 | ドライバーに依存 | ドライバーに依存 |
FC | ✓ | ✓ | - |
FlexVolume | ✓ | ✓ | ドライバーに依存 |
Flocker | ✓ | - | - |
GCEPersistentDisk | ✓ | ✓ | - |
Glusterfs | ✓ | ✓ | ✓ |
HostPath | ✓ | - | - |
iSCSI | ✓ | ✓ | - |
Quobyte | ✓ | ✓ | ✓ |
NFS | ✓ | ✓ | ✓ |
RBD | ✓ | ✓ | - |
VsphereVolume | ✓ | - | - (Podが連結されている場合のみ) |
PortworxVolume | ✓ | - | ✓ |
ScaleIO | ✓ | ✓ | - |
StorageOS | ✓ | - | - |
Class
PVはクラスを持つことができます。これはstorageClassName
属性をストレージクラスの名前に設定することで指定されます。特定のクラスのPVは、そのクラスを要求するPVCにのみバインドできます。storageClassName
にクラスがないPVは、特定のクラスを要求しないPVCにのみバインドできます。
以前volume.beta.kubernetes.io/storage-class
アノテーションは、storageClassName
属性の代わりに使用されていました。このアノテーションはまだ機能しています。ただし、将来のKubernetesリリースでは完全に非推奨です。
再クレームポリシー
現在の再クレームポリシーは次のとおりです。
- 保持 -- 手動再クレーム
- リサイクル -- 基本的な削除 (
rm -rf /thevolume/*
) - 削除 -- AWS EBS、GCE PD、Azure Disk、もしくはOpenStack Cinderボリュームに関連するストレージアセットを削除
現在、NFSとHostPathのみがリサイクルをサポートしています。AWS EBS、GCE PD、Azure Disk、およびCinder volumeは削除をサポートしています。
マウントオプション
Kubernetes管理者は永続ボリュームがNodeにマウントされるときの追加マウントオプションを指定できます。
次のボリュームタイプがマウントオプションをサポートしています。
- AWSElasticBlockStore
- AzureDisk
- AzureFile
- CephFS
- Cinder (OpenStackブロックストレージ)
- GCEPersistentDisk
- Glusterfs
- NFS
- Quobyte Volumes
- RBD (Ceph Block Device)
- StorageOS
- VsphereVolume
- iSCSI
マウントオプションは検証されないため、不正だった場合マウントは失敗します。
以前volume.beta.kubernetes.io/mount-options
アノテーションがmountOptions
属性の代わりに使われていました。このアノテーションはまだ機能しています。ただし、将来のKubernetesリリースでは完全に非推奨です。
ノードアフィニティ
PVはノードアフィニティを指定して、このボリュームにアクセスできるNodeを制限する制約を定義できます。PVを使用するPodは、ノードアフィニティによって選択されたNodeにのみスケジュールされます。
フェーズ
ボリュームは次のフェーズのいずれかです。
- 利用可能 -- まだクレームに紐付いていない自由なリソース
- バウンド -- クレームに紐付いている
- リリース済み -- クレームが削除されたが、クラスターにまだクレームされている
- 失敗 -- 自動再クレームに失敗
CLIにはPVに紐付いているPVCの名前が表示されます。
永続ボリューム要求
各PVCにはspecとステータスが含まれます。これは、仕様とクレームのステータスです。
PersistentVolumeClaimオブジェクトの名前は、有効な DNSサブドメイン名である必要があります。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
アクセスモード
クレームは、特定のアクセスモードでストレージを要求するときにボリュームと同じ規則を使用します。
ボリュームモード
クレームは、ボリュームと同じ規則を使用して、ファイルシステムまたはブロックデバイスとしてのボリュームの消費を示します。
リソース
Podと同様に、クレームは特定の量のリソースを要求できます。この場合、要求はストレージ用です。同じリソースモデルがボリュームとクレームの両方に適用されます。
セレクター
クレームでは、ラベルセレクターを指定して、ボリュームセットをさらにフィルター処理できます。ラベルがセレクターに一致するボリュームのみがクレームにバインドできます。セレクターは2つのフィールドで構成できます。
matchLabels
- ボリュームはこの値のラベルが必要ですmatchExpressions
- キー、値のリスト、およびキーと値を関連付ける演算子を指定することによって作成された要件のリスト。有効な演算子は、In、NotIn、ExistsおよびDoesNotExistです。
matchLabels
とmatchExpressions
の両方からのすべての要件はANDで結合されます。一致するには、すべてが一致する必要があります。
クラス
クレームは、storageClassName
属性を使用してストレージクラスの名前を指定することにより、特定のクラスを要求できます。PVCにバインドできるのは、PVCと同じstorageClassName
を持つ、要求されたクラスのPVのみです。
PVCは必ずしもクラスをリクエストする必要はありません。storageClassName
が""
に設定されているPVCは、クラスのないPVを要求していると常に解釈されるため、クラスのないPVにのみバインドできます(アノテーションがないか、""
に等しい1つのセット)。storageClassName
のないPVCはまったく同じではなく、DefaultStorageClass
アドミッションプラグインがオンになっているかどうかによって、クラスターによって異なる方法で処理されます。
- アドミッションプラグインがオンになっている場合、管理者はデフォルトの
StorageClass
を指定できます。storageClassName
を持たないすべてのPVCは、そのデフォルトのPVにのみバインドできます。デフォルトのStorageClass
の指定は、StorageClass
オブジェクトでstorageclass.kubernetes.io/is-default-class
アノテーションをtrue
に設定することにより行われます。管理者がデフォルトを指定しない場合、クラスターは、アドミッションプラグインがオフになっているかのようにPVC作成をレスポンスします。複数のデフォルトが指定されている場合、アドミッションプラグインはすべてのPVCの作成を禁止します。 - アドミッションプラグインがオフになっている場合、デフォルトの
StorageClass
の概念はありません。storageClassName
を持たないすべてのPVCは、クラスを持たないPVにのみバインドできます。この場合、storageClassNameを持たないPVCは、storageClassName
が""
に設定されているPVCと同じように扱われます。
インストール方法によっては、インストール時にアドオンマネージャーによってデフォルトのストレージクラスがKubernetesクラスターにデプロイされる場合があります。
PVCがselector
を要求することに加えてStorageClass
を指定する場合、要件はANDで一緒に結合されます。要求されたクラスのPVと要求されたラベルのみがPVCにバインドされます。
selector
が空ではないPVCは、PVを動的にプロビジョニングできません。
以前は、storageClassName
属性の代わりにvolume.beta.kubernetes.io/storage-class
アノテーションが使用されていました。このアノテーションはまだ機能しています。ただし、今後のKubernetesリリースではサポートされません。
ボリュームとしてのクレーム
Podは、クレームをボリュームとして使用してストレージにアクセスします。クレームは、そのクレームを使用するPodと同じ名前空間に存在する必要があります。クラスターは、Podの名前空間でクレームを見つけ、それを使用してクレームを支援しているPersistentVolumeを取得します。次に、ボリュームがホストとPodにマウントされます。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
名前空間に関する注意
PersistentVolumeバインドは排他的であり、PersistentVolumeClaimは名前空間オブジェクトであるため、"多"モード(ROX
、RWX
)でクレームをマウントすることは1つの名前空間内でのみ可能です。
Rawブロックボリュームのサポート
Kubernetes v1.18 [stable]
次のボリュームプラグインは、必要に応じて動的プロビジョニングを含むrawブロックボリュームをサポートします。
- AWSElasticBlockStore
- AzureDisk
- CSI
- FC (Fibre Channel)
- GCEPersistentDisk
- iSCSI
- Local volume
- OpenStack Cinder
- RBD (Ceph Block Device)
- VsphereVolume
Rawブロックボリュームを使用した永続ボリューム
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
Rawブロックボリュームを要求する永続ボリュームクレーム
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
コンテナにRawブロックデバイスパスを追加するPod仕様
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: [ "tail -f /dev/null" ]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
ブロックボリュームのバインド
ユーザーがPersistentVolumeClaim specのvolumeMode
フィールドを使用してrawブロックボリュームの要求を示す場合、バインディングルールは、このモードをspecの一部として考慮しなかった以前のリリースとわずかに異なります。表にリストされているのは、ユーザーと管理者がrawブロックデバイスを要求するために指定可能な組み合わせの表です。この表は、ボリュームがバインドされるか、組み合わせが与えられないかを示します。静的にプロビジョニングされたボリュームのボリュームバインディングマトリクスはこちらです。
PVボリュームモード | PVCボリュームモード | 結果 |
---|---|---|
未定義 | 未定義 | バインド |
未定義 | ブロック | バインドなし |
未定義 | ファイルシステム | バインド |
ブロック | 未定義 | バインドなし |
ブロック | ブロック | バインド |
ブロック | ファイルシステム | バインドなし |
ファイルシステム | ファイルシステム | バインド |
ファイルシステム | ブロック | バインドなし |
ファイルシステム | 未定義 | バインド |
ボリュームのスナップショットとスナップショットからのボリュームの復元のサポート
Kubernetes v1.17 [beta]
ボリュームスナップショット機能は、CSIボリュームプラグインのみをサポートするために追加されました。詳細については、ボリュームのスナップショットを参照してください。
ボリュームスナップショットのデータソースからボリュームを復元する機能を有効にするには、apiserverおよびcontroller-managerでVolumeSnapshotDataSource
フィーチャーゲートを有効にします。
ボリュームスナップショットから永続ボリュームクレームを作成する
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
ボリュームの複製
ボリュームの複製はCSIボリュームプラグインにのみ利用可能です。
PVCデータソースからのボリューム複製機能を有効にするには、apiserverおよびcontroller-managerでVolumeSnapshotDataSource
フィーチャーゲートを有効にします。
既存のPVCからの永続ボリュームクレーム作成
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
可搬性の高い設定の作成
もし幅広いクラスターで実行され、永続ボリュームが必要となる構成テンプレートやサンプルを作成している場合は、次のパターンを使用することをお勧めします。
-
構成にPersistentVolumeClaimオブジェクトを含める(DeploymentやConfigMapと共に)
-
ユーザーが設定をインスタンス化する際にPersistentVolumeを作成する権限がない場合があるため、設定にPersistentVolumeオブジェクトを含めない。
-
テンプレートをインスタンス化する時にストレージクラス名を指定する選択肢をユーザーに与える
- ユーザーがストレージクラス名を指定する場合、persistentVolumeClaim.storageClassName フィールドにその値を入力する。これにより、クラスターが管理者によって有効にされたストレージクラスを持っている場合、PVCは正しいストレージクラスと一致する。
- ユーザーがストレージクラス名を指定しない場合、
persistentVolumeClaim.storageClassName
フィールドはnilのままにする。これにより、PVはユーザーにクラスターのデフォルトストレージクラスで自動的にプロビジョニングされる。多くのクラスター環境ではデフォルトのストレージクラスがインストールされているが、管理者は独自のデフォルトストレージクラスを作成することができる。
-
ツールがPVCを監視し、しばらくしてもバインドされないことをユーザーに表示する。これはクラスターが動的ストレージをサポートしない(この場合ユーザーは対応するPVを作成するべき)、もしくはクラスターがストレージシステムを持っていない(この場合ユーザーはPVCを必要とする設定をデプロイできない)可能性があることを示す。
次の項目
- Creating a Persistent Volumeについて学ぶ
- Creating a Persistent Volume Claimについて学ぶ
- Persistent Storage design documentを読む
リファレンス
3 - 投影ボリューム
このドキュメントでは、Kubernetesの投影ボリュームについて説明します。ボリュームに精通していることをお勧めします。
概要
ボリュームは、いくつかの既存の投影
ボリュームソースを同じディレクトリにマップします。
現在、次のタイプのボリュームソースを投影できます。
secret
downwardAPI
configMap
serviceAccountToken
すべてのソースは、Podと同じnamespaceにある必要があります。詳細はall-in-one volumeデザインドキュメントを参照してください。
secret、downwardAPI、およびconfigMapを使用した構成例
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: container-test
resource: limits.cpu
- configMap:
name: myconfigmap
items:
- key: config
path: my-group/my-config
構成例:デフォルト以外のアクセス許可モードが設定されたsecret
apiVersion: v1
kind: Pod
metadata:
name: volume-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: mysecret
items:
- key: username
path: my-group/my-username
- secret:
name: mysecret2
items:
- key: password
path: my-group/my-password
mode: 511
各投影ボリュームソースは、specのsources
にリストされています。パラメーターは、2つの例外を除いてほぼ同じです。
- secretについて、ConfigMapの命名と一致するように
secretName
フィールドがname
に変更されました。 defaultMode
はprojectedレベルでのみ指定でき、各ボリュームソースには指定できません。ただし上に示したように、個々の投影ごとにmode
を明示的に設定できます。
TokenRequestProjection
機能が有効になっている場合、現在のサービスアカウントトークンを指定されたパスのPodに挿入できます。例えば:
apiVersion: v1
kind: Pod
metadata:
name: sa-token-test
spec:
containers:
- name: container-test
image: busybox
volumeMounts:
- name: token-vol
mountPath: "/service-account"
readOnly: true
serviceAccountName: default
volumes:
- name: token-vol
projected:
sources:
- serviceAccountToken:
audience: api
expirationSeconds: 3600
path: token
この例のPodには、挿入されたサービスアカウントトークンを含む投影ボリュームがあります。このトークンはPodのコンテナがKubernetes APIサーバーにアクセスするために使用できます。このaudience
フィールドにはトークンの受信対象者が含まれています。トークンの受信者は、トークンのaudience
フィールドで指定された識別子で自分自身であるかを識別します。そうでない場合はトークンを拒否します。このフィールドはオプションで、デフォルトではAPIサーバーの識別子が指定されます。
expirationSeconds
はサービスアカウントトークンが有効であると予想される期間です。
デフォルトは1時間で、最低でも10分(600秒)でなければなりません。
管理者は、APIサーバーに--service-account-max-token-expiration
オプションを指定することで、その最大値を制限することも可能です。
path
フィールドは、投影ボリュームのマウントポイントへの相対パスを指定します。
subPath
ボリュームマウントとして使用しているコンテナは、それらのボリュームソースの更新を受信しません。
SecurityContextの相互作用
サービスアカウントの投影ボリューム拡張でのファイル権限処理の提案により、正しい所有者権限が設定された投影ファイルが導入されました。
Linux
投影ボリュームがあり、PodのSecurityContext
にRunAsUser
が設定されているLinux Podでは、投影されたファイルには、コンテナユーザーの所有権を含む正しい所有権が設定されます。
Windows
投影ボリュームを持ち、PodのSecurityContext
でRunAsUsername
を設定したWindows Podでは、Windowsのユーザーアカウント管理方法により所有権が強制されません。
Windowsは、ローカルユーザーとグループアカウントをセキュリティアカウントマネージャー(SAM)と呼ばれるデータベースファイルに保存し、管理します。
各コンテナはSAMデータベースの独自のインスタンスを維持し、コンテナの実行中はホストはそのインスタンスを見ることができません。
Windowsコンテナは、OSのユーザーモード部分をホストから分離して実行するように設計されており、そのため仮想SAMデータベースを維持することになります。
そのため、ホスト上で動作するkubeletには、仮想化されたコンテナアカウントのホストファイル所有権を動的に設定する機能がありません。
ホストマシン上のファイルをコンテナと共有する場合は、C:\
以外の独自のボリュームマウントに配置することをお勧めします。
デフォルトでは、投影ボリュームファイルの例に示されているように、投影されたファイルには次の所有権があります。
PS C:\> Get-Acl C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt | Format-List
Path : Microsoft.PowerShell.Core\FileSystem::C:\var\run\secrets\kubernetes.io\serviceaccount\..2021_08_31_22_22_18.318230061\ca.crt
Owner : BUILTIN\Administrators
Group : NT AUTHORITY\SYSTEM
Access : NT AUTHORITY\SYSTEM Allow FullControl
BUILTIN\Administrators Allow FullControl
BUILTIN\Users Allow ReadAndExecute, Synchronize
Audit :
Sddl : O:BAG:SYD:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU)
これは、ContainerAdministrator
のようなすべての管理者ユーザーが読み取り、書き込み、および実行アクセス権を持ち、非管理者ユーザーが読み取りおよび実行アクセス権を持つことを意味します。
一般に、コンテナにホストへのアクセスを許可することは、潜在的なセキュリティの悪用への扉を開く可能性があるため、お勧めできません。
Windows PodのSecurityContext
にRunAsUser
を指定して作成すると、PodはContainerCreating
で永久に固まります。したがって、Windows PodでLinux専用のRunAsUser
オプションを使用しないことをお勧めします。
4 - CSI Volume Cloning
このドキュメントではKubernetesで既存のCSIボリュームの複製についてのコンセプトを説明します。このページを読む前にあらかじめボリュームについてよく理解していることが望ましいです。
イントロダクション
CSIのボリューム複製機能は、ユーザーがボリュームの複製を作成することを示すdataSource
フィールドで既存のPVCを指定するためのサポートを追加します。
複製は既存のKubernetesボリュームの複製として定義され、標準のボリュームと同じように使用できます。唯一の違いは、プロビジョニング時に「新しい」空のボリュームを作成するのではなく、バックエンドデバイスが指定されたボリュームの正確な複製を作成することです。
複製の実装は、Kubernetes APIの観点からは新しいPVCの作成時に既存のPVCをdataSourceとして指定する機能を追加するだけです。ソースPVCはバインドされており、使用可能でなければなりません(使用中ではありません)。
この機能を使用する場合、ユーザーは次のことに注意する必要があります:
- 複製のサポート(
VolumePVCDataSource
)はCSIドライバーのみです。 - 複製のサポートは動的プロビジョニングのみです。
- CSIドライバーはボリューム複製機能を実装している場合としていない場合があります。
- PVCは複製先のPVCと同じ名前空間に存在する場合にのみ複製できます(複製元と複製先は同じ名前空間になければなりません)。
- 複製は同じストレージクラス内でのみサポートされます。
- 宛先ボリュームは、ソースと同じストレージクラスである必要があります。
- デフォルトのストレージクラスを使用でき、仕様ではstorageClassNameを省略できます。
- 複製は同じVolumeMode設定を使用する2つのボリューム間でのみ実行できます(ブロックモードのボリュームを要求する場合、ソースもブロックモードである必要があります)。
プロビジョニング
複製は同じ名前空間内の既存のPVCを参照するdataSourceを追加すること以外は他のPVCと同様にプロビジョニングされます。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: clone-of-pvc-1
namespace: myns
spec:
accessModes:
- ReadWriteOnce
storageClassName: cloning
resources:
requests:
storage: 5Gi
dataSource:
kind: PersistentVolumeClaim
name: pvc-1
spec.resources.requests.storage
に容量の値を指定する必要があります。指定する値は、ソースボリュームの容量と同じかそれ以上である必要があります。
このyamlの作成結果は指定された複製元であるpvc-1
と全く同じデータを持つclone-of-pvc-1
という名前の新しいPVCです。
使い方
新しいPVCが使用可能になると、複製されたPVCは他のPVCと同じように利用されます。またこの時点で新しく作成されたPVCは独立したオブジェクトであることが期待されます。元のdataSource PVCを考慮せず個別に利用、複製、スナップショット、削除できます。これはまた複製元が新しく作成された複製にリンクされておらず、新しく作成された複製に影響を与えずに変更または削除できることを意味します。
5 - VolumeSnapshotClass
このドキュメントでは、KubernetesにおけるVolumeSnapshotClass
のコンセプトについて説明します。
関連する項目として、Volumeのスナップショットとストレージクラスも参照してください。
イントロダクション
StorageClass
はVolumeをプロビジョンするときに、ストレージの"クラス"に関する情報を記述する方法を提供します。それと同様に、VolumeSnapshotClass
ではVolumeSnapshotをプロビジョンするときに、ストレージの"クラス"に関する情報を記述する方法を提供します。
VolumeSnapshotClass リソース
各VolumeSnapshotClass
はdriver
、deletionPolicy
とparameters
フィールドを含み、それらは、そのクラスに属するVolumeSnapshot
が動的にプロビジョンされるときに使われます。
VolumeSnapshotClass
オブジェクトの名前は重要であり、それはユーザーがどのように特定のクラスをリクエストできるかを示したものです。管理者は初めてVolumeSnapshotClass
オブジェクトを作成するときに、その名前と他のパラメーターをセットし、そのオブジェクトは一度作成されるとそのあと更新することができません。
管理者は、バインド対象のクラスを1つもリクエストしないようなVolumeSnapshotのために、デフォルトのVolumeSnapshotClass
を指定することができます。
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
name: csi-hostpath-snapclass
driver: hostpath.csi.k8s.io
deletionPolicy: Delete
parameters:
Driver
VolumeSnapshotClassは、VolumeSnapshotをプロビジョンするときに何のCSIボリュームプラグインを使うか決定するためのdriver
フィールドを持っています。このフィールドは必須となります。
DeletionPolicy
VolumeSnapshotClassにはdeletionPolicyがあります。これにより、バインドされている VolumeSnapshot
オブジェクトが削除されるときに、VolumeSnapshotContent
がどうなるかを設定することができます。VolumeSnapshotのdeletionPolicyは、Retain
またはDelete
のいずれかです。このフィールドは指定しなければなりません。
deletionPolicyがDelete
の場合、元となるストレージスナップショットは VolumeSnapshotContent
オブジェクトとともに削除されます。deletionPolicyがRetain
の場合、元となるスナップショットとVolumeSnapshotContent
の両方が残ります。
Parameters
VolumeSnapshotClassは、そのクラスに属するVolumeSnapshotを指定するパラメータを持っています。
driver
に応じて様々なパラメータを使用できます。
6 - ボリュームの動的プロビジョニング(Dynamic Volume Provisioning)
ボリュームの動的プロビジョニングにより、ストレージ用のボリュームをオンデマンドに作成することができます。
動的プロビジョニングなしでは、クラスター管理者はクラウドプロバイダーまたはストレージプロバイダーに対して新規のストレージ用のボリュームとPersistentVolume
オブジェクトを作成するように手動で指示しなければなりません。動的プロビジョニングの機能によって、クラスター管理者がストレージを事前にプロビジョンする必要がなくなります。その代わりに、ユーザーによってリクエストされたときに自動でストレージをプロビジョンします。
バックグラウンド
ボリュームの動的プロビジョニングの実装はstorage.k8s.io
というAPIグループ内のStorageClass
というAPIオブジェクトに基づいています。クラスター管理者はStorageClass
オブジェクトを必要に応じていくつでも定義でき、各オブジェクトはボリュームをプロビジョンするVolumeプラグイン (別名プロビジョナー)と、プロビジョンされるときにプロビジョナーに渡されるパラメータを指定します。
クラスター管理者はクラスター内で複数の種類のストレージ(同一または異なるストレージシステム)を定義し、さらには公開でき、それらのストレージはパラメータのカスタムセットを持ちます。この仕組みにおいて、エンドユーザーはストレージがどのようにプロビジョンされるか心配する必要がなく、それでいて複数のストレージオプションから選択できることを保証します。
StorageClassに関するさらなる情報はStorage Classを参照ください。
動的プロビジョニングを有効にする
動的プロビジョニングを有効にするために、クラスター管理者はユーザーのために1つまたはそれ以上のStorageClassを事前に作成する必要があります。StorageClassオブジェクトは、動的プロビジョニングが実行されるときに、どのプロビジョナーが使用されるべきか、またどのようなパラメーターをプロビジョナーに渡すべきか定義します。StorageClassオブジェクトの名前は、有効なDNSサブドメイン名である必要があります。
下記のマニフェストでは標準的な永続化ディスクをプロビジョンする"slow"というStorageClassを作成します。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
下記のマニフェストではSSDを使った永続化ディスクをプロビジョンする"fast"というStorageClassを作成します。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
動的プロビジョニングの使用
ユーザーはPersistentVolumeClaim
リソース内でStorageClassを含むことで、動的にプロビジョンされたStorageをリクエストできます。Kubernetes v1.6以前では、この機能はvolume.beta.kubernetes.io/storage-class
アノテーションを介して使うことができました。しかしこのアノテーションではv1.6から廃止になりました。その代わりユーザーは現在ではPersistentVolumeClaim
オブジェクトのstorageClassName
を使う必要があります。このフィールドの値は、管理者によって設定されたStorageClass
の名前と一致しなければなりません(下記のセクションも参照ください)。
"fast"というStorageClassを選択するために、例としてユーザーは下記のPersistentVolumeClaimを作成します。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim1
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast
resources:
requests:
storage: 30Gi
このリソースによってSSDのような永続化ディスクが自動的にプロビジョンされます。このリソースが削除された時、そのボリュームは削除されます。
デフォルトの挙動
動的プロビジョニングは、もしStorageClassが1つも指定されていないときに全てのPersistentVolumeClaimが動的にプロビジョンされるようにクラスター上で有効にできます。クラスター管理者は、下記を行うことによりこのふるまいを有効にできます。
- 1つの
StorageClass
オブジェクトをdefault としてマーキングする - API Server上で
DefaultStorageClass
管理コントローラーを有効にする。
管理者はStorageClass
に対してstorageclass.kubernetes.io/is-default-class
アノテーションをつけることで、デフォルトのStorageClassとしてマーキングできます。
デフォルトのStorageClass
がクラスター内で存在し、かつユーザーがPersistentVolumeClaim
リソースでstorageClassName
を指定しなかった場合、DefaultStorageClass
という管理コントローラーはstorageClassName
フィールドの値をデフォルトのStorageClassを指し示すように自動で追加します。
注意点として、クラスター上では最大1つしかデフォルト のStorageClassが指定できず、storageClassName
を明示的に指定しないPersistentVolumeClaim
は作成することもできません。
トポロジーに関する注意
マルチゾーンクラスター内では、Podは単一のリージョン内のゾーンをまたいでしか稼働できません。シングルゾーンのStorageバックエンドはPodがスケジュールされるゾーン内でプロビジョンされる必要があります。これはVolume割り当てモードを設定することにより可能となります。
7 - ストレージ容量
ストレージ容量は、Podが実行されるノードごとに制限があったり、大きさが異なる可能性があります。たとえば、NASがすべてのノードからはアクセスできなかったり、初めからストレージがノードローカルでしか利用できない可能性があります。
Kubernetes v1.19 [alpha]
このページでは、Kubernetesがストレージ容量を追跡し続ける方法と、スケジューラーがその情報を利用して、残りの未作成のボリュームのために十分なストレージ容量へアクセスできるノード上にどのようにPodをスケジューリングするかについて説明します。もしストレージ容量の追跡がなければ、スケジューラーは、ボリュームをプロビジョニングするために十分な容量のないノードを選択してしまい、スケジューリングの再試行が複数回行われてしまう恐れがあります。
ストレージ容量の追跡は、Container Storage Interface(CSI)向けにサポートされており、CSIドライバーのインストール時に有効にする必要があります。
API
この機能には、以下の2つのAPI拡張があります。
-
CSIStorageCapacityオブジェクト: このオブジェクトは、CSIドライバーがインストールされた名前空間に生成されます。各オブジェクトには1つのストレージクラスに対する容量の情報が含まれ、そのストレージに対してどのノードがアクセス権を持つかが定められています。
-
CSIDriverSpec.StorageCapacity
フィールド:true
に設定すると、Kubernetesのスケジューラーが、CSIドライバーを使用するボリュームに対してストレージ容量を考慮するようになります。
スケジューリング
ストレージ容量の情報がKubernetesのスケジューラーで利用されるのは、以下のすべての条件を満たす場合です。
CSIStorageCapacity
フィーチャーゲートがtrueである- Podがまだ作成されていないボリュームを使用する時
- そのボリュームが、CSIドライバーを参照し、volume binding modeに
WaitForFirstConsumer
を使うStorageClassを使用している - ドライバーに対する
CSIDriver
オブジェクトのStorageCapacity
がtrueに設定されている
その場合、スケジューラーはPodに対して、十分なストレージ容量が利用できるノードだけを考慮するようになります。このチェックは非常に単純で、ボリュームのサイズと、CSIStorageCapacity
オブジェクトに一覧された容量を、ノードを含むトポロジーで比較するだけです。
volume binding modeがImmediate
のボリュームの場合、ストレージドライバーはボリュームを使用するPodとは関係なく、ボリュームを作成する場所を決定します。次に、スケジューラーはボリュームが作成された後、Podをボリュームが利用できるノードにスケジューリングします。
CSI ephemeral volumesの場合、スケジューリングは常にストレージ容量を考慮せずに行われます。このような動作になっているのは、このボリュームタイプはノードローカルな特別なCSIドライバーでのみ使用され、そこでは特に大きなリソースが必要になることはない、という想定に基づいています。
再スケジューリング
WaitForFirstConsumer
ボリュームがあるPodに対してノードが選択された場合は、その決定はまだ一時的なものです。次のステップで、CSIストレージドライバーに対して、選択されたノード上でボリュームが利用可能になることが予定されているというヒントを使用してボリュームの作成を要求します。
Kubernetesは古い容量の情報をもとにノードを選択する場合があるため、実際にはボリュームが作成できないという可能性が存在します。その場合、ノードの選択がリセットされ、KubernetesスケジューラーはPodに割り当てるノードを再び探します。
制限
ストレージ容量を追跡することで、1回目の試行でスケジューリングが成功する可能性が高くなります。しかし、スケジューラーは潜在的に古い情報に基づいて決定を行う可能性があるため、成功を保証することはできません。通常、ストレージ容量の情報が存在しないスケジューリングと同様のリトライの仕組みによって、スケジューリングの失敗に対処します。
スケジューリングが永続的に失敗する状況の1つは、Podが複数のボリュームを使用する場合で、あるトポロジーのセグメントで1つのボリュームがすでに作成された後、もう1つのボリュームのために十分な容量が残っていないような場合です。この状況から回復するには、たとえば、容量を増加させたり、すでに作成されたボリュームを削除するなどの手動での対応が必要です。この問題に自動的に対処するためには、まだ追加の作業が必要となっています。
ストレージ容量の追跡を有効にする
ストレージ容量の追跡はアルファ機能であり、CSIStorageCapacity
フィーチャーゲートとstorage.k8s.io/v1alpha1
API groupを有効にした場合にのみ、有効化されます。詳細については、--feature-gates
および--runtime-config
kube-apiserverパラメータを参照してください。
Kubernetesクラスターがこの機能をサポートしているか簡単に確認するには、以下のコマンドを実行して、CSIStorageCapacityオブジェクトを一覧表示します。
kubectl get csistoragecapacities --all-namespaces
クラスターがCSIStorageCapacityをサポートしていれば、CSIStorageCapacityのリストが表示されるか、次のメッセージが表示されます。
No resources found
もしサポートされていなければ、代わりに次のエラーが表示されます。
error: the server doesn't have a resource type "csistoragecapacities"
クラスター内で機能を有効化することに加えて、CSIドライバーもこの機能をサポートしている必要があります。詳細については、各ドライバーのドキュメントを参照してください。
次の項目
- 設計に関するさらなる情報について知るために、Storage Capacity Constraints for Pod Scheduling KEPを読む。
- この機能の今後の開発に関する情報について知るために、enhancement tracking issue #1472を参照する。
- Kubernetesのスケジューラーについてもっと学ぶ。