EKS Fargate で DNS (Route53) を使いたい時


TL;DR

EKS で DNS を使いたいので、その辺りをうまくやってくれるコントローラをセットアップする

関連プロジェクトにある、ExternalDNS コントローラ

オリジナルの手順はここ

モチベーション

なるべく、helm を使ってセットアップしたい

ALB もセットで使いたい場合はこちら参照

前提

  • 以下のコマンドをインストール済み

    • eksctl
    • aws
    • kubectl

手順

  1. クラスタ作成
  2. クラスターの IAM OIDC プロバイダーを作成
  3. ポリシー作成
  4. サービスアカウント作成
  5. helm でインストール

クラスタ作成

これは略

クラスターの IAM OIDC プロバイダーを作成

これも、一回だけやっておけば良いから、略。
一応

ポリシー作成

  1. ポリシーが記載された json ファイルを、テキストエディタ等で作成。ファイル名は iam_policy.json。

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": ["route53:ChangeResourceRecordSets"],
          "Resource": ["arn:aws:route53:::hostedzone/*"]
        },
        {
          "Effect": "Allow",
          "Action": [
            "route53:ListHostedZones",
            "route53:ListResourceRecordSets"
          ],
          "Resource": ["*"]
        }
      ]
    }
    
  2. ポリシーの作成

    $ aws iam create-policy \
       --policy-name externalDnsPolicy \
       --policy-document file://iam_policy.json
    
  3. Arn をメモしておく

サービスアカウント作成

  1. 作成

    $ eksctl create iamserviceaccount \
        --cluster=<YOUR_CLUSTER_NAME> \
        --namespace=kube-system \
        --name=external-dns \
        --attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/externalDnsPolicy \
        --override-existing-serviceaccounts \
        --approve
    
  2. 確認

    $ kubectl describe sa/external-dns -n kube-system
    
    Name:                external-dns
    Namespace:           kube-system
    Labels:              app.kubernetes.io/managed-by=eksctl
    Annotations:         eks.amazonaws.com/role-arn: arn:aws:iam::xxx:role/xxx
    ...
    

helm でインストール

  1. Amazon EKS チャートレポを Helm に追加

    $ helm repo add bitnami https://charts.bitnami.com/bitnami
    
    "bitnami" has been added to your repositories
    
  2. 念のため、更新しておく

    $ helm repo update
    
    Hang tight while we grab the latest from your chart repositories...
    ...Successfully got an update from the "bitnami" chart repository
    Update Complete. ⎈Happy Helming!⎈
    
  3. Helm チャートをインストール

    helm install external-dns bitnami/external-dns \
        --set serviceAccount.create=false \
        --set serviceAccount.name=external-dns \
        --set policy=sync \
        --set aws.zoneType=public \
        --set txtOwnerId=<ホストゾーンID> \
        --set domainFilters[0]=<ドメイン> \
        -n kube-system
    
    NAME: external-dns
    LAST DEPLOYED: Tue Aug 24 13:46:57 2021
    NAMESPACE: kube-system
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    ** Please be patient while the chart is being deployed **
    
    To verify that external-dns has started, run:
    
    kubectl --namespace=kube-system get pods -l "app.kubernetes.io/name=external-dns,app.kubernetes.io/instance=external-dns"
    

動作確認

test-nginx1 というネームスペースに nginx を起動させてみる

  1. まず、fargate profile を作成する。忘れがち。

    $ eksctl create fargateprofile \
        --cluster <YOUR_CLUSTER_NAME> \
        --region <REGION_CODE> \
        --name test-nginx1 \
        --namespace test-nginx1
    
  2. マニフェストを準備

    ---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: test-nginx1
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: test-nginx1
      name: deployment-nginx
    spec:
      selector:
        matchLabels:
          app.kubernetes.io/name: app-nginx
      replicas: 1
      template:
        metadata:
          labels:
            app.kubernetes.io/name: app-nginx
        spec:
          containers:
            - image: nginx:1.16.1
              imagePullPolicy: Always
              name: app-nginx
              ports:
                - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      namespace: test-nginx1
      name: service-nginx
    spec:
      ports:
        - port: 80
          targetPort: 80
          protocol: TCP
      type: NodePort
      selector:
        app.kubernetes.io/name: app-nginx
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      namespace: test-nginx1
      name: ingress-nginx
      annotations:
        kubernetes.io/ingress.class: alb
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
        # group.name 使うと ALB を共有できる
        alb.ingress.kubernetes.io/group.name: my-group
    spec:
      rules:
        - host: test-nginx1.<ドメイン>
          http:
            paths:
              - backend:
                  serviceName: service-nginx
                  servicePort: 80
    
  3. デプロイ

    $ kubectl apply -f ./test-nginx1.yml
    
  4. ログ

    $ kubectl logs -f deployment/external-dns -n kube-system
    
  5. 結果
    DNS の状況