これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.
ストレージ
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: registry.k8s.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
ボリュームは複数の書き込み元によって同時にマウントすることができます。
備考:
事前に共有をエクスポートした状態で、自分のCephサーバーを起動しておく必要があります。詳細についてはCephFSの例を参照してください。
cinder
備考:
KubernetesはOpenStackクラウドプロバイダーで構成する必要があります。cinder
ボリュームタイプは、PodにOpenStackのCinderのボリュームをマウントするために使用されます。
Cinderボリュームの設定例
apiVersion: v1
kind: Pod
metadata:
name: test-cinder
spec:
containers:
- image: registry.k8s.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
内のデータは永久に削除されます。
備考:
コンテナがクラッシュしても、ノードからPodが削除されることはありません。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: registry.k8s.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がマルチパス接続からのものであると想定します。
備考:
Kubernetesホストがアクセスできるように、事前にこれらのLUN(ボリューム)をターゲットWWNに割り当ててマスクするようにFCSANゾーニングを構成する必要があります。詳細についてはfibre channelの例を参照してください。
flocker (非推奨)
Flockerはオープンソースのクラスター化されたコンテナデータボリュームマネージャーです。 Flockerは、さまざまなストレージバックエンドに支えられたデータボリュームの管理とオーケストレーションを提供します。
flocker
ボリュームを使用すると、FlockerデータセットをPodにマウントできます。
もしデータセットがまだFlockerに存在しない場合は、まずFlocker CLIかFlocker APIを使ってデータセットを作成する必要があります。
データセットがすでに存在する場合は、FlockerによってPodがスケジュールされているノードに再アタッチされます。
これは、必要に応じてPod間でデータを共有できることを意味します。
備考:
使用する前に、独自のFlockerインストールを実行する必要があります。詳細については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: registry.k8s.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を使用するためには、事前に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: registry.k8s.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: registry.k8s.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サーバーを起動する必要があります。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が持つ可能性のある他のノード制約も含めて評価されるようになります。
ローカルボリュームのライフサイクルの管理を改善するために、外部の静的プロビジョナーを個別に実行できます。 このプロビジョナーはまだ動的プロビジョニングをサポートしていないことに注意してください。 外部ローカルプロビジョナーの実行方法の例については、ローカルボリュームプロビジョナーユーザーガイドを参照してください。
備考:
ボリュームのライフサイクルを管理するために外部の静的プロビジョナーが使用されていない場合、ローカルのPersistentVolumeは、ユーザーによる手動のクリーンアップと削除を必要とします。nfs
nfs
ボリュームは、既存のNFS(Network File System)共有をPodにマウントすることを可能にします。Podを取り外すと消去されるemptyDir
とは異なり、nfs
ボリュームのコンテンツは保存され、単にアンマウントされるだけです。
つまり、NFSボリュームにはあらかじめデータを入れておくことができ、そのデータをPod間で共有することができます。
NFSは複数のライターによって同時にマウントすることができます。
備考:
使用する前に、共有をエクスポートして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: registry.k8s.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>"
備考:
Podで使用する前に、pxvol
という名前の既存のPortworxVolumeがあることを確認してください。詳細についてはPortworxボリュームの例を参照してください。
投影
投影ボリュームは、複数の既存のボリュームソースを同じディレクトリにマッピングします。 詳細については投影ボリュームを参照してください。
quobyte(非推奨)
quobyte
ボリュームは、既存のQuobyteボリュームをPodにマウントすることができます。
備考:
使用する前にQuobyteをセットアップして、ボリュームを作成した状態で動作させる必要があります。CSIは、Kubernetes内部でQuobyteボリュームを使用するための推奨プラグインです。 QuobyteのGitHubプロジェクトには、CSIを使用してQuobyteをデプロイするための手順と例があります
rbd
rbd
ボリュームはRados Block Device(RBD)ボリュームをPodにマウントすることを可能にします。
Podを取り外すと消去されるemptyDir
とは異なり、rbd
ボリュームの内容は保存され、ボリュームはアンマウントされます。つまり、RBDボリュームにはあらかじめデータを入れておくことができ、そのデータをPod間で共有することができるのです。
備考:
RBDを使用する前に、Cephのインストールが実行されている必要があります。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)によってバックアップされるため、不揮発性ストレージに書き込まれることはありません。
備考:
使用する前にKubernetes APIでSecretを作成する必要があります。備考:
SubPath
ボリュームマウントとしてSecretを使用しているコンテナは、Secretの更新を受け取りません。詳細についてはSecretの設定を参照してください。
storageOS(非推奨)
storageos
ボリュームを使用すると、既存のStorageOSボリュームをPodにマウントできます。
StorageOSは、Kubernetes環境内でコンテナとして実行され、Kubernetesクラスター内の任意のノードからローカルストレージまたは接続されたストレージにアクセスできるようにします。 データを複製してノードの障害から保護することができます。シンプロビジョニングと圧縮により使用率を向上させ、コストを削減できます。
根本的にStorageOSは、コンテナにブロックストレージを提供しファイルシステムからアクセスできるようにします。
StorageOS Containerは64ビットLinuxを必要とし、追加の依存関係はありません。 無償の開発者ライセンスが利用可能です。
注意:
StorageOSボリュームにアクセスする、またはプールにストレージ容量を提供する各ノードでStorageOSコンテナを実行する必要があります。 インストール手順については、StorageOSドキュメントを参照してください。次の例は、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
備考:
KubernetesvSphereクラウドプロバイダーを設定する必要があります。クラウドプロバイダーの設定については、vSphere入門ガイドを参照してください。vsphereVolume
は、vSphereVMDKボリュームをPodにマウントするために使用されます。
ボリュームの内容は、マウント解除されたときに保持されます。VMFSとVSANの両方のデータストアをサポートします。
備考:
Podで使用する前に、次のいずれかの方法を使用してvSphereVMDKボリュームを作成する必要があります。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: registry.k8s.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仕様バージョン0.2および0.3のサポートは、Kubernetes v1.13で非推奨になり、将来のリリースで削除される予定です。備考:
CSIドライバーは、すべてのKubernetesリリース間で互換性があるとは限りません。各Kubernetesリリースでサポートされているデプロイ手順と互換性マトリックスについては、特定のCSIドライバーのドキュメントを確認してください。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に共有できます。
ボリュームのマウント伝播は、containers[*].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)がシステムから削除されないようにすることです。
備考:
PVCを使用しているPodオブジェクトが存在する場合、PVCはPodによって実際に使用されています。ユーザーが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: "registry.k8s.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.24 [stable]
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.24 [stable]
CSIボリュームの拡張のサポートはデフォルトで有効になっていますが、ボリューム拡張をサポートするにはボリューム拡張を利用できるCSIドライバーも必要です。詳細については、それぞれのCSIドライバーのドキュメントを参照してください。
ファイルシステムを含むボリュームのリサイズ
ファイルシステムがXFS、Ext3、またはExt4の場合にのみ、ファイルシステムを含むボリュームのサイズを変更できます。
ボリュームにファイルシステムが含まれる場合、新しいPodがPersistentVolumeClaim
でReadWriteモードを使用している場合にのみ、ファイルシステムのサイズが変更されます。ファイルシステムの拡張は、Podの起動時、もしくはPodの実行時で基盤となるファイルシステムがオンラインの拡張をサポートする場合に行われます。
FlexVolumesでは、ドライバのRequiresFSResize
機能がtrueに設定されている場合、サイズを変更できます。
FlexVolumeは、Podの再起動時にサイズ変更できます。
使用中の永続ボリュームクレームのリサイズ
Kubernetes v1.15 [beta]
備考:
使用中のPVCの拡張は、Kubernetes 1.15以降のベータ版と、1.11以降のアルファ版として利用可能です。ExpandInUsePersistentVolume
機能を有効化する必要があります。これはベータ機能のため多くのクラスターで自動的に行われます。詳細については、フィーチャーゲートのドキュメントを参照してください。この場合、既存のPVCを使用しているPodまたはDeploymentを削除して再作成する必要はありません。使用中のPVCは、ファイルシステムが拡張されるとすぐにPodで自動的に使用可能になります。この機能は、PodまたはDeploymentで使用されていないPVCには影響しません。拡張を完了する前に、PVCを使用するPodを作成する必要があります。
他のボリュームタイプと同様、FlexVolumeボリュームは、Podによって使用されている最中でも拡張できます。
備考:
FlexVolumeのリサイズは、基盤となるドライバーがリサイズをサポートしている場合のみ可能です。備考:
EBSの拡張は時間がかかる操作です。また変更は、ボリュームごとに6時間に1回までというクォータもあります。ボリューム拡張時の障害からの復旧
基盤ストレージの拡張に失敗した際には、クラスターの管理者は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
備考:
クラスター内でPersistentVolumeを使用するには、ボリュームタイプに関連するヘルパープログラムが必要な場合があります。 この例では、PersistentVolumeはNFSタイプで、NFSファイルシステムのマウントをサポートするためにヘルパープログラム/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リリースでは完全に非推奨です。
ノードアフィニティ
備考:
ほとんどのボリュームタイプはこのフィールドを設定する必要がありません。AWS EBS、GCE PD、もしくはAzure Diskボリュームブロックタイプの場合自動的に設定されます。localボリュームは明示的に設定する必要があります。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
備考:
Podにrawブロックデバイスを追加する場合は、マウントパスの代わりにコンテナでデバイスパスを指定します。ブロックボリュームのバインド
ユーザーがPersistentVolumeClaim specのvolumeMode
フィールドを使用してrawブロックボリュームの要求を示す場合、バインディングルールは、このモードをspecの一部として考慮しなかった以前のリリースとわずかに異なります。表にリストされているのは、ユーザーと管理者がrawブロックデバイスを要求するために指定可能な組み合わせの表です。この表は、ボリュームがバインドされるか、組み合わせが与えられないかを示します。静的にプロビジョニングされたボリュームのボリュームバインディングマトリクスはこちらです。
PVボリュームモード | PVCボリュームモード | 結果 |
---|---|---|
未定義 | 未定義 | バインド |
未定義 | ブロック | バインドなし |
未定義 | ファイルシステム | バインド |
ブロック | 未定義 | バインドなし |
ブロック | ブロック | バインド |
ブロック | ファイルシステム | バインドなし |
ファイルシステム | ファイルシステム | バインド |
ファイルシステム | ブロック | バインドなし |
ファイルシステム | 未定義 | バインド |
備考:
アルファリリースでは、静的にプロビジョニングされたボリュームのみがサポートされます。管理者は、rawブロックデバイスを使用する場合、これらの値を考慮するように注意する必要があります。ボリュームのスナップショットとスナップショットからのボリュームの復元のサポート
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 - エフェメラルボリューム
このドキュメントでは、Kubernetesのエフェメラルボリュームについて説明します。ボリューム、特にPersistentVolumeClaimとPersistentVolumeに精通していることをお勧めします。
一部のアプリケーションでは追加のストレージが必要ですが、そのデータが再起動後も永続的に保存されるかどうかは気にしません。 たとえば、キャッシュサービスは多くの場合メモリサイズによって制限されており、使用頻度の低いデータを、全体的なパフォーマンスにほとんど影響を与えずに、メモリよりも低速なストレージに移動できます。
他のアプリケーションは、構成データや秘密鍵など、読み取り専用の入力データがファイルに存在することを想定しています。
エフェメラルボリュームは、これらのユースケース向けに設計されています。 ボリュームはPodの存続期間に従い、Podとともに作成および削除されるため、Podは、永続ボリュームが利用可能な場所に制限されることなく停止および再起動できます。
エフェメラルボリュームはPod仕様でインラインで指定されているため、アプリケーションの展開と管理が簡素化されます。
エフェメラルボリュームのタイプ
Kubernetesは、さまざまな目的のためにいくつかの異なる種類のエフェメラルボリュームをサポートしています。
- emptyDir:Podの起動時には空で、ストレージはkubeletベースディレクトリ(通常はルートディスク)またはRAMからローカルに取得されます。
- configMap、downwardAPI、secret:Podにさまざまな種類のKubernetesデータを挿入します。
- CSIエフェメラルボリューム:上のボリュームの種類に似ていますが、特にこの機能をサポートする特別なCSIドライバーによって提供されます。
- 汎用エフェメラルボリューム:これは、永続ボリュームもサポートするすべてのストレージドライバーで提供できます。
emptyDir
、configMap
、downwardAPI
、secret
はローカルエフェメラルストレージとして提供されます。
これらは、各ノードのkubeletによって管理されます。
CSIエフェメラルボリュームは、サードパーティーのCSIストレージドライバーによって提供される必要があります。
汎用エフェメラルボリュームは、サードパーティーのCSIストレージドライバーによって提供される可能性がありますが、動的プロビジョニングをサポートする他のストレージドライバーによって提供されることもあります。一部のCSIドライバーは、CSIエフェメラルボリューム用に特別に作成されており、動的プロビジョニングをサポートしていません。これらは汎用エフェメラルボリュームには使用できません。
サードパーティー製ドライバーを使用する利点は、Kubernetes自体がサポートしていない機能を提供できることです。たとえば、kubeletによって管理されるディスクとは異なるパフォーマンス特性を持つストレージや、異なるデータの挿入などです。
CSIエフェメラルボリューム
Kubernetes v1.25 [stable]
備考:
CSIエフェメラルボリュームは、CSIドライバーのサブセットによってのみサポートされます。 Kubernetes CSIドライバーリストには、エフェメラルボリュームをサポートするドライバーが表示されます。概念的には、CSIエフェメラルボリュームはconfigMap
、downwardAPI
、およびsecret
ボリュームタイプに似ています。
ストレージは各ノードでローカルに管理され、Podがノードにスケジュールされた後に他のローカルリソースと一緒に作成されます。Kubernetesには、この段階でPodを再スケジュールするという概念はもうありません。
ボリュームの作成は、失敗する可能性が低くなければなりません。さもないと、Podの起動が停止します。
特に、ストレージ容量を考慮したPodスケジューリングは、これらのボリュームではサポートされていません。
これらは現在、Podのストレージリソースの使用制限の対象外です。これは、kubeletが管理するストレージに対してのみ強制できるものであるためです。
CSIエフェメラルストレージを使用するPodのマニフェストの例を次に示します。
kind: Pod
apiVersion: v1
metadata:
name: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/data"
name: my-csi-inline-vol
command: [ "sleep", "1000000" ]
volumes:
- name: my-csi-inline-vol
csi:
driver: inline.storage.kubernetes.io
volumeAttributes:
foo: bar
volumeAttributes
は、ドライバーによって準備されるボリュームを決定します。これらの属性は各ドライバーに固有のものであり、標準化されていません。詳細な手順については、各CSIドライバーのドキュメントを参照してください。
CSIドライバーの制限事項
CSIエフェメラルボリュームを使用すると、ユーザーはPod仕様の一部としてvolumeAttributes
をCSIドライバーに直接提供できます。
通常は管理者に制限されているvolumeAttributes
を許可するCSIドライバーは、インラインエフェメラルボリュームでの使用には適していません。
たとえば、通常StorageClassで定義されるパラメーターは、インラインエフェメラルボリュームを使用してユーザーに公開しないでください。
Pod仕様内でインラインボリュームとして使用できるCSIドライバーを制限する必要があるクラスター管理者は、次の方法で行うことができます。
- CSIドライバー仕様の
volumeLifecycleModes
からEphemeral
を削除します。これにより、ドライバーをインラインエフェメラルボリュームとして使用できなくなります。 - admission webhookを使用して、このドライバーの使用方法を制限します。
汎用エフェメラルボリューム
Kubernetes v1.23 [stable]
汎用エフェメラルボリュームは、プロビジョニング後に通常は空であるスクラッチデータ用のPodごとのディレクトリを提供するという意味で、emptyDir
ボリュームに似ています。ただし、追加の機能がある場合もあります。
- ストレージは、ローカルまたはネットワークに接続できます。
- ボリュームは、Podが超えることができない固定サイズを持つことができます。
- ボリュームには、ドライバーとパラメーターによっては、いくつかの初期データがある場合があります。
- スナップショット、クローン作成、サイズ変更、ストレージ容量の追跡などボリュームに対する一般的な操作は、ドライバーがそれらをサポートしていることを前提としてサポートされています。
例:
kind: Pod
apiVersion: v1
metadata:
name: my-app
spec:
containers:
- name: my-frontend
image: busybox:1.28
volumeMounts:
- mountPath: "/scratch"
name: scratch-volume
command: [ "sleep", "1000000" ]
volumes:
- name: scratch-volume
ephemeral:
volumeClaimTemplate:
metadata:
labels:
type: my-frontend-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "scratch-storage-class"
resources:
requests:
storage: 1Gi
LifecycleとPersistentVolumeClaim
設計上の重要なアイデアは、ボリュームクレームのパラメーターがPodのボリュームソース内で許可されることです。 PersistentVolumeClaimのラベル、アノテーション、および一連のフィールド全体がサポートされています。 そのようなPodが作成されると、エフェメラルボリュームコントローラーは、Podと同じ名前空間に実際のPersistentVolumeClaimオブジェクトを作成し、Podが削除されたときにPersistentVolumeClaimが確実に削除されるようにします。
これにより、ボリュームバインディングおよび/またはプロビジョニングがトリガーされます。
これは、StorageClassが即時ボリュームバインディングを使用する場合、またはPodが一時的にノードにスケジュールされている場合(WaitForFirstConsumer
ボリュームバインディングモード)のいずれかです。
後者は、スケジューラーがPodに適したノードを自由に選択できるため、一般的なエフェメラルボリュームに推奨されます。即時バインディングでは、ボリュームが利用可能になった時点で、ボリュームにアクセスできるノードをスケジューラーが選択する必要があります。
リソースの所有権に関して、一般的なエフェメラルストレージを持つPodは、そのエフェメラルストレージを提供するPersistentVolumeClaimの所有者です。Podが削除されると、KubernetesガベージコレクターがPVCを削除します。これにより、通常、ボリュームの削除がトリガーされます。これは、ストレージクラスのデフォルトの再利用ポリシーがボリュームを削除することであるためです。retain
の再利用ポリシーを持つStorageClassを使用して、準エフェメラルなローカルストレージを作成できます。ストレージはPodよりも長く存続します。この場合、ボリュームのクリーンアップが個別に行われるようにする必要があります。
これらのPVCは存在しますが、他のPVCと同様に使用できます。特に、ボリュームのクローン作成またはスナップショットでデータソースとして参照できます。PVCオブジェクトは、ボリュームの現在のステータスも保持します。
PersistentVolumeClaimの命名
自動的に作成されたPVCの命名は決定論的です。名前はPod名とボリューム名を組み合わせたもので、途中にハイフン(-
)があります。上記の例では、PVC名はmy-app-scratch-volume
になります。この決定論的な命名により、Pod名とボリューム名が分かればPVCを検索する必要がないため、PVCとの対話が容易になります。
また、決定論的な命名では、異なるPod間、およびPodと手動で作成されたPVCの間で競合が発生する可能性があります(ボリュームが"scratch"のPod"pod-a"と、名前が"pod"でボリュームが"a-scratch"の別のPodは、どちらも同じPVC名"pod-a-scratch")。
次のような競合が検出されます。Pod用に作成された場合、PVCはエフェメラルボリュームにのみ使用されます。このチェックは、所有関係に基づいています。既存のPVCは上書きまたは変更されません。ただし、適切なPVCがないとPodを起動できないため、これでは競合が解決されません。
注意:
これらの競合が発生しないように、同じ名前空間内でPodとボリュームに名前を付けるときは注意してください。セキュリティ
GenericEphemeralVolume機能を有効にすると、ユーザーは、PVCを直接作成する権限がなくても、Podを作成できる場合、間接的にPVCを作成できます。クラスター管理者はこれを認識している必要があります。これがセキュリティモデルに適合しない場合は、一般的なエフェメラルボリュームを持つPodなどのオブジェクトを拒否するadmission webhookを使用する必要があります。
通常のPVCの名前空間割り当ては引き続き適用されるため、ユーザーがこの新しいメカニズムの使用を許可されたとしても、他のポリシーを回避するために使用することはできません。
次の項目
kubeletによって管理されるエフェメラルボリューム
ローカルエフェメラルボリュームを参照してください。
CSIエフェメラルボリューム
- 設計の詳細についてはエフェメラルインラインCSIボリュームKEPを参照してください。
- この機能のさらなる開発の詳細については、KEPのトラッキングイシューを参照してください。
汎用エフェメラルボリューム
- 設計の詳細については、汎用インラインエフェメラルボリュームKEPを参照してください。
5 - VolumeAttributesClass
Kubernetes v1.29 [alpha]
このページでは、Kubernetesのストレージクラス、 ボリュームおよび永続ボリュームについてよく理解していることを前提としています。
VolumeAttributesClassは、管理者がストレージの変更可能な「クラス」を表現する方法を提供します。 異なるクラスは異なるサービス品質レベルに対応する場合があります。 Kubernetes自体は、これらのクラスが何を表すかかについては見解を持っていません。
これはアルファ機能であり、デフォルトで無効化されています。
アルファ機能であるうちにテストしたい場合は、kube-controller-managerおよびkube-apiserverでVolumeAttributesClass
フィーチャーゲートを有効化する必要があります。
コマンドライン引数の--feature-gates
を使用します:
--feature-gates="...,VolumeAttributesClass=true"
VolumeAttributesClassはContainer Storage Interfaceをバックエンドとするストレージでのみ使用することができ、
関連するCSIドライバーがModifyVolume
APIを実装している場合にのみ使用することができます
VolumeAttributesClass API
各VolumeAttributesClassにはdriverName
とparameters
が含まれており、
クラスに属する永続ボリューム(PV)を動的にプロビジョニングまたは変更する際に利用されます。
VolumeAttributesClassのオブジェクト名は重要であり、ユーザーが特定のクラスを要求する方法です。
管理者はVolumeAttributesClassのオブジェクトを最初に作成する際に、クラス名や他のパラメータを設定します。
PersistentVolumeClaim
内のVolumeAttributesClassのオブジェクト名は変更可能ですが、
既存のクラスのパラメータは変更できません。
apiVersion: storage.k8s.io/v1alpha1
kind: VolumeAttributesClass
metadata:
name: silver
driverName: pd.csi.storage.gke.io
parameters:
provisioned-iops: "3000"
provisioned-throughput: "50"
プロビジョナー
各VolumeAttributesClassには、PVのプロビジョニングにどのボリュームプラグインを使用するかを決定するプロビジョナが備わっています。
VolumeAttributesClassに関する機能のサポートはkubernetes-csi/external-provisionerに実装されています。
kubernetes-csi/external-provisionerに限定されることはありません。 Kubernetesによって定義された仕様にそった独立したプログラムである、外部プロビジョナを実行、指定することもできます。 外部プロビジョナの作成者は、コードの保存場所、プロビジョナの配布方法、実行方法、使用するボリュームプラグインなど、あらゆる裁量を持っています。
リサイザー
各VolumeAttributesClassには、PVの変更にどのボリュームプラグインを使用するかを決定するリサイザが備わっています。
driverName
フィールドの指定は必須です。
VolumeAttributesClassに関するボリューム変更機能のサポートはkubernetes-csi/external-resizerに実装されています。
例えば、既存のPersistentVolumeClaimがsilverという名前のVolumeAttributesClassを使用しているとします:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pv-claim
spec:
…
volumeAttributesClassName: silver
…
新しいgoldというVolumeAttributesClassがクラスターで使用可能です:
apiVersion: storage.k8s.io/v1alpha1
kind: VolumeAttributesClass
metadata:
name: gold
driverName: pd.csi.storage.gke.io
parameters:
iops: "4000"
throughput: "60"
エンドユーザーは新しいgoldというVolumeAttributesClassを使ってPVCを更新、適用できます:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-pv-claim
spec:
…
volumeAttributesClassName: gold
…
パラメーター
VolumeAttributesClassにはそれらに属するボリュームを記述するパラメータがあります。
プロビジョナまたはリサイザによって、異なるパラメータを受け取る場合があります。
例えば、パラメータiops
の値4000
や、パラメータthroughput
はGCE Persistent Disk固有のものです。
パラメータを省略した場合は、デフォルト値がボリュームのプロビジョニング時に使用されます。
ユーザーがパラメータを省略して異なるPVCを適用する場合、CSIドライバーの実装に応じてデフォルトのパラメータが使用されることがあります。
詳細については、関連するCSIドライバーのドキュメントを参照してください。
VolumeAttributesClassには最大512個のパラメータを定義できます。 キーと値を含むパラメータオブジェクトの合計の長さは256KiBを超過することはできません。
6 - ストレージクラス
このドキュメントでは、KubernetesにおけるStorageClassの概念について説明します。ボリュームと永続ボリュームに精通していることをお勧めします。
概要
StorageClassは、管理者が提供するストレージの「クラス」を記述する方法を提供します。さまざまなクラスが、サービス品質レベル、バックアップポリシー、またはクラスター管理者によって決定された任意のポリシーにマップされる場合があります。Kubernetes自体は、クラスが何を表すかについて意見を持っていません。この概念は、他のストレージシステムでは「プロファイル」と呼ばれることがあります。
StorageClassリソース
各StorageClassには、クラスに属するPersistentVolumeを動的にプロビジョニングする必要がある場合に使用されるフィールドprovisioner
、parameters
、およびreclaimPolicy
が含まれています。
StorageClassオブジェクトの名前は重要であり、ユーザーが特定のクラスを要求する方法です。管理者は、最初にStorageClassオブジェクトを作成するときにクラスの名前とその他のパラメーターを設定します。オブジェクトは、作成後に更新することはできません。
管理者は、バインドする特定のクラスを要求しないPVCに対してのみ、デフォルトのStorageClassを指定できます。詳細については、PersistentVolumeClaimセクションを参照してください。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- debug
volumeBindingMode: Immediate
プロビジョナー
各StorageClassには、PVのプロビジョニングに使用するボリュームプラグインを決定するプロビジョナーがあります。このフィールドを指定する必要があります。
Volume Plugin | Internal Provisioner | Config Example |
---|---|---|
AWSElasticBlockStore | ✓ | AWS EBS |
AzureFile | ✓ | Azure File |
AzureDisk | ✓ | Azure Disk |
CephFS | - | - |
Cinder | ✓ | OpenStack Cinder |
FC | - | - |
FlexVolume | - | - |
GCEPersistentDisk | ✓ | GCE PD |
Glusterfs | ✓ | Glusterfs |
iSCSI | - | - |
NFS | - | NFS |
RBD | ✓ | Ceph RBD |
VsphereVolume | ✓ | vSphere |
PortworxVolume | ✓ | Portworx Volume |
Local | - | Local |
ここにリストされている「内部」プロビジョナー(名前には「kubernetes.io」というプレフィックスが付いており、Kubernetesと共に出荷されます)を指定することに制限はありません。Kubernetesによって定義された仕様に従う独立したプログラムである外部プロビジョナーを実行して指定することもできます。外部プロビジョナーの作成者は、コードの保存場所、プロビジョナーの出荷方法、実行方法、使用するボリュームプラグイン(Flexを含む)などについて完全な裁量権を持っています。リポジトリkubernetes-sigs/sig-storage-lib-external-provisionerには、仕様の大部分を実装する外部プロビジョナーを作成するためのライブラリが含まれています。一部の外部プロビジョナーは、リポジトリkubernetes-sigs/sig-storage-lib-external-provisionerの下にリストされています。
たとえば、NFSは内部プロビジョナーを提供しませんが、外部プロビジョナーを使用できます。サードパーティのストレージベンダーが独自の外部プロビジョナーを提供する場合もあります。
再利用ポリシー
StorageClassによって動的に作成されるPersistentVolumeには、クラスのreclaimPolicy
フィールドで指定された再利用ポリシーがあり、Delete
またはRetain
のいずれかになります。StorageClassオブジェクトの作成時にreclaimPolicy
が指定されていない場合、デフォルトでDelete
になります。
手動で作成され、StorageClassを介して管理されるPersistentVolumeには、作成時に割り当てられた再利用ポリシーが適用されます。
ボリューム拡張の許可
Kubernetes v1.11 [beta]
PersistentVolumeは、拡張可能になるように構成できます。この機能をtrue
に設定すると、ユーザーは対応するPVCオブジェクトを編集してボリュームのサイズを変更できます。
次のタイプのボリュームは、基になるStorageClassのフィールドallowVolumeExpansion
がtrueに設定されている場合に、ボリュームの拡張をサポートします。
Volume type | Required Kubernetes version |
---|---|
gcePersistentDisk | 1.11 |
awsElasticBlockStore | 1.11 |
Cinder | 1.11 |
glusterfs | 1.11 |
rbd | 1.11 |
Azure File | 1.11 |
Azure Disk | 1.11 |
Portworx | 1.11 |
FlexVolume | 1.13 |
CSI | 1.14 (alpha), 1.16 (beta) |
備考:
ボリューム拡張機能を使用してボリュームを拡張することはできますが、縮小することはできません。マウントオプション
StorageClassによって動的に作成されるPersistentVolumeには、クラスのmountOptions
フィールドで指定されたマウントオプションがあります。
ボリュームプラグインがマウントオプションをサポートしていないにもかかわらず、マウントオプションが指定されている場合、プロビジョニングは失敗します。マウントオプションは、クラスまたはPVのいずれでも検証されません。マウントオプションが無効な場合、PVマウントは失敗します。
ボリュームバインディングモード
volumeBindingMode
フィールドは、ボリュームバインディングと動的プロビジョニングが発生するタイミングを制御します。設定を解除すると、デフォルトで"Immediate"モードが使用されます。
Immediate
モードは、PersistentVolumeClaimが作成されると、ボリュームバインディングと動的プロビジョニングが発生することを示します。トポロジに制約があり、クラスター内のすべてのノードからグローバルにアクセスできないストレージバックエンドの場合、PersistentVolumeはPodのスケジューリング要件を知らなくてもバインドまたはプロビジョニングされます。これにより、Podがスケジュール不能になる可能性があります。
クラスター管理者は、PersistentVolumeClaimを使用するPodが作成されるまでPersistentVolumeのバインドとプロビジョニングを遅らせるWaitForFirstConsumer
モードを指定することで、この問題に対処できます。
PersistentVolumeは、Podのスケジュール制約によって指定されたトポロジに準拠して選択またはプロビジョニングされます。これらには、リソース要件、ノードセレクター、ポッドアフィニティとアンチアフィニティ、およびtaints and tolerationsが含まれますが、これらに限定されません。
次のプラグインは、動的プロビジョニングでWaitForFirstConsumer
をサポートしています。
次のプラグインは、事前に作成されたPersistentVolumeバインディングでWaitForFirstConsumer
をサポートします。
- 上記のすべて
- Local
Kubernetes v1.17 [stable]
備考:
WaitForFirstConsumer
の使用を選択した場合は、Pod仕様でnodeName
を使用してノードアフィニティを指定しないでください。この場合にnodeNameを使用すると、スケジューラはバイパスされ、PVCは保留状態のままになります。
代わりに、以下に示すように、この場合はホスト名にノードセレクターを使用できます。
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
nodeSelector:
kubernetes.io/hostname: kube-01
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
許可されたトポロジー
クラスターオペレーターがWaitForFirstConsumer
ボリュームバインディングモードを指定すると、ほとんどの状況でプロビジョニングを特定のトポロジに制限する必要がなくなります。ただし、それでも必要な場合は、allowedTopologies
を指定できます。
この例は、プロビジョニングされたボリュームのトポロジを特定のゾーンに制限する方法を示しており、サポートされているプラグインのzone
およびzones
パラメーターの代わりとして使用する必要があります。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: failure-domain.beta.kubernetes.io/zone
values:
- us-central-1a
- us-central-1b
パラメーター
ストレージクラスには、ストレージクラスに属するボリュームを記述するパラメーターがあります。プロビジョナー
に応じて、異なるパラメーターが受け入れられる場合があります。たとえば、パラメーターtype
の値io1
とパラメーターiopsPerGB
はEBSに固有です。パラメーターを省略すると、デフォルトが使用されます。
StorageClassに定義できるパラメーターは最大512個です。 キーと値を含むパラメーターオブジェクトの合計の長さは、256KiBを超えることはできません。
AWS EBS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
iopsPerGB: "10"
fsType: ext4
type
:io1
、gp2
、sc1
、st1
。詳細については、AWSドキュメントを参照してください。デフォルト:gp2
。zone
(非推奨):AWS zone。zone
もzones
も指定されていない場合、ボリュームは通常、Kubernetesクラスターにノードがあるすべてのアクティブなゾーンにわたってラウンドロビン方式で処理されます。zone
パラメーターとzones
パラメーターを同時に使用することはできません。zones
(非推奨):AWS zoneのコンマ区切りリスト。zone
もzones
も指定されていない場合、ボリュームは通常、Kubernetesクラスターにノードがあるすべてのアクティブなゾーンにわたってラウンドロビン方式で処理されます。zone
パラメーターとzones
パラメーターを同時に使用することはできません。iopsPerGB
:io1
ボリュームのみ。GiBごとの1秒あたりのI/O操作。AWSボリュームプラグインは、これを要求されたボリュームのサイズで乗算して、ボリュームのIOPSを計算し、上限を20,000IOPSに設定します(AWSでサポートされる最大値については、AWSドキュメントを参照してください)。ここでは文字列が必要です。つまり、10
ではなく"10"
です。fsType
:kubernetesでサポートされているfsType。デフォルト:"ext4"
。encrypted
:EBSボリュームを暗号化するかどうかを示します。有効な値は"true"
または"false"
です。ここでは文字列が必要です。つまり、true
ではなく"true"
です。kmsKeyId
:オプション。ボリュームを暗号化するときに使用するキーの完全なAmazonリソースネーム。何も指定されていなくてもencrypted
がtrueの場合、AWSによってキーが生成されます。有効なARN値については、AWSドキュメントを参照してください。
GCE PD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
fstype: ext4
replication-type: none
type
:pd-standard
またはpd-ssd
。デフォルト:pd-standard
zone
(非推奨):GCE zone。zone
もzones
も指定されていない場合、ボリュームは通常、Kubernetesクラスターにノードがあるすべてのアクティブなゾーンにわたってラウンドロビン方式で処理されます。zone
パラメーターとzones
パラメーターを同時に使用することはできません。zones
(非推奨):GCE zoneのコンマ区切りリスト。zone
もzones
も指定されていない場合、ボリュームは通常、Kubernetesクラスターにノードがあるすべてのアクティブなゾーンにわたってラウンドロビン方式で処理されます。zone
パラメーターとzones
パラメーターを同時に使用することはできません。fstype
:ext4
またはxfs
。デフォルト:ext4
。定義されたファイルシステムタイプは、ホストオペレーティングシステムでサポートされている必要があります。replication-type
:none
またはregional-pd
。デフォルト:none
。
replication-type
がnone
に設定されている場合、通常の(ゾーン)PDがプロビジョニングされます。
replication-type
がregional-pd
に設定されている場合、Regional Persistent Diskがプロビジョニングされます。volumeBindingMode: WaitForFirstConsumer
を設定することを強くお勧めします。この場合、このStorageClassを使用するPersistentVolumeClaimを使用するPodを作成すると、Regional Persistent Diskが2つのゾーンでプロビジョニングされます。1つのゾーンは、Podがスケジュールされているゾーンと同じです。もう1つのゾーンは、クラスターで使用可能なゾーンからランダムに選択されます。ディスクゾーンは、allowedTopologies
を使用してさらに制限できます。
Glusterfs(非推奨)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://127.0.0.1:8081"
clusterid: "630372ccdc720a92c681fb928f27b53f"
restauthenabled: "true"
restuser: "admin"
secretNamespace: "default"
secretName: "heketi-secret"
gidMin: "40000"
gidMax: "50000"
volumetype: "replicate:3"
resturl
:glusterボリュームをオンデマンドでプロビジョニングするGluster RESTサービス/HeketiサービスのURL。一般的な形式はIPaddress:Port
である必要があり、これはGlusterFS動的プロビジョナーの必須パラメーターです。Heketiサービスがopenshift/kubernetesセットアップでルーティング可能なサービスとして公開されている場合、これはhttp://heketi-storage-project.cloudapps.mystorage.com
のような形式になる可能性があります。ここで、fqdnは解決可能なHeketiサービスURLです。restauthenabled
:RESTサーバーへの認証を有効にするGluster RESTサービス認証ブール値。この値が"true"
の場合、restuser
とrestuserkey
またはsecretNamespace
+secretName
を入力する必要があります。このオプションは非推奨です。restuser
、restuserkey
、secretName
、またはsecretNamespace
のいずれかが指定されている場合、認証が有効になります。restuser
:Gluster Trusted Poolでボリュームを作成するためのアクセス権を持つGluster RESTサービス/Heketiユーザー。restuserkey
:RESTサーバーへの認証に使用されるGluster RESTサービス/Heketiユーザーのパスワード。このパラメーターは、secretNamespace
+secretName
を優先されて廃止されました。secretNamespace
、secretName
:Gluster RESTサービスと通信するときに使用するユーザーパスワードを含むSecretインスタンスの識別。これらのパラメーターはオプションです。secretNamespace
とsecretName
の両方が省略された場合、空のパスワードが使用されます。提供されたシークレットには、タイプkubernetes.io/glusterfs
が必要です。たとえば、次のように作成されます。kubectl create secret generic heketi-secret \ --type="kubernetes.io/glusterfs" --from-literal=key='opensesame' \ --namespace=default
シークレットの例はglusterfs-provisioning-secret.yamlにあります。
clusterid
:630372ccdc720a92c681fb928f27b53f
は、ボリュームのプロビジョニング時にHeketiによって使用されるクラスターのIDです。また、クラスターIDのリストにすることもできます。これはオプションのパラメーターです。gidMin
、gidMax
:StorageClassのGID範囲の最小値と最大値。この範囲内の一意の値(GID)(gidMin-gidMax)が、動的にプロビジョニングされたボリュームに使用されます。これらはオプションの値です。指定しない場合、ボリュームは、それぞれgidMinとgidMaxのデフォルトである2000から2147483647の間の値でプロビジョニングされます。volumetype
:ボリュームタイプとそのパラメーターは、このオプションの値で構成できます。ボリュームタイプが記載されていない場合、プロビジョニング担当者がボリュームタイプを決定します。 例えば、- レプリカボリューム:
volumetype: replica:3
ここで、'3'はレプリカ数です。 - Disperse/ECボリューム:
volumetype: disperse:4:2
ここで、'4'はデータ、'2'は冗長数です。 - ボリュームの分配:
volumetype: none
利用可能なボリュームタイプと管理オプションについては、管理ガイドを参照してください。
詳細な参考情報については、Heketiの設定方法を参照してください。
永続ボリュームが動的にプロビジョニングされると、Glusterプラグインはエンドポイントとヘッドレスサービスを
gluster-dynamic-<claimname>
という名前で自動的に作成します。永続ボリューム要求が削除されると、動的エンドポイントとサービスは自動的に削除されます。- レプリカボリューム:
NFS
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: example-nfs
provisioner: example.com/external-nfs
parameters:
server: nfs-server.example.com
path: /share
readOnly: "false"
server
:サーバーは、NFSサーバーのホスト名またはIPアドレスです。path
:NFSサーバーによってエクスポートされるパス。readOnly
:ストレージが読み取り専用としてマウントされるかどうかを示すフラグ(デフォルトはfalse)。
Kubernetesには、内部NFSプロビジョナーは含まれていません。NFS用のStorageClassを作成するには、外部プロビジョナーを使用する必要があります。 ここではいくつかの例を示します。
OpenStack Cinder
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gold
provisioner: kubernetes.io/cinder
parameters:
availability: nova
availability
:アベイラビリティゾーン。指定されていない場合、ボリュームは通常、Kubernetesクラスターにノードがあるすべてのアクティブなゾーンにわたってラウンドロビン方式で処理されます。
備考:
Kubernetes v1.11 [deprecated]
このOpenStackの内部プロビジョナーは非推奨です。OpenStackの外部クラウドプロバイダーをご利用ください。
vSphere
vSphereストレージクラスのプロビジョナーには2つのタイプがあります。
- CSIプロビジョナー:
csi.vsphere.vmware.com
- vCPプロビジョナー:
kubernetes.io/vsphere-volume
インツリープロビジョナーは非推奨です。CSIプロビジョナーの詳細については、Kubernetes vSphere CSIドライバーおよびvSphereVolume CSI移行を参照してください。
CSIプロビジョナー
vSphere CSI StorageClassプロビジョナーは、Tanzu Kubernetesクラスターと連携します。例については、vSphere CSIリポジトリを参照してください。
vCPプロビジョナー
次の例では、VMware Cloud Provider(vCP) StorageClassプロビジョナーを使用しています。
ユーザー指定のディスク形式でStorageClassを作成します。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick
diskformat
:thin
、zeroedthick
、eagerzeroedthick
。デフォルト:"thin"
.ユーザー指定のデータストアにディスクフォーマットのStorageClassを作成します。
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: fast provisioner: kubernetes.io/vsphere-volume parameters: diskformat: zeroedthick datastore: VSANDatastore
datastore
:ユーザーはStorageClassでデータストアを指定することもできます。 ボリュームは、StorageClassで指定されたデータストア(この場合はVSANDatastore
)に作成されます。このフィールドはオプションです。データストアが指定されていない場合、vSphere Cloud Providerの初期化に使用されるvSphere構成ファイルで指定されたデータストアにボリュームが作成されます。kubernetes内のストレージポリシー管理
既存のvCenter SPBMポリシーを使用
vSphere for Storage Managementの最も重要な機能の1つは、ポリシーベースの管理です。Storage Policy Based Management(SPBM)は、幅広いデータサービスとストレージソリューションにわたって単一の統合コントロールプレーンを提供するストレージポリシーフレームワークです。SPBMにより、vSphere管理者は、キャパシティプランニング、差別化されたサービスレベル、キャパシティヘッドルームの管理など、事前のストレージプロビジョニングの課題を克服できます。SPBMポリシーは、
storagePolicyName
パラメーターを使用してStorageClassで指定できます。Kubernetes内でのVirtual SANポリシーのサポート
Vsphere Infrastructure(VI)管理者は、動的ボリュームプロビジョニング中にカスタムVirtual SANストレージ機能を指定できます。動的なボリュームプロビジョニング時に、パフォーマンスや可用性などのストレージ要件をストレージ機能の形で定義できるようになりました。ストレージ機能の要件はVirtual SANポリシーに変換され、永続ボリューム(仮想ディスク)の作成時にVirtual SANレイヤーにプッシュダウンされます。仮想ディスクは、要件を満たすためにVirtual SANデータストア全体に分散されます。
永続的なボリューム管理にストレージポリシーを使用する方法の詳細については、ボリュームの動的プロビジョニングのためのストレージポリシーベースの管理を参照してください。
vSphereの例 では、Kubernetes for vSphere内で永続的なボリューム管理を試すことができます。
Ceph RBD
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/rbd
parameters:
monitors: 10.16.153.105:6789
adminId: kube
adminSecretName: ceph-secret
adminSecretNamespace: kube-system
pool: kube
userId: kube
userSecretName: ceph-secret-user
userSecretNamespace: default
fsType: ext4
imageFormat: "2"
imageFeatures: "layering"
monitors
:カンマ区切りのCephモニター。このパラメーターは必須です。adminId
:プールにイメージを作成できるCephクライアントID。デフォルトは"admin"です。adminSecretName
:adminId
のシークレット名。このパラメーターは必須です。指定されたシークレットのタイプは"kubernetes.io/rbd"である必要があります。adminSecretNamespace
:adminSecretName
の名前空間。デフォルトは"default"です。pool
:Ceph RBDプール。デフォルトは"rbd"です。userId
:RBDイメージのマッピングに使用されるCephクライアントID。デフォルトはadminId
と同じです。userSecretName
:RBDイメージをマップするためのuserId
のCephシークレットの名前。PVCと同じ名前空間に存在する必要があります。このパラメーターは必須です。提供されたシークレットのタイプは"kubernetes.io/rbd"である必要があります。たとえば、次のように作成されます。kubectl create secret generic ceph-secret --type="kubernetes.io/rbd" \ --from-literal=key='QVFEQ1pMdFhPUnQrSmhBQUFYaERWNHJsZ3BsMmNjcDR6RFZST0E9PQ==' \ --namespace=kube-system
userSecretNamespace
:userSecretName
の名前空間。fsType
:kubernetesでサポートされているfsType。デフォルト:"ext4"
。imageFormat
:Ceph RBDイメージ形式、"1"または"2"。デフォルトは"2"です。imageFeatures
:このパラメーターはオプションであり、imageFormat
を"2"に設定した場合にのみ使用する必要があります。現在サポートされている機能はlayering
のみです。デフォルトは""で、オンになっている機能はありません。
Azure Disk
Azure Unmanaged Disk storage class
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/azure-disk
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name
skuName
:AzureストレージアカウントのSku層。デフォルトは空です。location
:Azureストレージアカウントの場所。デフォルトは空です。storageAccount
:Azureストレージアカウント名。ストレージアカウントを指定する場合、それはクラスターと同じリソースグループに存在する必要があり、location
は無視されます。ストレージアカウントが指定されていない場合、クラスターと同じリソースグループに新しいストレージアカウントが作成されます。
Azure Disk storage class (starting from v1.7.2)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/azure-disk
parameters:
storageaccounttype: Standard_LRS
kind: managed
storageaccounttype
:AzureストレージアカウントのSku層。デフォルトは空です。kind
:可能な値は、shared
、dedicated
、およびmanaged
(デフォルト)です。kind
がshared
の場合、すべてのアンマネージドディスクは、クラスターと同じリソースグループ内のいくつかの共有ストレージアカウントに作成されます。kind
がdedicated
の場合、新しい専用ストレージアカウントが、クラスターと同じリソースグループ内の新しいアンマネージドディスク用に作成されます。kind
がmanaged
の場合、すべてのマネージドディスクはクラスターと同じリソースグループに作成されます。resourceGroup
:Azureディスクが作成されるリソースグループを指定します。これは、既存のリソースグループ名である必要があります。指定しない場合、ディスクは現在のKubernetesクラスターと同じリソースグループに配置されます。
- Premium VMはStandard_LRSディスクとPremium_LRSディスクの両方を接続できますが、Standard VMはStandard_LRSディスクのみを接続できます。
- マネージドVMはマネージドディスクのみをアタッチでき、アンマネージドVMはアンマネージドディスクのみをアタッチできます。
Azure File
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azurefile
provisioner: kubernetes.io/azure-file
parameters:
skuName: Standard_LRS
location: eastus
storageAccount: azure_storage_account_name
skuName
:AzureストレージアカウントのSku層。デフォルトは空です。location
:Azureストレージアカウントの場所。デフォルトは空です。storageAccount
:Azureストレージアカウント名。デフォルトは空です。ストレージアカウントが指定されていない場合は、リソースグループに関連付けられているすべてのストレージアカウントが検索され、skuName
とlocation
に一致するものが見つかります。ストレージアカウントを指定する場合は、クラスターと同じリソースグループに存在する必要があり、skuName
とlocation
は無視されます。secretNamespace
:Azureストレージアカウント名とキーを含むシークレットの名前空間。デフォルトはPodと同じです。secretName
:Azureストレージアカウント名とキーを含むシークレットの名前。デフォルトはazure-storage-account-<accountName>-secret
ですreadOnly
:ストレージが読み取り専用としてマウントされるかどうかを示すフラグ。デフォルトはfalseで、読み取り/書き込みマウントを意味します。この設定は、VolumeMountsのReadOnly
設定にも影響します。
ストレージのプロビジョニング中に、secretName
という名前のシークレットがマウント資格証明用に作成されます。クラスターでRBACとController Rolesの両方が有効になっている場合は、追加します。clusterrolesystem:controller:persistent-volume-binder
に対するリソースsecret
のcreate
パーミッション。
マルチテナンシーコンテキストでは、secretNamespace
の値を明示的に設定することを強くお勧めします。そうしないと、ストレージアカウントの資格情報が他のユーザーに読み取られる可能性があります。
Portworx Volume
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: portworx-io-priority-high
provisioner: kubernetes.io/portworx-volume
parameters:
repl: "1"
snap_interval: "70"
priority_io: "high"
fs
:配置するファイルシステム:none/xfs/ext4
(デフォルト:ext4
)。block_size
:キロバイト単位のブロックサイズ(デフォルト:32
)。repl
:レプリケーション係数1..3
の形式で提供される同期レプリカの数(デフォルト:1
)。ここでは文字列が期待されます。つまり、1
ではなく"1"
です。priority_io
:ボリュームがパフォーマンスの高いストレージから作成されるか、優先度の低いストレージhigh/medium/low
(デフォルト:low
)から作成されるかを決定します。snap_interval
:スナップショットをトリガーするクロック/時間間隔(分単位)。スナップショットは、前のスナップショットとの差分に基づいて増分されます。0はスナップを無効にします(デフォルト:0
)。ここでは文字列が必要です。つまり、70
ではなく"70"
です。aggregation_level
:ボリュームが分散されるチャンクの数を指定します。0は非集約ボリュームを示します(デフォルト:0
)。ここには文字列が必要です。つまり、0
ではなく"0"
です。ephemeral
:アンマウント後にボリュームをクリーンアップするか、永続化するかを指定します。emptyDir
ユースケースではこの値をtrueに設定でき、Cassandraなどのデータベースのようなpersistent volumes
ユースケースではfalse、true/false
(デフォルトはfalse
)に設定する必要があります。ここでは文字列が必要です。つまり、true
ではなく"true"
です。
Local
Kubernetes v1.14 [stable]
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
ローカルボリュームは現在、動的プロビジョニングをサポートしていませんが、Podのスケジューリングまでボリュームバインドを遅らせるには、引き続きStorageClassを作成する必要があります。これは、WaitForFirstConsumer
ボリュームバインディングモードによって指定されます。
ボリュームバインディングを遅延させると、PersistentVolumeClaimに適切なPersistentVolumeを選択するときに、スケジューラはPodのスケジューリング制約をすべて考慮することができます。
7 - ボリュームの動的プロビジョニング(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.9から非推奨になりました。その代わりユーザーは現在では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割り当てモードを設定することにより可能となります。
8 - ボリュームのスナップショット
Kubernetesでは、VolumeSnapshotはストレージシステム上のボリュームのスナップショットを表します。このドキュメントは、Kubernetes永続ボリュームに既に精通していることを前提としています。
概要
APIリソースPersistentVolume
とPersistentVolumeClaim
を使用してユーザーと管理者にボリュームをプロビジョニングする方法と同様に、VolumeSnapshotContent
とVolumeSnapshot
APIリソースは、ユーザーと管理者のボリュームスナップショットを作成するために提供されます。
VolumeSnapshotContent
は、管理者によってプロビジョニングされたクラスター内のボリュームから取得されたスナップショットです。PersistentVolumeがクラスターリソースであるように、これはクラスターのリソースです。
VolumeSnapshot
は、ユーザーによるボリュームのスナップショットの要求です。PersistentVolumeClaimに似ています。
VolumeSnapshotClass
を使用すると、VolumeSnapshot
に属するさまざまな属性を指定できます。これらの属性は、ストレージシステム上の同じボリュームから取得されたスナップショット間で異なる場合があるため、PersistentVolumeClaim
の同じStorageClass
を使用して表現することはできません。
ボリュームスナップショットは、完全に新しいボリュームを作成することなく、特定の時点でボリュームの内容をコピーするための標準化された方法をKubernetesユーザーに提供します。この機能により、たとえばデータベース管理者は、編集または削除の変更を実行する前にデータベースをバックアップできます。
この機能を使用する場合、ユーザーは次のことに注意する必要があります。
- APIオブジェクト
VolumeSnapshot
、VolumeSnapshotContent
、およびVolumeSnapshotClass
はCRDであり、コアAPIの一部ではありません。 VolumeSnapshot
のサポートは、CSIドライバーでのみ利用できます。VolumeSnapshot
の展開プロセスの一環として、Kubernetesチームは、コントロールプレーンに展開されるスナップショットコントローラーと、CSIドライバーと共に展開されるcsi-snapshotterと呼ばれるサイドカーヘルパーコンテナを提供します。スナップショットコントローラーは、VolumeSnapshot
およびVolumeSnapshotContent
オブジェクトを管理し、VolumeSnapshotContent
オブジェクトの作成と削除を担当します。サイドカーcsi-snapshotterは、VolumeSnapshotContent
オブジェクトを監視し、CSIエンドポイントに対してCreateSnapshot
およびDeleteSnapshot
操作をトリガーします。- スナップショットオブジェクトの厳密な検証を提供するvalidation Webhookサーバーもあります。これは、CSIドライバーではなく、スナップショットコントローラーおよびCRDと共にKubernetesディストリビューションによってインストールする必要があります。スナップショット機能が有効になっているすべてのKubernetesクラスターにインストールする必要があります。
- CSIドライバーは、ボリュームスナップショット機能を実装している場合と実装していない場合があります。ボリュームスナップショットのサポートを提供するCSIドライバーは、csi-snapshotterを使用する可能性があります。詳細については、CSIドライバーのドキュメントを参照してください。
- CRDとスナップショットコントローラーのインストールは、Kubernetesディストリビューションの責任です。
ボリュームスナップショットとボリュームスナップショットのコンテンツのライフサイクル
VolumeSnapshotContents
はクラスター内のリソースです。VolumeSnapshots
は、これらのリソースに対するリクエストです。VolumeSnapshotContents
とVolumeSnapshots
の間の相互作用は、次のライフサイクルに従います。
プロビジョニングボリュームのスナップショット
スナップショットをプロビジョニングするには、事前プロビジョニングと動的プロビジョニングの2つの方法があります。
事前プロビジョニング
クラスター管理者は、多数のVolumeSnapshotContents
を作成します。それらは、クラスターユーザーが使用できるストレージシステム上の実際のボリュームスナップショットの詳細を保持します。それらはKubernetesAPIに存在し、消費することができます。
動的プロビジョニング
既存のスナップショットを使用する代わりに、スナップショットをPersistentVolumeClaimから動的に取得するように要求できます。VolumeSnapshotClassは、スナップショットを作成するときに使用するストレージプロバイダー固有のパラメーターを指定します。
バインディング
スナップショットコントローラーは、事前プロビジョニングされたシナリオと動的にプロビジョニングされたシナリオの両方で、適切なVolumeSnapshotContent
オブジェクトを使用したVolumeSnapshot
オブジェクトのバインディングを処理します。バインディングは1対1のマッピングです。
事前プロビジョニングされたバインディングの場合、要求されたVolumeSnapshotContentオブジェクトが作成されるまで、VolumeSnapshotはバインドされないままになります。
スナップショットソース保護としてのPersistentVolumeClaim
この保護の目的は、スナップショットがシステムから取得されている間、使用中のPersistentVolumeClaimAPIオブジェクトがシステムから削除されないようにすることです(これにより、データが失われる可能性があります)。
PersistentVolumeClaimのスナップショットが作成されている間、そのPersistentVolumeClaimは使用中です。スナップショットソースとしてアクティブに使用されているPersistentVolumeClaim APIオブジェクトを削除しても、PersistentVolumeClaimオブジェクトはすぐには削除されません。代わりに、PersistentVolumeClaimオブジェクトの削除は、スナップショットがReadyToUseになるか中止されるまで延期されます。
削除
削除はVolumeSnapshot
オブジェクトの削除によってトリガーされ、DeletionPolicy
に従います。DeletionPolicy
がDelete
の場合、基になるストレージスナップショットはVolumeSnapshotContent
オブジェクトとともに削除されます。DeletionPolicy
がRetain
の場合、基になるスナップショットとVolumeSnapshotContent
の両方が残ります。
ボリュームスナップショット
各VolumeSnapshotには、仕様とステータスが含まれています。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: new-snapshot-test
spec:
volumeSnapshotClassName: csi-hostpath-snapclass
source:
persistentVolumeClaimName: pvc-test
persistentVolumeClaimName
は、スナップショットのPersistentVolumeClaimデータソースの名前です。このフィールドは、スナップショットを動的にプロビジョニングするために必要です。
ボリュームスナップショットは、属性volumeSnapshotClassName
を使用してVolumeSnapshotClassの名前を指定することにより、特定のクラスを要求できます。何も設定されていない場合、利用可能な場合はデフォルトのクラスが使用されます。
事前プロビジョニングされたスナップショットの場合、次の例に示すように、スナップショットのソースとしてvolumeSnapshotContentName
を指定する必要があります。事前プロビジョニングされたスナップショットには、volumeSnapshotContentName
ソースフィールドが必要です。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: test-snapshot
spec:
source:
volumeSnapshotContentName: test-content
ボリュームスナップショットコンテンツ
各VolumeSnapshotContentには、仕様とステータスが含まれています。動的プロビジョニングでは、スナップショット共通コントローラーがVolumeSnapshotContent
オブジェクトを作成します。以下に例を示します。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: snapcontent-72d9a349-aacd-42d2-a240-d775650d2455
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
volumeHandle: ee0cfb94-f8d4-11e9-b2d8-0242ac110002
sourceVolumeMode: Filesystem
volumeSnapshotClassName: csi-hostpath-snapclass
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
uid: 72d9a349-aacd-42d2-a240-d775650d2455
volumeHandle
は、ストレージバックエンドで作成され、ボリュームの作成中にCSIドライバーによって返されるボリュームの一意の識別子です。このフィールドは、スナップショットを動的にプロビジョニングするために必要です。これは、スナップショットのボリュームソースを指定します。
事前プロビジョニングされたスナップショットの場合、(クラスター管理者として)次のようにVolumeSnapshotContent
オブジェクトを作成する必要があります。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: new-snapshot-content-test
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
sourceVolumeMode: Filesystem
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
snapshotHandle
は、ストレージバックエンドで作成されたボリュームスナップショットの一意の識別子です。このフィールドは、事前プロビジョニングされたスナップショットに必要です。このVolumeSnapshotContent
が表すストレージシステムのCSIスナップショットIDを指定します。
sourceVolumeMode
は、スナップショットが作成されるボリュームのモードです。sourceVolumeMode
フィールドの値は、Filesystem
またはBlock
のいずれかです。ソースボリュームモードが指定されていない場合、Kubernetesはスナップショットをソースボリュームのモードが不明であるかのように扱います。
volumeSnapshotRef
は、対応するVolumeSnapshot
の参照です。VolumeSnapshotContent
が事前プロビジョニングされたスナップショットとして作成されている場合、volumeSnapshotRef
で参照されるVolumeSnapshot
がまだ存在しない可能性があることに注意してください。
スナップショットのボリュームモードの変換
クラスターにインストールされているVolumeSnapshots
APIがsourceVolumeMode
フィールドをサポートしている場合、APIには、権限のないユーザーがボリュームのモードを変換するのを防ぐ機能があります。
クラスターにこの機能の機能があるかどうかを確認するには、次のコマンドを実行します。
$ kubectl get crd volumesnapshotcontent -o yaml
ユーザーが既存のVolumeSnapshot
からPersistentVolumeClaim
を作成できるようにしたいが、ソースとは異なるボリュームモードを使用する場合は、VolumeSnapshot
に対応するVolumeSnapshotContent
にアノテーションsnapshot.storage.kubernetes.io/allow-volume-mode-change: "true"
を追加する必要があります。
事前プロビジョニングされたスナップショットの場合、クラスター管理者がspec.sourceVolumeMode
を入力する必要があります。
この機能を有効にしたVolumeSnapshotContent
リソースの例は次のようになります。
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
name: new-snapshot-content-test
annotations:
- snapshot.storage.kubernetes.io/allow-volume-mode-change: "true"
spec:
deletionPolicy: Delete
driver: hostpath.csi.k8s.io
source:
snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
sourceVolumeMode: Filesystem
volumeSnapshotRef:
name: new-snapshot-test
namespace: default
スナップショットからのボリュームのプロビジョニング
PersistentVolumeClaim
オブジェクトのdataSourceフィールドを使用して、スナップショットからのデータが事前に取り込まれた新しいボリュームをプロビジョニングできます。
詳細については、ボリュームのスナップショットとスナップショットからのボリュームの復元を参照してください。
9 - 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
に応じて様々なパラメーターを使用できます。
10 - 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を考慮せず個別に利用、複製、スナップショット、削除できます。これはまた複製元が新しく作成された複製にリンクされておらず、新しく作成された複製に影響を与えずに変更または削除できることを意味します。
11 - ストレージ容量
ストレージ容量は、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のスケジューラーについてもっと学ぶ。
12 - ノード固有のボリューム制限
このページでは、さまざまなクラウドプロバイダーのノードに接続できるボリュームの最大数について説明します。
通常、Google、Amazon、Microsoftなどのクラウドプロバイダーには、ノードに接続できるボリュームの数に制限があります。Kubernetesがこれらの制限を尊重することが重要です。 そうしないと、ノードでスケジュールされたPodが、ボリュームが接続されるのを待ってスタックする可能性があります。
Kubernetesのデフォルトの制限
Kubernetesスケジューラーには、ノードに接続できるボリュームの数にデフォルトの制限があります。
クラウドサービス | ノード当たりの最大ボリューム |
---|---|
Amazon Elastic Block Store (EBS) | 39 |
Google Persistent Disk | 16 |
Microsoft Azure Disk Storage | 16 |
カスタム制限
これらの制限を変更するには、KUBE_MAX_PD_VOLS
環境変数の値を設定し、スケジューラーを開始します。CSIドライバーの手順は異なる場合があります。制限をカスタマイズする方法については、CSIドライバーのドキュメントを参照してください。
デフォルトの制限よりも高い制限を設定する場合は注意してください。クラウドプロバイダーのドキュメントを参照して、設定した制限をノードが実際にサポートしていることを確認してください。
制限はクラスター全体に適用されるため、すべてのノードに影響します。
動的ボリューム制限
Kubernetes v1.17 [stable]
動的ボリューム制限は、次のボリュームタイプでサポートされています。
- Amazon EBS
- Google Persistent Disk
- Azure Disk
- CSI
ツリー内のボリュームプラグインによって管理されるボリュームの場合、Kubernetesはノードタイプを自動的に決定し、ノードに適切なボリュームの最大数を適用します。例えば:
Google Compute Engine上ではノードタイプに応じて、最大127個のボリュームをノードに接続できます。
M5、C5、R5、T3、およびZ1DインスタンスタイプのAmazon EBSディスクの場合、Kubernetesは25ボリュームのみをノードにアタッチできます。Amazon Elastic Compute Cloud (EC2)の他のインスタンスタイプの場合、Kubernetesでは39個のボリュームをノードに接続できます。
Azureでは、ノードの種類に応じて、最大64個のディスクをノードに接続できます。詳細については、Azureの仮想マシンのサイズを参照してください。
CSIストレージドライバーが(
NodeGetInfo
を使用して)ノードの最大ボリューム数をアドバタイズする場合、kube-schedulerはその制限を尊重します。詳細については、CSIの仕様を参照してください。CSIドライバーに移行されたツリー内プラグインによって管理されるボリュームの場合、ボリュームの最大数はCSIドライバーによって報告される数になります。
13 - ボリュームヘルスモニタリング
Kubernetes v1.21 [alpha]
CSIボリュームヘルスモニタリングにより、CSIドライバーは、基盤となるストレージシステムから異常なボリューム状態を検出し、それらをPVCまたはPodのイベントとして報告できます。
ボリュームヘルスモニタリング
Kubernetes volume health monitoring は、KubernetesがContainerStorageInterface(CSI)を実装する方法の一部です。ボリュームヘルスモニタリング機能は、外部のヘルスモニターコントローラーとkubeletの2つのコンポーネントで実装されます。
CSIドライバーがコントローラー側からのボリュームヘルスモニタリング機能をサポートしている場合、CSIボリュームで異常なボリューム状態が検出されると、関連するPersistentVolumeClaim(PVC)でイベントが報告されます。
外部ヘルスモニターコントローラーも、ノード障害イベントを監視します。enable-node-watcher
フラグをtrueに設定することで、ノード障害の監視を有効にできます。外部ヘルスモニターがノード障害イベントを検出すると、コントローラーは、このPVCを使用するポッドが障害ノード上にあることを示すために、PVCでイベントが報告されることを報告します。
CSIドライバーがノード側からのボリュームヘルスモニタリング機能をサポートしている場合、CSIボリュームで異常なボリューム状態が検出されると、PVCを使用するすべてのPodでイベントが報告されます。さらに、ボリュームヘルス情報はKubelet VolumeStatsメトリクスとして公開されます。新しいメトリックkubelet_volume_stats_health_status_abnormalが追加されました。このメトリックにはnamespace
とpersistentvolumeclaim
の2つのラベルが含まれます。カウントは1または0です。1はボリュームが異常であることを示し、0はボリュームが正常であることを示します。詳細については、KEPを確認してください。
次の項目
CSIドライバーのドキュメントを参照して、この機能を実装しているCSIドライバーを確認してください。