Edited at

Cluster APIをつかってvSphere環境にKubernetesクラスターを作成する

Kubernetes Cluster API Provider vSphereで、vSphere上にKubernetesクラスターを作成します。Getting Stargedを参考にしています。


Cluster API

Cluster APIを使うとKubernetesのAPIを使って宣言的にKubernetesクラスターを作成することができます。クラスターはCRD(Custom Resource Definition)で定義され、マニフェストの編集するだけでKubernetesクラスターに対するノードの追加や削除も行われます。Cluster APIはいくつかのProviderによって、様々なクラウドやオンプレミスの環境にKubernetesクラスターを作成することができます。


準備


必要なもの


  • Linuxホスト : Bootstrapingに必要なKuberntes環境をDockerでホストします。

  • Docker : kindによりDocker上でBootstrap用のKubernetesを起動します。各種マニフェストファイルの作成にも利用します。


  • kind(Kubernetes IN Docker) : Docker上にKubernetesを構築するのに利用します。

  • clusterctl : Cluster APIを利用してManagementクラスターを作成するために利用します。

  • kubectl

  • DHCP : 今回は作成されるKubernetes環境のMaster/NodeはすべてDHCPでIPアドレスを構成しています。


クラスター作成の概要

vSphere上にKubernetes Workload Clusterを作成することがゴールです。


  1. kindでLinuxホストのDocker上にKubernetesを作成し、kindで作成したLinuxマシン上のKuberntesのCluster APIからvSphere上にManagement用のKubernetes Clusterを作成します。

  2. Management Clusterを利用して、vSphere上にWorkload Kubernetes Clusterを作成します。


clusterctl

clusterctlコマンドをダウンロードします。今回はv0.4.1を利用しています。(バージョン毎にオプションが変わっているので注意が必要です。)

# wget https://github.com/kubernetes-sigs/cluster-api-provider-vsphere/releases/download/v0.4.1/clusterctl.linux_amd64

# chmod +x clusterctl.linux_amd64
# mv clusterctl.linux_amd64 $PWD/bin/clusterctl


kind

kindコマンドをダウンロードします。今回はv0.5.1を利用しています。

# curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.5.1/kind-$(uname)-amd64

# chmod +x ./kind
# mv kind $PWD/bin/kind


envファイルの作成

Kubernetesクラスターを作成するターゲットのvSphereに関するパラメーターや、作成する仮想マシンのパラメータをenvvars.txtで指定します。SSH_AUTHORIZED_KEYは作成されるノードにSSHするための公開鍵を指定します。(以下の例では省略しています。)

# vCenter config/credentials

export VSPHERE_SERVER='10.0.0.1' # (required) The vCenter server IP or FQDN
export VSPHERE_USERNAME='viadmin@vmware.local' # (required) The username used to access the remote vSphere endpoint
export VSPHERE_PASSWORD='some-secure-password' # (required) The password used to access the remote vSphere endpoint

# vSphere deployment configs
export VSPHERE_DATACENTER='Datacenter' # (required) The vSphere datacenter to deploy the management cluster on
export VSPHERE_DATASTORE='vsanDatastore' # (required) The vSphere datastore to deploy the management cluster on
export VSPHERE_NETWORK='vm-network-1' # (required) The VM network to deploy the management cluster on
export VSPHERE_RESOURCE_POOL='Resources' # (required) The vSphere resource pool for your VMs
export VSPHERE_FOLDER='vm' # (optional) The VM folder for your VMs, defaults to the root vSphere folder if not set.
export VSPHERE_TEMPLATE='ubuntu-1804-kube-v1.15.3' # (required) The VM template to use for your management cluster.
export VSPHERE_DISK_GIB='50' # (optional) The VM Disk size in GB, defaults to 20 if not set
export VSPHERE_NUM_CPUS='2' # (optional) The # of CPUs for control plane nodes in your management cluster, defaults to 2 if not set
export VSPHERE_MEM_MIB='2048' # (optional) The memory (in MiB) for control plane nodes in your management cluster, defaults to 2048 if not set
export SSH_AUTHORIZED_KEY='ssh-rsa AAAAB3N...' # (optional) The public ssh authorized key on all machines in this cluster

# Kubernetes configs
export KUBERNETES_VERSION='1.15.3' # (optional) The Kubernetes version to use, defaults to 1.13.6
export SERVICE_CIDR='100.64.0.0/13' # (optional) The service CIDR of the management cluster, defaults to "100.64.0.0/13"
export CLUSTER_CIDR='100.96.0.0/11' # (optional) The cluster CIDR of the management cluster, defaults to "100.96.0.0/11"


テンプレート用OVAファイルのデプロイ

