🌏

Cluster API Provider AWS を使って、一撃で世界中にEKSクラスターを構築してみた

2023/02/06に公開

マルチクラスター Kubernetes を運用をしていると、クラスターの管理をもっと効率的におこなっていきたいと感じることがあるかなと思います。その解決策のひとつとして、Kubernetes クラスターを Kubernetes で管理する Cluster API という機能が存在します。

この記事では「一撃で世界中にEKSクラスターを構築する」をテーマに、Cluster API に入門してみようと思います。

Cluster API とは

Cluster API とは、Kubernetes の Cluster Lifecycle SIGs で開発されている OSS です。Cluster API の登場以前は、Kubernetes 環境を構築するツールが多岐にわたり、ツールごとに個別で各種クラウドなどの環境をサポートする必要がありました。Cluster API は Kubernetes クラスターを包括的に管理するための仕組みであり、宣言的な API を用いて Kubernetes クラスターそのものの作成・削除をおこなうことができます。

よりわかりやすく言えば、管理用クラスターに YAML マニフェストをデプロイすることで、複数のクラスターを作成できます。Cluster API 自体は汎用的な実装のみを提供していて、クラウド固有のサービス(EKSやGKEなど)に対する操作は環境固有の Provider によって実装されます。AWSの場合は Cluster API Provider AWS (CAPA) という Provider が存在します。

やりたいこと

Cluster API を使って、複数リージョンにまたがって EKS クラスターをデプロイします。実現したいことのイメージは以下のとおりです。

アメリカ、イギリス、シンガポールに EKS クラスターを 一撃で デプロイすることが、この記事のゴールです。

事前準備

一撃でデプロイするとはいえ、流石に事前準備は必要となります。The Cluster API Bookこちらの記事を参考にしながら事前準備をおこなっていきます。今回はマニフェストを管理クラスターに適用するために、Argo CD を用いることとします。

まずはじめに、Kind を使ってローカル環境に管理用クラスターを作成します。このローカルに作成する管理用クラスターに Cluster API のカスタムリソースを適用し、EKS クラスター(ワークロードクラスター)を作成していくことになります。

kind create cluster
kubectl cluster-info --context kind-kind

EKS クラスターを作成するために必要な IAM リソースを作成します。clusterawsadm コマンドは、CAPA のヘルパー CLI ツールです。以下のコマンドを、IAM へのアクセス権限を持つクレデンシャルが設定されたコマンドラインで実行します。

clusterawsadm bootstrap iam create-cloudformation-stack --region ap-northeast-1

EKS クラスターを作成する権限を環境変数に設定します。clusterawsadm bootstrap credentials encode-as-profileドキュメントに記載された順序にしたがって AWS のクレデンシャルを走査し、Base64 でエンコードして出力するコマンドです。

export AWS_B64ENCODED_CREDENTIALS=$(clusterawsadm bootstrap credentials encode-as-profile --region ap-northeast-1)
export AWS_REGION=ap-northeast-1

次に、EKS クラスターを作成するために必要なパラメータを環境変数で定義しておきます。

export EKS=true
export EXP_MACHINE_POOL=true
export CAPA_EKS_IAM=true

次に、Kind クラスターを管理用クラスターとして初期化します。

clusterctl init --infrastructure aws

これでローカルの Kind クラスターが 管理用クラスターとして初期化され、EKS クラスターを構築する準備ができました。次に、管理用クラスターに Cluster API のカスタムリソースを適用するために、Argo CD をインストールしていきます。

kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
kubectl port-forward svc/argocd-server 8080:80

ブラウザから http://localhost:8080で Argo CD の画面を開いてみましょう。

ArgoCD-1

Argo CD では管理者アカウントとして admin ユーザーが用意されています。初期パスワードは argocd-initial-admin-secret という名前の Secret に格納されているので、kubectl を叩いて初期パスワードを取得します。

kubectl get secret/argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d ; echo

次に Argo CD と GitHub 間の接続を確立します。Argo CD の Web UI のメニューバーにある Setting ページに移動し Repositories 画面を開きます。次に CONNECT REPO をクリックします。Git リポジトリに接続するために必要な適切な設定を入力します。

Argo CD に Cluster API オブジェクトを管理する権限を付与します。今回は Argo CD が使用する argocd-application-controller ServiceAccount に cluster-admin Role を追加しておきます。

cat <<EOF > argocd-cluster-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: cluster-admin-argocd-contoller
subjects:
  - kind: ServiceAccount
    name: argocd-application-controller
    namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
EOF
kubectl apply -f ./argocd-cluster-role-binding.yaml

次に、クラスターをデプロイするためのカスタムリソースを定義したマニフェストを用意します。こちらのリポジトリに複数のリージョンに EKS クラスターをデプロイするマニフェストを用意しました。この Helm チャートでは values.yaml にリージョンのリストを定義していて、定義したリージョンごとに EKS クラスターを作成するマニフェストが生成されます。

target_regions:
- us-east-1
- eu-west-2
- ap-southeast-1 

カスタムリソースの詳細については公式ドキュメント、あるいは僕が別途公開したCluster API Provider AWS を QuickStart するための知見などの記事を参照いただければと思います。

次に Argo CD の Application を登録するため、以下のマニフェストを適用します。

cat <<EOF > argocd-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: multi-eks-cluster
spec:
  destination:
    name: ''
    namespace: default
    server: 'https://kubernetes.default.svc'
  source:
    path: .
    repoURL: 'https://github.com/kennygt51/multi-eks-cluster-manifests'
    targetRevision: HEAD
    helm:
      valueFiles:
        - values.yaml
  project: default
EOF
kubectl apply -f argocd-application.yaml

Argo CD の UI から Application が作成されたことが確認できます。

ArgoCD-3

長かったですが、これでようやく事前準備は完了です。

EKS クラスターをデプロイする

さて、世界に向けて EKS クラスターをデプロイしていきましょう。Argo CD 上で Sync ボタンを押すことで、デプロイが開始されます。クラスターの作成状況については kubectl get clusters でも確認することができます。

> k get clusters
NAME                                   PHASE          AGE   VERSION
ap-southeast-1-multi-eks-cluster-eks   Provisioning   7s
eu-west-2-multi-eks-cluster-eks        Provisioning   7s
us-east-1-multi-eks-cluster-eks        Provisioning   7s

Cluster の状態が Provisioned になれば、EKS クラスターの作成が完了しています。実際に AWS マネジメントコンソールを確認してみると、各リージョンに EKS クラスターが作成されているはずです。

EKS-Cluster

コマンドラインからも、EKS クラスターの作成が完了していることを確認できます。

> k get clusters
NAME                                   PHASE         AGE   VERSION
ap-southeast-1-multi-eks-cluster-eks   Provisioned   14m
eu-west-2-multi-eks-cluster-eks        Provisioned   14m
us-east-1-multi-eks-cluster-eks        Provisioned   14m

お片付け

もし検証をされている方がいたら、不要な課金を避けるためにリソースを削除してください。Cluster リソースを削除することで AWS のリソースを削除できます。(少し時間がかかります)

まとめ

今回は「全世界に一撃で EKS クラスターをデプロイする」をテーマに、Cluster API Provider AWS を利用し、宣言的な API で複数のリージョンに EKS クラスターを作成してみました。クラスター自体にクラスターを管理する能力を持たせて宣言的な API で管理するというコンセプトは、マルチクラスターを運用していく上でとても面白いアプローチだと思いました。

Discussion