はじめに
プラットフォームエンジニアリングチームの齊藤(id:saitoperf)です。 マイクロアドでは、Kubernetes (K8s) クラスタのライフサイクル管理に Rancher を使用しています。
Rancher は、OSS の K8s クラスタ管理ツールで、クラスタの構築・可視化・バージョンアップなど、運用を効率化する様々な機能を提供しています。 Cluster API は Rancher の内部で使われていますが、今まで意識することはありませんでした。
今回は、Cluster API を使って K8s クラスタを構築して管理していく方法をご紹介します。 再現には MAAS の環境が必要になるので、Cluster API でプラットフォームを操作して K8s のライフサイクルを管理していく雰囲気を感じていただければ幸いです。
※ 本記事では見やすさを優先させるためコマンドの出力結果などを一部省略しています。
- はじめに
- 対象読者
- 前提知識
- MAAS について
- Cluster API について
- Cluster API を使って MAAS 上に K8s クラスタを構築
- Pivot の手順 (セルフホスト化)
- Kubernetes バージョンアップ
- おわりに
- 新卒インフラエンジニア絶賛採用中
対象読者
- K8s や MAAS を運用しているインフラエンジニア
- Cluster API の雰囲気を知りたい方
前提知識
- カスタムリソースなどを含む K8s の知識
MAAS について
MAAS (Metal as a Service) は Canonical 社が開発しているベアメタル管理ツールです。 MAAS を使うことで、物理サーバの OS インストールや管理がクラウドリソースのように利用可能になります。
マイクロアドで MAAS を導入した経緯などはこちらをご覧ください。
今回は、Cluster API を初めて触ることもあり、データセンタの MAAS 環境とは切り離して検証したかったので、 こちらの記事で作成したオフィス内サーバルームの MAAS 環境を使いました。
Cluster API について
Cluster API とは K8s クラスタのプロビジョニング・アップグレード・運用を簡素化するための宣言的 API です。 Cluster API では、以下を含む情報をマニフェストに記載することで K8s クラスタを宣言的に管理します。
- Pod CIDR, Service CIDR
- K8s のバージョン
- K8s のバージョンアップポリシー
- Control-plane や Worker の台数
- Control-plane や Worker に使われる VM/PM (Physical Machine) のスペック
- etc...
Cluster API では、クラスタに関して 2 つのロールが登場します。
- Workload cluster
- Cluster API によってライフサイクルを管理されるクラスタ
- Management cluster
- Workload cluster を管理するクラスタ
- このクラスタに、Cluster API の Operator (カスタムコントローラ + CRD) をインストールする

プロバイダについて
Cluster API は 3つのレイヤで構成されており、役割ごとに独立した実装がコミュニティやベンダーから「プロバイダ」として提供されています (プロバイダの実装はこちら)。
- Infrastructure provider
- K8s クラスタを乗せるプラットフォーム
- 例: OpenStack, MAAS, GoogleCloud, etc...
- Control plane provider
- Control-plane の K8s エンジン
- 例: Kubeadm, RKE2, etc...
- Bootstrap provider
- Worker の K8s エンジン
- 通常は Control plane provider と同じ
基本的に、Control plane provider と Bootstrap provider は同じものを使うので、Infrastructure provider と Bootstrap provider の組み合わせを選んでいきます。
- MAAS × RKE2
- MAAS × kubeadm
- OpenStack × RKE2
- OpenStack × kubeadm
Image Builder について
Cluster API は、MAAS や OpenStack といったプラットフォームから VM/PM を払い出して OS をインストールする所から K8s のライフサイクルを管理していくため、OS イメージが必要になります。 OS イメージは一部提供されていますが、現行の OS や K8s バージョンから古い場合があります1。 そのため Image Builder というツールを使ってビルドします。
例えば、MAAS 用のイメージを作る場合、こちらのマトリクスで MAAS に対応している OS を確認します。 2026年4月時点では Ubuntu 22.04 と 24.04 に対応していました。
Cluster API を使って MAAS 上に K8s クラスタを構築
※ 正しくは、MAAS の API を叩いて MAAS 管理下のサーバを使って K8s クラスタを構築しますが、便宜上「MAAS 上に構築」と記載しています。
実施する作業
- Step 1: Image Builder で OS イメージを作る
- Step 2: OS イメージを MAAS にアップロードする
- Step 3: kind に Cluster API の Operator をインストールして Management cluster 化する
- Step 4: Cluster API のリソースを作る
- Step 5: Control-plane の作成 (Step 4 でリソースを作ると Control-plane が作られる)
- Step 6: Worker の作成 (Step 5 完了後に自動で作られる)

