この記事は、Udemyの講座 https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests および https://kodekloud.com/ の内容を学習しながらまとめたものです。
- 186 Container Storage Interface
- 188 Volumes
- 189 Persistent Volumes
- 190 Persistent Volume Claims
- 196 Storage Class
Kubernetes上でデータを永続的に保存する方法であるPersistent Volumeについて学びます。KubernetesのStorageを理解するには、まずDockerでのストレージの扱い方を知る必要があります。
Storage DriverとVolume Driverをしっかり理解することが重要です。
Dockerをインストールすると /var/lib/docker フォルダが作成され、その配下にさまざまなフォルダも作成されます。

Dockerは以前使用したdocker imageをキャッシュに保存し、再利用することで高速にビルドできます。

Read Write領域はコンテナが削除される際に一緒に削除されるため、データを永続的に保存するには別の方法が必要です。 Read Write領域にホストのストレージと接続されたフォルダをマウントする方法で対応します。
Volume mountとBind mountがあります。Bind mountはDockerホストの任意のディレクトリをマウントできます。

--mountオプションの方がより良い方法です。
$ dockker run --mount type=bind,source/data/mysql,target=/var/lib/mysql mysql
Storage driverは複数ありますが、Dockerが自動的に最適なものを選択します。
- AUFS(Ubuntu)
- ZFS
- BTRFS
- Device Mapper
- Overlay
- Overlay2
Volume DriverにはLocal、Azure File Storage、Convoy、DigitalOcean Block Storage、RexRayなどがあります。

186 Container Storage Interface
Container Runtime Interface Standardが存在することで、KubernetesとContainer Runtime(Docker、cri-o、rkt)間の依存性がなくなりました。同様に、CNIがあることでKubernetesとネットワークアドオン(Flannel、Cilium、Calico)を分離できました。ストレージ側にもCSI(Container Storage Interface)があることで、プラガブルに使用できるようになっています。


188 Volumes
KubernetesのSingle Nodeクラスター環境であれば、以下のように簡単にホストマシンのボリュームをコンテナにマウントできます。しかし、Multi Node環境では問題があります。Podが作成される場所によってホストがいつでも変わる可能性があるため、ボリュームのデータ内容が変わることがあります。そのため、Kubernetesが提供するPersistent Volumeを使用する必要があります。

189 Persistent Volumes
Persistent Volumeは以下のように定義でき、作成されたPersistent VolumeはPersistent Volume Claimで使用できます。HostPath部分を awsElasticBlockStore などに変更すれば、他のデータストレージとして使用できます。

190 Persistent Volume Claims
一般的に、AdministratorがPersistent Volumeを作成し、UserがPersistent Volume Claimを使用する構造です。SelectorでLabelを使って選択することもでき、候補が2つ以上ある場合はKubernetesが適切なvolumeをバインディングします。PVとPVCは1対1の関係であるため、PVCがPVを確保する際にぴったり合う容量がなく、大きな容量にバインドされた場合、無駄なストレージが発生する可能性があります。

Persistent Volume Claimを最初に作成した時はpending状態になり、一致するPersistent Volumeが見つかった場合にbound状態に変更されます。

PVCが削除された場合、PVはどうなるのでしょうか?デフォルトでは Retain 方式で動作し、PVはそのまま残ります。手動でPVを削除する必要があります。自動的にPVを削除する Delete や Recycle もあります。

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
以下の設定でPersistent Volumeを作成: Volume Name: pv-log Storage: 100Mi Access Modes: ReadWriteMany Host Path: /pv/log Reclaim Policy: Retain
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-log
spec:
capacity:
storage: 100Mi
accessModes:
- ReadWriteMany
hostPath:
path: "/pv/log"
persistentVolumeReclaimPolicy: Retain
Persistent Volume Claimの作成方法: Volume Name: claim-log-1 Storage Request: 50Mi Access Modes: ReadWriteOnce
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: claim-log-1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
PodでpersistentVolumeを使用する方法:
spec:
containers:
volumeMounts:
- mountPath: /log
name: webapp
volumes
- name: webapp
persistentVolumeClaim:
claimName: claim-log-1

196 Storage Class
PVとPVCを事前に設定してからアプリケーションで使用するのをstatic provisioningと呼びます。

Google Cloudを利用している場合、Persistent Volumeを毎回作成する代わりに、Persistent Volume Claimが作成されるたびに自動で生成されるようにできます。これを可能にするのがStorage Classです。
provisionerは複数あります。AWS EBS、GCE、Ceph、Azureなど。
また、Storage Classに応じてレプリケーションの有無やディスクの種類(HDD、SSD、NVMe SSD)を分けることもできます。

$ kubectl get storageclasses
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 15m
The Storage Class called local-storage makes use of VolumeBindingMode set to WaitForFirstConsumer. This will delay the binding and provisioning of a PersistentVolume until a Pod using the PersistentVolumeClaim is created.
クイズ
Q1: 「CKA_8_Storage」の主なトピックは何ですか?
CKA_8_Storage
Q2: この記事の重要なポイントは何ですか?
CKA_8_Storage
Q3: この記事の概念を実践にどう適用できますか?
記事全体で議論されている実践的な例やパターンを参考にしてください。