こんにちは、ACS事業部の谷合です。
事業部内の有志でCluster APIを触ってまして、とりあえずAKSにCluster APIリソースをデプロイしてAKS on K8sクラスタができることを確認できたのでご紹介します。
Cluster APIとは
KubernetesのSIG Cluster Lifecycleのsubprojectであり、ホストKubernetesにKubernetesクラスタAPIのリソースを作成し、そのリソースに沿ったクラスタを自動でプロビジョニング可能とするツールです。宣言的にKubernetesクラスタを管理できることからKubernetes as a Service(以降KaaS)などのKubernetesクラスタ払い出し自動化分野で使われることが期待されます。 また、弊社はMicrosoft Partnerでありますが、Microsoftからも以下の資料のようにCluster APIに注目している旨の記事が提供されています。GitOpsでKubernetesクラスタAPIのリソースマニフェストをホストKubernetesにデプロイし、自動でクラスタ払い出しの仕組みはとても面白いですね。 cloudblogs.microsoft.com
以下のCluster API公式ドキュメントでもユースケースごとに「現時点でのプロジェクトの優先順位」が公表されており、 Managed Cluster、KaaSの順で優先度が設定されているようです。
https://cluster-api.sigs.k8s.io/user/personas.html#use-case-driven-personascluster-api.sigs.k8s.io
Cluster APIコンセプト
以下のようにnamespceごとに異なるProviderをデプロイし、各Providerが協調しながらClusterを払い出します。
各ProviderはControllerとして実装されており、CRD経由でCustomResourceを提供することでクラスタのコンポーネントを宣言的に管理しています。
このProviderについてこのセクションで触れてみます。
Infrastracture
クラスタノードの実行に必要な前提条件をすべて提供します。
例えば、VM、ネットワーク、ロードバランサー、ファイアウォールルールなどです。
主要なクラウドサービス向けのプロバイダーが公開されています。
Bootstrap
ノードのブートストラップに使用されるブートストラップデータを生成します。
kubeadmなどを使ったBootstrap手段が提供されます。
Control plane
Control planeを作成します。 以下のリソースをインスタンス化して作成するとのことです。
- etcd
- Kubernetes APIサーバー
- Kubernetes コントローラーマネージャー
- Kubernetes スケジューラ
- クラウドコントローラーマネージャー
- クラスタDNS(CoreDNSなど)
- サービスプロキシ(例:kube-proxy)
Azure用であれば、以下のCluster API Provider Azureというものが提供されており、多様な設定が可能となっています。 capz.sigs.k8s.io
Kubernetes払い出し
今回は以下の手順に沿って作業します。 cluster-api.sigs.k8s.io なお、AKSで作業を行うため、ドキュメント内のInstall clusterctlの手順からスタートします。
clusterctlインストール
まず、clusterctlコマンドをインストールします。
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.4.1/clusterctl-linux-amd64 -o clusterctl sudo install -o root -g root -m 0755 clusterctl /usr/local/bin/clusterctl clusterctl version
Feature Gateの有効化
export CLUSTER_TOPOLOGY=true
管理クラスターを初期化
初期化を行い、Cluster APIリソースをデプロイします。
サービスプリンシパル作成
作成後に出力される結果から、appIdとpasswordを控えておいてください。
export AZURE_SUBSCRIPTION_ID=$(az account show -o tsv --query id) export AZURE_TENANT_ID=$(az account show -o tsv --query tenantId) az ad sp create-for-rbac --role contributor --scopes="/subscriptions/${AZURE_SUBSCRIPTION_ID}" --display-name "capi-sp"
出力例
The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli { "appId": "d3029603-0320-4f4f-af59-1ecb75065ada", "displayName": "capi-sp", "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
環境変数設定
AZURE_CLIENT_IDとAZURE_CLIENT_SECRETには、前の作業で控えておいたappIdとpasswordを入れます。
export AZURE_CLIENT_ID=<appId> export AZURE_CLIENT_SECRET=<password> export AZURE_SUBSCRIPTION_ID_B64="$(echo -n "$AZURE_SUBSCRIPTION_ID" | base64 | tr -d '\n')" export AZURE_TENANT_ID_B64="$(echo -n "$AZURE_TENANT_ID" | base64 | tr -d '\n')" export AZURE_CLIENT_ID_B64="$(echo -n "$AZURE_CLIENT_ID" | base64 | tr -d '\n')" export AZURE_CLIENT_SECRET_B64="$(echo -n "$AZURE_CLIENT_SECRET" | base64 | tr -d '\n')" export AZURE_CLUSTER_IDENTITY_SECRET_NAME="cluster-identity-secret" export CLUSTER_IDENTITY_NAME="cluster-identity" export AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE="default"
kubectlシークレット作成
上記で設定した環境変数を使用し、シークレットを作成します。
kubectl create secret generic "${AZURE_CLUSTER_IDENTITY_SECRET_NAME}" \ --from-literal=clientSecret="${AZURE_CLIENT_SECRET}" \ --namespace "${AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE}"
初期化
clusterctl init --infrastructure azure
出力例
Fetching providers Installing cert-manager Version="v1.11.0" Waiting for cert-manager to be available... Installing Provider="cluster-api" Version="v1.0.0" TargetNamespace="capi-system" Installing Provider="bootstrap-kubeadm" Version="v1.0.0" TargetNamespace="capi-kubeadm-bootstrap-system" Installing Provider="control-plane-kubeadm" Version="v1.0.0" TargetNamespace="capi-kubeadm-control-plane-system" Installing Provider="infrastructure-docker" Version="v1.0.0" TargetNamespace="capd-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 -
初期化を行うことで、以下のようにAzure用のAPIが追加されていることが確認可能となります。
kubectl api-resources -o name | grep azure azureidentities.aadpodidentity.k8s.io azureidentitybindings.aadpodidentity.k8s.io azurepodidentityexceptions.aadpodidentity.k8s.io azureclusteridentities.infrastructure.cluster.x-k8s.io azureclusters.infrastructure.cluster.x-k8s.io azureclustertemplates.infrastructure.cluster.x-k8s.io azuremachinepoolmachines.infrastructure.cluster.x-k8s.io azuremachinepools.infrastructure.cluster.x-k8s.io azuremachines.infrastructure.cluster.x-k8s.io azuremachinetemplates.infrastructure.cluster.x-k8s.io azuremanagedclusters.infrastructure.cluster.x-k8s.io azuremanagedcontrolplanes.infrastructure.cluster.x-k8s.io azuremanagedmachinepools.infrastructure.cluster.x-k8s.io
払い出すターゲットクラスタyaml生成
環境変数設定
export AZURE_LOCATION=<リージョン> export AZURE_CONTROL_PLANE_MACHINE_TYPE="Standard_D2s_v3"※VMサイズ export AZURE_NODE_MACHINE_TYPE="Standard_D2s_v3"※VMサイズ export AZURE_RESOURCE_GROUP="<ResourceGroupName>"
クラスタyaml生成
clusterctl generate cluster capi-quickstart \ --kubernetes-version v1.27.0 \ --control-plane-machine-count=3 \ --worker-machine-count=3 \ > capi-quickstart.yaml
(オプション)ノード数を1にし、Clusterリソースのlocationをjapaneastにする
sed -i -e 's/location: centralus/location: japaneast/g' -e 's/replicas: 3/replicas: 1/g' capi-quickstart.yaml
yamlファイルは以下のようになります。
クラスタyaml適用
kubectl apply -f capi-quickstart.yaml
出力例
cluster.cluster.x-k8s.io/capi-quickstart created azurecluster.infrastructure.cluster.x-k8s.io/capi-quickstart created kubeadmcontrolplane.controlplane.cluster.x-k8s.io/capi-quickstart-control-plane created azuremachinetemplate.infrastructure.cluster.x-k8s.io/capi-quickstart-control-plane created machinedeployment.cluster.x-k8s.io/capi-quickstart-md-0 created azuremachinetemplate.infrastructure.cluster.x-k8s.io/capi-quickstart-md-0 created kubeadmconfigtemplate.bootstrap.cluster.x-k8s.io/capi-quickstart-md-0 created azureclusteridentity.infrastructure.cluster.x-k8s.io/cluster-identity created
クラスタ確認
プロビジョニングには数分かかるため、数分後に以下のコマンドでクラスタが確認可能となります。
kubectl get kubeadmcontrolplane NAME CLUSTER INITIALIZED API SERVER AVAILABLE REPLICAS READY UPDATED UNAVAILABLE AGE VERSION capi-quickstart-control-plane capi-quickstart true 1 1 1 5m36s v1.26.3
クラスタアクセス
kubeconfig生成
clusterctl get kubeconfig capi-quickstart > .kube/capi-quickstart.kubeconfig
クラスタアクセス
この時まだ、CNIがインストールされていないため、ノードはNotReadyとなっています。
export KUBECONFIG=.kube/capi-quickstart.kubeconfig kubectl config use-context=<コンテキスト> kubectl get node -owide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME capi-quickstart-control-plane-q45qm NotReady control-plane 2m34s v1.26.3 10.0.0.4 <none> Ubuntu 22.04.2 LTS 5.15.0-1034-azure containerd://1.6.19 capi-quickstart-md-0-rmbpv NotReady <none> 34s v1.26.3 10.1.0.4 <none> Ubuntu 22.04.2 LTS 5.15.0-1034-azure containerd://1.6.19
CNIインストール
今回はCalicoをインストールします。
kubectl --kubeconfig=.kube/capi-quickstart.kubeconfig \ apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml # taint削除 # ノードはWorkerNodeとします。 kubectl taint node capi-quickstart-md-0-rmbpv node.cloudprovider.kubernetes.io/uninitialized- kubectl taint node capi-quickstart-md-0-rmbpv node.cluster.x-k8s.io/uninitialized-
Node確認
kubectl get node NAME STATUS ROLES AGE VERSION capi-quickstart-control-plane-q45qm Ready control-plane 22m v1.26.3 capi-quickstart-md-0-rmbpv Ready <none> 20m v1.26.3
管理クラスタ側で再度確認すると、以下のようにクラスタが起動していることが確認できます。
$ kubectl get kubeadmcontrolplane NAME CLUSTER INITIALIZED API SERVER AVAILABLE REPLICAS READY UPDATED UNAVAILABLE AGE VERSION capi-quickstart-control-plane capi-quickstart true true 1 1 1 0 28m v1.26.3
Azureリソース確認
クラスタを払い出すと、以下のようにAzureリソースも作成されます。
この時、Control PlaneとWorkerそれぞれにVM, NIC, Disk, NSGが作成されます。
また、別でLB, Route Table, VNet, Public IPも作成されます。
名前 種類 場所 capi-quickstart-control-plane-skgrq 仮想マシン Japan East capi-quickstart-control-plane-skgrq-nic ネットワーク インターフェイス Japan East capi-quickstart-control-plane-skgrq_etcddisk ディスク Japan East capi-quickstart-control-plane-skgrq_OSDisk ディスク Japan East capi-quickstart-controlplane-nsg ネットワーク セキュリティ グループ Japan East capi-quickstart-md-0-wcr72 仮想マシン Japan East capi-quickstart-md-0-wcr72-nic ネットワーク インターフェイス Japan East capi-quickstart-md-0-wcr72_OSDisk ディスク Japan East capi-quickstart-node-nsg ネットワーク セキュリティ グループ Japan East capi-quickstart-node-routetable ルート テーブル Japan East capi-quickstart-public-lb ロード バランサー Japan East capi-quickstart-vnet 仮想ネットワーク Japan East pip-capi-quickstart-apiserver パブリック IP アドレス Japan East pip-capi-quickstart-node-subnet-natgw パブリック IP アドレス Japan East
ここまでくると、通常のKuberntestクラスタとして自由に遊べるようになります。
yaml適用でクラスタ払い出しできるなんて、便利!!!!!!
Azure Service Operatorとの違い
実は、ClusterAPIを使わずともAKS上にKubernetesクラスタ(AKS)を立てることは可能です。
これについて、Microsoftは以下のように述べています。
クラスタのテストや、設定項目の多様さはClusterAPIに分がありそうですね。
ただ、最新AKSを使えるというのはAzure Service Operatorの大きなメリットとなりそうです。
ケースバイケースで使い分けるといいでしょう。
Both are valid options to provision AKS clusters. The benefit of using CAPZ is it has several elements of testing to ensure that provisioning this specific type of IaC configuration for an AKS cluster will work. Also, it enables a consistent CAPI cluster YAML definition across cloud providers. The advantage of ASO is that it enables provisioning of whatever features are available in AKS the moment it comes out, whereas today CAPZ needs time to add and test available AKS features to fit into the requirements needed to be consistent with the cluster API framework. CAPZ does bi-weekly patch releases and major releases every two months.
なお、Azure Service Operatorは以前以下のポストで検証をしています。 techblog.ap-com.co.jp
さいごに
いかがでしたでしょうか?
Kubernetesを宣言的に管理できるというのは非常に面白みがあります。
今回はAKS on K8sクラスタを試してみましたが、次回はAKS on AKSも試してみたいと思います。
AKS on AKSは以下のドキュメントに記載ありますので、もしご興味あればご覧ください。
また、自由度も高く、なんとProviderの自作までできちゃいます!!!
次回以降でProvider自作にチャレンジしたいと思います。
capz.sigs.k8s.io
前述したMicrosoftの記事内でも言及されていますが、Cluster APIはPlatform Engineeringと非常に相性がいいです。
弊社でもPlatform Engineeringは注目して、啓蒙活動にも力を入れているため、Cluster APIの調査は継続していきたいと思います。
The other big benefit this pattern provides is a foundation for platform engineering in an organization.
ACS事業部のご紹介
私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。
www.ap-com.co.jp
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。
www.ap-com.co.jp