Cluster API Provider AWS を使って、一撃で世界中にEKSクラスターを構築してみた
マルチクラスター 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 の画面を開いてみましょう。
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 が作成されたことが確認できます。
長かったですが、これでようやく事前準備は完了です。
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 クラスターの作成が完了していることを確認できます。
> 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