この記事はOpenShift Advent Calendar 2022とvExpert Advent Calendar 2022の12月23日分の投稿記事です。
はじめに
vSphere環境で利用OpenShiftを利用する場合、PV/PVCを利用するためのボリュームプラグインとして今後CSIドライバが推奨され、将来的にIn-Treeドライバが削除される予定です。CSI Migrationを有効化することで、現在利用しているIn-Treeボリュームプラグインで作成されたPV・PVCリソースがどのように扱われるかを確認してみます。
In-Tree Volume PluginとCSI
Kubernetes環境でPersistent Volume(永続ボリューム)を利用するためのボリュームプラグインとして、Kubernetesに組み込まれたIn-Tree Volume PluginとCSIを利用することが可能です。現在はCSIの利用が推奨されており、すでにいくつかのIn-Tree Volume PluginはKubernetesから削除されています。In-TreeボリュームプラグインではなくContainer Storage Interface (CSI)として実装することにより、サードパーティーのストレージプロバイダーは、Kubernetesのコードを変更せずに標準のインターフェイスを使用してストレージプラグインを提供できます。
vSphere環境におけるIn-Tree Volume PluginとvSphere CSIの利用
vSphere環境ではIn-TreeボリュームプラグインとしてvsphereVolume(kubernetes.io/vsphere-volume
)の利用が可能ですがすでにDeprecatedとなっており、vSphere CSIの利用が推奨されています。OpenShiftでは4.8でvSphere CSI が TechPreview となり、4.10でGA になりました。2022年12月の最新バージョンである4.11をIPIでインストールすると、In-Treeドライバ(kubernetres.io/vsphere-volume
)とCSIドライバ(csi.vsphere.vmware.com
)の両方がStorageClassとして構成され、デフォルトフラグはthin(In-Treeドライバ)となっています。
$ oc version
Client Version: 4.11.0-202210262118.p0.g142cb44.assembly.stream-142cb44
Kustomize Version: v4.5.4
Server Version: 4.11.13
Kubernetes Version: v1.24.6+5157800
$ oc get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
thin (default) kubernetes.io/vsphere-volume Delete Immediate false 37m
thin-csi csi.vsphere.vmware.com Delete WaitForFirstConsumer true 35m
$ oc get csidrivers.storage.k8s.io
NAME ATTACHREQUIRED PODINFOONMOUNT STORAGECAPACITY TOKENREQUESTS REQUIRESREPUBLISH MODES AGE
csi.vsphere.vmware.com true false false <unset> false Persistent 37m
OpenShift 4.11のドキュメントの「VMware vSphere CSI ドライバー Operator」の説明として以下の記載があり、今後In-Treeドライバが削除される予定であることが明記されています。
OpenShift Container Platform は、vSphere ストレージをプロビジョニングするためにデフォルトで in-tree または CSI 以外のドライバの使用に設定されます。
今後の OpenShift Container Platform バージョンでは、既存の in-tree プラグインを使用してプロビジョニングされるボリュームは、同等の CSI ドライバーに移行される予定です。CSI 自動マイグレーションはシームレスに行ってください。移行をしても、永続ボリューム、永続ボリューム要求、ストレージクラスなどの既存の API オブジェクトを使用する方法は変更されません。移行についての詳細は、CSI の自動移行を参照してください。
完全な移行後、in-tree プラグインは最終的に OpenShift Container Platform の今後のバージョンで削除されます。
CSI Migraition
CSI MigrationはIn-Treeドライバに対する操作をCSIの同等のAPIに変換して代替のCSIドライバで実現する機能です。KubernetesクラスターでCSI Migrationを有効化すると、ユーザーは既存のStorageClass、PersistentVolume、PersistentVolumeClaimをそのまま利用することができますが、KubernetesはIn-Treeドライバに対するストレージ操作をCSIドライバに渡します。CSI MigrationによりユーザーはシームレスにCSIドライバに移行することができ、最終的にはIn-TreeストレージドライバをKubernetesのコアバイナリから削除することが可能になります。
OpenShift 4.11(Kubernetes v1.24)ではAzure DiskとOpenStack CinderのAutomatic CSI Migrationが利用可能になっています。
- Kubernetes 1.24 Stargazer : Storage Plugin Migration
- OpenShift 4.11 : Automatic CSI migration for OpenStack Cinder is generally available / Automatic CSI migration for Microsoft Azure Disk is generally available
vSphere向けのIn-Treeプラグインであるkubernetes.io/vsphere-volume
をvSphere CSI (csi.vsphere.vmware.com
)として利用可能にするための、vSphere CSI Migrationは今月リリースのKubernetes v1.26でStable になっています。
また、vSphere向けのIn-TreeドライバはKubernetes v1.28で削除される予定になっているようです。
OpenShift 4.11におけるvSphere CSI Migrationの有効化
OpenShift 4.11でPVCを作成して、vSphere CSI Migrationを有効化して挙動を確認してみます。
OpenShift 4.10以降でvSphere CSIに対するCSI Migrationを利用することができますが、現時点では Technology Preview(TP) 扱いとなっており、デフォルトで無効化されています。この機能を有効化するには、Feature Gateで明示的に有効化する必要があります。一度有効化したFeature Gateは無効化することができず、Feature Gateを有効化するとクラスターのマイナーアップグレードが不可能となるため注意してください。
機能ゲートを使用してテクノロジープレビュー機能をオンにした後にそれらをオフにすることはできません。その結果、クラスターのアップグレードはできなくなります。
テスト用PV/PVCの作成
vSphere IPIでインストールした環境でStorageClassthin
とthin-csi
を利用してPVCを作成してみます。
$ oc get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
vsphere-csi-pvc Bound pvc-cfd35e01-9b4c-41d9-a229-ffaca40c5496 10Gi RWO thin-csi 126m
vsphere-pvc Bound pvc-188bdcc2-943b-4788-8c33-297c917bbd77 10Gi RWO thin 126m
vSphere Clientで確認すると、thin-csi
として作成したPVC(pvc-cfd35e01-9b4c-41d9-a229-ffaca40c5496)はコンテナボリュームとして認識されていますが、thin
を指定して作成したPVC(pvc-188bdcc2-943b-4788-8c33-297c917bbd77)はコンテナボリュームとして認識されていません。
govcでCNS Volumesを確認すると、thin-csi
として作成したボリュームだけが表示されています。
$ govc volume.ls -l
098ea18d-457d-4349-b8b3-8e86c525a652 pvc-cfd35e01-9b4c-41d9-a229-ffaca40c5496 10.0GB KUBERNETES nvaie-9pfjt
Feature Gateの有効化
Feature Gateはfeaturegates.config.openshift.io
リソースとして管理されています。
$ oc get featuregates.config.openshift.io
NAME AGE
cluster 20h
featuregates.config.openshift.io
リソースを以下のように修正します。
apiVersion: config.openshift.io/v1
kind: FeatureGate
metadata:
name: cluster
spec:
featureSet: CustomNoUpgrade
customNoUpgrade:
enabled:
- CSIMigrationvSphere
CSIMigrationvSphere
を有効化してfeaturegates.config.openshift.io
リソースを更新します。
$ oc apply -f featuregate.yaml
Warning: resource featuregates/cluster is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by oc apply. oc apply should only be used on resources created declaratively by either oc create --save-config or oc apply. The missing annotation will be patched automatically.
featuregate.config.openshift.io/cluster configured
しばらくすると各ノードの設定が変更されます。Masterのkubee-schedulerとkube-controller-managerでは、--feature-gatess=CSIMigrationvSPhere=ture
が追加されています。
sh-4.4# hostname
nvaie-9pfjt-master-0
sh-4.4# ps ax | grep -i CSIMigrationvSphere
1946 ? Ssl 0:06 kube-controller-manager --openshift-config=/etc/kubernetes/static-pod-resources/configmaps/config/config.yaml --kubeconfig=/etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig --authentication-kubeconfig=/etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig --authorization-kubeconfig=/etc/kubernetes/static-pod-resources/configmaps/controller-manager-kubeconfig/kubeconfig --client-ca-file=/etc/kubernetes/static-pod-certs/configmaps/client-ca/ca-bundle.crt --requestheader-client-ca-file=/etc/kubernetes/static-pod-certs/configmaps/aggregator-client-ca/ca-bundle.crt -v=2 --tls-cert-file=/etc/kubernetes/static-pod-resources/secrets/serving-cert/tls.crt --tls-private-key-file=/etc/kubernetes/static-pod-resources/secrets/serving-cert/tls.key --allocate-node-cidrs=false --cert-dir=/var/run/kubernetes --cloud-config=/etc/kubernetes/static-pod-resources/configmaps/cloud-config/cloud.conf --cloud-provider=vsphere --cluster-cidr=10.128.0.0/14 --cluster-name=nvaie-9pfjt --cluster-signing-cert-file=/etc/kubernetes/static-pod-certs/secrets/csr-signer/tls.crt --cluster-signing-duration=720h --cluster-signing-key-file=/etc/kubernetes/static-pod-certs/secrets/csr-signer/tls.key --configure-cloud-routes=false --controllers=* --controllers=-bootstrapsigner --controllers=-tokencleaner --controllers=-ttl --enable-dynamic-provisioning=true --feature-gates=CSIMigrationvSphere=true --flex-volume-plugin-dir=/etc/kubernetes/kubelet-plugins/volume/exec --kube-api-burst=300 --kube-api-qps=150 --leader-elect-resource-lock=configmapsleases --leader-elect-retry-period=3s --leader-elect=true --pv-recycler-pod-template-filepath-hostpath=/etc/kubernetes/static-pod-resources/configmaps/recycler-config/recycler-pod.yaml --pv-recycler-pod-template-filepath-nfs=/etc/kubernetes/static-pod-resources/configmaps/recycler-config/recycler-pod.yaml --root-ca-file=/etc/kubernetes/static-pod-resources/configmaps/serviceaccount-ca/ca-bundle.crt --secure-port=10257 --service-account-private-key-file=/etc/kubernetes/static-pod-resources/secrets/service-account-private-key/service-account.key --service-cluster-ip-range=172.30.0.0/16 --use-service-account-credentials=true --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 --tls-min-version=VersionTLS12
10209 ? Ssl 0:06 kube-scheduler --config=/etc/kubernetes/static-pod-resources/configmaps/config/config.yaml --cert-dir=/var/run/kubernetes --authentication-kubeconfig=/etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig --authorization-kubeconfig=/etc/kubernetes/static-pod-resources/configmaps/scheduler-kubeconfig/kubeconfig
--feature-gates=CSIMigrationvSphere=true -v=2 --tls-cert-file=/etc/kubernetes/static-pod-resources/secrets/serving-cert/tls.crt --tls-private-key-file=/etc/kubernetes/static-pod-resources/secrets/serving-cert/tls.key --tls-cipher-suites=TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 --tls-min-version=VersionTLS12
93836 ? S+ 0:00 grep -i CSIMigrationvSphere
kubeletの設定にもfeatureGates
として"CSIMigrationvSphere": true
という設定が追加されています。
sh-4.4# cat /etc/kubernetes/kubelet.conf
{
"kind": "KubeletConfiguration",
"apiVersion": "kubelet.config.k8s.io/v1beta1",
"staticPodPath": "/etc/kubernetes/manifests",
...
"featureGates": {
"APIPriorityAndFairness": true,
"CSIMigrationAzureFile": false,
"CSIMigrationvSphere": true,
"DownwardAPIHugePages": true,
"RotateKubeletServerCertificate": true
},
...
}
vSphere CSIの設定が含まれるConfgMapでもcsi-migration: "true"
となっています。
$ oc get cm -n openshift-cluster-csi-drivers internal-feature-states.csi.vsphere.vmware.com -oyaml
apiVersion: v1
data:
csi-auth-check: "true"
csi-migration: "true"
online-volume-extend: "true"
kind: ConfigMap
metadata:
creationTimestamp: "2022-12-21T05:38:50Z"
name: internal-feature-states.csi.vsphere.vmware.com
namespace: openshift-cluster-csi-drivers
resourceVersion: "8652"
uid: e5199f4e-b962-4802-9798-b8256a42376f
Migrationの確認
In-Treeドライバで作成したPVCを確認すると、Annotationsにpv.kubernetes.io/migrated-to: csi.vsphere.vmware.com
がついています。
$ oc describe pvc vsphere-pvc
Name: vsphere-pvc
Namespace: masanara
StorageClass: thin
Status: Bound
Volume: pvc-188bdcc2-943b-4788-8c33-297c917bbd77
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
pv.kubernetes.io/migrated-to: csi.vsphere.vmware.com
volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/vsphere-volume
volume.kubernetes.io/storage-provisioner: kubernetes.io/vsphere-volume
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 10Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: vsphere-pod-dc88dd678-wtqpv
Events: <none>
PVのAnnotationsにもpv.kubernetes.io/migrated-to: csi.vsphere.vmware.com
がついていますが、Volumeはkubernetes.io/vsphere-volume
として作成したものが参照されています。
$ oc describe pv pvc-188bdcc2-943b-4788-8c33-297c917bbd77
Name: pvc-188bdcc2-943b-4788-8c33-297c917bbd77
Labels: <none>
Annotations: kubernetes.io/createdby: vsphere-volume-dynamic-provisioner
pv.kubernetes.io/bound-by-controller: yes
pv.kubernetes.io/migrated-to: csi.vsphere.vmware.com
pv.kubernetes.io/provisioned-by: kubernetes.io/vsphere-volume
Finalizers: [kubernetes.io/pv-protection external-attacher/csi-vsphere-vmware-com]
StorageClass: thin
Status: Bound
Claim: masanara/vsphere-pvc
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 10Gi
Node Affinity: <none>
Message:
Source:
Type: vSphereVolume (a Persistent Disk resource in vSphere)
VolumePath: [Unity-Tanzu] kubevols/nvaie-9pfjt-dynamic-pvc-188bdcc2-943b-4788-8c33-297c917bbd77.vmdk
FSType: ext4
StoragePolicyName:
Events: <none>
vSphere Clientで確認すると、thin
を指定して作成したPVC(pvc-188bdcc2-943b-4788-8c33-297c917bbd77)もvSphere CSI経由の管理に移行されたため、コンテナボリュームとして認識されています。
CNS volumesを確認すると、thin
として作成したボリュームもCNS volumeに変換されたため一覧に表示されています。
$ govc volume.ls -l
b86b065f-bfc2-4eb7-9780-cd388b20d991 429ddb9e-7ed2-11ed-8ee7-005056ae3ff8 10.0GB KUBERNETES nvaie-9pfjt
098ea18d-457d-4349-b8b3-8e86c525a652 pvc-cfd35e01-9b4c-41d9-a229-ffaca40c5496 10.0GB KUBERNETES nvaie-9pfjt
新規PVCの作成
Migrationが有効になった状態で、In-Treeドライバを指定する以下のマニフェストでPVCを作成してみます。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vsphere-pvc2
spec:
storageClass: thin
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
PVCが作成されました。StorageClassはthin
を利用しているため、kubernetes.io/vsphere-volume
が指定されることになります。
$ oc apply -f vsphere-pvc2.yaml
persistentvolumeclaim/vsphere-pvc2 created
$ oc get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
vsphere-csi-pvc Bound pvc-cfd35e01-9b4c-41d9-a229-ffaca40c5496 10Gi RWO thin-csi 3d13h
vsphere-pvc Bound pvc-188bdcc2-943b-4788-8c33-297c917bbd77 10Gi RWO thin 3d13h
vsphere-pvc2 Bound pvc-1b3e1910-94e7-4394-942a-46098f1aa550 10Gi RWO thin 4s
作成されたPVC/PVを確認すると、内部ではCSIを利用してプロビジョニングされていることがわかります。
$ oc describe pvc vsphere-pvc2
Name: vsphere-pvc2
Namespace: masanara
StorageClass: thin
Status: Bound
Volume: pvc-1b3e1910-94e7-4394-942a-46098f1aa550
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: csi.vsphere.vmware.com
volume.kubernetes.io/storage-provisioner: csi.vsphere.vmware.com
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 10Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ExternalProvisioning 2m39s persistentvolume-controller waiting for a volume to be created, either by external provisioner "csi.vsphere.vmware.com" or manually created by system administrator
Normal Provisioning 2m39s csi.vsphere.vmware.com_nvaie-9pfjt-master-2_58e8e693-9e8e-4a85-b45d-54e386a87db7 External provisioner is provisioning volume for claim "masanara/vsphere-pvc2"
Normal ProvisioningSucceeded 2m38s csi.vsphere.vmware.com_nvaie-9pfjt-master-2_58e8e693-9e8e-4a85-b45d-54e386a87db7 Successfully provisioned volume pvc-1b3e1910-94e7-4394-942a-46098f1aa550
$ oc describe pv pvc-1b3e1910-94e7-4394-942a-46098f1aa550
Name: pvc-1b3e1910-94e7-4394-942a-46098f1aa550
Labels: <none>
Annotations: pv.kubernetes.io/migrated-to: csi.vsphere.vmware.com
pv.kubernetes.io/provisioned-by: kubernetes.io/vsphere-volume
volume.kubernetes.io/provisioner-deletion-secret-name:
volume.kubernetes.io/provisioner-deletion-secret-namespace:
Finalizers: [kubernetes.io/pv-protection]
StorageClass: thin
Status: Bound
Claim: masanara/vsphere-pvc2
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 10Gi
Node Affinity: <none>
Message:
Source:
Type: vSphereVolume (a Persistent Disk resource in vSphere)
VolumePath: [ESA] 8e5c9e63-3078-f184-2bb6-b8cef6a515b8/ba9e5f035b7943dfa38f694b4492d671.vmdk
FSType: ext4
StoragePolicyName:
Events: <none>
govcでCNS Volumeを確認するとCSIによって作成されたボリューム(pvc-1b3e1910-94e7-4394-942a-46098f1aa550
)が存在することを確認できます。
$ govc volume.ls -l
f30b40be-89ac-4a4a-8e36-e530529e7f1d pvc-1b3e1910-94e7-4394-942a-46098f1aa550 10.0GB KUBERNETES nvaie-9pfjt
b86b065f-bfc2-4eb7-9780-cd388b20d991 429ddb9e-7ed2-11ed-8ee7-005056ae3ff8 10.0GB KUBERNETES nvaie-9pfjt
098ea18d-457d-4349-b8b3-8e86c525a652 pvc-cfd35e01-9b4c-41d9-a229-ffaca40c5496 10.0GB KUBERNETES nvaie-9pfjt
まとめ
vSphere CSI Migrationを利用することで、過去にIn-Treeドライバ作成したPV/PVCを意識すること無くvSphere CSI管理下に移行することができます。ただし、現在のOpenShiftでvSphere CSI Migrationを有効にするのはやめたほうが良さそうです。今後リリースされる Kubernetes v1.26ベースのOpenShiftでは問題なく利用できるようになりそうです。