vCSA6.7U3 + vSAN環境での"Cloud Native Storage"項目について 【2 -導入 ;vSphere環境への連結編】

 

Announcement:本記事は複数に分けている記事の2番目となります。
一番目の記事をご確認されたい方は以下リンクへアクセスいただければ幸いです。

vCSA6.7U3 + vSAN環境での"Cloud Native Storage"項目について 【1 - 事前準備;Kubernetes Cluster構築編】
https://pocmemo.hatenablog.com/entry/2020/01/13/161344

 

Kubernetes ClusterをvSphere環境へ接続するまで

導入環境:
初回の記事でも記載しましたので簡単に再掲として記載しておきます。
なお、特にKubernetesはライフサイクルが非常に速いので、
記事掲載日時と各種バージョンリリース等にご注意いただければ幸いです。

・Nested vCSA 6.7 Update3
・ Nested vSAN 6.7 Update3(今回はAll FlashですがHybridでもOKです)
Ubuntu 18.04 - LTS *3台
kubernetes v1.14.2-00
※ 記事掲載時点での最新は1.17.0
・CNI:flannel

・公式Docs:https://docs.vmware.com/jp/VMware-vSphere/6.7/vsphere-673-cloud-native-storage.pdf

 

前回の記事により、以下のようにKubernetes Clusterを構築した段階まで
ご紹介させていただきました。
今回は以下状態からの続きとなります。
本記事ではKubernetesとvSphereが連携可能になるまでを確認していきます。
次回記事で実際の挙動等について追いかけたいと思います。

 

前回完了時点:Kubernetes Clusterを構築完了した時点から再開します。

f:id:pocmemo:20200113160229p:plain

 

Cloud Controller Managerの導入

そもそもCloud Controller Managerとはどのようなものでしょうか。
Kubernetesはその設計・目的上様々なクラウド環境へ接続する事を半ば前提として
設計・改良が進められています。
しかしご存知のように今や"クラウド"と言ってもサービスを展開している企業は
非常に多数存在しており、それぞれ違うソースコードであるのに対して
Kubernetesが各接続先クラウドのコードを認識できなくてはなりません。

プロビジョニングされる接続先環境を、k8sが認識する為に必要なマネージャが
この"Cloud Controller Manager"となります。

 

以下Kubernetes公式Docsから引っ張ってきたアーキテクチャです。

f:id:pocmemo:20200113175005p:plain

 

今回はクラウドではなくオンプレミスのvSphere環境が接続先となりますが、
接続先の認証を正しく出来るようにするためこのマネージャが使用されます。

とりあえずは"Kubernetes ClusterがvSphere環境を認識するために必要なもの"
と把握いただいて問題ありません。

 

実際の導入手順について

※ 本記事で実行する内容は特段の記載がない場合すべてMaster Node上での作業です。

 

実際の導入手順ですが、まずはconfigmapを事前作成し、環境のvsphere情報を
Kubernetes Cluster側で正しく把握できるようにしておきます。

・公式Docsの以下記述について確認いたします。
a configmap cloud-config vsphere.conf ファイルを定義します。

 

上記項目にて、公式Docsには以下のように記述されております。
基本的に以下に沿う形式で記載すれば問題ないです。

[Global]
insecure-flag = "true"

[VirtualCenter "vCenter Server IP address"]
user = "user"
password = "password"
port = "443"
datacenters = "datacenter"

[Network]
public-network = "VM Network"

 

上記について、例えば私の環境だと以下記述で実施しました。
[Network]については今回テスト環境で特段指定の必要が無かったため
割愛しております。

f:id:pocmemo:20200113175826p:plain

vCenterを複数参加させたい場合、下記のようにエントリを増やせばOKです。

 

[Global]
xxxx
[VirtualCenter "x.x.x.x"]
xxxx
[VirtualCenter "y.y.y.y"] 
xxxx

 

テスト環境でない方は、"Secretを使用したい"というニーズが出てくるかと思います。
その場合は以下のように記述する事でSecretを使用可能です。

vsphere.confに対し、以下のように記述

[Global]
port = "443"
insecure-flag = "true"

[VirtualCenter "10.10.38.150"]
secret-name = "vsphere-config-secret"
secret-namespace = "kube-system"

 

別途以下のように記述されたyamlファイルを作成し、--from-fileで指定して
kind: Secretのデプロイを実行する

 

