CDK で EKS構築してみる
morishitaです。
アクトインディは基本Railsでサービスシステムを開発している会社ですが、 私はこの1ヶ月ほどRubyを書かずにCDK+Typescriptでインフラをいろいろいじっています。
いこーよは当社では最も長いサービスで、それを支えるインフラ構成も改善はしていますが、長年大きくは変更しておらず幾分古さが気になる状況になってきました。 そこで、コンテナベースのインフラに移行しようと思うのですが、今やるならやはり kubernetes で GitOps な環境を構築したいなぁと検討しているところです。
自前でKubernetesのクラスターを構築・運用するのは大変そうなので、Amazon EKS を検討しています。
AWS EKS
EKS は AWS の Kubernetesのサービスで、マネージドなコントロールプレーンを提供してくれます。
AWSコンソールや専用CLIの ekscli
から Kubernetes クラスターを作成するのは簡単で、10-15分ほど待てば構築されます。
プロダクションへの導入を検討しているもの
クラスタそのものを作るのは簡単ですが、本番環境での運用を考えると、素のEKSは幾分機能不足です。 本番運用に向けて次のKubernetesリソースの導入を検討しています。
- Metrics Server
- Cluster Auto Scaler
- EBS CSI Driver
- ALB Ingress Controller
- External DNS
Metrics Server
クラスター内のリソース使用状況データを収集してくれます。 Horizontal Pod Autoscaler や Vertical Pod Autoscaler を利用するのに必要、 つまり、Pod をオートスケールさせるのに必須となります。
Cluster Auto Scaler
Horizontal Pod Autoscaler や Vertical Pod Autoscaler はクラスター内で Pod の数や大きさを負荷に応じて自動調整してくれるものです。
なので、クラスターに Pod を追加する余地がなければ、それ以上はどうしようもない状態になります。
CPUやメモリの不足が原因でポッドが起動できなかった場合にワーカーノードを追加してクラスタそのものをスケールアウトしてくれるリソースです。
クラスター内のノードの利用率が低く、そのポッドをクラスター内の他のノードに再スケジュールできる場合には減らしてもくれます。
Fargate が Pod の実行環境として使えるようなりましたが、制約があるので 本番サービスでは Cluster Auto Scaler も導入したほうがいいと思います。
EBS CSI Driver
EBS ボリュームをクラスタ内から永続化ストレージとして利用できるようにするドライバーです。
ワーカーノードのストレージを不用意に圧迫してしまいたくないですし、Podがなくなっても消えてほしくないデータの保管に役立ちます。
EBSに対応するストレージクラスを追加して、それを指定した PersistentVolumeClaim
を作ると、EBSボリュームを作成しPodから利用できるようにしてくれます。PersistentVolumeClaim
を削除すると、EBSボリュームも削除されます。EBSのライフサイクルを Kubernetes 側から制御できるので運用が楽になります。
ちなみに同様のドライバーにストレージとしてEFSを利用する EFS CSI Driver もあります。
ALB Ingress Controller と External DNS
ALB Ingress Controller は ALB を Kubernetesリソースとして登録するためのコントローラです。
metadata.annotations.kubernetes.io/ingress.class: alb
のIngressを作成すると、自動的にALBが作成されます。Kubernetes のサービスにつないでやるとWebアプリケーションをインターネットに公開できるようになります。
External DNS は Kubernetes から Route53 のレコードを制御できる様になります。 ALB Ingress で指定したホスト名でアクセスできるように Route53 のレコードも追加してくれます。 本番環境で利用するかはともかく、テスト環境を作ってインターネットからアクセスできるにする場合などにとても重宝しそうです。
まあ、ALB Ingressは使わない運用をすることもあるかと思いますが、使えるようにしておくと便利だと思います。
習作
上記のセットアップと動作確認のための習作として上記リソースをすべて使える状態で Kubernetes クラスタを作成するCDKプロジェクトを作成しました。
AWSのルートアカウントではない AdministratorAccess権限のあるIAMユーザで実行してください。
$ git clone https://github.com/HeRoMo/cdk-eks.git $ cd cdk-eks $ yarn $ yarn build $ yarn cdk deploy *Stack
コマンドを実行して15 ~ 20分程度待つとクラスターの出来上がると思います。
最後に次のようなコマンドが出力出力されるので、コピって実行すると、kubectlで接続できるようになります。
aws eks update-kubeconfig --name MyEKSCluster ...
削除するには次のコマンドを実行します。
$ yarn cdk destory *Stack
EKSはただクラスターを立ち上げておくだけで $144/month(30days) +ワーカーノードの稼働費がかかってしまうので使いもしないのに立ち上げっぱなしにしないように注意が必要です。
おすすめ開発環境
CDK & Kubernetes の開発のおすすめ環境を紹介します。
ずばり、VSCodeに次の拡張を入れるのがおすすめです。
AWS謹製の拡張。まだPreview版ですが、最近CDKに対応した機能が追加されました。 最近CDKプロジェクト内のスタックとリソースがツリーで確認できるようになりました。
Microsoft謹製の拡張です。kubeconfigで設定されているクラスタのリソースを手軽に確認できます。リソースを選択するとそのマニフェストもYAMLで表示できます。
まとめ
CDK 使って EKS クラスタはもちろん、kubernetes リソースも作成できます。 AWSのリソースを利用する kubernetesリソースはIAMロールをワーカーノードに付与する必要があったりするので一緒に作ってしまうと便利です。
便利ですが kubernetesリソースはできるだけKubernetesウェイで管理したほうがいいと思っており、CDKコードの中にマニフェストを入れるのはどうなのだろうかと思っているところです。
実際のプロダクション環境ではAWSリソースはCDK、kubernetesリソースはそれとは別にmanifest群のリポジトリで管理する方針なのですが、迷うところです。
また、ちょっと触れましたが、EKS で Pod を Fargate を使って動かせる機能が GA になりました。
Persistent volumes はダメ、Daemonsetsはダメとかいくつか制限はあるもののクラスタ自体のサイズを気にせず Pod を増やせるのは良さそうです。
まだ、CDKどころか、CFn でも扱えないようですが試してみたいと思います。
面白くなってきました。
最後に
アクトインディではGitOpsでサクサク開発 -> リリースできる環境を作りたいエンジニアを募集しています。