なになれ

IT系のことを記録していきます

Kubernetesのマルチクラスタ管理に役立ちそうなCluster API Provider AWSを試した

Kubecon EU 2021のセッションで知ったCluster API Provider AWSを軽く試したので、その内容を紹介します。
Cluster API Provider AWSを使って、EKSでKubernetes Clusterを作成しました。

ちなみにセッションはこれです。
kccnceu2021.sched.com youtu.be

なお、上記セッションで知った程度の知識なので、ご了承ください。

Cluster APIとは

Kubernetes Clusterの作成、更新、削除などのライフサイクルを管理するAPIです。
KubernetesAPIなので、YAMLで宣言的にClusterを管理できるのが良いところです。
また、各種クラウドプロバイダーやオンプレミス上でClusterを管理できます。

Cluster API Provider AWSとは

Cluster APIに対応したAWS向けのプロダクトです。
Cluster APIを介して、AWS上でKubernetes Clusterを管理します。
Clusterの作り方として、EC2とKubeadmによる非マネージドなClusterとEKSによるマネージドなClusterがあります。

Cluster API Provider AWSを試す

今回は、EKSでClusterを作成します。
前提事項としては以下になります。

  • macOS
  • AdministratorAccessのIAMポリシーでAWSの認証情報を設定済み

各種インストール

clusterctlをインストールします。
clusterctlはCluster APIに対応したCLIツールです。

$ curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.16/clusterctl-darwin-amd64 -o clusterctl
$ chmod +x ./clusterctl
$ sudo mv ./clusterctl /usr/local/bin/clusterctl
$ clusterctl version
clusterctl version: &version.Info{Major:"0", Minor:"3", GitVersion:"v0.3.16", GitCommit:"6d7649fc5f407ac48b6d8e3929c97822527c0454", GitTreeState:"clean", BuildDate:"2021-04-16T01:01:59Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"darwin/amd64"}

clusterawsadmをインストールします。
clusterawsadmはCluster API Provider AWSCLIツールです。

$ curl -L https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases/download/v0.6.5/clusterawsadm-darwin-amd64 -o clusterawsadm
$ chmod +x ./clusterawsadm
$ sudo mv ./clusterawsadm /usr/local/bin/clusterawsadm
$ clusterawsadm version
clusterawsadm version: &version.Info{Major:"0", Minor:"6", GitVersion:"v0.6.5", GitCommit:"c7c8ae1ee071afbb33c3b45b0f9adbea149581ce", GitTreeState:"clean", BuildDate:"2021-04-15T17:03:17Z", GoVersion:"go1.13.15", AwsSdkVersion:"v1.36.26", Compiler:"gc", Platform:"darwin/amd64"}

セットアップ用Cluster準備

Cluster APIKubernetesAPIなので、APIを実行するのにKubernetes Clusterが必要になります。
Clusterを作るためのClusterということになります。
今回は簡単に試すということで、公式で紹介されているkindを使用して、Cluster APIを実行します。

kindでClusterを作るには、以下のコマンドを実行します。

$ kind create cluster

ちなみに、kindはbrewでインストールできます。

$ brew install kind

Cluster API用Clusterのセットアップ

AWSでKuberentes Clusterを作成する際に必要となるIAMリソースを用意します。

以下のようにEKS用の設定ファイルを用意します。

bootstrap-config.yaml

apiVersion: bootstrap.aws.infrastructure.cluster.x-k8s.io/v1alpha1
kind: AWSIAMConfiguration
spec:
  eks:
    enable: true
    iamRoleCreation: false # Set to true if you plan to use the EKSEnableIAM feature flag to enable automatic creation of IAM roles
    defaultControlPlaneRole:
      disable: false # Set to false to enable creation of the default control plane role
    managedMachinePool:
      disable: false # Set to false to enable creation of the default node role for managed machine pools

以下のコマンドでIAMリソースを作成します。

$ clusterawsadm bootstrap iam create-cloudformation-stack --config bootstrap-config.yaml

実際には、cloudformationによって、IAMリソースが作られます。

次に、Cluster APIに対応したClusterのセットアップを行います。

clusterctl initを実行すると、Cluster APIで利用するプログラムが該当のClusterにデプロイされます。
Cluster APIでのEKS対応は、まだ実験段階なので、環境変数で有効化する必要があります。

$ export AWS_B64ENCODED_CREDENTIALS=$(clusterawsadm bootstrap credentials encode-as-profile)
$ export EXP_MACHINE_POOL=true
$ export EXP_EKS=true
$ export EXP_EKS_IAM=true
$ export EXP_EKS_ADD_ROLES=true
$ clusterctl init --infrastructure=aws --control-plane aws-eks:v0.6.4 --bootstrap aws-eks
Fetching providers
Installing cert-manager Version="v1.1.0"
Waiting for cert-manager to be available...
Installing Provider="cluster-api" Version="v0.3.16" TargetNamespace="capi-system"
Installing Provider="bootstrap-aws-eks" Version="v0.6.5" TargetNamespace="capa-eks-bootstrap-system"
Installing Provider="control-plane-aws-eks" Version="v0.6.4" TargetNamespace="capa-eks-control-plane-system"
Installing Provider="infrastructure-aws" Version="v0.6.5" TargetNamespace="capa-system"

Your management cluster has been initialized successfully!

You can now create your first workload cluster by running the following:

  clusterctl config cluster [name] --kubernetes-version [version] | kubectl apply -f -

aws-eksをv0.6.4でインストールしているのは、最新のv.0.6.5だと以下のバグがあり、動かなかったためです。

github.com

Podを表示して、以下のようにCluster API関連のプログラムが動いていれば成功です。

$ kubectl get pods --all-namespaces
NAMESPACE                       NAME                                                         READY   STATUS    RESTARTS   AGE
capa-eks-bootstrap-system       capa-eks-bootstrap-controller-manager-6dcb5d65f4-wgvc5       2/2     Running   0          37s
capa-eks-control-plane-system   capa-eks-control-plane-controller-manager-dd97fff6b-s9dq8    2/2     Running   0          36s
capa-system                     capa-controller-manager-9fb754f96-5sj4j                      2/2     Running   0          35s
capi-system                     capi-controller-manager-646bf68fcd-gxmf9                     2/2     Running   0          14m
capi-webhook-system             capa-controller-manager-77d85d849b-dss7b                     2/2     Running   0          14m
capi-webhook-system             capa-eks-control-plane-controller-manager-7495467677-fhbpg   2/2     Running   0          14m
capi-webhook-system             capi-controller-manager-74656f94d9-v2xgj                     2/2     Running   0          14m
cert-manager                    cert-manager-86cb5dcfdd-vllgc                                1/1     Running   0          15m
cert-manager                    cert-manager-cainjector-84cf775b89-7kgvd                     1/1     Running   0          15m
cert-manager                    cert-manager-webhook-5d5dc765f6-dv8tp                        1/1     Running   0          15m
...

Cluster APIを使ってClusterを作成する

以下のように、Cluster API向けのyamlファイルを用意します。

eks-example.yaml

apiVersion: cluster.x-k8s.io/v1alpha3
kind: Cluster
metadata:
  name: eks-example
  namespace: default
spec:
  clusterNetwork:
    pods:
      cidrBlocks:
      - 192.168.0.0/16
  controlPlaneRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1alpha3
    kind: AWSManagedControlPlane
    name: eks-example-control-plane
  infrastructureRef:
    apiVersion: controlplane.cluster.x-k8s.io/v1alpha3
    kind: AWSManagedControlPlane
    name: eks-example-control-plane
---
apiVersion: controlplane.cluster.x-k8s.io/v1alpha3
kind: AWSManagedControlPlane
metadata:
  name: eks-example-control-plane
  namespace: default
spec:
  region: ap-northeast-1
  sshKeyName: default
  version: v1.19.0
  networkSpec:
    vpc:
      id: vpc-91d60cf4
    subnets:
    - id: subnet-4a0fa53d
    - id: subnet-a768a4fe
  iamAuthenticatorConfig:
    mapUsers:
    - username: "kubernetes-admin"
      userarn: "arn:aws:iam::1234567890:user/hi1280"
      groups:
      - "system:masters"
---
apiVersion: exp.cluster.x-k8s.io/v1alpha3
kind: MachinePool
metadata:
  name: eks-example-pool-0
  namespace: default
spec:
  clusterName: eks-example
  replicas: 2
  template:
    spec:
      bootstrap:
        dataSecretName: ""
      clusterName: eks-example
      infrastructureRef:
        apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
        kind: AWSManagedMachinePool
        name: eks-example-pool-0
---
apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3
kind: AWSManagedMachinePool
metadata:
  name: eks-example-pool-0
  namespace: default
spec:
  roleName: "eks-example"
  instanceType: t3.small

AWSManagedControlPlaneがEKSのコントロールプレーン向けのオブジェクトです。
ここでは、既存のVPCを使用したり、aws-authの設定を行なっています。
AWSManagedMachinePoolがEKSのマネージドノードグループ向けのオブジェクトです。
ここでは、インスタンスタイプを指定したり、IAMロールの名前を指定しています。

なお、Cluster API向けのyamlファイルを簡単に作成できるようにテンプレートを出力するコマンドがあります。

$ export AWS_SSH_KEY_NAME=default
$ clusterctl config cluster eks-example --flavor eks-managedmachinepool --kubernetes-version v1.19.0 --worker-machine-count=2 > eks-example.yaml

作成したyamlファイルをapplyします。

$ kubectl apply -f eks-example.yaml

以下のコマンドで作成状況を確認できます。

$ clusterctl describe cluster eks-example
NAME                                                                 READY  SEVERITY  REASON  SINCE  MESSAGE
/eks-example                                                         True                     80s
└─ControlPlane - AWSManagedControlPlane/eks-example-control-plane  True                     74s

作成結果の確認

kubeconfigを出力します。

$ clusterctl get kubeconfig eks-example > eks-example.kubeconfig

ノード、Podを表示します。

$ kubectl get node --kubeconfig eks-example.kubeconfig
NAME                                               STATUS   ROLES    AGE     VERSION
ip-172-31-11-205.ap-northeast-1.compute.internal   Ready    <none>   4m57s   v1.19.6-eks-49a6c0
ip-172-31-18-175.ap-northeast-1.compute.internal   Ready    <none>   4m46s   v1.19.6-eks-49a6c0
$ kubectl get pods --kubeconfig eks-example.kubeconfig --all-namespaces
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   aws-node-nng86             1/1     Running   0          4m57s
kube-system   aws-node-s7frk             1/1     Running   0          5m7s
kube-system   coredns-59847d77c8-fwb99   1/1     Running   0          21m
kube-system   coredns-59847d77c8-qgkz8   1/1     Running   0          21m
kube-system   kube-proxy-dmd7l           1/1     Running   0          5m7s
kube-system   kube-proxy-q67zv           1/1     Running   0          4m57s

特に変わり映えはないですが、EKSを使ったKubernetesの環境が作れました。

まとめ

今回は単純にClusterを作ってみただけなので、eksctlでEKS環境を作るのとほぼ変わらない形だと思います。
ただkubectl applyを使って宣言的にクラスタを作れる体験は良さそうに思います。
クラスタバージョンのアップデートにも対応しているようなので、これも近いうちに試してみたいです。
マルチクラスタになってくると管理が大変になってくるので、ある程度統一されたAPIで管理できるのは良さげなので今後に期待したいと思います。

参考