vSphere / vSAN 6.7 U3 と Kubernetes で VMware Cloud Native Storage を試してみる。

vSphere / vSAN 6.7 U3 と Kubernetes で VMware Cloud Native Storage を試してみる。

vSphere 6.7 U3 / vSAN 6.7 U3 から、VMware Cloud Native Storage と呼ばれるソリューションが提供されました。

これにより、Kubernetes から vSphere Container Storage Interface(CSI)Driver で利用されているボリュームが確認しやすくなります。

vmw-cns-00.png

さっそく、ドキュメントをもとに試してみます。

About Getting Started with VMware Cloud Native Storage

今回の環境。

Kubernetes のバージョンは、ドキュメントで利用しているものにしましたが、

Kubernetes の Maser / Worker は個人的に使い慣れている Oracle Linux 7 にしています。

  • vCenter Server 6.7 U3 / ESXi 6.7 U3 / vSAN 6.7 U3
  • Kubenetes Node OS: Oracle Linux 7
    • Master x 1、Worker x3
    • ESXi / vSAN 上の VM として作成。
  • Kubernetes 1.14.2

VM の設定。

Cloud Native Storage(CNS)を利用する Kubernetes ノードの VM では、

disk.EnableUUID というパラメータを設定しておきます。

vSphere Client から設定可能ですが、今回は PowerCLI で設定しています。

PowerCLI> Get-Folder -Type VM -Name "ol7-k8s-lab-03" | Get-VM | Get-AdvancedSetting -Name disk.EnableUUID | select Entity,Name,Value | sort Entity

Entity   Name            Value

------   ----            -----

k8s-m-31 disk.EnableUUID TRUE

k8s-w-31 disk.EnableUUID TRUE

k8s-w-32 disk.EnableUUID TRUE

k8s-w-33 disk.EnableUUID TRUE

また、Kubernetes のセットアップで利用する kubeadm の要件を考慮して

VM あたりのリソースは、2 vCPU、メモリ 4GB 以上にしてあります。

PowerCLI> Get-Folder -Type VM -Name "ol7-k8s-lab-03" | Get-VM | select Name,PowerState,NumCPU,MemoryGB | sort Name | ft -AutoSize

Name     PowerState NumCpu MemoryGB

----     ---------- ------ --------

k8s-m-31  PoweredOn      2        4

k8s-w-31  PoweredOn      2        4

k8s-w-32  PoweredOn      2        4

k8s-w-33  PoweredOn      2        4

Linux OS の準備。

ドキュメントでは Ubuntu を使用していますが、

今回は、あえて Oracle Linux を使用してみました。

ただし Kubernetes にかかわる kubeadm と Docker は、Oracle Linux むけのものではなく

それぞれのプロダクトの Yum リポジトリを追加して、そこからインストールしています。

Linux OS は ISO インストーラからインストールし、ネットワーク設定を済ませた状態です。

今回は、kubernetes のセットアップからを手動で試しやすいように、

下記のような Ansible Playbook を作成して、OS のセットアップとファイル配布をしています。

GitHub - gowatana/vmware-cns-demo

Kubernetes クラスタ(Master)のセットアップ。

まず、kubeadm で Master ノードをセットアップします。

この環境での Master ノードは 1台のみです。

Master ノードにセットアップする OS に root ユーザでログインします。

Ansible で /root/01_kubeadm/kubeadm-init-master.yml ファイルを配置してあるので、

これをもとに kubeadm init コマンドを実行します。

[root@k8s-m-31 ~]# kubeadm init --config ./01_kubeadm/kubeadm-init-master.yml

Master ノードがセットアップされました。

まだ NotReady ですが、このまま進めます。

[root@k8s-m-31 ~]# export KUBECONFIG=/etc/kubernetes/admin.conf

[root@k8s-m-31 ~]# kubectl get nodes

NAME       STATUS     ROLES    AGE   VERSION

k8s-m-31   NotReady   master   58s   v1.14.2

今回は root ユーザのみですすめるので、

再ログイン時に環境変数 KUBECONFIG が設定されるように、.bash_profile にも追記しておきます。

[root@k8s-m-31 ~]# echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> /root/.bash_profile

Worker ノードのセットアップで利用する discovery.yml を取得しておきます。

[root@k8s-m-31 ~]# kubectl -n kube-public get configmap cluster-info -o jsonpath='{.data.kubeconfig}' > /etc/kubernetes/discovery.yml

discovery.yml ファイルは、これから Worker ノードにする OS の、/etc/kubernetes/ ディレクトリ配下に

scp などでコピーしておきます。

[root@k8s-m-31 ~]# scp /etc/kubernetes/discovery.yml <Worker Nodeのアドレス>:/etc/kubernetes/

