Cluster API operator で宣言的に k8s クラスタを作成する
概要
Cluster API は様々なクラウド上に k8s クラスタを展開・管理するための k8s サブプロジェクトです。cluster API 固有のカスタムリソースを使うことで以下のようなリソースを管理できます。
- クラスタ用のノードやスケーリング
- クラスタが稼働するネットワーク、ロードバランサー等のインフラ
- ノードの bootstrap 処理
カスタムリソースの管理がそのまま上記のリソース管理につながるため、インフラも含めてクラスタのライフサイクルをより柔軟に管理できるようになっています。また、provider と呼ばれるカスタムリソースによって複数のクラウド上におけるクラスタを一元的に管理できるようなメリットもあります。
前に書いた Flatcar Container Linux を試してみる の記事では cluster API を使って flatcar container linux ノードからなるクラスタを openstack 上に作成しました。このときは clusterctl
を使って主に CLI からリソース作成を実行しましたが、cluster API では各種リソースのマニフェストや cluster API operator を使って宣言的にリソースを定義、管理することも可能なので、今回はそちらの内容をメインに取り扱います。
aws 上にクラスタを作成する
ここでは cluster API のマニフェストを利用した宣言的なアプローチで実際に aws 上にクラスタを作成していきます。単に作成するだけなら Cluster API の quickstart に沿って clusterctl
を使って進めていくのが楽ですが、理解を深めるために Cluster API operator を使いつつクラスタの作成に必要なリソースを確認しながら作業していきます。
事前準備
管理クラスタの準備
cluster API を使っていずれかのクラウド上にクラスタを作成するには cluster API の実行基盤となる k8s クラスタが必要となるので、管理クラスタ用の k8s クラスタを準備しておきます。
CLI インストール
cluster API では CLI から容易にクラスタを作成するためのユーティリティツール clusterctl
が提供されています。宣言的に作成する場合は必ずしも必要ではないですが、あると便利なので以下でインストールしておきます。
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.8.5/clusterctl-linux-amd64 -o clusterctl
chmod +x clusterctl
sudo mv clusterctl /usr/local/bin
また、aws 上にクラスタを展開するためには cluster API カスタムリソースの aws infrastructure provider を利用します。この際に aws での IAM 認証情報の管理を補助する clusterawsadm
が提供されているのでこちらもインストールしておきます。
curl -L https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases/download/v2.7.1/clusterawsadm-linux-amd64 -o clusterawsadm
chmod +x clusterawsadm
sudo mv clusterawsadm /usr/local/bin
IAM ロールの作成
aws infrastructure provider で AWS クラスタを作成する際はノードに IAM ロール(インスタンスプロファイル)を設定することで適切なアクセス権限を設定するようになっています。デフォルトで利用されるロールやポリシーは clusterawsadm
の bootstrap iam create-cloudformation-stack コマンドで作成できます。
# The clusterawsadm utility takes the credentials that you set as environment
# variables and uses them to create a CloudFormation stack in your AWS account
# with the correct IAM resources.
$ clusterawsadm bootstrap iam create-cloudformation-stack
これを実行すると aws 側に cloudformation スタックが作成され、その中でデフォルトの IAM ロールやロールが作成されます。ここで作成したロールは後ほどクラスタの control plane, worker 用のノードで利用されます。
Cert manager のインストール
cluster API では証明書管理に cert manager を利用しますが、これ自体は cluster API のインストール過程には含まれていないので helm で別途インストールしておきます。
helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true
Cluster API operator のインストール
はじめにまっさらな状態の k8s クラスタに cluster API operator をインストールします。
helm repo add capi-operator https://kubernetes-sigs.github.io/cluster-api-operator
helm install capi-operator capi-operator/cluster-api-operator --create-namespace -n capi-operator-system
これにより provider リソースを監視するための operator pod が作成されます。
$ k get pod
capi-operator-system capi-operator-cluster-api-operator-85bbb77577-kxkwr 1/1 Running 0 2d2h
cluster API operator は k8s でよくある operator で、cluster API の provider リソースのライフサイクルを管理するコンポーネントになっています。cluster API では コンセプト にもあるように以下 4 つの provider でクラスタ関連のカスタムリソースを管理します。
- Core Provider (cluster API 本体)
- Bootstrap Provider
- Infrastructure Provider
- ControlPlane Provider
(上記にはないですが Addon Provider (helm) も使えます)
cluster API operator では上記の provider を operator pattern で取り扱い各 provider の作成やアップグレードを容易に行えるようにする立ち位置になっています。
provider のインストール
次に管理クラスタを構成する各 provider をインストールしていきます。
Core Provider
core provider は cluster API の CRD をインストールして、カスタムリソースに応じてリソースのライフサイクル管理を行う cluster api のコアな部分の役割があります。
apiVersion: operator.cluster.x-k8s.io/v1alpha2
kind: CoreProvider
metadata:
name: cluster-api
namespace: capi-system
spec:
version: v1.4.3
上記のようなマニフェストでリソースを作成することにより、cluster API operator がこのリソース作成を検知して cluster API リソースを管理する controller manager pod が起動します。
$ k get pod
capi-system capi-controller-manager-647769958c-xrsfg 1/1 Running 0 26h
Bootstrap Provider
Bootstrap Provider ではクラスタ証明書の作成や control plane の bootstrap 等の処理を管理します。kubeadm init のような bootstrap 処理に対応。
cluster API における provider はあくまでインターフェースのようなものであり、provider の実装はそれぞれの機能に特化したいろいろなプロジェクトのツールを利用できるようになっています。
例えば BootstrapProvider の実装では事前定義済みの以下のツールが利用できます。
- Amazon Elastic Kubernetes Service (EKS)
- Kubeadm
- MicroK8s
- Oracle Cloud Native Environment (OCNE)
- Talos
- K3s
- k0smotron/k0s
各 provider がサポートしている実装の一覧は https://cluster-api.sigs.k8s.io/reference/providers を参照。
ここでは BootstrapProvider に kubeadm を使います。マニフェストは以下。
apiVersion: operator.cluster.x-k8s.io/v1alpha2
kind: BootstrapProvider
metadata:
name: kubeadm
namespace: capi-kubeadm-bootstrap-system
spec:
version: v1.8.5
内部的には metadata.name
が ここ にある事前定義済み provider のリストに一致する場合は指定した provider が自動で選択され、それ以外の場合にはカスタム provider としてインストール処理が行われるようです。kubeadm
は bootstrapprovider のリストにあるので自動で検出されてインストールされます。
インストールが完了すると kubeadm bootstrap provider の controller pod が起動し、この中で bootstrapprovider 関連の CRD のインストールが実行されます。
NAME READY STATUS RESTARTS AGE
capi-kubeadm-bootstrap-controller-manager-6c46687b5d-7rth5 1/1 Running 0 4h32m
Controlplane Provider
control plane provider ではクラウド上に展開したクラスタの control plane の管理(ノードの追加やクラスタの kubernetes バージョンのアップグレードなど)を担当します。
こちらも bootstrapprovider と同じ kubeadm を使用します。
apiVersion: operator.cluster.x-k8s.io/v1alpha2
kind: ControlPlaneProvider
metadata:
name: kubeadm
namespace: capi-kubeadm-control-plane-system
spec:
version: v1.4.3
Infrastructure Provider
Infrastructure Provider はクラスタ用のノードやインフラストラクチャを管理するコンポーネントとなっています。各クラウド上のノード、ネットワーク、セキュリティグループ、ロードバランサーなど様々なリソースのライフサイクルを管理するため、こちらも cluster API におけるコアな基盤のひとつになっています。InfrastructureProvider は各種クラウドに対応するので provider の中でも定義済み provider が最も多く、現時点で以下のクラウドがサポートされています。
リスト
- Akamai (Linode)
- AWS
- Azure
- Azure Stack HCI
- Bring Your Own Host (BYOH)
- CloudStack
- CoxEdge
- DigitalOcean
- Equinix Metal (formerly Packet)
- Google Cloud Platform (GCP)
- Hetzner
- Hivelocity
- IBM Cloud
- IONOS Cloud
- KubeKey
- KubeVirt
- MAAS
- Metal3
- Microvm
- Nested
- Nutanix
- Oracle Cloud Infrastructure (OCI)
- OpenStack
- Outscale
- Proxmox
- Sidero
- Tinkerbell
- vcluster
- Virtink
- VMware Cloud Director
- vSphere
- Vultr
- k0smotron RemoteMachine (SSH)
今回は aws 上にクラスタを展開するので AWS infrastructure provider を使用します。
aws infrastructure provider では aws 関連のカスタムリソースが変更された際に aws の API を実行してリソースを管理するため、API を実行する IAM 認証情報が必要になります。
なので予め aws 側で IAM ユーザー等を作成し、その認証情報(aws_access_key_id, aws_secret_access_key) を以下のコマンドで base64 encode して AWS_B64ENCODED_CREDENTIALS
に代入します。
export AWS_REGION=ap-northeast-1
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=yyy
export AWS_B64ENCODED_CREDENTIALS=$(clusterawsadm bootstrap credentials encode-as-profile)
上記は cluster API のクイックスタートで記載されている方法ですが、clusterawsadm bootstrap credentials
は認証情報を base64 encode しているだけなのでファイルに保存して base64
コマンドで encode する方法でも代用できます。
aws_access_key_id = xxx
aws_secret_access_key = xxx
region = ap-northeast-1
cat credential | base64 | tr -d '\n'
この認証情報を secret に保存します。
apiVersion: v1
kind: Secret
metadata:
name: aws-variables
namespace: capa-system
type: Opaque
data:
AWS_B64ENCODED_CREDENTIALS: ...
InfrastructureProvider
では configSecret
に上記で作成した secret を指定します。
---
apiVersion: operator.cluster.x-k8s.io/v1alpha2
kind: InfrastructureProvider
metadata:
name: aws
namespace: capa-system
spec:
version: v2.1.4
configSecret:
name: aws-variables
deployment:
containers:
- name: manager
args:
# These are controller flags that are specific to a provider; usage
# is reserved for advanced scenarios only.
"--awscluster-concurrency": "12"
"--awsmachine-concurrency": "11"
上記マニフェストを適用することで aws リソースを管理するための aws controller manager pod が起動します。
$ k get pod
capa-system capa-controller-manager-55f847998b-jwnxn 1/1 Running 0 17h
Addon Provider
Addon Provider は k8s の addon を管理する provider で、現時点では addon provider helm のみが定義済みの AddonProvider になっています。
helm provider は文字通り展開先のクラスタ上で helm chart をインストールしたり削除する機能を持ちます。これにより helm chart でインストール可能なツールの展開や削除・バージョンアップなどの作業を自動化できます。
helm provider は以下のマニフェストでインストールできます(ちなみに capph
は cluster api add-on provider helm の頭文字らしい)。
apiVersion: operator.cluster.x-k8s.io/v1alpha2
kind: AddonProvider
metadata:
name: helm
namespace: caaph-system
spec:
version: v0.2.6
以上で今回の検証で使用する provider の準備ができて管理クラスタが完成しました。この時点で各 namespace 内に provider に対応する controller manager pod が作成され、cluster API 関連のリソースの作成に応じてクラスタの展開などを行います。
NAMESPACE NAME READY STATUS RESTARTS AGE
caaph-system caaph-controller-manager-56869c9964-tzjr9 1/1 Running 0 5h22m
capa-system capa-controller-manager-55f847998b-7cp5w 1/1 Running 0 5h22m
capi-kubeadm-bootstrap-system capi-kubeadm-bootstrap-controller-manager-6c46687b5d-7rth5 1/1 Running 0 5h22m
capi-kubeadm-control-plane-system capi-kubeadm-control-plane-controller-manager-6cd976b78c-cp4fp 1/1 Running 0 5h22m
capi-operator-system capi-operator-cluster-api-operator-85bbb77577-kxkwr 1/1 Running 0 5h57m
capi-system capi-controller-manager-c54fb98f4-ghj4m 1/1 Running 0 5h23m
クラスタ control plane の作成
cluster API の管理クラスタのセットアップが完了したので、次にワークロードクラスタを作成するためのリソースを作っていきます。
クイックスタートでは clusterctl generate cluster
コマンドでクラスタ作成用のマニフェストがいい感じに作成されるのでそのまま kubectl apply
することで手早くクラスタを作成できるのですが、ここではマニフェスト内で定義されているリソースを確認しながらクラスタを作っていきます。
cluster API では k8s クラスタを表現するためのリソースは kind: Cluster
となっています。
kind: Cluster
apiVersion: cluster.x-k8s.io/v1beta1
metadata:
name: my-cluster
namespace: capa-system
spec:
infrastructureRef:
kind: AWSCluster
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
name: my-cluster-aws
controlPlaneRef:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
name: aws-control-plane
cluster のプロパティの定義は kubernetes-sigs/cluster-api@v1.8.5 にありますが、上記のように infrastructureRef
と controlPlaneRef
が定義されていればひとまず動くものは作れます。
infrastructureRef でどのクラウド上でクラスタを作成するかといったインフラに関する情報を表し、具体的なプロパティはクラウド毎に固有の別リソースで定義します。aws の場合は AWSCluster が対応。
controlPlaneRef ではクラスタの control plane に関する情報を記述します。こちらも具体的な設定は KubeadmControlPlane リソースに書きます。
AWS Cluster
AWSCluster
リソースは aws 上でクラスタを作成するための環境を定義する aws provider 固有のカスタムリソースとなっています。
AWSCluster では VPC やサブネット、セキュリティグループなどクラスタを動かすために必要となるインフラを自動で作成してくれるようになっていますが、リソース定義の spec
でいろいろな項目をカスタマイズできるようになっています。https://cluster-api-aws.sigs.k8s.io/topics/bring-your-own-aws-infrastructure ではいろいろなカスタマイズ例が記載されています。
デフォルトの設定では aws 上に以下のリソースが自動で作成されます。
- vpc x1
- パブリックサブネット x3
- プライベートサブネット x3
- インターネットゲートウェイ
- NAT gateway x3
- ルートテーブル x6
- セキュリティグループ x4
- LB 用
- control plane 用
- ノード用
- api server 用
- Classic Load Balancer (CLB)
この設定をそのまま使ってもいいですが、今回は以下のカスタマイズを行います。
-
region: ap-northeast-1
- リソースを作成するリージョンを指定
-
network.vpc.availabilityZoneUsageLimit: 2
- サブネット数を 2 にする。ロードバランサーを使うので最小が 2
-
sshKeyName: [ssh-keyname]
- ノードに ssh する場合は ssh keypair 名を指定。key pair は事前に作成しておく。
-
controlPlaneLoadBalancer.loadBalancerType: nlb
- CLB は既に非推奨なので NLB を使うように切り替え。
マニフェストは以下のようになります。
kind: AWSCluster
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
metadata:
name: my-cluster-aws
namespace: capa-system
spec:
region: ap-northeast-1
sshKeyName: (ssh-keyname)
controlPlaneLoadBalancer:
loadBalancerType: nlb
network:
vpc:
availabilityZoneSelection: Ordered
availabilityZoneUsageLimit: 2
KubeadmControlPlane
KubeadmControlPlane
リソースは kubeadm controlplane provider 固有のリソースでクラスタの control plane を kubeadm で管理するための設定を記述します。
これに関してはあまり詳細な設定が見つかりませんでしたが、クイックスタートで作成されるマニフェストを見てみると以下のような形式になっています。
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
name: aws-control-plane
namespace: capa-system
spec:
kubeadmConfigSpec:
clusterConfiguration:
apiServer:
extraArgs:
cloud-provider: external
controllerManager:
extraArgs:
cloud-provider: external
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
name: '{{ ds.meta_data.local_hostname }}'
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
name: '{{ ds.meta_data.local_hostname }}'
machineTemplate:
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
name: aws-control-plane
replicas: 1
version: v1.30.5
kubeadmConfigSpec 内の initConfiguration, joinConfiguration は文字通り kubeadm init
や kubeadm join
で control plane ノードを追加するときの設定に対応します。
machineTemplate は control plane を構成するノード (VM) のプロパティを記述します。ここでも具体的な設定は AWSMachineTemplate
という aws infra provider 固有の別リソースで定義して参照する形式となっています。
基本的にクイックスタートのマニフェストをそのまま使用する形式で問題ないですが、今回の用途に合わせて以下の部分を変更・追加します。
-
networking.podSubnet: "10.244.0.0/16"
- 明示的に指定しないと node の spec に podSubnet が設定されない。この状態では後述する flannel のインストールがうまく行かなかったのでここで明示的に指定する。
spec:
kubeadmConfigSpec:
clusterConfiguration:
apiServer:
extraArgs:
cloud-provider: external
controllerManager:
extraArgs:
cloud-provider: external
networking:
podSubnet: "10.244.0.0/16"
-
replicas: 1
- control plane 用のノードの台数。多いとコストが増えるので 1 に設定。
-
version: v1.30.5
- クラスタの kubernetes のバージョンを v1.30.5 に設定。
AWSMachineTemplate
cluster API ではノード (VM) のイメージやスペック、情報などを定義する Machine リソース があります。ただ実際のプロパティは展開先のクラウドに依存する部分が多いので、具体的な設定は各 infrastructure provider に固有のカスタムリソース上で定義し、machine リソースでは infrastructureRef でその情報を参照する構成になっています。そして aws provider でノードの設定を定義するためのリソースが AWSMachineTemplate となっています。
AWSMachineTemplate
ではノードに使用する AMI やインスタンスタイプなど AWS 固有の EC2 インスタンスに関する設定を行います。EC2 インスタンスの設定だけあって様々な項目がカスタマイズできるようになっていますが、ここでは以下の設定を行います。サポートされているフィールドは https://cluster-api-aws.sigs.k8s.io/crd/#infrastructure.cluster.x-k8s.io/v1beta1.AWSMachineTemplateResource を参照。
-
iamInstanceProfile: control-plane.cluster-api-provider-aws.sigs.k8s.io
- インスタンスに設定されるインスタンスプロファイルを指定。これは事前準備の
clusterawsadm bootstrap iam create-cloudformation-stack
内で作成される。
- インスタンスに設定されるインスタンスプロファイルを指定。これは事前準備の
-
instanceType: t2.medium
- 検証なので小さめのインスタンスを選択してコストを節約。
-
sshKeyName
- ノードに ssh するための ssh keypair を指定。
Published AMIs によると AMI を指定しない場合は cluster API 用のパブリック AMI を自動で選択するようになっているみたいですが、実際試してみると ami が見つけられずエラーとなることがあったので ami.id
でインスタンスの AMI を明示的に指定します。
clusterawsadm ami list
を実行すると k8s バージョン毎に利用可能なパブリック AMI の一覧が取得できます。
$ clusterawsadm ami list
KUBERNETES VERSION REGION OS NAME AMI ID
v1.30.5 ap-northeast-1 ubuntu-24.04 capa-ami-ubuntu-24.04-v1.30.5-1728924607 ami-09a92f3026810e9f2
v1.30.5 ap-northeast-1 ubuntu-22.04 capa-ami-ubuntu-22.04-v1.30.5-1728920688 ami-09122308bcde879e4
v1.30.5 ap-northeast-1 flatcar-stable capa-ami-flatcar-stable-v1.30.5-1728926211 ami-0b81c1f65029d1a0a
v1.30.2 ap-northeast-1 ubuntu-24.04 capa-ami-ubuntu-24.04-v1.30.2-1729082892 ami-01bf294409a2c9d81
v1.30.2 ap-northeast-1 ubuntu-22.04 capa-ami-ubuntu-22.04-v1.30.2-1729078952 ami-078c506c537e24edd
v1.30.2 ap-northeast-1 flatcar-stable capa-ami-flatcar-stable-v1.30.2-1729094390 ami-062493054dbc3c4d6
v1.29.9 ap-northeast-1 ubuntu-24.04 capa-ami-ubuntu-24.04-v1.29.9-1728670729 ami-028f63e957acb2bd5
v1.29.9 ap-northeast-1 ubuntu-22.04 capa-ami-ubuntu-22.04-v1.29.9-1728669184 ami-0f677c9f38a2afede
v1.29.9 ap-northeast-1 flatcar-stable capa-ami-flatcar-stable-v1.29.9-1728672309 ami-04e24db7c2817bc76
v1.29.8 ap-northeast-1 ubuntu-24.04 capa-ami-ubuntu-24.04-v1.29.8-1729074685 ami-0de86d149aaaa25be
v1.29.8 ap-northeast-1 ubuntu-22.04 capa-ami-ubuntu-22.04-v1.29.8-1729071846 ami-0a1447ec5d15ad6d8
v1.29.8 ap-northeast-1 flatcar-stable capa-ami-flatcar-stable-v1.29.8-1729076396 ami-00853021326bce295
v1.29.7 ap-northeast-1 ubuntu-24.04 capa-ami-ubuntu-24.04-v1.29.7-1729177869 ami-05e360b1eb1c2f074
v1.29.7 ap-northeast-1 ubuntu-22.04 capa-ami-ubuntu-22.04-v1.29.7-1729176322 ami-0428bf6453b1ed71d
v1.29.7 ap-northeast-1 flatcar-stable capa-ami-flatcar-stable-v1.29.7-1729181280 ami-032c045b8e02f5259
今回は v1.30.5 のクラスタを作ろうとしているので、選択肢としては上から 3 つの v1.30.5 用の ubuntu-24.04, ubuntu-22.04, flatcar-stable があります。ここでは ubuntu-24.04 の ami-09a92f3026810e9f2
を使うことにします。
これらの設定を考慮したマニフェストは以下。
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
metadata:
name: aws-control-plane
namespace: capa-system
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
spec:
template:
spec:
iamInstanceProfile: control-plane.cluster-api-provider-aws.sigs.k8s.io
instanceType: t2.medium
sshKeyName: [ssh_keyname]
ami:
id: "ami-09a92f3026810e9f2"
まとめ
以上をまとめると、aws に必要なインフラと k8s クラスタ (control plane) を作成するためのマニフェストは以下のようになります。
マニフェスト
kind: AWSCluster
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
metadata:
name: my-cluster-aws
namespace: capa-system
spec:
region: ap-northeast-1
sshKeyName: [keyname]
controlPlaneLoadBalancer:
loadBalancerType: nlb
network:
vpc:
availabilityZoneSelection: Ordered
availabilityZoneUsageLimit: 2
---
kind: Cluster
apiVersion: cluster.x-k8s.io/v1beta1
metadata:
name: my-cluster
namespace: capa-system
spec:
infrastructureRef:
kind: AWSCluster
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
name: my-cluster-aws
controlPlaneRef:
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
name: aws-control-plane
---
apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
name: aws-control-plane
namespace: capa-system
spec:
kubeadmConfigSpec:
clusterConfiguration:
apiServer:
extraArgs:
cloud-provider: external
controllerManager:
extraArgs:
cloud-provider: external
networking:
podSubnet: "10.244.0.0/16"
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
name: "{{ ds.meta_data.local_hostname }}"
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
name: "{{ ds.meta_data.local_hostname }}"
machineTemplate:
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
name: aws-control-plane
replicas: 1
version: v1.30.5
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
metadata:
name: aws-control-plane
namespace: capa-system
spec:
template:
spec:
iamInstanceProfile: control-plane.cluster-api-provider-aws.sigs.k8s.io
instanceType: t2.medium
sshKeyName: [keyname]
ami:
id: "ami-09a92f3026810e9f2"
これを適用すると、aws infrastructure controller pod がリソースの作成を検知して aws 上に各種インフラ等を作成します。pod ログを見ることでリソースが順次作成されていく様子が確認できます。
I1114 15:54:53.304864 1 logger.go:67] "Created subnet" controller="awscluster" controllerGroup="infrastructure.cluster.x-k8s.io" controllerKind="AWSCluster" AWSCluster="capa-system/my-cluster-aws" namespace="capa-system" name="my-cluster-aws" reconcileID="a1d1af43-7565-48d6-8657-099172fefebc" cluster="capa-system/my-cluster" id="subnet-044e6839f7291a990" public=true az="ap-northeast-1a" cidr="10.0.0.0/19" ipv6=false ipv6-cidr=""
I1114 15:54:53.992968 1 logger.go:67] "Created subnet" controller="awscluster" controllerGroup="infrastructure.cluster.x-k8s.io" controllerKind="AWSCluster" AWSCluster="capa-system/my-cluster-aws" namespace="capa-system" name="my-cluster-aws" reconcileID="a1d1af43-7565-48d6-8657-099172fefebc" cluster="capa-system/my-cluster" id="subnet-089f85c5a7283a2f4" public=false az="ap-northeast-1a" cidr="10.0.64.0/18" ipv6=false ipv6-cidr=""
I1114 15:54:54.492166 1 logger.go:67] "Created subnet" controller="awscluster" controllerGroup="infrastructure.cluster.x-k8s.io" controllerKind="AWSCluster" AWSCluster="capa-system/my-cluster-aws" namespace="capa-system" name="my-cluster-aws" reconcileID="a1d1af43-7565-48d6-8657-099172fefebc" cluster="capa-system/my-cluster" id="subnet-0b16b0de8a5313f97" public=true az="ap-northeast-1c" cidr="10.0.32.0/19" ipv6=false ipv6-cidr=""
I1114 15:54:55.253627 1 logger.go:67] "Created subnet" controller="awscluster" controllerGroup="infrastructure.cluster.x-k8s.io" controllerKind="AWSCluster" AWSCluster="capa-system/my-cluster-aws" namespace="capa-system" name="my-cluster-aws" reconcileID="a1d1af43-7565-48d6-8657-099172fefebc" cluster="capa-system/my-cluster" id="subnet-014bd88cea2db893d" public=false az="ap-northeast-1c" cidr="10.0.128.0/18" ipv6=false ipv6-cidr=""
インフラ作成では NLB 作成 ~ アクティブになるのが一番時間がかかるためその過程で pod にエラー等が出力されますが、アクティブになるとそのまま EC2 インスタンス作成や control plane bootstrap の処理が続行されます。内部的には Bootstrap provider が kubeadm の bootstrap、control plane provider が control plane の管理を行うため、これらの controller pod ログでも各リソース作成の処理が進んでいることが確認できます。
I1114 15:59:50.650716 1 kubeadmconfig_controller.go:394] "Creating BootstrapData for the first control plane" controller="kubeadmconfig" controllerGroup="bootstrap.cluster.x-k8s.io" controllerKind="KubeadmConfig" KubeadmConfig="capa-system/aws-control-plane-q4bts" namespace="capa-system" name="aws-control-plane-q4bts" reconcileID=ef0b41b4-5c64-4faa-ae71-56c3addd6fed Machine="capa-system/aws-control-plane-pjq7k" Machine="capa-system/aws-control-plane-pjq7k" resourceVersion="3731" Cluster="capa-system/my-cluster"
I1114 16:01:17.158910 1 controller.go:276] "Reconcile KubeadmControlPlane" controller="kubeadmcontrolplane" controllerGroup="controlplane.cluster.x-k8s.io" controllerKind="KubeadmControlPlane" KubeadmControlPlane="capa-system/aws-control-plane" namespace="capa-system" name="aws-control-plane" reconcileID=8903f69f-3408-486c-9266-ab9b0c6699c4 Cluster="capa-system/my-cluster"
無事に処理が完了すると 1 つのノードから構成される k8s クラスタの control plane が完成します。 kubeadmcontrolplanes
の replica (ノード数) が 1 になりますが、CNI をインストールしていないのでクラスタとしてはまだ利用できずステータスは UNAVAILABLE になっています。
$ k get kubeadmcontrolplanes.controlplane.cluster.x-k8s.io
NAME CLUSTER INITIALIZED API SERVER AVAILABLE REPLICAS READY UPDATED UNAVAILABLE AGE VERSION
aws-control-plane my-cluster true 1 1 1 12m v1.30.5
クラスタにアクセスするための kubeconfig は control plane 作成に完了した時点で [cluster-name]-kubeconfig
として secret に保存されるので以下で取得できます。
k get secrets my-cluster-kubeconfig -o yaml | yq -r ".data.value" | base64 -d
これで kubectl でアクセスできます。
$ export KUBECONFIG=./kubeconfig
$ k get node
NAME STATUS ROLES AGE VERSION
ip-10-0-89-4.ap-northeast-1.compute.internal NotReady control-plane 9m4s v1.30.5
Cloud Controller のインストール
作った control plane ノードのプロパティを見てみると taint に node.cloudprovider.kubernetes.io/uninitialized
が設定されていて pod 等が配置できなくなっています。これ自体は k8s で想定されている動作のようで、cloud provider を使う場合は cloud controller manager と呼ばれるコンポーネントを使ってこのあたりを管理する必要があります。詳細は以下を参照。
今回は aws 上でクラスタを構築しているため、AWS 用の cloud provider である cloud-provider-aws をインストールする必要があります。
一方で aws cloud controller は helm chart があるので helm でインストールできます。
作成したクラスタ上に helm chart をインストールしたい場合は helm addon provider の HelmChartProxy
リソースが利用できます。
HelmChartProxy では以下のように chart の repo url や release name 等を指定してデプロイします。これを作成すると helm addon provider がリソース作成を検知し、clusterSelector
で指定したクラスタ上に helm chart をインストールします( matchLabels: {}
の場合はすべてのクラスタが対象になる)。
apiVersion: addons.cluster.x-k8s.io/v1alpha1
kind: HelmChartProxy
metadata:
name: cloud-controller-manager
namespace: capa-system
spec:
clusterSelector:
matchLabels: {}
releaseName: aws-cloud-controller-manager
repoURL: https://kubernetes.github.io/cloud-provider-aws
chartName: aws-cloud-controller-manager
namespace: kube-system
というわけで HelmChartProxy を使って aws cloud controller をインストールすれば ok ですが、実際に試すと pod が正常に起動せずにエラーとなりました、quick start のマニフェストと比較しながら原因を調べると、どうやら helm chart では pod の引数と SA に関連づく ClusterRole system:cloud-controller-manage
で以下の権限が不足しているため controller manager のコンテナがエラーで終了しているようでした。
# コンテナの引数の差分
args:
- --v=2
- --cloud-provider=aws
+ - --use-service-account-credentials=true
+ - --configure-cloud-routes=false
# clusterRole の差分
clusterRoleRules:
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
+ - get
+ - list
+ - watch
HelmChartProxy では valuesTemplate
で chart value の値を上書きすることができるので (helm install の -f values.yml
と同じ)、values.yml の clusterRole に相当する部分を追加します。
修正後の HelmChartProxy
apiVersion: addons.cluster.x-k8s.io/v1alpha1
kind: HelmChartProxy
metadata:
name: cloud-controller-manager
namespace: capa-system
spec:
clusterSelector:
matchLabels: {}
releaseName: aws-cloud-controller-manager
repoURL: https://kubernetes.github.io/cloud-provider-aws
chartName: aws-cloud-controller-manager
namespace: kube-system
valuesTemplate: |
clusterRoleRules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- '*'
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- ""
resources:
- services
verbs:
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- services/status
verbs:
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- get
- list
- watch
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- get
- list
- watch
- update
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- get
- list
- watch
- update
- apiGroups:
- ""
resources:
- serviceaccounts/token
verbs:
- create
- apiGroups:
- authentication.k8s.io
resources:
- tokenreviews
verbs:
- create
- apiGroups:
- authorization.k8s.io
resources:
- subjectaccessreviews
verbs:
- create
これで再度適用することで正常にインストールできました。
CNI のインストール
クラスタを使うには CNI のインストールが必要です。クイックスタートでは github 上のマニフェストを使って calico をインストールしていますが、ここではせっかくなので HelmChartProxy で flannel をインストールします。
apiVersion: addons.cluster.x-k8s.io/v1alpha1
kind: HelmChartProxy
metadata:
name: flannel
namespace: capa-system
spec:
clusterSelector:
matchLabels: {}
releaseName: flannel
repoURL: https://flannel-io.github.io/flannel/
chartName: flannel
namespace: kube-flannel
これでクラスタ内のノードに IP address が割り振られて正常に使用できようになります。
worker node の追加
作成したクラスタにはまだ worker node がないので MachineDeployment リソースを作成して worker node をクラスタに追加します。
Machine Deployment
MachineDeployment
はクラスタ内のノードを管理するためのリソースとなっています。
k8s では pod を管理するためのリソースに deployment - replicaset - pod の関係がありますが、 cluster API では machinedeployment - machineset - machine がこの関係に対応しています。pod をノード (VM) に置き換えればだいたい同じ概念が通用します。
MachineDeployment リソースによって作成されたノードは worker node としてクラスタに追加されますが、その際の bootstrap などの設定を bootstrap.configRef
で指定します。VM のスペック等は control plane と同様に infrastructureRef
で参照します。
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
name: md
namespace: capa-system
spec:
clusterName: my-cluster
replicas: 1
selector:
matchLabels: null
template:
spec:
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
name: aws-ct
clusterName: my-cluster
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
name: aws-mt-worker
version: v1.30.5
今回は control plane と worker node で特に設定を変えないので、AWSMachineTemplate と KubeadmConfigTemplate は control plane に指定したものとほぼ同じように設定します。
マニフェスト
apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
name: md
namespace: capa-system
spec:
clusterName: my-cluster
replicas: 1
selector:
matchLabels: null
template:
spec:
bootstrap:
configRef:
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
name: aws-ct
clusterName: capi-quickstart
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
name: aws-mt-worker
version: v1.30.5
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSMachineTemplate
metadata:
name: aws-mt-worker
namespace: capa-system
spec:
template:
spec:
iamInstanceProfile: nodes.cluster-api-provider-aws.sigs.k8s.io
instanceType: t2.medium
sshKeyName: docker_aws
ami:
id: "ami-09a92f3026810e9f2"
---
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
metadata:
name: aws-ct
namespace: capa-system
spec:
template:
spec:
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
cloud-provider: external
name: "{{ ds.meta_data.local_hostname }}"
このリソースをデプロイ後、作成したクラスタを見ると worker node が 1 台追加されていることが確認できます。
$ k get node
NAME STATUS ROLES AGE VERSION
ip-10-0-81-101.ap-northeast-1.compute.internal NotReady <none> 47s v1.30.5
ip-10-0-89-4.ap-northeast-1.compute.internal NotReady control-plane 14m v1.30.5
一方で cluster API 側から見た worker node のデプロイ状況は machinedeployments リソースの replica で確認できます。
$ k get machinedeployments.cluster.x-k8s.io
NAME CLUSTER REPLICAS READY UPDATED UNAVAILABLE PHASE AGE VERSION
md my-cluster 1 1 1 ScalingUp 2m27s v1.30.5
これで worker node の追加も完了したので、後は通常の k8s クラスタと同様に pod などを配置できます。
クリーンアップ
作ったリソースを削除する場合はそのまま Cluster や AWSCluster などのカスタムリソースを削除すれば ok です。
$ k delete -f aws-cluster
awscluster.infrastructure.cluster.x-k8s.io "my-cluster-aws" deleted
cluster.cluster.x-k8s.io "my-cluster" deleted
kubeadmcontrolplane.controlplane.cluster.x-k8s.io "aws-control-plane" deleted
awsmachinetemplate.infrastructure.cluster.x-k8s.io "aws-control-plane" deleted
helmchartproxy.addons.cluster.x-k8s.io "cloud-controller-manager" deleted
helmchartproxy.addons.cluster.x-k8s.io "flannel" deleted
awsmachinetemplate.infrastructure.cluster.x-k8s.io "aws-mt-worker" deleted
kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io "aws-ct" deleted
Error from server (NotFound): error when deleting "aws-cluster/worker.yml": machinedeployments.cluster.x-k8s.io "md" not found
場合によっては削除実行時にプロンプトがしばらく返ってきませんが、この裏では provider がリソースの削除を検知して aws 側のリソースを削除する処理を実行しています。aws infrastructure provider pod ログを見ることで VPC やロードバランサー、EC2 インスタンスの削除が行われている様子が確認できます。aws 側リソースの依存関係も考慮しながら削除するため結構時間がかかりますが、最終的に VPC まで削除されれば作成したリソースのクリーンアップが完了となります。
Argocd でデプロイする
上で見たようにクラスタの展開に必要なリソースのプロパティを 1 つずつ設定していくのはけっこう面倒なので、シンプルな用途であれば clusterctl
を使ってデプロイする方が楽です。一方で operator やマニフェストを使って宣言的にクラスタを管理する方法では以下のようなメリットがあります。
- マニフェストに対して linter やポリシーチェックが実行でき、リソースをより厳密に管理できる。
- argocd などのデプロイツールと統合してクラスタのライフサイクル管理を GitOps で自動化する。
要は宣言的に記述できるので IaC の管理方法や利点を享受できる点が強みとなります。
ここでは Argocd を使って今までのクラスタ展開作業を自動化してみます。
ディレクトリ構成は以下。
.
├── argocd
│ ├── aws-cluster.yml
│ ├── cert-manager.yml
│ ├── cluster-api-operator.yml
│ ├── management.yml
├── aws-cluster
│ ├── control-plane.yml
│ ├── helm-cloud-controller.yml
│ ├── helm-flannel.yml
│ └── worker.yml
└── management-cluster
└── provider.yml
-
management-cluster
では管理クラスタを構成するための provider をインストール -
aws-cluster
では aws 上に control plane + worker node のクラスタを作成 -
argocd
では上記リソースを展開する argocd project を定義。
各マニフェストは github にも保存してあります。
今まで使っていた管理クラスタを一度まっさらな状態にして、管理クラスタの構築から AWS 上へのクラスタ展開までを argocd 経由で行います。まずはじめに cert manager と cluster api operator を argocd で helm を使ってインストール。
$ k apply -f argocd/cert-manager.yml
$ k apply -f argocd/cluster-api-operator.yml
$ argocd app sync argocd/cert-manager
$ argocd app sync argocd/capi-operator
次に management-cluster project を sync して管理クラスタを構築します。
$ k apply -f argocd/management.yml
$ argocd app sync argocd/management-cluster.yml
正常に完了すると、管理クラスタ上に各種 provider の CRD がインストールされます。
$ k get customresourcedefinitions.apiextensions.k8s.io \
addonproviders.operator.cluster.x-k8s.io \
infrastructureproviders.operator.cluster.x-k8s.io \
coreproviders.operator.cluster.x-k8s.io \
bootstrapproviders.operator.cluster.x-k8s.io \
controlplaneproviders.operator.cluster.x-k8s.io
NAME CREATED AT
addonproviders.operator.cluster.x-k8s.io 2024-11-16T08:47:45Z
infrastructureproviders.operator.cluster.x-k8s.io 2024-11-16T08:47:45Z
coreproviders.operator.cluster.x-k8s.io 2024-11-16T08:47:45Z
bootstrapproviders.operator.cluster.x-k8s.io 2024-11-16T08:47:45Z
controlplaneproviders.operator.cluster.x-k8s.io 2024-11-16T08:47:45Z
$ k get addonproviders,infrastructureproviders,coreproviders,bootstrapproviders,controlplaneproviders -A
NAMESPACE NAME INSTALLEDVERSION READY
caaph-system addonprovider.operator.cluster.x-k8s.io/helm v0.2.6 True
NAMESPACE NAME INSTALLEDVERSION READY
capa-system infrastructureprovider.operator.cluster.x-k8s.io/aws v2.1.4 True
NAMESPACE NAME INSTALLEDVERSION READY
capi-system coreprovider.operator.cluster.x-k8s.io/cluster-api v1.4.3 True
NAMESPACE NAME INSTALLEDVERSION READY
capi-kubeadm-bootstrap-system bootstrapprovider.operator.cluster.x-k8s.io/kubeadm v1.4.3 True
NAMESPACE NAME INSTALLEDVERSION READY
capi-kubeadm-control-plane-system controlplaneprovider.operator.cluster.x-k8s.io/kubeadm v1.4.3 True
controller manager pod も起動します。
NAMESPACE NAME READY STATUS RESTARTS AGE
caaph-system caaph-controller-manager-56869c9964-tzjr9 1/1 Running 0 31s
capa-system capa-controller-manager-55f847998b-7cp5w 1/1 Running 0 24s
capi-kubeadm-bootstrap-system capi-kubeadm-bootstrap-controller-manager-6c46687b5d-7rth5 1/1 Running 0 30s
capi-kubeadm-control-plane-system capi-kubeadm-control-plane-controller-manager-6cd976b78c-cp4fp 1/1 Running 0 29s
capi-operator-system capi-operator-cluster-api-operator-85bbb77577-kxkwr 1/1 Running 0 35m
capi-system capi-controller-manager-c54fb98f4-ghj4m 1/1 Running 0 59s
これで管理クラスタの構築は完了です。
次に aws cluster project を sync して aws 上にクラスタを作成します。
$ k apply -f argocd/aws-cluster.yml
$ argocd app sync argocd/aws-cluster
インフラ構築 ~ control plane 作成 ~ worker node 追加まで実行するので結構時間がかかりますが、クラスタに必要な各リソースが自動で作成されます。すべての作業が完了したら secret から kubeconfig を取得することでクラスタにアクセスできます。
$ k get secrets my-cluster-kubeconfig -o yaml | yq -r ".data.value" | base64 -d > kubeconfig
$ export KUBECONFIG=./kubeconfig
ノードの状態は Ready
$ k get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-10-0-124-217.ap-northeast-1.compute.internal Ready <none> 2m14s v1.30.5 10.0.124.217 <none> Ubuntu 24.04.1 LTS 6.8.0-1016-aws containerd://1.7.20
ip-10-0-142-70.ap-northeast-1.compute.internal Ready control-plane 3m17s v1.30.5 10.0.142.70 <none> Ubuntu 24.04.1 LTS 6.8.0-1016-aws containerd://1.7.20
pod の状態
$ k get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-flannel kube-flannel-ds-qrf6t 1/1 Running 1 (2m5s ago) 2m47s
kube-flannel kube-flannel-ds-xmrpt 1/1 Running 1 (2m42s ago) 3m23s
kube-system aws-cloud-controller-manager-xt8tp 1/1 Running 0 3m13s
kube-system coredns-55cb58b774-q6hrp 1/1 Running 0 3m42s
kube-system coredns-55cb58b774-xrbkc 1/1 Running 0 3m42s
kube-system etcd-ip-10-0-142-70.ap-northeast-1.compute.internal 1/1 Running 0 3m42s
kube-system kube-apiserver-ip-10-0-142-70.ap-northeast-1.compute.internal 1/1 Running 0 3m42s
kube-system kube-controller-manager-ip-10-0-142-70.ap-northeast-1.compute.internal 1/1 Running 0 3m42s
kube-system kube-proxy-4tqqx 1/1 Running 0 2m47s
kube-system kube-proxy-kxkv2 1/1 Running 0 3m42s
kube-system kube-scheduler-ip-10-0-142-70.ap-northeast-1.compute.internal 1/1 Running 0 3m42s
というわけで最初にマニフェストを作ってしまえばデプロイの作業は argocd で自動化でき、クラスタのライフサイクル管理も Gitops に組み込むことができます。
別クラウド上にクラスタを作成する
aws 上にクラスタを作成する際は aws infrastructure provider を利用しましたが、別のクラウド上にクラスタを追加したい場合は対応する provider をインストールしてリソースを展開することで簡単に追加できます。ここでは openstack 上に新しくクラスタを作成してみます。
openstack 上に作成する場合は openstack 用の infrastructure provider を追加する必要があります。これは argocd デプロイ時に使用したマニフェストに openstack
という名前の InfrastructureProvider
リソースを追加すれば ok。
---
apiVersion: v1
kind: Namespace
metadata:
name: capo-system
---
apiVersion: v1
kind: Secret
metadata:
name: openstack-cloud-config
namespace: capo-system
data:
cacert: ...
clouds.yaml: ...
---
apiVersion: operator.cluster.x-k8s.io/v1alpha2
kind: InfrastructureProvider
metadata:
name: openstack
namespace: capo-system
spec:
version: v0.11.2
クラスタの展開には aws クラスタと同様に control plane, worker node, CNI, cloud controller のデプロイが必要です。aws のときと比較すると AWSCluster
など aws 固有のリソースを OpenstackCluster
等 openstack 用のカスタムリソースに置き換える必要がありますが、基本的なリソースの構造は aws クラスタのときと変わらないので細かい部分は割愛します。クラスタ作成のためのリソースを新しく作った openstack-cluster
ディレクトリに入れて argocd のプロジェクトを追加します。
.
├── argocd
│ └── openstack-cluster.yml
└── openstack-cluster
├── control-plane.yml
├── helm-cloud-controller.yml
├── helm-flannel.yml
└── worker.yml
上記のマニフェストも github repo に上げてあるので詳細はそちらを参照。
クラスタ作成時は aws のときと同様に provider をインストールしたのち、上記のディレクトリを app sync します。
# openstack infrastructure provider のインストール
$ argocd app sync argocd/management-cluster.yml
# openstack cluster 作成
$ k apply -f argocd/openstack-cluster.yml
$ argocd app sync argocd/openstack-cluster.yml
少し待つと openstack 上にクラスタが作成されます。
cluster API では cluster
リソースで作成済みのクラスタを確認できます。ただ k get cluster
ではどのクラスタがどのクラウド上に展開されているかは区別できません(cluster が存在する namespace である程度推測はできますが)。
$ k get cluster -A -o wide
NAMESPACE NAME CLUSTERCLASS PHASE AGE VERSION
capa-system my-cluster Provisioned 8m10s
capo-system my-cluster2 Provisioned 8m1s
describe して infrastructure Ref などを見れば確認可能。
$ k describe cluster -A
Name: my-cluster
Namespace: capa-system
Labels: app.kubernetes.io/instance=aws-cluster
Annotations: <none>
API Version: cluster.x-k8s.io/v1beta1
Kind: Cluster
Spec:
Control Plane Ref:
API Version: controlplane.cluster.x-k8s.io/v1beta1
Kind: KubeadmControlPlane
Name: aws-control-plane
Namespace: capa-system
Infrastructure Ref:
API Version: infrastructure.cluster.x-k8s.io/v1beta2
Kind: AWSCluster
Name: my-cluster-aws
Namespace: capa-system
Name: my-cluster2
Namespace: capo-system
Labels: app.kubernetes.io/instance=openstack-cluster
cloud=openstack
Annotations: <none>
API Version: cluster.x-k8s.io/v1beta1
Kind: Cluster
Spec:
Cluster Network:
Pods:
Cidr Blocks:
192.168.0.0/16
Service Domain: cluster.local
Control Plane Endpoint:
Host: 192.168.3.195
Port: 6443
Control Plane Ref:
API Version: controlplane.cluster.x-k8s.io/v1beta1
Kind: KubeadmControlPlane
Name: openstack-control-plane
Namespace: capo-system
Infrastructure Ref:
API Version: infrastructure.cluster.x-k8s.io/v1beta1
Kind: OpenStackCluster
Name: my-cluster-openstack
Namespace: capo-system
複数クラウド上で多数のクラスタを動かすような環境ではどのクラウド上で動いているか区別できるようにリソース名やラベルを適切に設定する、用途に合わせて ClusterClass を作って割り当てるなどの工夫が必要になります。
cluster API では展開先クラスタに合わせた infrastructure provider を利用する構成となっているため、複数のクラウドに展開されたクラスタを 1 つの管理クラスタで一括で管理できるようになっています。
その他
Feature Gate の有効化
clutser API ではいくつかの機能は Feature Gate として実装されています。例えば bootstrap における ignition format のサポート などがこれに対応。
clsuterctl で各種 provider をインストールする場合は対応する機能を環境変数に設定した上で clusterctl init
を実行すれば有効化されますが、cluster API operator を使う場合は以下のように provider マニフェストの spec.manager.featureGates
に key-value で指定することで有効化されます。
spec:
manager:
featureGates:
FeatureA: true
FeatureB: false
例えば flatcar イメージでクラスタを構成する場合は ignition 形式で bootstrap を記述する必要があるため、bootstrapprovider の定義に KubeadmBootstrapFormatIgnition: true
を追加します。
apiVersion: operator.cluster.x-k8s.io/v1alpha2
kind: BootstrapProvider
metadata:
name: kubeadm
namespace: capi-kubeadm-bootstrap-system
spec:
version: v1.8.5
manager:
featureGates:
KubeadmBootstrapFormatIgnition: true
イメージのビルド
aws などのパブリッククラウドでは既に登録済みの cluster API 用のイメージを使ってノードを作成できますが、自分でビルドしたイメージを使用することもできます。
イメージ作成には以下の image-builder が活用可能。
- https://image-builder.sigs.k8s.io/capi/capi#prerequisites
- https://github.com/kubernetes-sigs/image-builder
リンク
- Cluster API ドキュメント
- Cluster API Operator ガイド
- Cluster API Operator github Getting Start
- helm addon provider github
- Cluster API AWS Infrastructure provider ドキュメント
- Cloud Provider AWS ドキュメント
- Cloud Provider AWS github
- Cluster API openstack Infrastructure provider ドキュメント
- Cluster API openstack Infrastructure provider github
- Cloud provider openstack helm chart
Discussion