Step 1. Image Builder で OS イメージをビルド
Image Builder の公式リポジトリをクローンして、必要なパッケージをインストールします。
git clone https://github.com/kubernetes-sigs/image-builder.git git checkout v0.1.49 # qemu 関連のパッケージをインストール sudo apt-get update sudo apt-get install -y qemu-system-x86 qemu-utils python3.12-venv # Ansible のインストール python3 -m venv .venv source .venv/bin/activate pip install ansible==13.3.0 # KVM 関連の操作ができるようにグループに所属させる sudo usermod -aG kvm $USER newgrp kvm
Image Builder のクローンが完了したら、設定を変更していきます。 まずは、最新の K8s のパッチバージョンを確認して変更します。
# v1.33 の最新パッチバージョン curl -s https://dl.k8s.io/release/stable-1.33.txt # kubernetes_deb_version の確認 curl -Ls https://pkgs.k8s.io/core:/stable:/v1.33/deb/Packages | grep Version # v1.34 の最新パッチバージョン curl -s https://dl.k8s.io/release/stable-1.34.txt # kubernetes_deb_version の確認 curl -Ls https://pkgs.k8s.io/core:/stable:/v1.34/deb/Packages | grep Version
パッチバージョンを確認したら、image-builder/images/capi/packer/config/kubernetes.json を変更します。
- "crictl_version": "1.34.0", + "crictl_version": "1.33.0", ... - "kubernetes_deb_version": "1.34.3-1.1", + "kubernetes_deb_version": "1.33.10-1.1", ... - "kubernetes_rpm_version": "1.34.3", - "kubernetes_semver": "v1.34.3", - "kubernetes_series": "v1.34", + "kubernetes_rpm_version": "1.33.10", + "kubernetes_semver": "v1.33.10", + "kubernetes_series": "v1.33", ...
続いて、images/capi/packer/config を編集して、イメージに追加でインストールするパッケージや Ansible のタスクで使う環境変数などを定義します。
今回は、サーバが古く grub-pc をイメージにインストールしておかないと、OS インストール時に失敗したため、grub-pc を指定しています。
また、プロキシ環境なので Ansible のタスク内でプロキシを使うようにしています。
(BIOS サポート関連のエラー issue)
- https://github.com/kubernetes-sigs/image-builder/pull/1784
- https://github.com/kubernetes-sigs/image-builder/pull/1828
- https://github.com/kubernetes-sigs/image-builder/pull/1906
- "extra_debs": "", + "extra_debs": "grub-pc", ... - "http_proxy": "", - "https_proxy": "", + "http_proxy": "http://192...:8000", + "https_proxy": "http://192...:8000",
変数を設定したら、OS イメージをビルドしていきます (参考)。
cd image-builder/images/capi source .venv/bin/activate # Ubuntu 24.04イメージビルド make build-maas-ubuntu-2404-efi
しばらくすると、イメージが image-builder/images/capi/output/ 配下に作られます。
ls output/ # ubuntu-2404-efi-kube-v1.33.10 # 以降の手順で分かりやすいように /tmp 配下にコピーしておきます cp ./output/ubuntu-2404-efi-kube-v1.33.10 /tmp/
Step 2. MAAS に OS イメージをアップロード
ビルドした OS イメージを MAAS にアップロードします。
VER_K8S=1.33 VER_K8S_PATCH=1.33.10 # MAAS にログイン maas login admin http://192...:5240/MAAS/api/2.0 h... # MAAS にアップロード maas admin boot-resources create \ name="custom/ubuntu-2404-efi-kube-v${VER_K8S_PATCH}" \ title="Ubuntu 24.04 CAPI v${VER_K8S_PATCH}" \ architecture='amd64/generic' \ filetype='tgz' \ content@=/tmp/ubuntu-2404-efi-kube-v${VER_K8S_PATCH}.tar.gz
MAAS コマンドでアップロードした OS イメージを確認します。
maas admin boot-resources read | \ jq '.[] | select(.name == "ubuntu-2404-efi-kube-v1.33.10")' # { # "id": 25, # "type": "Uploaded", # "name": "ubuntu-2404-efi-kube-v1.33.10", # "architecture": "amd64/generic", # "resource_uri": "/MAAS/api/2.0/boot-resources/25/", # "last_deployed": null, # "title": "Ubuntu 24.04 CAPI v1.33.10", # "subarches": "generic", # "base_image": "ubuntu/jammy" # }
Step 3. kind で Management Cluster の作成
事前準備として、MAAS の Machine にタグをつけます。 タグが一致した Machine を Cluster API で使うようにします。
# タグの作成 maas admin tags create name=control-plane maas admin tags create name=worker # Machine 一覧を取得 maas admin machines read | jq '[.[] | {hostname, system_id}] | sort_by(.hostname)' # [ # { # "hostname": "1...", # "system_id": "f..." # }, # { # "hostname": "1...", # "system_id": "k..." # ... # ] # Worker maas admin tag update-nodes worker add=k... maas admin tag update-nodes worker add=p... maas admin tag update-nodes worker add=r... # Control-plane maas admin tag update-nodes control-plane add=8... maas admin tag update-nodes control-plane add=4...
UI から見るとこのようにタグが付与されています。

