1
0

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.

Class BasedのTKGのノードの中身をカスタマイズする

Last updated at Posted at 2023-04-28

これまでのTanzu Kubernetes Grid(TKG)でノードの中身を設定する場合(例えば証明書を入れるとか)、設定ファイルにパラメータがない場合はytt overlayでカスタマイズしてきた。
しかし、Class BasedのTKGでは従来のytt overlayが利用できなくなり、ClusterClassをカスタマイズして修正する必要がある。
この修正が非常に癖があるので、今回は試しにスタティックルートの設定をWorkload ClusterのWorkerノードに追加して、どういう手順が必要になるを検証する。
なお、公式ドキュメントのこちらを参考にした。

スタティックルートの設定をWorkerノードに追加するには、kind: VSphereMachineTemplatedevicesにroutesを足して実現できる。

      network:
        devices:
        - dhcp4: true
          networkName: /vSAN-DC/network/VM Network
+         routes:
+         - metric: 1
+           to: 192.168.111.200
+           via: 192.168.111.1

これをClusterClassをカスタマイズして実現する。

事前準備

Management Clusterの作成

今回はManagement Clusterを作成した状態から始める。作成手順は省略する。

Carvelのインストール

${HOME}/bin/以下にインストールする。(パスは通っているものとしている)

cd ~
mkdir ~/bin/
curl -L https://carvel.dev/install.sh | K14SIO_INSTALL_BIN_DIR=bin bash
vendir version

ベースとなるManifestの入手

BaseとなるManifestをDownloadして解凍し、ディレクトリをコピーする。

wget https://github.com/vmware-tanzu/tanzu-framework/archive/refs/tags/v0.28.1.zip
unzip v0.28.1.zip
cp -r tanzu-framework-0.28.1/packages/tkg-clusterclass-vsphere/bundle/ .

中身は以下のようになっている。

bundle/
└── config
    ├── upstream
    │   ├── base.yaml
    │   ├── overlay-kube-apiserver-admission.yaml
    │   └── overlay.yaml
    └── values.yaml

設定作業

ベースのManifestに既存設定をマージ

Management Clusterにコンテキストをあわせて、以下を実行する。

cat <<EOF > default_values.yaml
#@data/values

#@overlay/match-child-defaults missing_ok=True
---
EOF
kubectl get secret tkg-clusterclass-infra-values -o jsonpath='{.data.values\.yaml}' -n tkg-system | base64 -d >> default_values.yaml

tkg-clusterclass-infra-valuesの中にはManagement Cluster構築時に使ったvalues.yaml(plan based)が入っているので、それが追記されることになる。

抜き出した、ベースとなるManifestと結合する。

ytt -f bundle/ -f default_values.yaml > default_cc.yaml

中身はClusterClassを含むクラスタ関連のリソースが定義されている。

$ grep "^kind" default_cc.yaml
kind: VSphereClusterTemplate
kind: VSphereMachineTemplate
kind: VSphereMachineTemplate
kind: KubeadmControlPlaneTemplate
kind: KubeadmConfigTemplate
kind: ClusterClass

なお、ここでは細かく紹介しないが、default_cc.yaml内のClusterClassでカスタマイズするための変数等が設定されている。
今回ytt overlayを作成するにあたり非常に参考になったので、実際にカスタマイズする際はこれをよく読んでおくとよい。

カスタムするoverlayの作成

最初にoverlayをまとめるディレクトリを作成する。

mkdir custom

kind: ClusterClass内のkind: VSphereMachineTemplateを修正するoverlayを作成する。

cat << EOF > ./custom/overlay_staticRoute.yaml
#@ load("@ytt:overlay", "overlay")
#@ load("@ytt:data", "data")