Flannel のセットアップ。

Kubernetes のノード間のネットワークを構成する、Flannel をセットアップしておきます。

[root@k8s-m-31 ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentat...

clusterrole.rbac.authorization.k8s.io/flannel created

clusterrolebinding.rbac.authorization.k8s.io/flannel created

serviceaccount/flannel created

configmap/kube-flannel-cfg created

daemonset.extensions/kube-flannel-ds-amd64 created

daemonset.extensions/kube-flannel-ds-arm64 created

daemonset.extensions/kube-flannel-ds-arm created

daemonset.extensions/kube-flannel-ds-ppc64le created

daemonset.extensions/kube-flannel-ds-s390x created

Kubernetes クラスタ(Worker)のセットアップ。

Worker ノードそれぞれで kubeadm join を実行し、セットアップをすすめます。

Ansible で配置ずみの 01_kubeadm/kubeadm-init-worker.yml ファイルと、

セットアップずみの Master ノードから取得した discovery.yml ファイルを使用しています。

[root@k8s-w-31 ~]# kubeadm join --config ./01_kubeadm/kubeadm-init-worker.yml

kubeadm join を実行したノードが追加されたことがわかります。

[root@k8s-m-31 ~]# kubectl get nodes

NAME       STATUS   ROLES    AGE   VERSION

k8s-m-31   Ready    master   16m   v1.14.2

k8s-w-31   Ready    <none>   32s   v1.14.2

今回は、Master 1台、Worker 3台の構成にしました。

[root@k8s-m-31 ~]# kubectl get nodes

NAME       STATUS   ROLES    AGE     VERSION

k8s-m-31   Ready    master   18m     v1.14.2

k8s-w-31   Ready    <none>   2m40s   v1.14.2

k8s-w-32   Ready    <none>   53s     v1.14.2

k8s-w-33   Ready    <none>   31s     v1.14.2

この時点だと、まだ Worker ノードがコンテナを起動しない状態(NoSchedule)ですが、

このまま次に進みます。

[root@k8s-m-31 ~]# kubectl describe nodes | egrep "Taints:|Name:"

Name:               k8s-m-31

Taints:             node-role.kubernetes.io/master:NoSchedule

Name:               k8s-w-31

Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule

Name:               k8s-w-32

Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule

Name:               k8s-w-33

Taints:             node.cloudprovider.kubernetes.io/uninitialized=true:NoSchedule

Cloud Provider for vSphere のセットアップ。

Kubernetes と vCenter が連携するための「Kubernetes Cloud Provider for vSphere」をセットアップします。

GitHub - kubernetes/cloud-provider-vsphere: Kubernetes Cloud Provider for vSphere

ここからは、すべて Master ノードで作業します。

今回のデモでは、Cloud Provider で指定する設定ファイルのテンプレートも、Ansible で配布しています。

[root@k8s-m-31 ~]# ls -1 ./02_k8s-csi/

csi-driver-deploy.yaml

csi-driver-rbac.yaml

csi-vsphere.conf

vsphere.conf

このうち、vsphere.conf を環境にあわせて編集します。

  • このサンプルファイルは自宅ラボの環境です。
  • ユーザー /  パスワードは、デモむけに あえて安直なものにしています。

[root@k8s-m-31 ~]# cat ./02_k8s-csi/vsphere.conf

[Global]

insecure-flag = "true"

[VirtualCenter "infra-vc-01.go-lab.jp"]

user = "administrator@vsphere.local"

password = "VMware1!"

port = "443"

datacenters = "infra-dc-01"

[Network]

public-network = "vxw-dvs-30-virtualwire-14-sid-10003-ls-lab-k8s-003"

vsphere.conf ファイルをもとに、cloud-config という ConfigMap を作成します。

この名前は、後続の kubectl apply で指定している YAML ファイルの内容に合わせてあります。

[root@k8s-m-31 ~]# kubectl create configmap cloud-config -n kube-system --from-file ./02_k8s-csi/vsphere.conf

configmap/cloud-config created

そして、GitHub にある YAML ファイルをもとにリソースを準備していきます。

ClusterRole・・・

[root@k8s-m-31 ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-vsphere/master/manifests/controller-mana...

clusterrole.rbac.authorization.k8s.io/system:cloud-controller-manager created

RoleBinding、ClusterRoleBinding・・・

[root@k8s-m-31 ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-vsphere/master/manifests/controller-mana...

rolebinding.rbac.authorization.k8s.io/servicecatalog.k8s.io:apiserver-authentication-reader created

clusterrolebinding.rbac.authorization.k8s.io/system:cloud-controller-manager created

ServiceAccount、DaemonSet、Service・・・

[root@k8s-m-31 ~]# kubectl apply -f https://github.com/kubernetes/cloud-provider-vsphere/raw/master/manifests/controller-manager/vsphere...

serviceaccount/cloud-controller-manager created

daemonset.extensions/vsphere-cloud-controller-manager created

service/vsphere-cloud-controller-manager created

これで、下記のような Pod が起動された状態になります。

[root@k8s-m-31 ~]# kubectl get pods -n kube-system -l k8s-app=vsphere-cloud-controller-manager

NAME                                     READY   STATUS    RESTARTS   AGE

vsphere-cloud-controller-manager-275cj   1/1     Running   0          4m27s

各ノードでは、ProviderID が確認できるようになります。

[root@k8s-m-31 ~]# kubectl describe nodes | egrep "Name:|ProviderID:"

Name:               k8s-m-31

ProviderID:                  vsphere://42362f4f-d91b-4747-9d05-18c4b7287d65

Name:               k8s-w-31

ProviderID:                  vsphere://42362124-8759-dab1-e1c2-2478c6ac8450

Name:               k8s-w-32

ProviderID:                  vsphere://4236fbb9-2e70-1fc3-c87b-9dc574e80623

Name:               k8s-w-33

ProviderID:                  vsphere://4236e12c-841e-5b39-04a6-3e6b80cdc93e

また、Worker ノードの「NoSchedule」も解除されます。

[root@k8s-m-31 ~]# kubectl describe nodes | egrep "Name:|Taints:"

Name:               k8s-m-31

Taints:             node-role.kubernetes.io/master:NoSchedule

Name:               k8s-w-31

Taints:             <none>

Name:               k8s-w-32

Taints:             <none>

Name:               k8s-w-33

Taints:             <none>

CSI のセットアップ。

Container Storage Interface(CSI)Driver をデプロイします。

下記の3つのファイルを用意します。

  • csi-vsphere.conf ※環境に合わせて編集
  • csi-driver-rbac.yaml ※今回はドキュメントのまま
  • csi-driver-deploy.yaml ※今回はドキュメントのまま

参考ドキュメント: Install the vSphere Container Storage Interface Driver

csi-vsphere.conf ファイルに、vSphere 環境の情報を記載しておきます。

先ほどのファイルと同様、これは私の自宅ラボのものなので、適宜編集します。

[root@k8s-m-31 ~]# cat ./02_k8s-csi/csi-vsphere.conf

[Global]

cluster-id = "infra-cluster-01"

[VirtualCenter "infra-vc-01.go-lab.jp"]

insecure-flag = "true"

user = "administrator@vsphere.local"

password = "VMware1!"

port = "443"

datacenters = "infra-dc-01"

vCenter の情報をもつ secret を作成します。

[root@k8s-m-31 ~]# kubectl create secret generic vsphere-config-secret -n kube-system --from-file=./02_k8s-csi/csi-vsphere.conf

secret/vsphere-config-secret created

vSphere CSI Driver の依存コンポーネントを準備します。

[root@k8s-m-31 ~]# kubectl create -f ./02_k8s-csi/csi-driver-rbac.yaml

serviceaccount/vsphere-csi-controller created

clusterrole.rbac.authorization.k8s.io/vsphere-csi-controller-role created

clusterrolebinding.rbac.authorization.k8s.io/vsphere-csi-controller-binding created

vSphere CSI Driver をデプロイします。

[root@k8s-m-31 ~]# kubectl create -f ./02_k8s-csi/csi-driver-deploy.yaml

statefulset.apps/vsphere-csi-controller created

csidriver.storage.k8s.io/csi.vsphere.vmware.com created

daemonset.apps/vsphere-csi-node created

少し待つと、CSI Driver の Pod がすべて READY になります。

[root@k8s-m-31 ~]# kubectl get pods -n kube-system | egrep "^NAME|vsphere"

NAME                                     READY   STATUS    RESTARTS   AGE

vsphere-cloud-controller-manager-275cj   1/1     Running   0          37m

vsphere-csi-controller-0                 5/5     Running   0          2m49s

vsphere-csi-node-4s2df                   3/3     Running   0          2m49s

vsphere-csi-node-8sspf                   3/3     Running   0          2m49s

vsphere-csi-node-c68fq                   3/3     Running   0          2m49s

これで、Worker ノードが CSI Node として利用できる状態になります。

[root@k8s-m-31 ~]# kubectl get csinode

NAME       CREATED AT

k8s-w-31   2019-08-27T23:29:37Z

k8s-w-32   2019-08-27T23:29:30Z

k8s-w-33   2019-08-27T23:29:27Z

サンプル アプリケーションのデプロイ。

CSI Driver によるボリュームを使用する、ステートフル アプリケーションをデプロイします。

ここでは、MongoDB をデプロイしますが、これをそのまま何かに利用するということではなく、

ただボリューム(Kubernetes の PVC / PV)の様子を見るデモのために利用します・・・

参考ドキュメント: Deploy a Stateful Application

1. vSphere 側の準備。

vCenter で、「仮想マシン ストレージ ポリシー」を作成しておきます。

今回は、vSAN 環境にデフォルトで作成される「vSAN Default Storage Policy」を利用します。

vmw-cns-07.png

2. Kubernetes でのアプリケーションのデプロイ。

ここでは、下記のファイルを使用します。

今回のデモでは、これらのファイルも Ansible で Master ノードに配布しています。

[root@k8s-m-31 ~]# ls -1 ./03_demo/

mongodb-key.txt

mongodb-service.yaml

mongodb-statefulset.yaml

mongodb-storageclass.yaml

Kubernetes の StorageClass で、下記を指定します。

provisioner として「csi.vsphere.vmware.com」、

仮想マシン ストレージ ポリシー として「vSAN Default Storage Policy」を指定します。

[root@k8s-m-31 ~]# cat ./03_demo/mongodb-storageclass.yaml

---

kind: StorageClass

apiVersion: storage.k8s.io/v1

metadata:

  name: mongodb-sc

  annotations:

    storageclass.kubernetes.io/is-default-class: "false"

provisioner: csi.vsphere.vmware.com

parameters:

  storagepolicyname: "vSAN Default Storage Policy"

  fstype: ext4

StorageClass を作成します。

[root@k8s-m-31 ~]# kubectl create -f ./03_demo/mongodb-storageclass.yaml

storageclass.storage.k8s.io/mongodb-sc created

StorageClassが作成されました。

[root@k8s-m-31 ~]# kubectl get storageclass mongodb-sc

NAME         PROVISIONER              AGE

mongodb-sc   csi.vsphere.vmware.com   51s

Service を作成します。

[root@k8s-m-31 ~]# kubectl create -f ./03_demo/mongodb-service.yaml

service/mongodb-service created

Secret を作成します。

[root@k8s-m-31 ~]# openssl rand -base64 741 > ./03_demo/mongodb-key.txt

[root@k8s-m-31 ~]# kubectl create secret generic shared-bootstrap-data --from-file=internal-auth-mongodb-keyfile=./03_demo/mongodb-key.txt

secret/shared-bootstrap-data created

そして、StatefulSet を作成します。

[root@k8s-m-31 ~]# kubectl create -f ./03_demo/mongodb-statefulset.yaml

statefulset.apps/mongod created

3. vCenter の vSphere Client での確認。

vSphere Client では、クラスタを選択して、

監視 → クラウド ネイティブ ストレージ → コンテナ ボリューム を開くと、Kubernetes のボリュームが確認できます。

vmw-cns-01.png

アプリケーションのデプロイをまち、

Kubernetes 側で PersistentVolume(PV) / PersistentVolumeClaim(PVC) が作成されたことを確認します。

※表示例は横に長いので、スクリーンショットにしてあります。

[root@k8s-m-31 ~]# kubectl get pv

[root@k8s-m-31 ~]# kubectl get pvc

vmw-cns-08.png

vSphere Client でも、PV が表示されるようになります。

vmw-cns-03.png

PV の先頭のアイコンをクリックすると、「Kubernetes オブジェクト」タブで

関連する Kubernetes オブジェクトの情報が表示できます。

vmw-cns-04.png

「基本」タブでは、PV の配置された vSAN データストア、VMDK の仮想マシン ストレージポリシー、

PV が接続している VM など、vSphere 管理者の視点での情報が表示されます。

vmw-cns-05.png

PV は、vSAN の仮想ディスクとして作成され、VM に接続されています。

上記のコンテナ ボリューム画面で PV のボリューム名をクリックするか、

監視 → vSAN → 仮想オブジェクト の画面をひらくと、VM に PV が接続されている様子がわかります。

vmw-cns-06.png

実は以前から Kubernetes にボリュームを提供する機能(Project Hatchway と呼ばれていた)はあったのですが、

vSphere 6.7 u3 からは、今回の例のように vSphere Clinet から「クラウド ボリューム」として

Kubernetes でボリュームとして利用している VMDK が見やすくなりました。

以上、vSphere / vSAN 6.7 U3 の Cloud Native Storage でした。

Version history
Revision #:
1 of 1
Last update:
‎08-28-2019 04:01 PM
Updated by: