1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Workload Clusterの構築

Last updated at Posted at 2023-08-22

はじめに

 本記事では、Management Clusterの構築で構築したManagementClusterを使ってWorkload Clusterを構築します。構築の前提となる環境はClusterAPIによるKubernetesクラスタの操作を参照してください。
 本記事では下図のようにControl planeノード3台(master1~3)、Workerノード2台(worker1~2)のworkload-clusterを構築します。

image.png

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.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にインストールする必要があります。

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で以下のような内容です。

/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パラメータを使ってラベルを付与しています。

master1,2,3
$ 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
worker1,2
$ 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用それぞれにラベル付与されていることが分かります。

Management Cluster用VM
$ 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を指定してまいます。

Management Cluster用VM
$ 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を追加します。

cluster.yaml
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します。

Management Cluster
$ 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台並列でデプロイ中であることを示しています。

Management Cluster
$ 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ノードがデプロイされています。

Management Cluster
$ 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のマニフェスト作成時に指定したクラスタ名が必要ですが、以下のコマンドで調べることもできます。

Management Cluster
$ kubectl get cluster
NAME               PHASE         AGE   VERSION
workload-cluster   Provisioned   24m

kubeconfigを取得するコマンドは以下の通りです。

Management Cluster
$ 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にデプロイされていることが分かります。

Management Cluster
$ 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で障害が発生した際の動作を確認していきます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?