タグ付けができたら、kind クラスタを構築します。
# kind の構成ファイル (C-plane 1台, Worker 1台) cat << EOF > config.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker EOF # kind クラスタを構築 kind create cluster --config ./config.yaml # kind のコンテキストを ~/.kube/config.kind に保存します cp ~/.kube/config ~/.kube/config.kind
続いて、clusterctl コマンドを使って Management cluster を作っていきます。
clusterctl は Management cluster のライフサイクルを管理する CLI ツールになります2。
clusterctl が読み込む設定ファイルは、デフォルトで ~/.cluster-api/clusterctl.yaml になりますが、実行時に引数でパスを指定することもできます3。
~/.cluster-api/clusterctl_133.yaml を作ります。
MAAS_API_KEY: h... MAAS_ENDPOINT: http://192...:5240/MAAS MAAS_DNS_DOMAIN: maas # Cluster configuration KUBERNETES_VERSION: v1.33.10 CONTROL_PLANE_MACHINE_IMAGE: custom/ubuntu-2404-efi-kube-v1.33.10 CONTROL_PLANE_MACHINE_MINCPU: 4 CONTROL_PLANE_MACHINE_MINMEMORY: 8192 CONTROL_PLANE_MACHINE_RESOURCEPOOL: default CONTROL_PLANE_MACHINE_TAG: control-plane WORKER_MACHINE_IMAGE: custom/ubuntu-2404-efi-kube-v1.33.10 WORKER_MACHINE_MINCPU: 4 WORKER_MACHINE_MINMEMORY: 8192 WORKER_MACHINE_RESOURCEPOOL: default WORKER_MACHINE_TAG: worker # カスタム変数 POD_CIDR: 172.18.0.0/17 SERVICE_CIDR: 10.43.0.0/16 KUBERNETES_VERSION_HYPHEN: v1-33-10
clusterctl CLI をインストールします4。
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.12.3/clusterctl-linux-amd64 -o clusterctl sudo install ./clusterctl /usr/local/bin/clusterctl
~/.cluster-api/clusterctl_133.yaml を指定して、Cluster API の Operator を kind にインストールします。
これにより、kind は Management cluster になります。
clusterctl init \ --core cluster-api:v1.12.3 \ --infrastructure maas:v0.6.1 \ --config ${HOME}/.cluster-api/clusterctl_133.yaml # 非推奨になった gcr.io/kubebuilder/kube-rbac-proxy が埋め込まれているので置き換える kubectl get po -n capmaas-system # NAME READY STATUS RESTARTS AGE # capmaas-controller-manager-7bc.. 1/2 ImagePullBackOff 0 26s kubectl set image -n capmaas-system deployment/capmaas-controller-manager \ kube-rbac-proxy=quay.io/brancz/kube-rbac-proxy:v0.15.0
Step 4. Cluster API のリソース作成
まず、Cluster API のマニフェストを生成するためのテンプレートを作ります。
2026年4月時点のMAAS Provider が提供しているテンプレートを見ると、Pod CIDR などの設定がハードコードされており、このままではクラスタの作成に失敗します。
そのため、自前で cluster-template.yaml というテンプレートを作って、先ほど作った ~/.cluster-api/clusterctl_133.yaml のカスタム変数 (POD_CIDR など) を埋め込みます。
cluster-template.yaml
--- apiVersion: cluster.x-k8s.io/v1beta1 kind: Cluster metadata: name: "${CLUSTER_NAME}" spec: clusterNetwork: services: cidrBlocks: ["${SERVICE_CIDR}"] pods: cidrBlocks: ["${POD_CIDR}"] serviceDomain: "cluster.local" infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasCluster name: "${CLUSTER_NAME}" controlPlaneRef: apiVersion: controlplane.cluster.x-k8s.io/v1beta1 kind: KubeadmControlPlane name: "${CLUSTER_NAME}-control-plane" --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasCluster metadata: name: "${CLUSTER_NAME}" spec: dnsDomain: ${MAAS_DNS_DOMAIN} --- apiVersion: controlplane.cluster.x-k8s.io/v1beta1 kind: KubeadmControlPlane metadata: name: "${CLUSTER_NAME}-control-plane" spec: replicas: ${CONTROL_PLANE_MACHINE_COUNT} version: "${KUBERNETES_VERSION}" machineTemplate: infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasMachineTemplate name: "${CLUSTER_NAME}-control-plane-${KUBERNETES_VERSION_HYPHEN}" kubeadmConfigSpec: clusterConfiguration: apiServer: certSANs: - 127.0.0.1 extraArgs: anonymous-auth: "true" authorization-mode: RBAC,Node default-not-ready-toleration-seconds: "60" default-unreachable-toleration-seconds: "60" disable-admission-plugins: AlwaysAdmit enable-admission-plugins: AlwaysPullImages,NamespaceLifecycle,ServiceAccount,NodeRestriction timeoutForControlPlane: 10m0s controllerManager: extraArgs: feature-gates: RotateKubeletServerCertificate=true terminated-pod-gc-threshold: "25" use-service-account-credentials: "true" dns: {} etcd: {} networking: {} scheduler: extraArgs: # 1台目の control-plane initConfiguration: nodeRegistration: kubeletExtraArgs: event-qps: "0" feature-gates: RotateKubeletServerCertificate=true read-only-port: "0" name: '{{ v1.local_hostname }}' # 2台目以降の control-plane joinConfiguration: controlPlane: discovery: {} nodeRegistration: kubeletExtraArgs: event-qps: "0" feature-gates: RotateKubeletServerCertificate=true read-only-port: "0" name: '{{ v1.local_hostname }}' files: - path: /etc/environment content: | http_proxy=http://... https_proxy=http://... no_proxy=192... preKubeadmCommands: - export http_proxy=http://... - export https_proxy=http://... - export no_proxy=192... - mkdir -p /etc/systemd/system/containerd.service.d - | cat <<EOF > /etc/systemd/system/containerd.service.d/http-proxy.conf [Service] Environment="HTTP_PROXY=http://... Environment="HTTPS_PROXY=http://... Environment="NO_PROXY=192... EOF - systemctl daemon-reload - systemctl restart containerd - while [ ! -S /var/run/containerd/containerd.sock ]; do echo 'Waiting for containerd...'; sleep 1; done - sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab - swapoff -a useExperimentalRetryJoin: true --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasMachineTemplate metadata: name: "${CLUSTER_NAME}-control-plane-${KUBERNETES_VERSION_HYPHEN}" spec: template: spec: minCPU: ${CONTROL_PLANE_MACHINE_MINCPU} minMemory: ${CONTROL_PLANE_MACHINE_MINMEMORY} image: ${CONTROL_PLANE_MACHINE_IMAGE} resourcePool: ${CONTROL_PLANE_MACHINE_RESOURCEPOOL} tags: [ ${ CONTROL_PLANE_MACHINE_TAG } ] --- apiVersion: cluster.x-k8s.io/v1beta1 kind: MachineDeployment metadata: name: "${CLUSTER_NAME}-md-0" spec: clusterName: "${CLUSTER_NAME}" replicas: 1 selector: matchLabels: cluster.x-k8s.io/cluster-name: "${CLUSTER_NAME}" # Pod の template と同じ思想 template: spec: clusterName: "${CLUSTER_NAME}" version: "${KUBERNETES_VERSION}" infrastructureRef: apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasMachineTemplate name: "${CLUSTER_NAME}-md-0-${KUBERNETES_VERSION_HYPHEN}" bootstrap: configRef: apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 kind: KubeadmConfigTemplate name: "${CLUSTER_NAME}-md-0" --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasMachineTemplate metadata: name: "${CLUSTER_NAME}-md-0-${KUBERNETES_VERSION_HYPHEN}" spec: template: spec: minCPU: ${WORKER_MACHINE_MINCPU} minMemory: ${WORKER_MACHINE_MINMEMORY} image: ${WORKER_MACHINE_IMAGE} resourcePool: ${WORKER_MACHINE_RESOURCEPOOL} tags: [ ${ WORKER_MACHINE_TAG } ] --- apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 kind: KubeadmConfigTemplate metadata: name: "${CLUSTER_NAME}-md-0" spec: template: spec: joinConfiguration: nodeRegistration: kubeletExtraArgs: event-qps: "0" feature-gates: RotateKubeletServerCertificate=true read-only-port: "0" name: '{{ v1.local_hostname }}' files: - content: | http_proxy=http://... https_proxy=http://... no_proxy=192... path: /etc/environment preKubeadmCommands: - export http_proxy=http://... - export https_proxy=http://... - export no_proxy=192... - mkdir -p /etc/systemd/system/containerd.service.d - | cat <<EOF > /etc/systemd/system/containerd.service.d/http-proxy.conf [Service] Environment="HTTP_PROXY=http://... Environment="HTTPS_PROXY=http://... Environment="NO_PROXY=192... EOF - systemctl daemon-reload - systemctl restart containerd - while [ ! -S /var/run/containerd/containerd.sock ]; do echo 'Waiting for containerd...'; sleep 1; done - sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab - swapoff -a useExperimentalRetryJoin: true
テンプレートができたら、Cluster API のマニフェストを生成します。
VER_K8S_PATCH=1.33.10 CLUSTER=t-cluster clusterctl generate cluster ${CLUSTER} \ --config ${HOME}/.cluster-api/clusterctl_133.yaml \ --target-namespace capmaas-system \ --kubernetes-version v${VER_K8S_PATCH} \ --control-plane-machine-count=1 \ --worker-machine-count=2 \ --from ./cluster-template.yaml \ --write-to ./${CLUSTER}_${VER_K8S_PATCH}.yaml
生成したマニフェストを apply して Cluster API のリソースを kind 上に作ります。
kubectl apply -f ./${CLUSTER}_${VER_K8S_PATCH}.yaml --kubeconfig ~/.kube/config.kind
Step 5, 6. Control-plane と Worker の作成
Management cluster に Cluster API のリソースを作ると、MAAS の API を叩いて OS をデプロイしてくれます。 OS デプロイが完了すると kubeadm で K8s を bootstrap します。
まず、Control-plane が作られます。
kubectl get machine -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane.. False False True Provisioning v1.33.10 # t-cluster-md-0-n6sg6-x8.. False False True Pending v1.33.10