#@overlay/match by=overlay.subset({"kind":"ClusterClass"})
---
apiVersion: cluster.x-k8s.io/v1beta1
kind: ClusterClass
spec:
  variables:
  - name: staticRoute
    required: false
    schema:
      openAPIV3Schema:
        type: object
        properties:
          metric:
            type: integer
          to:
            type: string
          via:
            type: string
  patches:
  - name: staticRoute
    enabledIf: '{{ not (empty .staticRoute) }}'
    definitions:
      - selector:
          apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
          kind: VSphereMachineTemplate
          matchResources:
            machineDeploymentClass:
              names:
              - tkg-worker
        jsonPatches:
          - op: add
            path: /spec/template/spec/network
            valueFrom:
              template: |
                devices:
                - dhcp4: true
                  networkName: {{ .vcenter.network }}
                  routes:
                  - metric: {{ .staticRoute.metric }}
                    to: {{ .staticRoute.to }}
                    via: {{ .staticRoute.via }}
EOF

書いている意味は以下となる。

  variables:
  - name: staticRoute
    required: false
    schema:
      openAPIV3Schema:
        type: object
        properties:
          metric:
            type: integer
          to:
            type: string
          via:
            type: string

variables:の中で変数を定義することが出来る。CRDではよく見るopenAPIV3Schemaの形式で記載する。
ここではstaticRouteというオブジェクトを定義し、中にmetrictoviaという変数的なものを定義した。
ベタ書きでいい場合は変数を作らなくても良さそう。

  patches:
  - name: staticRoute
    enabledIf: '{{ not (empty .staticRoute) }}'

中のyamlを修正する場合、patches:で修正箇所と修正内容を定義する。
enabledIfでstaticRouteが指定された場合のみファイルを修正するようにしている。

    definitions:
      - selector:
          apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
          kind: VSphereMachineTemplate
          matchResources:
            machineDeploymentClass:
              names:
              - tkg-worker

書き換え場所を指定する。MachineDeploymentに使うVSphereMachineTemplateを書き換える。
matchResourcesも必須で、書き換え対象を指定する。ControlPlaneに関するものだったらcontrolPlane: true、Workerに関するものだったらmachineDeploymentClassで対象MachineDeploymentを指定する。クラスタに関するものはinfrastructureCluster: trueを指定する。

        jsonPatches:
          - op: add
            path: /spec/template/spec/network
            valueFrom:
              template: |
                devices:
                - dhcp4: true
                  networkName: {{ .vcenter.network }}
                  routes:
                  - metric: {{ .staticRoute.metric }}
                    to: {{ .staticRoute.to }}
                    via: {{ .staticRoute.via }}

上では実際のパラメータの設定を行っている。json patch形式で書くようで、pathがVSphereMachineTemplateリソースの書き換え対象(spec.template.spec.network)でopでjson patchでのopを指定する。
作成した変数については{{ .<変数名> }}で参照できる。
.vcenter.network は作成していないが別で定義されているのでそちらを引っ張ってきている。

また、defaultのClusterClassは変更できないため、別名をつけるためのytt overlayを作成する。なお公式ドキュメントではCC-VERSIONとなってるが、VSPHERE_CLUSTER_CLASS_VERSIONが正しいと思われる。

cat << EOF > ./custom/values.yaml
#@data/values

#@overlay/match-child-defaults missing_ok=True
---
#! Change the suffix so we know from which default ClusterClass it is extended
VSPHERE_CLUSTER_CLASS_VERSION: extended-v1.0.0

#! Add other variables below if necessary
EOF

カスタムのClusterClassを作成するのに必要な最終的なファイル構成は以下となった。

├── bundle
│   └── config
│       ├── upstream
│       │   ├── base.yaml
│       │   ├── overlay-kube-apiserver-admission.yaml
│       │   └── overlay.yaml
│       └── values.yaml
├── custom
│   ├── overlay_staticRoute.yaml
│   └── values.yaml
└── default_values.yaml

カスタムのClusterClassを作成する。

ytt -f bundle/ -f default_values.yaml -f custom/ > custom_cc.yaml

diffを取って、名前と追加した項目以外変わっていないことを確認する。

diff default_cc.yaml custom_cc.yaml

applyする。

kubectl apply -f ./custom_cc.yaml

追加されているのを確認する。

$ kubectl get clusterclass
NAME                                  AGE
tkg-vsphere-default-extended-v1.0.0   23h
tkg-vsphere-default-v1.0.0            27h

Workloadクラスタの作成