apiVersion: v1
kind: Secret
metadata:
name: vsphere-config-secret
namespace: kube-system
stringData:
10.10.38.150.username: "administrator@vsphere.local"
10.10.38.150.password: "VMware1!"

 

その後実際にvsphere.confからcomfigmapを作成します。

・kubectl create cm cloud-config --from-file=<path>/vsphere.conf -n kube-system

作成確認のコマンドは以下となります。

・kubectl get cm cloud-config -n kube-system

 

Configmap作成後、実際に導入を実行していきます。

公式DocsにはTaintを確認する項目もございますが、こちらについても
念のため必ず実行をしておきましょう。

・kubectl describe nodes | egrep "Taints:|Name:"

余談ですがTaintとは各Nodeに対して設定するもので、これが設定されていると
Taint設定値の合わないPodの配置を拒否する動作が走ります。
WorkerNode上に予期せぬPodの配置を避ける為に設定される場合がほとんどです。
Master Nodeに対してデフォルトでシステム系以外のPodが配置されないのも
このTaintを利用しているためです。


上から一行ずつ実行をしていきます。

・kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-vsphere/master/manifests/controller-manager/cloud-controller-manager-roles.yaml

kind: ClusterRoleが設定されます。
・kubectl apply -f https://raw.githubusercontent.com/kubernetes/cloud-provider-vsphere/master/manifests/controller-manager/cloud-controller-manager-role-bindings.yaml

kind: RoleBindingが設定されます。
・kubectl apply -f https://github.com/kubernetes/cloud-provider-vsphere/raw/master/manifests/controller-manager/vsphere-cloud-controller-manager-ds.yaml

kind: ServiceAccount,DaemonSet,Service が設定されます。

 

実行後、各Nodeに対してProviderIDが発行されているか確認してみてください。

f:id:pocmemo:20200113183558p:plain

このProviderIDが正しく発行されていない場合は以下を改めて確認してみてください。
1. 作成したvsphere.confは正しい値を入れられているか

2. 各種実行して作成されたリソースは正しく設定・構築されているか

3. kubectl describeで作成された各項目を確認し、Event項目でErrorを出力しているか

 

CSI Driverの導入

事前準備の最終段階がこの"CSI Driver"の導入となります。
CSIについてもこのタイミングで確認したいと思います。

CSI(Container Storage Interface)はKubernetesとvSphere環境間で
ストレージのプロビジョニングに関するやり取りを司るコンポーネントです。
この場合、Kubernetesが"ストレージの要求をする側"、
vSphere環境が"Kubernetes Clusterからの要求に応える側"として疎通を実施します。
この機能により、必要に応じてvSphere環境に存在するストレージ容量を切り出して
Kubernetesに払い出す事が可能となります。

 

以下の画像はvmware社で公開された画像の一部となります。
Kubernetes Clusterに"CSI"と記載されているコンポーネントが今回導入するDriverで、
このCSIが"CNS Control Plane"と疎通を図る様子が記載されています。
この"CNS Control Plane"とは"vCenter"を指してます。
vCSA 6.7 Update3を導入した際デフォルトでクラウドネイティブストレージの項目が
存在している事からもわかるように
CNS Control PlaneはデフォルトでvCenterに組み込まれているため、
このCNS Control Planeの導入作業は必要ありません。

f:id:pocmemo:20200113185232p:plain

 

実際に実行する手順については公式Docsにも記載があるように、
ほとんどがCloud Controller Managerの導入時に行った手順と類似しています。

csi-vsphere.conf


[Global]
cluster-id = "cluster-id"
[VirtualCenter "vCenter Server IP address"]
insecure-flag = "true"
user = "user"
password = "password"
port = "443"
datacenters = "datacenter"

先ほど作成した時とほとんど同じ内容ですね。
※  cluster-id = "cluster-id" 当該行についてですが、
     どこかでUUIDなどをチェックする必要はありません。
     管理しやすい文言を好みで付与するだけでOKです。
  私はCluster名が"test-vSAN"だったので、同じでいいか...とそのまま付けました。
     複数のKubernetes Cluster環境下ではそれぞれ違うIDを設定しておくのが無難です。

以下コマンドを入力し、作成を実行します。

・kubectl create secret generic vsphere-config-secret --from-file=csi-vsphere.conf --namespace=kube-system

 

その後、公式Docs記載の”2 vSphere CSI ドライバに必要なすべてのコンポーネントを展開します。” へ移ります。

実際にこの作業によりRepositoryからPullされてくるイメージ一覧は以下となります。

