hidemium's blog

日々学んだことをアウトプットする。

KubernetesクラスタにvSphere CPIとvSphere CSIをインストールする

前回は、Cluster APIを使ってvSphere上にKubernetesクラスタを作成してみました。今回は、vSphere CPIとvSphere CSIのインストールを試してみたいと思います。

hidemium.hatenablog.com

構成

  • vCenter 7.0 U3
  • ESXi 7.0 Update 3
  • Kubespray
  • kubernetes v1.25.5
  • vSphere CPI v1.25.0
  • vSphere CSI v2.7.0

vSphere CPIとvSphere CSIについて

vSphere CSI は、KubernetesのPersistentVolume(PV)にてvSphere ストレージを利用するための、Container Storage Interface(CSI)プラグインになります。vSphere CSIを使うと、PVは仮想マシンの1つの仮想ディスクとしてworkerノードに接続されます。また、vSphere CSIで作成された仮想ディスクはFirst Class Disk(FCD)と呼ばれ、仮想マシンに接続しないと管理ができなかった通常の仮想ディスクと異なり、EBSのように独立して仮想ディスクの管理をすることができます。。FCDは、vSAN、VMFS、NFS、vVols データストアで利用でき、ReadWriteOnceのPVを作成することができます。vSANファイル共有を使うと、ReadWriteManyのPVを作成することができるようです。ストレージポリシーも利用でき、ディスクごとの可用性設定やIOコントロールをすることができます。

また、vSphere CSIは、vSphereのCloud Provider Interface (CPI) とともに使用されます。Controller Managerは、Kubernetesのコントローラをまとめて実行するコンポーネントです。Cloud Controller Managerは、Kubernetesで使用したいリソースと任意のクラウドで使用しているリソースの連携を行うCloud Providerを動作するためのコンポーネントです。In-Tree内のCloud Providerは、 vSphere Cloud Provider (VCP)と呼ばれていましたが、In-Tree外のCloud ProviderはvSphere CPIと呼ばれるようになりました。vSphere CPIは、vCenter Serverに接続し、VM、ディスクなどのインフラストラクチャに関する情報をKubernetes APIマッピングすることができます。

vSphere CPIのインストールの事前準備

vSphere CPIのインストールをする際に、vsphere-cloud-controller-managerがノードのリソースが少ない場合、起動してこないため、ノードのスペックを2vCPU、4GBメモリに変更しておきます。

Kubernetesクラスタのmasterノードとworkerノードの仮想マシンに対して、disk.EnableUUIDを有効にします。また、仮想ハードウェアバージョンは15以上、Paravirtual SCSIコントローラーが必要なようですが、すでに設定済みのためスキップします。

$ for VMNAME in kube-master0{1..3}; do
  echo ${VMNAME}
  export VM="/Datacenter/vm/k8s/$VMNAME"
  govc vm.change -vm $VM -e="disk.enableUUID=1"
done
$ for VMNAME in kube-worker0{1..2}; do
  echo ${VMNAME}
  export VM="/Datacenter/vm/k8s/$VMNAME"
  govc vm.change -vm $VM -e="disk.enableUUID=1"
done

masterノードとworkerノードに node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule というTaintを設定します。 Taintはノードに配置したくないPodの条件を指定し、Tolerationで容認がない場合は、Taintを設定したノードにPodが配置されない状態となります。

Taintを設定前の状態はこちらになります。

$ kubectl describe nodes | egrep "Taints:|Name:"
Name:               kube-master01
Taints:             node-role.kubernetes.io/master:NoSchedule
Name:               kube-master02
Taints:             node-role.kubernetes.io/master:NoSchedule
Name:               kube-master03
Taints:             node-role.kubernetes.io/master:NoSchedule
Name:               kube-worker01
Taints:             <none>
Name:               kube-worker02
Taints:             <none>

ノードにTaintを設定します。

$ for VMNAME in kube-master0{1..3}; do
  echo $VMNAME
  kubectl taint node $VMNAME node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule
done
$ for VMNAME in kube-worker0{1..2}; do
  echo $VMNAME
  kubectl taint node $VMNAME node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule
done

Taintの設定後の状態はこちらです。masterノードは設定前と変わっていないように見えました。

$ kubectl describe nodes | egrep "Taints:|Name:"
Name:               kube-master01
Taints:             node-role.kubernetes.io/master:NoSchedule
Name:               kube-master02
Taints:             node-role.kubernetes.io/master:NoSchedule
Name:               kube-master03
Taints:             node-role.kubernetes.io/master:NoSchedule
Name:               kube-worker01
Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule
Name:               kube-worker02
Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule

vSphere CPIのインストール

vsphere-cloud-controller-manager.yamlをダウンロードします

$ VERSION=1.25
$ wget https://raw.githubusercontent.com/kubernetes/cloud-provider-vsphere/release-$VERSION/releases/v$VERSION/vsphere-cloud-controller-manager.yaml

vsphere-cloud-controller-manager.yamlにて、vCenterなどの情報を書き換えます。

$ vi vsphere-cloud-controller-manager.yaml
apiVersion: v1
kind: Secret
metadata:
  name: vsphere-cloud-secret
  labels:
    vsphere-cpi-infra: secret
    component: cloud-controller-manager
  namespace: kube-system
  # NOTE: this is just an example configuration, update with real values based on your environment
stringData:
  10.0.10.5.username: "vCenter username"
  10.0.10.5.password: "vCenter password"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: vsphere-cloud-config
  labels:
    vsphere-cpi-infra: config
    component: cloud-controller-manager
  namespace: kube-system
