ClusterAPIの変遷 〜v1alpha1からv1alpha2・v1alpha3へ〜

8月末から9月にかけてClusterAPIを触っていたのですが、それ以降の動向を追っていなかったので、まとめてみようと思います。

良くも悪くも、このプロジェクトはまだalphaリリースのみで、ここ2ヶ月でアーキテクチャのレベルでかなり更新されています。
特にv1alpha1からv1alpha2への変遷について追っていきます。

なお、本記事ではClusterAPIの変更部分に着目していきますので、
基本的な構成については言及しません。詳細については[本家レポジトリ](https://github.com/kubernetes-sigs/cluster-api)や[proposal](https://github.com/kubernetes-sigs/cluster-api/blob/master/docs/proposals/20190610-machine-states-preboot-bootstrapping.md)を参照してください。

# The Cluster API Book

[The Cluster API book](https://cluster-api.sigs.k8s.io/introduction.html)は、
ClusterAPIの構成や内部のコンポーネントなどが解説されたドキュメント群です。

開発者はだいたいこのbookや本家レポジトリを見ながら開発を進めていきます。
僕の記憶だと、9月上旬にREADMEとこのbookが改変され、その当時は真っ白なbookを拝むことができました。

それから2ヶ月ほどたった今、（あまり変化ないようにも見えますが）いくつかの情報が追加されています。
その中で、以前なかった項目があります。

[Cluster API v1alpha1 compared to v1alpha2](https://cluster-api.sigs.k8s.io/providers/v1alpha1-to-v1alpha2.html)には、v1alpha1からv1alpha2にかけての変更について記述されており、変遷を俯瞰して見ることができそうなので、これを読んでいきたいと思います。

## Providers

### v1alpha1

v1alpha1のプロバイダー[^1]について、インフラの作成やBootstrapのための環境固有の部分の実装は、ClusterAPIのコントローラーをラップしていく形で開発されていました。ここで言う環境とは、GCPやAWSなどのクラウドのことです。
[^1]: BootstrapクラスターからGCPやAWSなどの各環境に応じたインスタンスを作成し、Kubernetesのノードとして機能させるもの
以下はGCPでの例[^2]です。

[^2]: [cluster-api-provider-gcp](https://github.com/kubernetes-sigs/cluster-api-provider-gcp/tree/release-0.1)

```go

func machineProviderFromProviderSpec(providerSpec clusterv1.ProviderSpec) (*gceconfigv1.GCEMachineProviderSpec, error) {
	var config gceconfigv1.GCEMachineProviderSpec
	if err := yaml.Unmarshal(providerSpec.Value.Raw, &config); err != nil {
		return nil, err
	}
	return &config, nil
}
```

また、プロバイダーの開発者は、
Actuator[^3]の実装をClusterAPIのコントローラーと共に1つのマネージャーに登録していました。

[^3]: MachineやClusterにおいて、Creat, Delete, Updateなどを提供するインターフェース

```go
// AddToManagerFuncs is a list of functions to add all Controllers to the Manager
var AddToManagerFuncs []func(manager.Manager) error

// AddToManager adds all Controllers to the Manager
func AddToManager(m manager.Manager) error {
	for _, f := range AddToManagerFuncs {
		if err := f(m); err != nil {
			return err
		}
	}

	return nil
}
```

### v1alpha2

v1alpha1では、Bootstrap後の処理(kuberadm等)もすべて1つのマネージャーによって行われていたのに対して、v1alpha2では、Bootstrapと各環境固有の処理を分離し、3つのプロバイダーに分割されています。

* Core (Cluster API)
* Bootstrap (kubeadm)
* Infrastructure (aws, gcp, azure, vsphere, etc)

![Concept](https://cluster-api.sigs.k8s.io/images/management-cluster.svg)

#### Bootstrap provider

Bootstrapプロバイダーの役割は、v1alpha1でプロバイダー特有の部分の実装にあった、Kubeadmの処理部分を減らすことです。
v1alpha1の時は、プロバイダー実装者が毎回シェルスクリプトなどを書いていましたが、その部分を切り出して、管理しやすくしています。

また、インスタンス（クラウド上のサーバーなど）をKubernetesノードにBootstrapするために必要なデータ[^4]を生成するコントローラーを実行することが期待されています。

[^4]: machineかnodeの`role specific`の初期化情報

#### Infrastructure provider

v1alpha1で「プロバイダー」と言っていた部分はInfrastructureプロバイダーになりました[^3]。InfrastructureプロバイダーはBootstrapのデータを利用して、インフラストラクチャを
Kubernetesクラスターに変えることのできるような、特定の環境のインフラストラクチャ（ネットワーク、LB、インスタンスやサーバーなど）を生成する役割を果たします。

以上からわかるように、プロバイダーの実装者はInfrastructureの実装に集中することができBootstrapなどを再実装しなくてよくなります。

#### Cluster API

ClusterAPIのコントローラーはプロバイダーによって提供されることはなくなり、
代わりにコアタイプを担う独立したコントローラーを提供します。

* Cluster
* Machine
* MachineSet
* MachineDeployment

これらのCRDについても、それぞれv1alpha1の時にあったプロパティーは置き換えや削除、新規追加、名前の変更などがなされています。

## Actuator

### v1alpah1

Actuatorは、ClusterAPIのコントローラーが呼ぶインターフェースでした。
プロバイダーはClusterAPIのコントローラーをとってきて、Infrastructurのロジックを持ったActuatorと共にマネージャーに登録していました。

### v1alpha2

このバージョンではActuatorを利用しません。というのも、ClusterAPIのコントローラーがプロバイダー間で共有されることがなくなり、Actuatorのインターフェースを知る必要がなくなったからです。
（先述したように、Infrastructureプロバイダーがこれらの実装を担い、提供しています）

その代わり、プロバイダー同士はClusterAPIの中心的なオブジェクトであるMachineやClusterを介して、やりとりをします。

## clusterctl

v1alpha2では、`clusterctl`コマンドはプロバイダーに依存せず、複数のプロバイダー間で再利用できます。
開発者は`clusterctl`パッケージをラップしたコマンドを作成する必要がなくなりました。

# v1alpha2における今後

## v1alpha1からの移行

[announce](https://discuss.kubernetes.io/t/announce-cluster-api-v1alpha2-released/7821)にはv1alpha2へ移行するためのツールを開発している、との記載があります。
無理にv1alpha2への移行を急ぐ必要は無さそうです。

# v1alpha3へ

こちらの[proposal](https://github.com/kubernetes-sigs/cluster-api/blob/master/docs/book/src/providers/v1alpha2-to-v1alpha3.md)にてv1alpha3の概要を見ることができます。

また、[issue](https://github.com/kubernetes-sigs/cluster-api/issues)から動向を見ることができます。
いくつか気になるものをピックアップしました。

* [Support Managed Kubernetes Provider](https://github.com/kubernetes-sigs/cluster-api/issues/980)
    * コントロールプレーンとして、EKSやGKEなどのサポートをしようというissue
    * 現時点ではMachine-basedのみサポート
    * 今後、Managed-service・Pod-based[^5]もサポート？
* [machine-controller problem self-detection](https://github.com/kubernetes-sigs/cluster-api/issues/1078)
    * machineコントローラーにCreateなどの処理が滞っていることを検知する機構を導入するissue
    * より早く、処理の停滞を検知できるかも
* [v1alpha2 infrastructure provider scaffolding](https://github.com/kubernetes-sigs/cluster-api/issues/1113)
    * これは是非とも作成していただきたい......！
* [Easier, simplified UX for cluster and machine creation](https://github.com/kubernetes-sigs/cluster-api/issues/1227)
    * ClusterやMachineのUX改善
* [Separate client vs provider APIEndpoints fields](https://github.com/kubernetes-sigs/cluster-api/issues/1197)

総じて、ドキュメントの更新に関するissueが多い印象を受けました。
上記で挙げた他にも、Clusterのインフラ部分を分割(LB, Network, Firewall)したり、クラスターに属しているリソース全てにラベルを付与して、ツールの開発をしやすくしたりと、様々なissueが提示されています。

また時間のある時に漁ってみようと思います。

[^5]: https://discuss.kubernetes.io/t/cluster-api-controlplane-lifecycle-management-workstream/5956/2?u=ncdc