クラスター作成時に利用する仮想マシンテンプレートを作成しておく必要があります。ここからインストールするKuberntesバージョン(今回は1.15.3)のOVAファイルをダウンロードして、vSphere上にデプロイします。OVAはCentOS 7ベースのものと、Ubuntu 18.04ベースのものが提供されています。今回はUbuntu 18.04を利用しました。VM名はenvvars.txtVSPHERE_TEMPLATEに指定した名前にしておきます。また、テンプレートのVMDKのタイプをThickにしておくと作成されるKubernetesクラスターがThickを継承するので必要がなければ、Thinでデプロイすることをお勧めします。


Managemt Clusterの作成


Management Cluster用マニフェストの作成

作成したenvファイルをもとにDockerコンテナを利用してマニフェストファイルを作成します。$PWD/out/management-cluster/配下にマニフェストファイルが作成されます。

# docker run --rm \

-v "$(pwd)":/out \
-v "$(pwd)/envvars.txt":/envvars.txt:ro \
gcr.io/cluster-api-provider-vsphere/release/manifests:v0.4.1 \
-c management-cluster

# ls -l out/management-cluster/
total 132
-rw-r--r-- 1 root root 19828 Sep 4 19:18 addons.yaml
-rw-r--r-- 1 root root 879 Sep 4 19:18 cluster.yaml
-rw-r--r-- 1 root root 1087 Sep 4 19:18 machineset.yaml
-rw-r--r-- 1 root root 774 Sep 4 19:18 machines.yaml
-rw-r--r-- 1 root root 101245 Sep 4 19:18 provider-components.yaml


clusterctlによるMnagement Clusterの作成

clusterctlコマンドを使って作成したマニフェストファイルから、Management Clusterを作成します。

# clusterctl create cluster \

--provider vsphere \
--bootstrap-type kind \
--cluster ./out/management-cluster/cluster.yaml \
--machines ./out/management-cluster/machines.yaml \
--provider-components ./out/management-cluster/provider-components.yaml \
--addon-components ./out/management-cluster/addons.yaml \
--kubeconfig-out ./out/management-cluster/kubeconfig
I0904 19:47:47.988375 23481 createbootstrapcluster.go:27] Preparing bootstrap cluster
I0904 19:48:28.796179 23481 clusterdeployer.go:78] Applying Cluster API stack to bootstrap cluster
I0904 19:48:28.796201 23481 applyclusterapicomponents.go:26] Applying Cluster API Provider Components
I0904 19:48:29.491992 23481 clusterdeployer.go:83] Provisioning target cluster via bootstrap cluster
I0904 19:48:29.497501 23481 applycluster.go:36] Creating cluster object management-cluster in namespace "default"
I0904 19:48:29.505449 23481 clusterdeployer.go:92] Creating control plane machine in namespace "default"
I0904 19:48:29.510339 23481 applymachines.go:36] Creating machines in namespace "default"
I0904 19:51:39.585337 23481 clusterdeployer.go:97] Updating bootstrap cluster object for cluster management-cluster in namespace "default" with control plane endpoint running on machine
I0904 19:51:39.676422 23481 clusterdeployer.go:102] Creating target cluster
I0904 19:51:39.954416 23481 applyaddons.go:25] Applying Addons
I0904 19:51:41.198014 23481 clusterdeployer.go:120] Pivoting Cluster API stack to target cluster
I0904 19:51:41.198058 23481 pivot.go:67] Applying Cluster API Provider Components to Target Cluster
I0904 19:51:42.138461 23481 pivot.go:72] Pivoting Cluster API objects from bootstrap to target cluster.
I0904 19:51:56.363443 23481 clusterdeployer.go:125] Saving provider components to the target cluster
I0904 19:51:56.386356 23481 clusterdeployer.go:133] Updating target cluster object with control plane endpoint running on machine
I0904 19:51:56.416666 23481 clusterdeployer.go:149] Creating node machines in target cluster.
I0904 19:51:56.422778 23481 applymachines.go:36] Creating machines in namespace "default"
I0904 19:51:56.422794 23481 clusterdeployer.go:154] Done provisioning cluster. You can now access your cluster with kubectl --kubeconfig ./out/management-cluster/kubeconfig
I0904 19:51:56.422904 23481 createbootstrapcluster.go:36] Cleaning up bootstrap cluster.

最初にkindがDockerイメージをダウンロードして、Docker上にKubernetesを作成します。しばらくすると、vSphere上にmanagement-cluster-controlplane-1という名前のVMが作成されます。ブートストラップ中は、kindがブートストラップ用のKubernetesを起動しているのが確認できますが、ブートストラップが終了するとDockerコンテナは自動的に削除されます。

# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5de63a2bc705 kindest/node:v1.15.3 "/usr/local/bin/entr…" About a minute ago Up About a minute 40323/tcp, 127.0.0.1:40323->6443/tcp clusterapi-control-plane

