EKS Auto Mode + EKS Pod Identity + ExternalDNS で DNS 連携のある EKS クラスターをなるべく簡単に構築する Terraform

はじめに

きちんとした Web サービスを展開しようと思ったとき、大手クラウドプロバイダーの AWS の上で、可用性の高い Kubernetes (K8s) を動かす (= EKS) という選択はよく挙がるパターンだと思います。
そうなると Terraform で EKS クラスターを IaC 化していきたいですよね。

しかし、難易度が高そう…。
そもそも Kubernetes 自体が難しいですし、それを AWS で動かすとなるとプロバイダー特有の知識が必要なうえ、必然的にネットワーク・セキュリティの難しさが乗っかってきます。
その状態でさらに、ドメインで公開するためには拡張機能まで投入しないといけないの…?

正直かなり高度な印象を受けてしまいます。
ただ、色々調べまくった結果、今は各所の努力のおかげでかなり少ないコードで実現できることが分かりました。
今回のコンセプトは「できるだけ簡単」です。
せっかくなので、ここにまとめておきたいと思います。

用語の説明

自分の理解の範囲になってしまいますが、それぞれ簡単に説明しておきます。

EKS Auto Mode

各種設定が自動化された EKS です。
大きなところとして、必須もしくは頻出アドオンが最初から組み込まれています。

Amazon EKS アドオン - アマゾン EKS
Amazon EKS アドオンを使用して Amazon EKS クラスターの運用ソフトウェアアドオンを管理し、AWS およびサードパーティーベンダーからのオブザーバビリティ、ネットワーキング、ストレージ、セキュリティを実現する方法について説...

ここでデカいなと感じるのは、ロードバランサーコントローラー、つまり AWS Load Balancer Controller が入っていることです。これは通常の EKS ではアドオンとしてすら存在しておらず、EKS クラスター上で Helm などで手動インストールする必要があるのですが、EKS Auto Mode ではその必要がありません。

また、Karpenter も組み込まれていてオートスケーリングの準備が整っています。オートスケーリングを利用しないにしても、インスタンスタイプを意識の外に追いやることができるのでメリットを享受できます。
かなりのマネージド感を浴びることができますね。

反面、個人的にかなり気になるデメリットとしてはインスタンス当たりの利用金額が高くなることです。

料金 - Amazon EKS | AWS
Amazon EC2、AWS Fargate、または AWS Outposts で Kubernetes を実行する場合の、Amazon EKS の料金について、ご説明します。

個人レベルで小さく運用するだけなら気にならない増分なのですが、仕事で大規模なサービス用だったりするとスケールアウトにより無視できないコストアップになる可能性があり、受け入れてもらいにくそうなのがしんどいです。
もしここが改善されたら大きなプロジェクトでも相当導入しやすくなるのですが…。

EKS Pod Identity

Pod に AWS アクセス権を付与する機能です。
同じ目的の機能で IAM roles for service accounts (IRSA) というものがありますが、EKS Pod Identity が後発でより使いやすくなっており、特別な理由がない限り EKS Pod Identity が推奨されるようです。それであれば使わない手はないですね。

ポイントは EKS Auto Mode には EKS Pod Identity Agent アドオンが組み込まれていることです。
つまり設定不要で EKS Pod Identity を使うことができます。

ExternalDNS

Kubernetes SIGs が提供する一つで DNS プロバイダーと自動で連携してくれる機能です。
AWS で言うと、Route 53 にレコードを自動設定してくれるようになります。

さて、EKS には ExternalDNS が外部アドオンとして存在します。
つまり Terraform コードに少しの行を追加するのみで使う準備が整うわけですね。

Terraform コード

全体を GitHub にアップロードしておきましたので、必要に応じて参照してください。

blog-examples/terraform-eks-auto-mode-with-external-dns at main · neuneu9/blog-examples
Contribute to neuneu9/blog-examples development by creating an account on GitHub.

まずは EKS のコードを描いていきます。
おなじみ terraform-aws-modules/eks/aws モジュールを使います。

module “eks” を作成
module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 20.37"

  cluster_name    = "example-eks"
  cluster_version = "1.33"

  cluster_endpoint_public_access = true

  enable_cluster_creator_admin_permissions = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  cluster_compute_config = {
    enabled    = true
    node_pools = ["general-purpose"]
  }
}

cluster_compute_config の部分が EKS Auto Mode を利用するための設定です。
EKS Managed Node Group のときに書いていた必須アドオンやインスタンス設定の記載を省略できています。

次に ExternalDNS をアドオンとして追加するコードを書きます。
本来 EKS Pod Identity と言えど、辛い IAM ロールの設定コードを書かなければならないのですが……
なんと eks-pod-identity という Terraform モジュールがあり、これは一般的に想定される IAM ポリシーを内部にもっている優れものです。
どうせ公式ドキュメントから探して JSON コピペするだけなんだから簡単に設定できるようになってくれないかなぁ(個人の感想です)という思いにピンポイントで応えてくれます。

留意点としては eks モジュールのアドオン側でロールを割り当てることです。
よく分からないまま eks-pod-identity モジュール側でも割り当ててしまうとクラスターに設定されてバッティングして apply に失敗します。私のように…。

module “eks” 内に追加
  cluster_addons = {
    external-dns = {
      pod_identity_association = [
        {
          role_arn        = module.external_dns_pod_identity.iam_role_arn
          service_account = "external-dns"
        }
      ]
    }
  }
module “external_dns_pod_identity” を作成
module "external_dns_pod_identity" {
  source  = "terraform-aws-modules/eks-pod-identity/aws"
  version = "1.12.1"

  name = "example-eks-external-dns"

  attach_external_dns_policy    = true
  external_dns_hosted_zone_arns = ["arn:aws:route53:::hostedzone/*"]

  # associations は指定しない
  # EKS アドオン (eks.cluster_addons.external-dns) 側で指定するため
}

最終的なコードはこんな感じになります。短い!

blog-examples/terraform-eks-auto-mode-with-external-dns/eks.tf at main · neuneu9/blog-examples
Contribute to neuneu9/blog-examples development by creating an account on GitHub.

これを terraform apply してみると、コンソール上で EKS クラスターができていることが確認でき、

アドオンに ExternalDNS が追加されています。ロールも割り当てられています。

おわりに

どうでしょう?かなりコードが少なく済んだのではないでしょうか?
同じような組み合わせを目指している方の参考になれば幸いです。

コメント

タイトルとURLをコピーしました