Workload Clusterのテンプレートは既にあるものとする(ここでは~/.config/tanzu/tkg/clusterconfigs/workload.yamlとする)。
既存のものを以下の点について修正する。

  • ClusterClassの指定をデフォルトのものから作成したものに変更
  • 作成したパラメータを使ってスタティックルートを指定

スタティックルートは192.168.201.10宛を192.168.201.1経由にする設定で入れる。
修正箇所は以下になる。

   topology:
-    class: tkg-vsphere-default-v1.0.0
+    class: tkg-vsphere-default-extended-v1.0.0
     controlPlane:
       metadata:
         annotations:
           run.tanzu.vmware.com/resolve-os-image: image-type=ova,os-name=ubuntu
       replicas: 1
     variables:
+    - name: staticRoute
+      value:
+        metric: 1
+        to: 192.168.201.10
+        via: 192.168.201.1
     - name: controlPlaneCertificateRotation
       value:
         activate: true

作成の前にdry-runが実行できる。dry-runを飛ばすことも可能だが、経験上凄く失敗するので、dry-runを試してからクラスタ作成に移った方がよい。
なお、clusterctlコマンドの古いバージョン(v1.2.0)が必要となる。(新しいバージョンだとエラーになる)
こちらにリンクを貼っておく。
https://github.com/kubernetes-sigs/cluster-api/releases/tag/v1.2.0

クラスタ作成時に使うWorkload Clusterのテンプレートをコピーする。

cp ~/.config/tanzu/tkg/clusterconfigs/workload.yaml ./dryrun.yaml

Management Clusterのkind: Clusterで持っているTKR_DATAというデータを表示する。

kubectl get cluster <Management Cluster名> -n tkg-system -o jsonpath='{.spec.topology.variables}' | jq -r '.[] | select(.name == "TKR_DATA")' | yq -p json '.'

表示されたTKR_DATAをdryrun.yamlの.spec.topology.variablesに挿入する。

@@ -69,6 +69,33 @@
           run.tanzu.vmware.com/resolve-os-image: image-type=ova,os-name=ubuntu
       replicas: 1
     variables:
+    - name: TKR_DATA
+      value:
+        v1.24.9+vmware.1:
+          kubernetesSpec:
+            coredns:
+              imageTag: v1.8.6_vmware.15
+            etcd:
+              imageTag: v3.5.6_vmware.3
+            imageRepository: projects.registry.vmware.com/tkg
+            kube-vip:
+              imageTag: v0.5.7_vmware.1
+            pause:
+              imageTag: "3.7"
+            version: v1.24.9+vmware.1
+          labels:
+            image-type: ova
+            os-arch: amd64
+            os-name: ubuntu
+            os-type: linux
+            os-version: "2004"
+            ova-version: v1.24.9---vmware.1-tkg.1-b030088fe71fea7ff1ecb87a4d425c93
+            run.tanzu.vmware.com/os-image: v1.24.9---vmware.1-tkg.1-b030088fe71fea7ff1ecb87a4d425c93
+            run.tanzu.vmware.com/tkr: v1.24.9---vmware.1-tkg.1
+          osImageRef:
+            moid: vm-51
+            template: /vSAN-DC/vm/ubuntu-2004-efi-kube-v1.24.9+vmware.1
+            version: v1.24.9+vmware.1-tkg.1-b030088fe71fea7ff1ecb87a4d425c93

dry-runの結果を保存するディレクトリを作成する。

mkdir plan

clusterctlを使ってdry-runを実行する。

./clusterctl alpha topology plan -f dryrun.yaml -o plan

実行して問題なければ今のManagement Clusterが持つリソースの差分が出力される。コンソール出力としては以下のようになり、planディレクトリ以下に作成される予定のManifestが格納される。

Detected a cluster with Cluster API installed. Will use it to fetch missing objects.
No ClusterClasses will be affected by the changes.
The following Clusters will be affected by the changes:
 * default/delme-wc-edit