Control-plane の構築が完了すると Worker が作られます。
kubectl get machine -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane.. False False True Running v1.33.10 # t-cluster-md-0-n6sg6-x8.. False False True Provisioning v1.33.10

Worker の構築が完了。
kubectl get machine -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane.. False False True Running v1.33.10 # t-cluster-md-0-n6sg6-x8.. False False True Running v1.33.10

Workload Cluster の kubeconfig を取得して、~/.kube/config.workload に保存します。
clusterctl get kubeconfig t-cluster -n capmaas-system > ~/.kube/config.workload kubectl get po -A --kubeconfig ~/.kube/config.workload # NAMESPACE NAME READY STATUS # kube-system coredns-674b8bbfcf-f7g7b 0/1 Pending # kube-system coredns-674b8bbfcf-pnfnq 0/1 Pending # kube-system etcd-1407-016-06 1/1 Running # kube-system kube-apiserver-1407-016-06 1/1 Running # kube-system kube-controller-manager-1407-016-06 1/1 Running # kube-system kube-proxy-jqhsg 1/1 Running # kube-system kube-proxy-kjjgg 1/1 Running # kube-system kube-scheduler-1407-016-06 1/1 Running
構築後の設定
本記事では省略しますが、Cluster API を使わない場合と同様で CNI をインストールする必要があります。
CNI インストール後に cluster リソースを確認すると AVAILABLE が True になっており、これにて Workload cluster の構築が完了になります!
# ※ 見やすいように分割して表示しています kubectl get cluster -n capmaas-system --kubeconfig ~/.kube/config.kind # NAME AVAILABLE # t-cluster True # CP DESIRED CP AVAILABLE CP UP-TO-DATE # 1 1 1 # W DESIRED W AVAILABLE W UP-TO-DATE # 1 1 1 # PHASE # Provisioned
Pivot の手順 (セルフホスト化)
ここまでで、kind を使って Workload cluster のデプロイを実施しましたが、今後も kind を使って管理していくわけにはいかないので、 今作成した Workload cluster を新たに Management cluster にさせます。 Management cluster の移行には Pivot という方法が用意されています。
まず、Workload Cluster に CAPI をインストールします。
clusterctl init \ --config ${HOME}/.cluster-api/clusterctl_133.yaml \ --kubeconfig ~/.kube/config.workload \ --core cluster-api:v1.12.3 \ --bootstrap kubeadm \ --control-plane kubeadm \ --infrastructure maas:v0.6.1 # 非推奨になった gcr.io/kubebuilder/kube-rbac-proxy:v0.5.0 が埋め込まれているので置き換える kubectl --kubeconfig ~/.kube/config.workload set image -n capmaas-system deployment/capmaas-controller-manager \ kube-rbac-proxy=quay.io/brancz/kube-rbac-proxy:v0.15.0
続いて、clusterctl move コマンドを使って kind (現 Management cluster) から Workload cluster へオブジェクトを移動します。
clusterctl move \ --kubeconfig ~/.kube/config.kind \ --to-kubeconfig ~/.kube/config.workload \ --namespace capmaas-system # Performing move... # Discovering Cluster API objects # Moving Cluster API objects Clusters=1 # Moving Cluster API objects ClusterClasses=0 # Waiting for all resources to be ready to move # Creating objects in the target cluster # Deleting objects from the source cluster
Management cluster 兼 Workload cluster になるため、ライフサイクルを自分自身で管理できるようになります。 Cluster API のリソースが見えるか確認します。 セルフホスト化したので自分のリソースが見えています。
kubectl get machine --kubeconfig ~/.kube/config.workload -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane-.. True True True Running v1.33.10 # t-cluster-md-0-n6sg6-x82.. True True True Running v1.33.10 # ※ 見やすいように分割して表示しています kubectl get cluster --kubeconfig ~/.kube/config.workload -n capmaas-system # NAME AVAILABLE # t-cluster True # CP DESIRED CP AVAILABLE CP UP-TO-DATE # 1 1 1 # W DESIRED W AVAILABLE W UP-TO-DATE # 1 1 1 # PHASE # Provisioned
Kubernetes バージョンアップ
※ 以下の手順は v1.34 のイメージを、Image builder でビルドして MAAS にアップロードされていることが前提になります。
マニフェスト生成
~/.cluster-api/clusterctl_134.yaml を作ります。
~/.cluster-api/clusterctl_133.yaml との差分はこのようになります。
-KUBERNETES_VERSION: v1.33.10 +KUBERNETES_VERSION: v1.34.3 -CONTROL_PLANE_MACHINE_IMAGE: custom/ubuntu-2404-efi-kube-v1.33.10 +CONTROL_PLANE_MACHINE_IMAGE: custom/ubuntu-2404-efi-kube-v1.34.3 -WORKER_MACHINE_IMAGE: custom/ubuntu-2404-efi-kube-v1.33.10 +WORKER_MACHINE_IMAGE: custom/ubuntu-2404-efi-kube-v1.34.3 -KUBERNETES_VERSION_HYPHEN: v1-33-10 +KUBERNETES_VERSION_HYPHEN: v1-34-3
テンプレートから Cluster API のマニフェストを生成します。
VER_K8S_PATCH=1.34.3 CLUSTER=t-cluster clusterctl generate cluster ${CLUSTER} \ --config ${HOME}/.cluster-api/clusterctl_134.yaml \ --target-namespace capmaas-system \ --kubernetes-version v${VER_K8S_PATCH} \ --control-plane-machine-count=1 \ --worker-machine-count=2 \ --from ./cluster-template.yaml \ --write-to ./${CLUSTER}_${VER_K8S_PATCH}.yaml
v1.33 との差分は以下のようになります。
diff t-cluster_1.33.10.yaml t-cluster_1.34.3.yaml -u --- t-cluster_1.33.10.yaml +++ t-cluster_1.34.3.yaml @@ -104,19 +104,19 @@ kind: KubeadmControlPlane metadata: name: t-cluster-control-plane spec: - name: t-cluster-control-plane-v1-33-10 + name: t-cluster-control-plane-v1-34-3 - version: v1.33.10 + version: v1.34.3 --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasMachineTemplate metadata: - name: t-cluster-control-plane-v1-33-10 + name: t-cluster-control-plane-v1-34-3 spec: template: spec: - image: custom/ubuntu-2404-efi-kube-v1.33.10 + image: custom/ubuntu-2404-efi-kube-v1.34.3 @@ -145,18 +145,18 @@ kind: MachineDeployment metadata: name: t-cluster-md-0 spec: - name: t-cluster-md-0-v1-33-10 - version: v1.33.10 + name: t-cluster-md-0-v1-34-3 + version: v1.34.3 --- apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 kind: MaasMachineTemplate metadata: - name: t-cluster-md-0-v1-33-10 + name: t-cluster-md-0-v1-34-3 spec: template: spec: - image: custom/ubuntu-2404-efi-kube-v1.33.10 + image: custom/ubuntu-2404-efi-kube-v1.34.3
バージョンアップ実施
v1.34 のマニフェストを適用します。
VER_K8S_PATCH=1.34.3 CLUSTER=t-cluster kubectl apply -f ./${CLUSTER}_${VER_K8S_PATCH}.yaml
まず、Control-plane が作られます。
kubectl get machine -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane.. False False True Provisioning v1.34.3 # t-cluster-control-plane.. True True False Running v1.33.10 # t-cluster-md-0-lrs27-z2.. True True False Running v1.33.10 # Cilium の Pod が作られる (↓様子の例) # cilium-d6qxz 0/1 Pending # cilium-envoy-5mwhr 0/1 Pending # cilium-d6qxz 0/1 Init:0/6 # cilium-envoy-5mwhr 0/1 ContainerCreating # cilium-d6qxz 0/1 Init:0/6 # cilium-d6qxz 0/1 Init:1/6
新しい Control-plane の準備ができると古い Control-plane が削除されます。
kubectl get machine -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane.. True True True Running v1.34.3 # t-cluster-control-plane.. False False False Deleting v1.33.10 # t-cluster-md-0-lrs27-z2.. True True False Running v1.33.10
古い Control-plane が削除されると新しい Worker が作られます。
kubectl get machine -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane.. True True True Running v1.34.3 # t-cluster-md-0-h4jd7-5l.. False False True Provisioning v1.34.3 # t-cluster-md-0-lrs27-z2.. True True False Running v1.33.10
新しい Worker の準備ができると古い Worker が削除され、最終的に新しいサーバのみになります。
kubectl get machine -n capmaas-system # NAME READY AVAILABLE UP-TO-DATE PHASE VERSION # t-cluster-control-plane.. True True True Running v1.34.3 # t-cluster-md-0-h4jd7-5l.. True True True Running v1.34.3
おわりに
今回は、Cluster API を使って MAAS 上で K8s のライフサイクルを管理する方法について紹介しました。
検証して分かった課題を以下にまとめます。
- Control-plane のエンドポイントを提供するためのプロキシ (HAProxyなど) は別で作らないといけないが、バージョンアップやノード障害時のセルフヒーリングのたびにバックエンドが変わるので、外部プロキシとの連携が必要になる
- OpenStack provider を使えば、Octavia と連携していい感じに control-plane 用のプロキシを設定してくれるっぽい?5
- バージョンアップは、OS インストールから実施するので Rancher と比較して時間がかかる & 余分にサーバが必要
MAAS プロバイダよりも OpenStack プロバイダの方が活発に開発されているため、今後は OpenStack プロバイダの検証や Rancher 環境で Cluster API を上手に使っていく方法を模索していきたいと考えています。
新卒インフラエンジニア絶賛採用中
マイクロアドでは技術への探究心があり、最新の技術・動向について積極的に学び活かす意欲を持った仲間を募集しています! またインフラエンジニアだけでなく、サーバサイド、機械学習エンジニアなど幅広く募集しています! 気になった方は以下からご応募ください!