kubectlの接続先をManagement Clusterに変更し、Management Clusterが正常なことを確認します。

# export KUBECONFIG=$PWD/out/management-cluster/kubeconfig

# kubectl get nodes
NAME STATUS ROLES AGE VERSION
management-cluster-controlplane-1 Ready master 6m50s v1.15.3

CRDを確認すると、ClusterAPIに関連するものが存在することが確認できます。

# kubectl get crd | grep cluster

clusterinformations.crd.projectcalico.org 2019-09-04T10:51:40Z
clusters.cluster.k8s.io 2019-09-04T10:51:41Z
machineclasses.cluster.k8s.io 2019-09-04T10:51:41Z
machinedeployments.cluster.k8s.io 2019-09-04T10:51:41Z
machines.cluster.k8s.io 2019-09-04T10:51:42Z
machinesets.cluster.k8s.io 2019-09-04T10:51:42Z
vsphereclusterproviderspecs.vsphere.cluster.k8s.io 2019-09-04T10:51:41Z
vsphereclusterproviderstatuses.vsphere.cluster.k8s.io 2019-09-04T10:51:41Z
vspheremachineproviderspecs.vsphere.cluster.k8s.io 2019-09-04T10:51:41Z
vspheremachineproviderstatuses.vsphere.cluster.k8s.io 2019-09-04T10:51:41Z

Management Clsuterにはcluster-api-systemとvsphere-provider-systemネームスペースが追加されています。

# kubectl get namespace

NAME STATUS AGE
cluster-api-system Active 7m12s
default Active 7m24s
kube-node-lease Active 7m28s
kube-public Active 7m28s
kube-system Active 7m28s
vsphere-provider-system Active 7m12s

cluster-api-systemにはStatefulSetが作成され、cluster-api-controller-manager Podが作成されています。

# kubectl get statefulset,pod -n cluster-api-system

NAME READY AGE
statefulset.apps/cluster-api-controller-manager 1/1 7m30s

NAME READY STATUS RESTARTS AGE
pod/cluster-api-controller-manager-0 1/1 Running 0 7m25s

vsphere-provider-systemにもStatefulSetが作成され、vsphere-provider-controller-managerが作成されています。

# kubectl get statefulset,pod -n vsphere-provider-system

NAME READY AGE
statefulset.apps/vsphere-provider-controller-manager 1/1 7m50s

NAME READY STATUS RESTARTS AGE
pod/vsphere-provider-controller-manager-0 1/1 Running 0 7m44s


Workload Clusterの作成


Workload Cluster用マニフェストの作成

# docker run --rm ¥

-v "$(pwd)":/out ¥
-v "$(pwd)/envvars.txt":/envvars.txt:ro ¥
gcr.io/cluster-api-provider-vsphere/release/manifests:v0.4.1 ¥
-c workload-cluster-1
# ls -l /root/out/workload-cluster-1/
total 132
-rw-r--r-- 1 root root 19828 Sep 4 20:00 addons.yaml
-rw-r--r-- 1 root root 879 Sep 4 20:00 cluster.yaml
-rw-r--r-- 1 root root 1087 Sep 4 20:00 machineset.yaml
-rw-r--r-- 1 root root 774 Sep 4 20:00 machines.yaml
-rw-r--r-- 1 root root 101245 Sep 4 20:00 provider-components.yaml


Workload Cluster用マニフェストの適用

Management Clusterに対してマニフェストを適用して、Workload Clusterを作成します。

kubectl apply -f ./out/workload-cluster-1/cluster.yaml

kubectl apply -f ./out/workload-cluster-1/machines.yaml
kubectl apply -f ./out/workload-cluster-1/machineset.yaml

しばらくすると、vSphere上にworkload-cluster-1-controlplane-1が作成され、WorkloadクラスターのMasterとして構成され、それを追ってworkload-cluster-1-machineset-1-xxxxが2台作成されます。

# kubectl get cluster

NAME AGE
management-cluster 11m
workload-cluster-1 2m10s
# kubectl get machineset
NAME AGE
workload-cluster-1-machineset-1 2m20s
# kubectl get machines
NAME PROVIDERID PHASE
management-cluster-controlplane-1 vsphere://422ae07d-1d4c-f94d-569d-fcd8a99c6e84
workload-cluster-1-controlplane-1 vsphere://422a4622-6591-7807-2f31-1f009f008951
workload-cluster-1-machineset-1-8kh2q
workload-cluster-1-machineset-1-sbv7x

しばらくすると、Machinesリソースが以下のようにすべてPROVIDEDに値が入ります。

# kubectl get machines