image: quay.io/k8scsi/csi-attacher:v1.1.1
image: vmware/vsphere-block-csi-driver:v1.0.0
image: quay.io/k8scsi/livenessprobe:v1.1.0
image: vmware/volume-metadata-syncer:v1.0.0
image: quay.io/k8scsi/csi-provisioner:v1.2.1
image: quay.io/k8scsi/csi-node-driver-registrar:v1.1.0

なおこの辺から teeコマンドで記述していくには少し長くなってきてますので
管理端末でコピー&ペーストしてmasterへscpで送ったりするのがいいかなと。
私のようにただテストするだけであればubuntuにdesktopを追加し、
Docsから直接viエディタでペーストしてしまうのも早いです。

 

・kubectl create -f csi-driver-deploy.yaml

導入後の状況は以下となります。

f:id:pocmemo:20200113200300p:plain

 

f:id:pocmemo:20200113200313p:plain



導入コンポーネントの動作確認

さて、Kubernetes側の設定はこれですべて完了しましたが、
この設定が完了した瞬間にGUIに何か通知が到着するわけではありません。

実際にVolumeの作成が正しく出来るかどうかの確認が必要となります。
残るは"KubernetesからのVolume要求に、vSphere側が応えられるか否か"
確認したいと思います。

 

なお実際に払い出しが実行されるまでの内容は以下となります。

1. 事前にvSANの仮想マシンストレージポリシーを作成する

2. StorageClassを設定し、Dynamic Volume Provisioningの実行準備をする

3. Volumeの要請に応じてvSphere環境側がVolumeを準備する
※ 今回のテストではStatefulset作成と同時にVolumeの払い出しが行われます。

4. 手順1番で作成したポリシーに則ってVolumeの作成がされる

 

vSANのポリシー作成についてはご存知の手順でOKです。
今回は"k8s-policy" として作成しており、内容はvSAN default policyと同一としてます。
また、Kubernetesを導入したUbuntu OSに割り当てられているポリシーとは
別のポリシーを割り当てても問題ありません。

 

f:id:pocmemo:20200113204929p:plain

 

実際にStorageClassを作成する際、Policy名を指定する必要があります。
このPolicy名は先ほどvSphere Client画面で作成したpolicy名と
同一にする必要があります。

f:id:pocmemo:20200113205112p:plain

 

Storage Class作成後、以下のようなテスト用statefulset・PVCを作成してます。

f:id:pocmemo:20200113213139p:plain

 

なお余談ですが私は手順の一番最初で、仮想マシンに対してdisk.EnableUUIDを
設定しないまま進めてしまい、PodがPendingのままSTOPしてしまいました。
対処:Worker Nodeを kubectl drain コマンドで安全に停止し、
停止した状態でVM上にパラメータを追加。
Worker起動後にkubectl uncordonでClusterに再参加させました。

なおその際の画像をたまたま収めてありました。
statefulsetはREADY:0/3だったんですが一つ目のVolumeは作成完了してましたね。
状況としては以下のような状態だったのだろうと推察しております。
"1個目Volumeを作成(その時点でVolumeはvSphereへ反映)するも
その後1個目のStatefulsetが当該Volumeをマウント出来ず再試行を繰り返す"

 

 参考:一つだけVolumeができている(正しいのは3つ作成されている状態)

f:id:pocmemo:20200113222432p:plain



 

実際にKubernetesから払い出し要請を受けた瞬間、vSphere Client側で
以下のような履歴が残ります。

vSphere Client GUIで"コンテナボリュームの接続"と表示がされるのは
感慨深いというか何というか、新たな時代を感じる事が出来ていいものですね。

f:id:pocmemo:20200113205727p:plain

 


実際のVolume認識状況はどうか確認すると、k8s上 / vSphere上双方で
問題なくVolumeの表記が確認されました。

f:id:pocmemo:20200113213549p:plain

 

 以下より、vsanDatastoreで正常にVolumeが作成されている事も確認ができました。

 

f:id:pocmemo:20200113213623p:plain

 

ProviderIDが正常に取れている事は先程確認しておりましたが、
Volumeの作成やvSphere Clientへの認識が問題ない事から、
CSIについてもひとまず導入については成功していると見てよさそうです。

 

 

 今回はvSphere Clientへ各種設定・Driver設定が完了したところまで確認致しました。

Kubernetes環境とvSphere環境への更なる連携はまた次回。