data:
  # NOTE: this is just an example configuration, update with real values based on your environment
  vsphere.conf: |
    # Global properties in this section will be used for all specified vCenters unless overriden in VirtualCenter section.
    global:
      port: 443
      # set insecureFlag to true if the vCenter uses a self-signed cert
      insecureFlag: true
      # settings for using k8s secret
      secretName: vsphere-cloud-secret
      secretNamespace: kube-system

    # vcenter section
    vcenter:
      vcsa-1.home.lab:
        server: 10.0.10.5
        user: <vCenter username>
        password: <vCenter password>
        datacenters:
          - <datascenter name>

vSphere CPIをインストールします。

$ kubectl apply -f vsphere-cloud-controller-manager.yaml

インストールに成功すると、podはこのようになりました。

$ kubectl get pod -A

kube-system                         vsphere-cloud-controller-manager-9zczs                           1/1     Running             0                155m
kube-system                         vsphere-cloud-controller-manager-fcs65                           1/1     Running             0                155m
kube-system                         vsphere-cloud-controller-manager-r5wfk                           1/1     Running             0                155m

vsphere-cloud-controller-manager の起動が失敗している場合は、以下のコマンドで原因を確認します。

$ kubectl describe pod vsphere-cloud-controller-manager -n kube-system

vSphere CSIのインストール

vmware-system-csi というネームスペースを作成します。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/vsphere-csi-driver/v2.7.0/manifests/vanilla/namespace.yaml

masterノードに対して、Taintを設定します。

for VMNAME in kube-master0{1..3}; do
  echo $VMNAME
  kubectl taint nodes $VMNAME node-role.kubernetes.io/control-plane=:NoSchedule
done

Taintの設定後の状態はこちらです。

kubectl describe nodes | egrep "Taints:|Name:"
Name:               kube-master01
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Name:               kube-master02
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Name:               kube-master03
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Name:               kube-worker01
Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule
Name:               kube-worker02
Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedul

vSphere CSIのためのcsi-vsphere.confという定義ファイルを作成します。

$ vi csi-vsphere.conf
[Global]
cluster-id = "cluster-1"

[VirtualCenter "vcsa-1.home.lab"]
insecure-flag = "true"
user = "vCenter username"
password = "vCenter password"
port = "443"
datacenters = "datacenter name"

csi-vsphere.confからsecretを作成します。

$ kubectl create secret generic vsphere-config-secret --from-file=csi-vsphere.conf --namespace=vmware-system-csi

vSphere CSIをインストールします。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/vsphere-csi-driver/v2.7.0/manifests/vanilla/vsphere-csi-driver.yaml

vSphere CSIがインストールされたことを確認します。

$ kubectl get deployment --namespace=vmware-system-csi
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
vsphere-csi-controller   3/3     3            3           141m

インストールに成功すると、podはこのようになりました。

$ kubectl get pod -A

kube-system                         vsphere-cloud-controller-manager-9zczs                           1/1     Running             0                155m
kube-system                         vsphere-cloud-controller-manager-fcs65                           1/1     Running             0                155m
kube-system                         vsphere-cloud-controller-manager-r5wfk                           1/1     Running             0                155m
vmware-system-csi                   vsphere-csi-controller-68d96d8597-2cfcf                          7/7     Running             0                141m
vmware-system-csi                   vsphere-csi-controller-68d96d8597-5dszx                          7/7     Running             0                141m
vmware-system-csi                   vsphere-csi-controller-68d96d8597-82mcm                          7/7     Running             0                141m
vmware-system-csi                   vsphere-csi-node-b9ztz                                           3/3     Running              0                141m
vmware-system-csi                   vsphere-csi-node-cshf7                                           3/3     Running             0                141m
vmware-system-csi                   vsphere-csi-node-dqc79                                           3/3     Running             0                141m
vmware-system-csi                   vsphere-csi-node-fp2zd                                           3/3     Running             0                141m
vmware-system-csi                   vsphere-csi-node-qnfx6                                           3/3     Running             0                141m

動作確認

動作確認のため、PersistentVolumeを作成していきます。

ストレージポリシーの設定が必要なため、前回作成した Normal-Storage-Policy というストレージポリシーを利用します。IOPS制限は外しておきます。

hidemium.hatenablog.com

StorageClassの定義を作成し、インストールします。定義ファイルの中で先ほど用意したストレージポリシーを指定しておきます。

$ vi example-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: example-sc
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: csi.vsphere.vmware.com
parameters:
  storagepolicyname: "Normal-Storage-Policy"
  csi.storage.k8s.io/fstype: "ext4"
$ kubectl apply -f example-sc.yaml

PVCの定義を作成し、インストールします。

$ vi example-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: example-sc
$ kubectl apply -f example-pvc.yaml

PVとPVCが作成できていることを確認します。

$ kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
persistentvolume/pvc-6c1bc194-bbc0-4e26-b77c-3b2412960200   5Gi        RWO            Delete           Bound    default/example-pvc   example-sc              16s

NAME                                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/example-pvc   Bound    pvc-6c1bc194-bbc0-4e26-b77c-3b2412960200   5Gi        RWO            example-sc     17s

vCenterを見ると、クラウドネイティブストレージ>コンテナ ボリュームにPVの情報が表示されていることが分かります。

さらにデータストアブラウザを見ると、First Class Disk用のフォルダのfcdフォルダ内にPVの実態となる、vmdkファイルが作成されいてることをが分かります。

上記の定義ファイルだと、workerノードにFCDのvmdkはまだアタッチされていない状態となるようです。

参考