EKSとExternalDNSでドメイン名を設定する
皆さん、こんにちは。技術開発グループのn-ozawanです。
暑いですね。部屋の中にいても熱中症になる危険がありますので、細目に水分補給するようにしましょう。
本題です。
EKSで構築されたアプリケーションに対してドメインを紐付ける方法としてExternalDNSがあります。ExternalDNSを利用すると、自動的にKubernetesのIngressで指定したホスト名でDNSホストゾーンのAレコードを登録してくれるので便利です。
目次
ExternalDNS
ExternalDNSはKubernetesのクラスタで動作するPODで、外部に公開するKubernetesのアプリケーションとDNSプロバイダーを同期してくれます。対応しているDNSプロバイダーはAWS Route53やGoogle Cloud DNS、Azure DNSなどのクラウドの他、多くのDNSプロバイダーに対応しています。詳細はこちらを参照してください。
今回はAWSのEKSで構築された環境と、AWS Route53と同期するやり方を紹介したいと思います。
ゴール
ExternalDNSをHELMでインストールします。また、ExternalDNSからRoute53へのアクセス権限が必要ですので、ポリシーの定義とServiceAccountの作成が必要になります。ここまでをTerraformで構築します。最後にKubernetesのIngressのマニフェストを定義します。

サービスアカウントの作成
ExternalDNSからRoute53への操作を行えるようにするためにサービスアカウントを作成する必要があります。作成手順については、以前の記事「EKSでロードバランサーを構築する」で記載した「サービスアカウントの作成」と同じです。以前の記事と異なるのはポリシーの定義だけですので、本稿ではポリシーの定義を紹介します。
resource "aws_iam_policy" "external_dns" {
name = "external-dns-policy"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets"
],
"Resource": [
"*"
]
}
]
}
POLICY
}
Route53のホストゾーンの参照と、そのホストゾーンのリソースレコードの変更および参照を許可しています。
ExternalDNSのインストール
ExternalDNSをHELMでインストールします。
resource "helm_release" "external_dns" {
name = "external-dns"
chart = "external-dns"
repository = "https://kubernetes-sigs.github.io/external-dns/"
namespace = "kube-system"
dynamic "set" {
for_each = {
"serviceAccount.create" = false
"serviceAccount.name" = "external-dns-service-account"
}
content {
name = set.key
value = set.value
}
}
}
chart
は”external-dns”で、repository
には”https://kubernetes-sigs.github.io/external-dns/”を指定します。
ExternalDNSは、デフォルトでサービスアカウントを作成します。今回は自前で用意したサービスアカウントを利用しますので、serviceAccount.create
を”false”に指定して、サービスアカウントを作成しないようにします。また、serviceAccount.name
に先ほど作成したサービスアカウントの名前を指定します。
Ingressの定義
KubernetesのIngressを定義します。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: http-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- host: www.ios-eks-example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: http-service
port:
number: 80
metadata.annotations
で指定しているのはALB(Application Load Balancer)と連携するための設定です。今回のExternalDNSとは関係ありませんが、外部へ公開するためには必要な設定となります。
ExternalDNSに関係するのはspec.rules.host
になります。クラスタにIngressリソースを反映した際に、spec.rules.host
に指定したホスト名で、Route53のホストゾーンにAレコードが登録されます。
spec.rules.http
には受け取ったトラフィックを、どのNodePortへ送るのかを指定します。
おわりに
Ingressの定義でAレコードまで登録してくれるExternalDNSは便利ではあります。ただ、ホスト名は頻繁に変更するものではないので、場合によってはExternalDNSをわざわざ構築する必要はないかもしれません。その辺は費用対効果を見て構築した方が良いでしょう。
ではまた。