NAME PROVIDERID PHASE
management-cluster-controlplane-1 vsphere://422ae07d-1d4c-f94d-569d-fcd8a99c6e84
workload-cluster-1-controlplane-1 vsphere://422a4622-6591-7807-2f31-1f009f008951
workload-cluster-1-machineset-1-8kh2q vsphere://422a6d58-1871-1e54-35e7-47baf346c149
workload-cluster-1-machineset-1-sbv7x vsphere://422a8747-6a1e-96b4-596c-8592edf6cc9f


Workload Cluster用設定ファイルの取得

Workloadクラスターに接続するための設定ファイルはManagemetクラスターのSecretとして格納されているので取り出して利用します。

# kubectl get secret

NAME TYPE DATA AGE
default-token-xprdb kubernetes.io/service-account-token 3 15m
management-cluster-kubeconfig Opaque 1 15m
workload-cluster-1-kubeconfig Opaque 1 4m21s
# kubectl get secret workload-cluster-1-kubeconfig -o jsonpath='{.data.value}' | base64 -d > ~/.kube/config

接続先をWorkloadクラスターに変更して状態を確認すると、すべてNotReadyとなっています。これはCNIが構成されていないためです。マニフェストファイルのaddons.yamlを利用するとCNIとしてCalicoを構成することができます。

# export KUBECONFIG=$HOME/.kube/config

# kubectl get nodes
NAME STATUS ROLES AGE VERSION
workload-cluster-1-controlplane-1 NotReady master 5m26s v1.15.3
workload-cluster-1-machineset-1-8kh2q NotReady node 3m48s v1.15.3
workload-cluster-1-machineset-1-sbv7x NotReady node 3m47s v1.15.3

# kubectl apply -f out/workload-cluster-1/addons.yaml

# kubectl get nodes
NAME STATUS ROLES AGE VERSION
workload-cluster-1-controlplane-1 Ready master 6m33s v1.15.3
workload-cluster-1-machineset-1-8kh2q Ready node 4m55s v1.15.3
workload-cluster-1-machineset-1-sbv7x Ready node 4m54s v1.15.3


Workload Clusterに対するノード追加

Workloadクラスターのノード数は、Machinesetによって定義されているため、Management ClusterのMachinsetのspec.replicasを変更することで簡単にノードを追加・削除することが可能です。

# export KUBECONFIG=/root/out/management-cluster/kubeconfig

# kubectl edit machineset workload-cluster-1-machineset-1

MachineSetマニフェストのレプリカ数を2から6に変更します。

apiVersion: cluster.k8s.io/v1alpha1

kind: MachineSet
metadata:
...
spec:
replicas: 6

しばらくするとvSphere上で仮想マシンが4台追加され、Management Cluster上のMachinesリソースが4つ増えていることを確認できます。

# kubectl get machines

NAME PROVIDERID PHASE
management-cluster-controlplane-1 vsphere://422ae07d-1d4c-f94d-569d-fcd8a99c6e84
workload-cluster-1-controlplane-1 vsphere://422a4622-6591-7807-2f31-1f009f008951
workload-cluster-1-machineset-1-5br4h vsphere://422a4ad5-763c-02a6-8278-1092a357b649
workload-cluster-1-machineset-1-8kh2q vsphere://422a6d58-1871-1e54-35e7-47baf346c149
workload-cluster-1-machineset-1-cwxrx vsphere://422ac22f-f47c-f411-8825-8a4cac60076c
workload-cluster-1-machineset-1-mjqck vsphere://422a1446-9374-bda1-6826-3f844d2879da
workload-cluster-1-machineset-1-pgb7l vsphere://422ae547-dafc-7177-a3ec-ef6d152005f0
workload-cluster-1-machineset-1-sbv7x vsphere://422a8747-6a1e-96b4-596c-8592edf6cc9f

Workloadクラスターに接続してノードを確認すると指定した6台にノード数が増えていることが確認できました。

# export KUBECONFIG=$HOME/.kube/config

# kubectl get nodes
NAME STATUS ROLES AGE VERSION
workload-cluster-1-controlplane-1 Ready master 15m v1.15.3
workload-cluster-1-machineset-1-5br4h Ready node 43s v1.15.3
workload-cluster-1-machineset-1-8kh2q Ready node 13m v1.15.3
workload-cluster-1-machineset-1-cwxrx Ready node 45s v1.15.3
workload-cluster-1-machineset-1-mjqck Ready node 45s v1.15.3
workload-cluster-1-machineset-1-pgb7l Ready node 44s v1.15.3
workload-cluster-1-machineset-1-sbv7x Ready node 13m v1.15.3


まとめ

Cluster APIを利用することでvSphere環境にとても簡単にKubernetesクラスターを作成することができました。また、マニフェストを更新することでクラスターのスケールアウト/インが簡単に行うことが可能です。