Changes for Cluster "default/delme-wc-edit":

  NAMESPACE  KIND                    NAME                                ACTION
  default    KubeadmConfigTemplate   delme-wc-edit-md-0-bootstrap-6cqsk  created
  default    KubeadmControlPlane     delme-wc-edit-jffv2                 created
  default    MachineDeployment       delme-wc-edit-md-0-jcbmj            created
  default    MachineHealthCheck      delme-wc-edit-jffv2                 created
  default    MachineHealthCheck      delme-wc-edit-md-0-jcbmj            created
  default    Secret                  delme-wc-edit-shim                  created
  default    VSphereCluster          delme-wc-edit-hj967                 created
  default    VSphereMachineTemplate  delme-wc-edit-control-plane-4bw9p   created
  default    VSphereMachineTemplate  delme-wc-edit-md-0-infra-755r7      created
  default    Cluster                 delme-wc-edit                       modified

Created objects are written to directory "plan/created"
Modified objects are written to directory "plan/modified"

なお、現在のManagement Clusterが持つリソースとの差分なので、クラスタ作成後は何も表示されなくなるので注意。
出力された中身を見て、意図したようにVSphereMachineTemplateが書き換わっていることを確認する。

      network:
        devices:
        - dhcp4: true
          networkName: /vSAN-DC/network/VM Network
          routes:
          - metric: 1
            to: 192.168.201.10
            via: 192.168.201.1

問題なさそうであれば、デプロイする。

tanzu cluster create -f workload.yaml -v9

問題なくデプロイ出来たら、動作確認する。NodeのIPに対してsshしてip routeで確認する。

$ ssh -l capv  10.151.206.93 ip route
default via 10.151.207.254 dev eth0 proto dhcp src 10.151.206.93 metric 100
10.151.192.0/20 dev eth0 proto kernel scope link src 10.151.206.93
10.151.207.254 dev eth0 proto dhcp scope link src 10.151.206.93 metric 100
100.96.0.0/24 via 100.96.0.1 dev antrea-gw0 onlink
100.96.1.0/24 dev antrea-gw0 proto kernel scope link src 100.96.1.1
192.168.201.10 via 192.168.201.1 dev eth0 proto static metric 1 onlink

追加した192.168.201.10宛の設定が追加されていることが分かる。

おまけ:失敗例

後方に追加したいので、/-を指定すればいい、と思って以下を書いた。

          - op: add
            path: /spec/template/spec/network/devices/-

結果は以下。

      network:
        devices:
        - dhcp4: true
          networkName: /vSAN-DC/network/VM Network
        - routes:
          - metric: 1
            to: 192.168.201.10
            via: 192.168.201.1

routesをpathに含めたパターン。

          - op: add
            path: /spec/template/spec/network/devices/routes

こちらはclusterctlが以下のエラーを出力した。

Detected a cluster with Cluster API installed. Will use it to fetch missing objects.
Error: failed to dry run the topology controller: error computing the desired state of the Cluster topology: failed to apply patches: failed to apply patch with uid "61c28a73-17ac-4425-b8c6-5f52cad035a7": error applying json patch (RFC6902): [{"op":"add","path":"/spec/template/spec/network/devices/routes","value":{"metric":1,"to":"192.168.201.10","via":"192.168.201.1"}}]: error in add for path: '/spec/template/spec/network/devices/routes': value was not a proper array index: 'routes': strconv.Atoi: parsing "routes": invalid syntax

あと、clusterctlが最新版だと以下のエラーが出る

Detected a cluster with Cluster API installed. Will use it to fetch missing objects.
Error: failed defaulting and validation on input objects: failed to run defaulting and validation on Clusters: failed defaulting of cluster.x-k8s.io/v1beta1, Kind=Cluster default/delme-wc-edit: Cluster.cluster.x-k8s.io "delme-wc-edit" is invalid: [spec.topology.variables: Invalid value: "": failed validation: "TKR_DATA.v1.24.9+vmware.1" fields are not specified in the variable schema of variable "TKR_DATA", spec.topology.variables: Invalid value: "": failed validation: "worker.count" fields are not specified in the variable schema of variable "worker"]

結論:

  • json patchは慣れが必要
  • clusterctlでの事前確認は大事
  • 早くclusterctlの最新版に対応して欲しい
1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?