Kubernetes Cluster API Provider Bring Your Own Host (BYOH)は、インストール済みのLinuxノードに対してClustere APIを利用してKubernetesクラスターを構成することが可能です。ベアメタル環境のLinuxマシン等、Infrastructure Providerが存在しない環境でCluster APIを利用してKubernetesを構成することができます。現在の最新バージョンはv0.2.0です。Getting Startedドキュメントに従ってkindでinfrastructure byohをホストして、LinxマシンでKubernetesクラスターを作成してみました。
Management Clusterの作成
Cluster APIをホストするManagement Clusterを作成します。kindで作ります。外部にKubernetes APIを公開するため、以下のようなkind.configファイルを作成してkindでKubernetesクラスターを作成します。
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
apiServerAddress: "192.168.200.107"
apiServerPort: 6443
kind.configファイルを指定してクラスターを作成します。
kind create cluster --config=kind.config
clusterctl
CLIをダウンロードしてインストールします。
wget https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.1.3/clusterctl-linux-amd64
sudo install clusterctl-linux-amd64 /usr/local/bin/clusterctl
clusterctl
CLIでManagement ClusterにCluster APIとinfrastructure-byohをインストールします。
$ clusterctl init --infrastructure byoh
Fetching providers
Installing cert-manager Version="v1.5.3"
Waiting for cert-manager to be available...
Installing Provider="cluster-api" Version="v1.1.3" TargetNamespace="capi-system"
Installing Provider="bootstrap-kubeadm" Version="v1.1.3" TargetNamespace="capi-kubeadm-bootstrap-system"
Installing Provider="control-plane-kubeadm" Version="v1.1.3" TargetNamespace="capi-kubeadm-control-plane-system"
Installing Provider="infrastructure-byoh" Version="v0.1.1" TargetNamespace="byoh-system"
Your management cluster has been initialized successfully!
You can now create your first workload cluster by running the following:
clusterctl generate cluster [name] --kubernetes-version [version] | kubectl apply -f -
Cluster APIとBYOH Infrastructure ProviderのCRDが追加されます。
$ kubectl get crd | grep cluster.x-k8s.io
byoclusters.infrastructure.cluster.x-k8s.io 2022-05-07T06:44:00Z
byohosts.infrastructure.cluster.x-k8s.io 2022-05-07T06:44:00Z
byomachines.infrastructure.cluster.x-k8s.io 2022-05-07T06:44:00Z
byomachinetemplates.infrastructure.cluster.x-k8s.io 2022-05-07T06:44:00Z
clusterclasses.cluster.x-k8s.io 2022-05-07T06:43:57Z
clusterresourcesetbindings.addons.cluster.x-k8s.io 2022-05-07T06:43:57Z
clusterresourcesets.addons.cluster.x-k8s.io 2022-05-07T06:43:57Z
clusters.cluster.x-k8s.io 2022-05-07T06:43:58Z
kubeadmconfigs.bootstrap.cluster.x-k8s.io 2022-05-07T06:43:58Z
kubeadmconfigtemplates.bootstrap.cluster.x-k8s.io 2022-05-07T06:43:58Z
kubeadmcontrolplanes.controlplane.cluster.x-k8s.io 2022-05-07T06:43:59Z
kubeadmcontrolplanetemplates.controlplane.cluster.x-k8s.io 2022-05-07T06:43:59Z
machinedeployments.cluster.x-k8s.io 2022-05-07T06:43:58Z
machinehealthchecks.cluster.x-k8s.io 2022-05-07T06:43:58Z
machinepools.cluster.x-k8s.io 2022-05-07T06:43:58Z
machines.cluster.x-k8s.io 2022-05-07T06:43:58Z
machinesets.cluster.x-k8s.io 2022-05-07T06:43:58Z
providers.clusterctl.cluster.x-k8s.io 2022-05-07T06:43:31Z
cert-managerが追加され、capi-controllerとbyoh-controller等がpodとして起動します。
$ kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
byoh-system byoh-controller-manager-5886bfb5df-v2rmw 2/2 Running 0 2d15h
capi-kubeadm-bootstrap-system capi-kubeadm-bootstrap-controller-manager-7694977987-9lr2d 1/1 Running 0 2d15h
capi-kubeadm-control-plane-system capi-kubeadm-control-plane-controller-manager-5c887bc7f9-6wh5t 1/1 Running 0 2d15h
capi-system capi-controller-manager-756b9b6576-xxmc8 1/1 Running 0 2d15h
cert-manager cert-manager-6888d6b69b-btbdj 1/1 Running 0 2d15h
cert-manager cert-manager-cainjector-76f7798c9-fw6n6 1/1 Running 0 2d15h
cert-manager cert-manager-webhook-7d4b5d8484-n5jsf 1/1 Running 0 2d15h
kube-system coredns-64897985d-jqc7q 1/1 Running 0 2d15h
kube-system coredns-64897985d-mg82d 1/1 Running 0 2d15h
kube-system etcd-kind-control-plane 1/1 Running 0 2d15h
kube-system kindnet-fr79p 1/1 Running 0 2d15h
kube-system kube-apiserver-kind-control-plane 1/1 Running 0 2d15h
kube-system kube-controller-manager-kind-control-plane 1/1 Running 0 2d15h
kube-system kube-proxy-rb5xr 1/1 Running 0 2d15h
kube-system kube-scheduler-kind-control-plane 1/1 Running 0 2d15h
local-path-storage local-path-provisioner-5ddd94ff66-286hb 1/1 Running 0 2d15h
byoshostで利用するため、Management Clusterに対するアクセス情報をファイルに出力しておきます。
kind get kubeconfig > management-cluster.conf
byohostの作成
KubernetesクラスターのノードとなるLinuxマシンを用意します。現在Cluster API Providere BYOHが対応しているのはUbuntu 20.04以上となっているため今回はUbuntu 20.04の仮想マシン(2vCPU/8GB RAM)を6台用意しました。
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.4 LTS
Release: 20.04
Codename: focal
byohostsリソースを確認すると、マシンは存在しません。
$ kubectl get byohosts.infrastructure.cluster.x-k8s.io
No resources found in default namespace.
リリースページからbyoh-hostagent-linux-amd64をダウンロードして各マシンに配布します。
wget https://github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/releases/download/v0.2.0/byoh-hostagent-linux-amd64
Management Clusterに対するアクセス情報(management-cluster.conf)もあわせて配布し、各マシンでbyoh-hostagentを起動します。
for i in byoh-master1 byoh-master2 byoh-master3 byoh-node1 byoh-node2 byoh-node3
do
scp management-cluster.conf root@$i:management-cluster.conf
scp byoh-hostagent-linux-amd64 root@$i:byoh-hostagent-linux-amd64
ssh root@$i chmod +x byoh-hostagent-linux-amd64
ssh root@$i './byoh-hostagent-linux-amd64 --kubeconfig management-cluster.conf > byoh-agent.log 2>&1 &'
ssh root@$i ps ax | grep byoh
done
各マシンでbyoh-hostagentが起動して、Management Clusterに登録されたのでbyohostsリソースとして確認できます。
$ kubectl get byohosts.infrastructure.cluster.x-k8s.io
NAME AGE
byoh-master1 9s
byoh-master2 8s
byoh-master3 7s
byoh-node1 6s
byoh-node2 5s
byoh-node3 4s
Kubernetesクラスターの作成
クラスターを作成するためのマニフェストを作成します。CONTROL_PLANE_ENDPOINT_IP
はkube-vipによりKubernetes APIのVIPとなります。--control-plane-machine-count
と--worker-machine-count
でMasterとNodeの台数を指定します。
BUNDLE_LOOKUP_TAG=v1.23.5 CONTROL_PLANE_ENDPOINT_IP=192.168.200.110 clusterctl generate cluster byoh-cluster \
--infrastructure byoh \
--kubernetes-version v1.23.5 \
--control-plane-machine-count 3 \
--worker-machine-count 3 > cluster.yaml
cluster.yamlは以下のような内容で作成されます。
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
metadata:
name: byoh-cluster-md-0
namespace: default
spec:
template:
spec: {}
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
labels:
cni: byoh-cluster-crs-0
crs: "true"
name: byoh-cluster
namespace: default
spec:
clusterNetwork:
pods:
cidrBlocks:
- 192.168.0.0/16
serviceDomain: cluster.local
services:
cidrBlocks:
- 10.128.0.0/12
controlPlaneRef:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
name: byoh-cluster-control-plane
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoCluster
name: byoh-cluster
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
name: byoh-cluster-md-0
namespace: default
spec:
clusterName: byoh-cluster
replicas: 3
selector:
matchLabels: null
template:
metadata:
labels:
nodepool: pool1
spec:
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
name: byoh-cluster-md-0
clusterName: byoh-cluster
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
name: byoh-cluster-md-0
version: v1.23.5
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
labels:
nodepool: pool0
name: byoh-cluster-control-plane
namespace: default
spec:
kubeadmConfigSpec:
clusterConfiguration:
apiServer:
certSANs:
- localhost
- 127.0.0.1
- 0.0.0.0
- host.docker.internal
controllerManager:
extraArgs:
enable-hostpath-provisioner: "true"
files:
- content: |
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
name: kube-vip
namespace: kube-system
spec:
containers:
- args:
- start
env:
- name: vip_arp
value: "true"
- name: vip_leaderelection
value: "true"
- name: vip_address
value: 192.168.200.110
- name: vip_interface
value: {{ .DefaultNetworkInterfaceName }}
- name: vip_leaseduration
value: "15"
- name: vip_renewdeadline
value: "10"
- name: vip_retryperiod
value: "2"
image: ghcr.io/kube-vip/kube-vip:v0.3.5
imagePullPolicy: IfNotPresent
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- SYS_TIME
volumeMounts:
- mountPath: /etc/kubernetes/admin.conf
name: kubeconfig
hostNetwork: true
volumes:
- hostPath:
path: /etc/kubernetes/admin.conf
type: FileOrCreate
name: kubeconfig
status: {}
owner: root:root
path: /etc/kubernetes/manifests/kube-vip.yaml
initConfiguration:
nodeRegistration:
criSocket: /var/run/containerd/containerd.sock
ignorePreflightErrors:
- Swap
- DirAvailable--etc-kubernetes-manifests
- FileAvailable--etc-kubernetes-kubelet.conf
joinConfiguration:
nodeRegistration:
criSocket: /var/run/containerd/containerd.sock
ignorePreflightErrors:
- Swap
- DirAvailable--etc-kubernetes-manifests
- FileAvailable--etc-kubernetes-kubelet.conf
machineTemplate:
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
name: byoh-cluster-control-plane
namespace: default
replicas: 3
version: v1.23.5
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoCluster
metadata:
name: byoh-cluster
namespace: default
spec:
bundleLookupBaseRegistry: projects.registry.vmware.com/cluster_api_provider_bringyourownhost
bundleLookupTag: v1.23.5
controlPlaneEndpoint:
host: 192.168.200.110
port: 6443
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
metadata:
name: byoh-cluster-md-0
namespace: default
spec:
template:
spec: {}
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
metadata:
name: byoh-cluster-control-plane
namespace: default
spec:
template:
spec: {}
このままクラスターを作成すると、6台のマシンがMasterとNodeに適当に割り当てらるので、マシンにラベルをつけてMaster用とNode用のマシンを区別します。cluster.yamlのControlPlaneとWorkerのByoMachineTempalteを以下のように修正します。 (参考 Ability to select a specific host/set of hosts for control plane / worker nodes #276)
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
metadata:
name: byoh-cluster-md-0
namespace: default
spec:
template:
spec:
selector:
matchLabels:
"type": "worker"
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
metadata:
name: byoh-cluster-control-plane
namespace: default
spec:
template:
spec:
selector:
matchLabels:
"type": "controlplane"
byohostsにMaster用とNode用のラベルをつけます。
kubectl label byohosts.infrastructure.cluster.x-k8s.io byoh-master1 type=controlplane
kubectl label byohosts.infrastructure.cluster.x-k8s.io byoh-master2 type=controlplane
kubectl label byohosts.infrastructure.cluster.x-k8s.io byoh-master3 type=controlplane
kubectl label byohosts.infrastructure.cluster.x-k8s.io byoh-node1 type=worker
kubectl label byohosts.infrastructure.cluster.x-k8s.io byoh-node2 type=worker
kubectl label byohosts.infrastructure.cluster.x-k8s.io byoh-node3 type=worker
ラベルが付いたことを確認します。
$ kubectl get byohosts.infrastructure.cluster.x-k8s.io -L type
NAME AGE TYPE
byoh-master1 7m2s controlplane
byoh-master2 7m1s controlplane
byoh-master3 7m controlplane
byoh-node1 6m59s worker
byoh-node2 6m58s worker
byoh-node3 6m57s worker
クラスター作成用のマニフェスト(cluster.yaml)を利用してクラスターを作成します。
$ kubectl apply -f cluster.yaml
kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/byoh-cluster-md-0 created
cluster.cluster.x-k8s.io/byoh-cluster created
machinedeployment.cluster.x-k8s.io/byoh-cluster-md-0 created
kubeadmcontrolplane.controlplane.cluster.x-k8s.io/byoh-cluster-control-plane created
byocluster.infrastructure.cluster.x-k8s.io/byoh-cluster created
byomachinetemplate.infrastructure.cluster.x-k8s.io/byoh-cluster-md-0 created
byomachinetemplate.infrastructure.cluster.x-k8s.io/byoh-cluster-control-plane created
しばらくすると、byohostsがMachineリソースとして登録され、Cluster APIによりクラスターが構成されます。
$ kubectl get cluster
NAME PHASE AGE VERSION
byoh-cluster Provisioned 4m56s
$ kubectl get byoclusters.infrastructure.cluster.x-k8s.io
NAME AGE
byoh-cluster 4m59s
$ kubectl get kubeadmcontrolplane
NAME CLUSTER INITIALIZED API SERVER AVAILABLE REPLICAS READY UPDATED UNAVAILABLE AGE VERSION
byoh-cluster-control-plane byoh-cluster true 3 3 3 5m5s v1.23.5
$ kubectl get machinesets.cluster.x-k8s.io
NAME CLUSTER REPLICAS READY AVAILABLE AGE VERSION
byoh-cluster-md-0-866c95bdcd byoh-cluster 3 5m13s v1.23.5
$ kubectl get machine
NAME CLUSTER NODENAME PROVIDERID PHASE AGE VERSION
byoh-cluster-control-plane-d9nm6 byoh-cluster byoh-master1 byoh://byoh-master1/i4szip Running 5m16s v1.23.5
byoh-cluster-control-plane-gbhld byoh-cluster byoh-master3 byoh://byoh-master3/6deh0f Running 113s v1.23.5
byoh-cluster-control-plane-qg6vf byoh-cluster byoh-master2 byoh://byoh-master2/0gbuc5 Running 3m51s v1.23.5
byoh-cluster-md-0-866c95bdcd-p7b7v byoh-cluster byoh-node3 byoh://byoh-node3/oymt6s Running 5m18s v1.23.5
byoh-cluster-md-0-866c95bdcd-sqcbz byoh-cluster byoh-node2 byoh://byoh-node2/cdyrn6 Running 5m18s v1.23.5
byoh-cluster-md-0-866c95bdcd-wf4jg byoh-cluster byoh-node1 byoh://byoh-node1/4qth8r Running 5m18s v1.23.5
作成したクラスターにアクセスするためのkubeconfigをsecretから取得します。
kubectl get secret/byoh-cluster-kubeconfig -o json | jq -r .data.value | base64 --decode > ./byoh-cluster.kubeconfig
作成したkubeconfigを指定してAPIにアクセスすると、6台のマシンでクラスターが構成されています。CNIが構成されないためNotReady
状態となっています。
$ kubectl --kubeconfig=byoh-cluster.kubeconfig get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
byoh-master1 NotReady control-plane,master 6m3s v1.23.5 192.168.200.41 <none> Ubuntu 20.04.4 LTS 5.4.0-109-generic containerd://1.6.0
byoh-master2 NotReady control-plane,master 4m40s v1.23.5 192.168.200.85 <none> Ubuntu 20.04.4 LTS 5.4.0-109-generic containerd://1.6.0
byoh-master3 NotReady control-plane,master 2m45s v1.23.5 192.168.200.43 <none> Ubuntu 20.04.4 LTS 5.4.0-109-generic containerd://1.6.0
byoh-node1 NotReady <none> 4m42s v1.23.5 192.168.200.82 <none> Ubuntu 20.04.4 LTS 5.4.0-109-generic containerd://1.6.0
byoh-node2 NotReady <none> 4m57s v1.23.5 192.168.200.83 <none> Ubuntu 20.04.4 LTS 5.4.0-109-generic containerd://1.6.0
byoh-node3 NotReady <none> 4m56s v1.23.5 192.168.200.21 <none> Ubuntu 20.04.4 LTS 5.4.0-109-generic containerd://1.6.0
CNIとしてCalicoをインストールします。
kubectl --kubeconfig=byoh-cluster.kubeconfig apply -f https://docs.projectcalico.org/v3.20/manifests/calico.yaml
暫く待つとReady
になりました。
$ kubectl --kubeconfig=byoh-cluster.kubeconfig get node
NAME STATUS ROLES AGE VERSION
byoh-master1 Ready control-plane,master 11m v1.23.5
byoh-master2 Ready control-plane,master 9m49s v1.23.5
byoh-master3 Ready control-plane,master 7m54s v1.23.5
byoh-node1 Ready <none> 9m51s v1.23.5
byoh-node2 Ready <none> 10m v1.23.5
byoh-node3 Ready <none> 10m v1.23.5