はじめに
本記事では、Management Clusterの構築で構築したManagementClusterを使ってWorkload Clusterを構築します。構築の前提となる環境はClusterAPIによるKubernetesクラスタの操作を参照してください。
本記事では下図のようにControl planeノード3台(master1~3)、Workerノード2台(worker1~2)のworkload-clusterを構築します。
Management Clusterの再構築
本連載ではManagement Clusterをkindのデフォルト構成で構築していますが、kindで構築したkubernetesクラスタはDockerコンテナ上にあり、ローカルホストアドレスをbindしているため、Workload Clusterを構築する他のVMからManagement Clusterにアクセスできません。ClusterAPIのBYOHプロバイダを使用する場合Workload Clusterを構成するVMにBYOHエージェントをインストールし、エージェントがManagement Clusterにアクセスするようにしなければならないため再構築が必要です。
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
da5882fa79d9 kindest/node:v1.25.3 "/usr/local/bin/entr…" 4 minutes ago Up 4 minutes 127.0.0.1:35311->6443/tcp management-cluster-control-plane
まずManegement Clusterを削除し、外部公開できるようにするため現在のクラスタを削除します。
$ sudo kind delete cluster --name=management-cluster
Deleting cluster "management-cluster" ...
その後、apiServerを外部公開するための設定ファイルを作成して再作成します。
$ vi kind.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
apiServerAddress: "10.100.2.38"
apiServerPort: 6443
$ sudo kind create cluster --name=management-cluster --config=kind.yaml
Creating cluster "management-cluster" ...
✓ Ensuring node image (kindest/node:v1.25.3) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-management-cluster"
You can now use your cluster with:
kubectl cluster-info --context kind-management-cluster
Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7d15e2787a63 kindest/node:v1.25.3 "/usr/local/bin/entr…" About a minute ago Up About a minute 10.100.2.38:6443->6443/tcp management-cluster-control-plane
これで外部からアクセスできるようになったので、BYOHをインストールしてManagement Clusterの再作成は完了です。
$ sudo clusterctl init --infrastructure=byoh --kubeconfig=/root/.kube/config
Fetching providers
Installing cert-manager Version="v1.11.0"
Waiting for cert-manager to be available...
Installing Provider="cluster-api" Version="v1.4.1" TargetNamespace="capi-system"
Installing Provider="bootstrap-kubeadm" Version="v1.4.1" TargetNamespace="capi-kubeadm-bootstrap-system"
Installing Provider="control-plane-kubeadm" Version="v1.4.1" TargetNamespace="capi-kubeadm-control-plane-system"
Installing Provider="infrastructure-byoh" Version="v0.3.2" 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 -
Workload Clusterの構築
BYOHエージェントのインストール
まずBYOHエージェントに必要なパッケージをインストールします。
$ sudo apt-get install -y socat ebtables ethtool conntrack
BYOHエージェントを公式ページのリリースからダウンロードし、実行権限を付与するだけでインストールは完了です。Workload Clusterを構成する全てのVMにインストールする必要があります。
$ wget https://github.com/vmware-tanzu/cluster-api-provider-bringyourownhost/releases/download/v0.3.2/byoh-hostagent-linux-amd64
$ chmod +x byoh-hostagent-linux-amd64
$ ls -l
total 37324
-rwxrwxr-x 1 kikutak kikutak 38215680 Apr 6 18:33 byoh-hostagent-linux-amd64
Management Clusterのkubeconfigの配布
BYOHエージェントがManagement Clusterにアクセスできるように、Workload Clusterを構成する全てのVMにManagement Clusterのkubeconfigを配布します。kubeconfigはManagement Cluster用VMの/root/.kube/config
で以下のような内容です。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <snip>
server: https://10.100.2.38:6443
name: kind-management-cluster
contexts:
- context:
cluster: kind-management-cluster
user: kind-management-cluster
name: kind-management-cluster
current-context: kind-management-cluster
kind: Config
preferences: {}
users:
- name: kind-management-cluster
user:
client-certificate-data: <snip>
client-key-data: <snip>
本記事では上記ファイルをWorkload Cluster用VMのBYOHエージェントと同じディレクトリに格納しました。
BYOHエージェントの起動
Workload Cluster用VMでBYOHエージェントを起動します。c-planeとworkerで使用するサーバを分けたいので、エージェント起動時に--label
パラメータを使ってラベルを付与しています。
$ sudo -E ./byoh-hostagent-linux-amd64 --bootstrap-kubeconfig config --label type=master > byoh-agent.log 2>&1 &
[1] 10750
$ ps ax | grep byoh
10732 pts/0 S 0:00 sudo -E ./byoh-hostagent-linux-amd64 --bootstrap-kubeconfig bootstrap-kubeconfig.conf --label type=master
10733 pts/0 Sl 0:00 ./byoh-hostagent-linux-amd64 --bootstrap-kubeconfig bootstrap-kubeconfig.conf --label type=master
10758 pts/0 S+ 0:00 grep --color=auto byoh
$ sudo -E ./byoh-hostagent-linux-amd64 --bootstrap-kubeconfig config --label type=worker > byoh-agent.log 2>&1 &
[1] 10224
$ ps ax | grep byoh
10206 pts/1 S 0:00 sudo -E ./byoh-hostagent-linux-amd64 --bootstrap-kubeconfig bootstrap-kubeconfig.conf --label type=worker
10207 pts/1 Sl 0:00 ./byoh-hostagent-linux-amd64 --bootstrap-kubeconfig bootstrap-kubeconfig.conf --label type=worker
10232 pts/1 S+ 0:00 grep --color=auto byoh
Management Clusterでbyohosts.infrastructure.cluster.x-k8s.io
リソースを確認するとWorkload Cluster用VMが登録されmaster, worker用それぞれにラベル付与されていることが分かります。
$ kubectl get byohost -L type
NAME OSNAME OSIMAGE ARCH TYPE
kikuta-k8s-master1 linux Ubuntu 20.04.6 LTS amd64 master
kikuta-k8s-master2 linux Ubuntu 20.04.6 LTS amd64 master
kikuta-k8s-master3 linux Ubuntu 20.04.6 LTS amd64 master
kikuta-k8s-worker1 linux Ubuntu 20.04.6 LTS amd64 worker
kikuta-k8s-worker2 linux Ubuntu 20.04.6 LTS amd64 worker
Workload Clusterマニフェストの作成
Workload Clusterのマニフェストは以下のコマンドで作成します。BUNDLE_LOOKUP_TAG
でkubernetesのバージョンを指定し、CONTROL_PLANE_ENDPOINT_IP
でWorkload Clusterのcontrol-planeのエンドポイントを指定します。またclusterctlコマンドでcluster名としてworkload-clusterを指定してまいます。
$ sudo -E BUNDLE_LOOKUP_TAG=v1.25.11 CONTROL_PLANE_ENDPOINT_IP=10.100.3.31 \
clusterctl generate cluster workload-cluster \
--kubeconfig config \
--infrastructure byoh\
--kubernetes-version v1.25.11 \
--control-plane-machine-count 3 \
--worker-machine-count 2 > cluster.yaml
c-planeをtype=master
のVMに、workerをtype=worker
のVMにデプロイするため作成したマニフェストのByoMachineTemplateにselectorを追加します。
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
metadata:
name: workload-cluster-md-0
namespace: default
spec:
template:
spec: {}
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
labels:
cni: workload-cluster-crs-0
crs: "true"
name: workload-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: workload-cluster-control-plane
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoCluster
name: workload-cluster
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
name: workload-cluster-md-0
namespace: default
spec:
clusterName: workload-cluster
replicas: 2
selector:
matchLabels: null
template:
metadata:
labels:
nodepool: pool1
spec:
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
name: workload-cluster-md-0
clusterName: workload-cluster
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
name: workload-cluster-md-0
version: v1.25.11
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
labels:
nodepool: pool0
name: workload-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:
- manager
env:
- name: cp_enable
value: "true"
- name: vip_arp
value: "true"
- name: vip_leaderelection
value: "true"
- name: vip_address
value: 10.100.3.31
- 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.5.0
imagePullPolicy: IfNotPresent
name: kube-vip
resources: {}
securityContext:
capabilities:
add:
- NET_ADMIN
- NET_RAW
volumeMounts:
- mountPath: /etc/kubernetes/admin.conf
name: kubeconfig
hostNetwork: true
hostAliases:
- hostnames:
- kubernetes
ip: 127.0.0.1
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: workload-cluster-control-plane
namespace: default
replicas: 3
version: v1.25.11
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoCluster
metadata:
name: workload-cluster
namespace: default
spec:
bundleLookupBaseRegistry: projects.registry.vmware.com/cluster_api_provider_bringyourownhost
controlPlaneEndpoint:
host: 10.100.3.31
port: 6443
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
metadata:
name: workload-cluster-control-plane
namespace: default
spec:
template:
spec:
selector: # 追加
matchLables:
"type": "master"
installerRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: K8sInstallerConfigTemplate
name: workload-cluster-control-plane
namespace: default
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: ByoMachineTemplate
metadata:
name: workload-cluster-md-0
namespace: default
spec:
template:
spec:
selector: # 追加
matchLables:
"type": "worker"
installerRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: K8sInstallerConfigTemplate
name: workload-cluster-md-0
namespace: default
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: K8sInstallerConfigTemplate
metadata:
name: workload-cluster-control-plane
namespace: default
spec:
template:
spec:
bundleRepo: projects.registry.vmware.com/cluster_api_provider_bringyourownhost
bundleType: k8s
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: K8sInstallerConfigTemplate
metadata:
name: workload-cluster-md-0
namespace: default
spec:
template:
spec:
bundleRepo: projects.registry.vmware.com/cluster_api_provider_bringyourownhost
bundleType: k8s
Workload Clusterの作成
Workload Clusterを作成するには先ほど作成したcluster.yamlをManagement ClusterにApplyします。
$ kubectl apply -f cluster.yaml
kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/workload-cluster-md-0 created
cluster.cluster.x-k8s.io/workload-cluster created
machinedeployment.cluster.x-k8s.io/workload-cluster-md-0 created
kubeadmcontrolplane.controlplane.cluster.x-k8s.io/workload-cluster-control-plane created
byocluster.infrastructure.cluster.x-k8s.io/workload-cluster created
byomachinetemplate.infrastructure.cluster.x-k8s.io/workload-cluster-control-plane created
byomachinetemplate.infrastructure.cluster.x-k8s.io/workload-cluster-md-0 created
k8sinstallerconfigtemplate.infrastructure.cluster.x-k8s.io/workload-cluster-control-plane created
k8sinstallerconfigtemplate.infrastructure.cluster.x-k8s.io/workload-cluster-md-0 created
Applyした後、Control-planeノードが1台ずつ、workerノードは並列でデプロイされていきます。以下はControl-planeノードの1台目の構築が終わり、2台目とworkerノードが2台並列でデプロイ中であることを示しています。
$ kubectl get machine -owide
NAME CLUSTER NODENAME PROVIDERID PHASE AGE VERSION
workload-cluster-control-plane-j996c workload-cluster kikuta-k8s-master2 byoh://kikuta-k8s-master2/4kmce9 Running 2m13s v1.25.11
workload-cluster-control-plane-nh4wm workload-cluster Provisioning 34s v1.25.11
workload-cluster-md-0-7dd6cd8845x4ccbd-4tc57 workload-cluster Provisioning 2m45s v1.25.11
workload-cluster-md-0-7dd6cd8845x4ccbd-bvbnn workload-cluster Provisioning 2m45s v1.25.11
最終的に以下のような状態になります。ラベル付けした通り、master1~3にcontrol-planeノード、worker1,2にworkerノードがデプロイされています。
$ kubectl get machine -owide
NAME CLUSTER NODENAME PROVIDERID PHASE AGE VERSION
workload-cluster-control-plane-j996c workload-cluster kikuta-k8s-master2 byoh://kikuta-k8s-master2/4kmce9 Running 5m41s v1.25.11
workload-cluster-control-plane-lm59v workload-cluster kikuta-k8s-master3 byoh://kikuta-k8s-master3/slyfth Running 99s v1.25.11
workload-cluster-control-plane-nh4wm workload-cluster kikuta-k8s-master1 byoh://kikuta-k8s-master1/w64ivn Running 4m2s v1.25.11
workload-cluster-md-0-7dd6cd8845x4ccbd-4tc57 workload-cluster kikuta-k8s-worker1 byoh://kikuta-k8s-worker1/frdboh Running 6m13s v1.25.11
workload-cluster-md-0-7dd6cd8845x4ccbd-bvbnn workload-cluster kikuta-k8s-worker2 byoh://kikuta-k8s-worker2/0vr4rh Running 6m13s v1.25.11
Workload Clusterへのアクセス
Workload Clusterのkubeconfigを取得してkubectlコマンドでアクセスします。
kubeconfig取得にはWorkload Clusterのマニフェスト作成時に指定したクラスタ名が必要ですが、以下のコマンドで調べることもできます。
$ kubectl get cluster
NAME PHASE AGE VERSION
workload-cluster Provisioned 24m
kubeconfigを取得するコマンドは以下の通りです。
$ sudo clusterctl get kubeconfig workload-cluster | tee workload-kubeconfig.yaml
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: <snip>
server: https://10.100.3.31:6443
name: workload-cluster
contexts:
- context:
cluster: workload-cluster
user: workload-cluster-admin
name: workload-cluster-admin@workload-cluster
current-context: workload-cluster-admin@workload-cluster
kind: Config
preferences: {}
users:
- name: workload-cluster-admin
user:
client-certificate-data: <snip>
client-key-data: <snip>
Workload Clusterの状態をpodを確認してみるとcontrol-planeがmaster1~3にデプロイされていることが分かります。
$ kubectl --kubeconfig workload-kubeconfig.yaml get pod -A -owide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-565d847f94-v4snk 0/1 Pending 0 31m <none> <none> <none> <none>
kube-system coredns-565d847f94-wx4ds 0/1 Pending 0 31m <none> <none> <none> <none>
kube-system etcd-kikuta-k8s-master1 1/1 Running 0 30m 10.100.2.33 kikuta-k8s-master1 <none> <none>
kube-system etcd-kikuta-k8s-master2 1/1 Running 0 32m 10.100.2.35 kikuta-k8s-master2 <none> <none>
kube-system etcd-kikuta-k8s-master3 1/1 Running 0 28m 10.100.2.36 kikuta-k8s-master3 <none> <none>
kube-system kube-apiserver-kikuta-k8s-master1 1/1 Running 2 (30m ago) 30m 10.100.2.33 kikuta-k8s-master1 <none> <none>
kube-system kube-apiserver-kikuta-k8s-master2 1/1 Running 1 32m 10.100.2.35 kikuta-k8s-master2 <none> <none>
kube-system kube-apiserver-kikuta-k8s-master3 1/1 Running 1 27m 10.100.2.36 kikuta-k8s-master3 <none> <none>
kube-system kube-controller-manager-kikuta-k8s-master1 1/1 Running 1 29m 10.100.2.33 kikuta-k8s-master1 <none> <none>
kube-system kube-controller-manager-kikuta-k8s-master2 1/1 Running 1 32m 10.100.2.35 kikuta-k8s-master2 <none> <none>
kube-system kube-controller-manager-kikuta-k8s-master3 1/1 Running 1 28m 10.100.2.36 kikuta-k8s-master3 <none> <none>
kube-system kube-proxy-285s4 1/1 Running 0 31m 10.100.2.35 kikuta-k8s-master2 <none> <none>
kube-system kube-proxy-csmmm 1/1 Running 0 30m 10.100.2.33 kikuta-k8s-master1 <none> <none>
kube-system kube-proxy-khvsl 1/1 Running 0 30m 10.100.2.46 kikuta-k8s-worker2 <none> <none>
kube-system kube-proxy-xlgpf 1/1 Running 0 28m 10.100.2.36 kikuta-k8s-master3 <none> <none>
kube-system kube-proxy-z65nd 1/1 Running 0 30m 10.100.2.42 kikuta-k8s-worker1 <none> <none>
kube-system kube-scheduler-kikuta-k8s-master1 1/1 Running 1 30m 10.100.2.33 kikuta-k8s-master1 <none> <none>
kube-system kube-scheduler-kikuta-k8s-master2 1/1 Running 1 32m 10.100.2.35 kikuta-k8s-master2 <none> <none>
kube-system kube-scheduler-kikuta-k8s-master3 1/1 Running 1 28m 10.100.2.36 kikuta-k8s-master3 <none> <none>
kube-system kube-vip-kikuta-k8s-master1 1/1 Running 1 29m 10.100.2.33 kikuta-k8s-master1 <none> <none>
kube-system kube-vip-kikuta-k8s-master2 1/1 Running 1 32m 10.100.2.35 kikuta-k8s-master2 <none> <none>
kube-system kube-vip-kikuta-k8s-master3 1/1 Running 1 27m 10.100.2.36 kikuta-k8s-master3 <none> <none>
まとめ
本記事ではCluster APIを使ってWorkload Clusterを構築しました。次回はWorkload Clusterで障害が発生した際の動作を確認していきます。