goodbyegangsterのブログ

備忘録的な

Amazon EKSでALB Ingress Controllerを利用する

EKSにて、ALBを利用したpodのロードバランシングを試します。AWSのドキュメントはこちら。

Amazon EKS の ALB Ingress Controller

ALB Ingress Controllerのドキュメントはこちら。

AWS ALB Ingress Controller

環境

  • EKS(Kubernetes) 1.14.9
  • ALB Ingress Controller v1.1.5
  • ExternalDNS v0.5.18
  • eksctl 0.13.0
  • kubectl v1.17.1

VPCの設定

ALBを配置したいSubnetに、下記の通りタギングを行います。

サブネット kubernetes.io/cluster/<k8s-cluster-name> kubernetes.io/role/elb kubernetes.io/role/internal-elb
VPC内全サブネット shared
Internet-facing ALBを配置するサブネット shared 1
Internal-facing ALBを配置するサブネット shared 1

こんな感じですね。

f:id:goodbyegangster:20200202233822p:plain

このタギングをしておくことで、ALB Ingress ContorollerがALBを配置するサブネットを自動検知してくれます。

Subnet Auto Discovery

SSL/TLS証明書の用意

ALBに配置したいSSL/TLS証明書を、ACMにて作成しておきます。

ALBアクセスログ配置用のS3バケットの用意

ALBのアクセスログを格納するS3バケットを作成し、必要なバケットポリシーを設定します。

バケットのアクセス許可

OpenID Connect ID プロバイダーの作成

KubernetesAWS間の認証に利用される、IAM OIDC ID プロバイダーをeksctlにて作成します。

$ eksctl utils associate-iam-oidc-provider --cluster <k8s-cluster-name> --region ap-northeast-1 --approve --profile xxx
[]  eksctl version 0.13.0
[]  using region ap-northeast-1
[]  will create IAM Open ID Connect provider for cluster "cluster-sample" in "ap-northeast-1"
[]  created IAM Open ID Connect provider for cluster "cluster-sample" in "ap-northeast-1"

eksctl を使用してクラスターの IAM OIDC ID プロバイダーを作成するには

ALB Ingress Controller向けサービスアカウントの作成

ALB Ingress Controllerで利用するサービスアカウントを作成します。

以前は kube2iam を利用していた部分が、AWS側のUpdateにより、KubernetesのサービスアカウントにIAM Roleを割り当てられるようなっています。

Kubernetes サービスアカウントに対するきめ細やかな IAM ロール割り当ての紹介

まず該当サービスアカウントで利用されるIAMポリシーを作成します。ポリシーファイルが公開されているので、それを用いて作成します。

$ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/iam-policy.json
$ aws iam create-policy \
--policy-name ALBIngressControllerIAMPolicy \
--policy-document file://iam-policy.json \
--profile xxxxxx
{
    "Policy": {
        "PolicyName": "ALBIngressControllerIAMPolicy",
        "PolicyId": "ANPAZDDARDEF23WPDYGNE",
        "Arn": "arn:aws:iam::XXXXXXXXXXXX:policy/ALBIngressControllerIAMPolicy",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2020-02-01T07:45:05Z",
        "UpdateDate": "2020-02-01T07:45:05Z"
    }
}

続いてkubernetesのサービスアカウントを作成します。サービスアカウント作成用のeksctl向けyamlファイルを作成します。

sa-alb-ingress-controller.yml

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: cluster-sample
  region: ap-northeast-1

iam:
  withOIDC: true
  serviceAccounts:
    - metadata:
        name: alb-ingress-controller
        namespace: kube-system
        labels:
          app.kubernetes.io/name: alb-ingress-controller
      attachPolicyARNs:
        - "arn:aws:iam::XXXXXXXXXXXX:policy/ALBIngressControllerIAMPolicy"

eksctlを実行します。

$ eksctl create iamserviceaccount -f sa-alb-ingress-controller.yml --approve --profile xxx
[]  eksctl version 0.13.0
[]  using region ap-northeast-1
[]  1 iamserviceaccount (kube-system/alb-ingress-controller) was included (based on the include/exclude rules)
[]  1 task: { 2 sequential sub-tasks: { create IAM role for serviceaccount "kube-system/alb-ingress-controller", create serviceaccount "kube-system/alb-ingress-controller" } }
[]  building iamserviceaccount stack "eksctl-cluster-sample-addon-iamserviceaccount-kube-system-alb-ingress-controller"
[]  deploying stack "eksctl-cluster-sample-addon-iamserviceaccount-kube-system-alb-ingress-controller"
[]  created serviceaccount "kube-system/alb-ingress-controller"

これにてサービスアカウントが作成されています。

kubectl get serviceaccount alb-ingress-controller -n kube-system -o yaml 結果

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxxxxxxxxxx:role/eksctl-cluster-sample-addon-iamserviceaccoun-Role1-AYTXHAS9IZA
  creationTimestamp: "2020-02-01T08:35:02Z"
  labels:
    app.kubernetes.io/name: alb-ingress-controller
  name: alb-ingress-controller
  namespace: kube-system
  resourceVersion: "5265"
  selfLink: /api/v1/namespaces/kube-system/serviceaccounts/alb-ingress-controller
  uid: bd6667e2-44cd-11ea-8640-0aa850b703aa
secrets:
- name: alb-ingress-controller-token-xhpvn

同時にCloudFormationが実行されており、 role/eksctl-cluster-sample-addon-iamserviceaccoun-RoleX-XXXXXXXXX というIAM Roleが作成されています。

最後に、作成したサービスアカウント向けの、CluterRoleとCluterRoleBindingを作成します。そのために、下記のkubernetesマニフェストファイルを用意します。

clusterrole-alb-ingress-controller.yml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: alb-ingress-controller
  labels:
    app.kubernetes.io/name: alb-ingress-controller
rules:
  - apiGroups:
      - ""
      - extensions
    resources:
      - configmaps
      - endpoints
      - events
      - ingresses
      - ingresses/status
      - services
    verbs:
      - create
      - get
      - list
      - update
      - watch
      - patch
  - apiGroups:
      - ""
      - extensions
    resources:
      - nodes
      - pods
      - secrets
      - services
      - namespaces
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: alb-ingress-controller
  labels:
    app.kubernetes.io/name: alb-ingress-controller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: alb-ingress-controller
subjects:
  - kind: ServiceAccount
    name: alb-ingress-controller
    namespace: kube-system

マニフェストファイルのサンプル

kubectlを実行します。

$ kubectl apply -f clusterrole-alb-ingress-controller.yml
clusterrole.rbac.authorization.k8s.io/alb-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/alb-ingress-controller created

ALB Ingress Controllerの作成

ALB Ingress Controllerにあたるpodを起動します。サンプルとなるマニフェストファイルが公開されているので、まずそれをダウンロードしてきます。

$ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.4/docs/examples/alb-ingre ss-controller.yaml

サンプルのマニフェストファイルから、以下のパラメーターをアンコメントアウト・値の修正をします。

パラメーター
cluster-name 利用するk8sクラスター名
aws-vpc-id 利用するVPC ID
aws-region 利用するリージョン名

修正したマニフェストファイルが下記です。

alb-ingress-controller.yaml

# Application Load Balancer (ALB) Ingress Controller Deployment Manifest.
# This manifest details sensible defaults for deploying an ALB Ingress Controller.
# GitHub: https://github.com/kubernetes-sigs/aws-alb-ingress-controller
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: alb-ingress-controller
  name: alb-ingress-controller
  # Namespace the ALB Ingress Controller should run in. Does not impact which
  # namespaces it's able to resolve ingress resource for. For limiting ingress
  # namespace scope, see --watch-namespace.
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: alb-ingress-controller
  template:
    metadata:
      labels:
        app.kubernetes.io/name: alb-ingress-controller
    spec:
      containers:
        - name: alb-ingress-controller
          args:
            # Limit the namespace where this ALB Ingress Controller deployment will
            # resolve ingress resources. If left commented, all namespaces are used.
            # - --watch-namespace=your-k8s-namespace

            # Setting the ingress-class flag below ensures that only ingress resources with the
            # annotation kubernetes.io/ingress.class: "alb" are respected by the controller. You may
            # choose any class you'd like for this controller to respect.
            - --ingress-class=alb

            # REQUIRED
            # Name of your cluster. Used when naming resources created
            # by the ALB Ingress Controller, providing distinction between
            # clusters.
            - --cluster-name=cluster-sample

            # AWS VPC ID this ingress controller will use to create AWS resources.
            # If unspecified, it will be discovered from ec2metadata.
            - --aws-vpc-id=vpc-xxxxxxx

            # AWS region this ingress controller will operate in.
            # If unspecified, it will be discovered from ec2metadata.
            # List of regions: http://docs.aws.amazon.com/general/latest/gr/rande.html#vpc_region
            - --aws-region=ap-northeast-1

            # Enables logging on all outbound requests sent to the AWS API.
            # If logging is desired, set to true.
            # - --aws-api-debug
            # Maximum number of times to retry the aws calls.
            # defaults to 10.
            # - --aws-max-retries=10
          # env:
            # AWS key id for authenticating with the AWS API.
            # This is only here for examples. It's recommended you instead use
            # a project like kube2iam for granting access.
            #- name: AWS_ACCESS_KEY_ID
            #  value: KEYVALUE

            # AWS key secret for authenticating with the AWS API.
            # This is only here for examples. It's recommended you instead use
            # a project like kube2iam for granting access.
            #- name: AWS_SECRET_ACCESS_KEY
            #  value: SECRETVALUE
          # Repository location of the ALB Ingress Controller.
          image: docker.io/amazon/aws-alb-ingress-controller:v1.1.4
      serviceAccountName: alb-ingress-controller

kubectlを実行します。

$ kubectl apply -f alb-ingress-controller.yaml
deployment.apps/alb-ingress-controller created

ちゃんと動いていることをログから確認します。

$ kubectl get pod -n kube-system -l app.kubernetes.io/name=alb-ingress-controller
NAME                                      READY   STATUS    RESTARTS   AGE
alb-ingress-controller-75cfcdd576-c2sj5   1/1     Running   0          106m
$
$ kubectl logs alb-ingress-controller-75cfcdd576-c2sj5 -n kube-system
-------------------------------------------------------------------------------
AWS ALB Ingress controller
  Release:    v1.1.4
  Build:      git-0db46039
  Repository: https://github.com/kubernetes-sigs/aws-alb-ingress-controller.git
-------------------------------------------------------------------------------

サンプルのWEBサイトを用意

ALBでロードバランスする先として、NginxのWEBサイトを作成します。Nginxのコンテナ1つを持ったpodを、ReplicaSetで2つ起動するマニフェストファイルを用意します。

deploy-nginx.yml

apiVersion: v1
kind: Namespace
metadata:
  name: sample
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-sample-nginx
  namespace: sample
  labels:
    app: ingress-test
spec:
  selector:
    matchLabels:
      app: sample-nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: sample-nginx
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: service-sample-nginx
  namespace: sample
spec:
  type: NodePort
  ports:
    - name: nginx-port
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: sample-nginx

kubectlを実行します。

$ kubectl apply -f deploy-nginx.yml
namespace/sample created
deployment.apps/deployment-sample-nginx created
service/service-sample-nginx created

確認。

$ kubectl get deployment -n sample -o wide
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS        IMAGES         SELECTOR
deployment-sample-nginx   2/2     2            2           4m52s   nginx-container   nginx:latest   app=sample-nginx
$ kubectl get service -n sample -o wide
NAME                   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE     SELECTOR
service-sample-nginx   NodePort   172.20.156.90   <none>        80:30296/TCP   5m11s   app=sample-nginx

WEBサイトのアクセス時に分かりやすいよう、各pod上のindex.htmlを編集します。

$ kubectl get pod -n sample
NAME                                      READY   STATUS    RESTARTS   AGE
deployment-sample-nginx-8c56d66c9-4pkqk   1/1     Running   0          5m34s
deployment-sample-nginx-8c56d66c9-9c4g6   1/1     Running   0          5m34s
$
$ kubectl exec -n sample -it deployment-sample-nginx-8c56d66c9-4pkqk -- cp /etc/hostname /usr/share/nginx/html/index.html
$ kubectl exec -n sample -it deployment-sample-nginx-8c56d66c9-9c4g6 -- cp /etc/hostname /usr/share/nginx/html/index.html

実際にWEBサイトが表示されることを確認します。まずNodePortとして利用されているポート番号を確認します。Kubernetesは、30000-32676間いずれかのポートを、NodePortとしてデフォルトで利用します。

$ kubectl get service -n sample
NAME                   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service-sample-nginx   NodePort   172.20.156.90   <none>        80:30296/TCP   6m24s

sshでEKS Worker NodeのEC2インスタンスにアクセスして、WEBページを表示します。

$ ssh -i <秘密鍵ファイル> ec2-user@<worker nodeのIPアドレス> "curl -s http://localhost:30296"
deployment-sample-nginx-8c56d66c9-4pkqk

ExternalDNSの設定

Ingressリソースを作成する前に、ExternalDNSの設定を実施します。ExternalDNSは、作成されたALBのエンドポイントを、Route53へカスタムドメインDNSレコードとして自動登録してくれるものとなります。Kubernetes Incubator Projectの1つとして開発されています。

ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.

ExternalDNS

AWS Route53だけでなく、様々なDNSサービスを利用できます。GitHubに記載されているRoute53向けの手順を参考に作業を進めます。

Setting up ExternalDNS for Services on AWS

まず、ExternalDNSで利用するサービスアカウントを作成します。Route53を操作できるIAMポリシーを定義してポリシーファイルを用意します。

iam-policy-external-dns.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "route53:ChangeResourceRecordSets"
      ],
      "Resource": [
        "arn:aws:route53:::hostedzone/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "route53:ListHostedZones",
        "route53:ListResourceRecordSets"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

ポリシーファイルを利用して、IAMポリシーを作成します。

$ aws iam create-policy \
--policy-name ExternalDNSIAMPolicy \
--policy-document file://iam-policy-external-dns.json \
--profile xxxxxx
{
    "Policy": {
        "PolicyName": "ExternalDNSIAMPolicy",
        "PolicyId": "ANPAZDDARDEFRZSVK722A",
        "Arn": "arn:aws:iam::xxxxxxxxxxxx:policy/ExternalDNSIAMPolicy",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2020-02-02T09:16:14Z",
        "UpdateDate": "2020-02-02T09:16:14Z"
    }
}

作成したIAMポリシーを紐付けるサービスアカウントを作成します。eksctl用のyamlファイルを用意します。

sa-external-dns.yml

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: cluster-sample
  region: ap-northeast-1

iam:
  withOIDC: true
  serviceAccounts:
    - metadata:
        name: external-dns
        namespace: kube-system
        labels:
          app.kubernetes.io/name: external-dns
      attachPolicyARNs:
        - "arn:aws:iam::xxxxxxxxxxxx:policy/ExternalDNSIAMPolicy"

eksctlを実行します。

$ eksctl create iamserviceaccount -f sa-external-dns.yml --approve --profile xxxx
[]  eksctl version 0.13.0
[]  using region ap-northeast-1
[]  1 iamserviceaccount(s) that already exist (kube-system/alb-ingress-controller) will be excluded
[]  1 iamserviceaccount (kube-system/external-dns) was included (based on the include/exclude rules)
[]  combined exclude rules: kube-system/alb-ingress-controller
[]  no iamserviceaccounts present in the current set were excluded by the filter
[!]  serviceaccounts that exists in Kubernetes will be excluded, use --override-existing-serviceaccounts to override
[]  1 task: { 2 sequential sub-tasks: { create IAM role for serviceaccount "kube-system/external-dns", create serviceaccount "kube-system/external-dns" } }
[]  building iamserviceaccount stack "eksctl-cluster-sample-addon-iamserviceaccount-kube-system-external-dns"
[]  deploying stack "eksctl-cluster-sample-addon-iamserviceaccount-kube-system-external-dns"
[]  created serviceaccount "kube-system/external-dns"

サービスアカウントが作成されている事を確認します。

kubectl get serviceaccount external-dns -n kube-system -o yaml結果

apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxxxxxxxx:role/eksctl-cluster-sample-addon-iamserviceaccoun-Role1-1UO6V35J8EAVP
  creationTimestamp: "2020-02-02T09:21:18Z"
  labels:
    app.kubernetes.io/name: external-dns
  name: external-dns
  namespace: kube-system
  resourceVersion: "27861"
  selfLink: /api/v1/namespaces/kube-system/serviceaccounts/external-dns
  uid: 5e83a074-459d-11ea-b9a5-0ab7d5b9f984
secrets:
- name: external-dns-token-bx26v

このサービスアカウントと紐づくClusterRoleとClusterRoleBindingを作成します。必要となるマニフェストファイルを用意します。

clusterrole-external-dns.yml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
  labels:
    app.kubernetes.io/name: external-dns
rules:
  - apiGroups:
      - ""
      - extensions
    resources:
      - services
      - pods
      - ingresses
    verbs:
      - get
      - watch
      - list
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - watch
      - list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns
  labels:
    app.kubernetes.io/name: external-dns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
  - kind: ServiceAccount
    name: external-dns
    namespace: kube-system

kubectlを実行します。

$ kubectl apply -f clusterrole-external-dns.yml
clusterrole.rbac.authorization.k8s.io/external-dns created
clusterrolebinding.rbac.authorization.k8s.io/external-dns created

ExternalDNSの処理を実行してくれるpodを作成します。必要となるマニフェストを用意します。

deploy-external-dns.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  namespace: kube-system
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: registry.opensource.zalan.do/teapot/external-dns:latest
        args:
        - --source=service
        - --source=ingress
        - --domain-filter=goodbyegangster.com # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
        - --provider=aws
        - --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
        - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
        - --registry=txt
        - --txt-owner-id=<Route53 HostzoneのID>
      securityContext:
        fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes and AWS token files

kubectlを実行します。

$ kubectl apply -f deploy-external-dns.yml
deployment.apps/external-dns created

podが作成されていることを確認します。

$ kubectl get deploy external-dns -n kube-system
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
external-dns   1/1     1            1           62s
$
$ kubectl get pod -n kube-system -l app=external-dns
NAME                            READY   STATUS    RESTARTS   AGE
external-dns-59d8d76b8c-dx8vm   1/1     Running   0          114s
$
$ kubectl logs external-dns-59d8d76b8c-dx8vm -n kube-system
...
time="2020-02-02T11:56:49Z" level=info msg="Instantiating new Kubernetes client"
time="2020-02-02T11:56:49Z" level=info msg="Using inCluster-config based on serviceaccount-token"
time="2020-02-02T11:56:49Z" level=info msg="Created Kubernetes client https://172.20.0.1:443"
time="2020-02-02T11:56:54Z" level=info msg="All records are already up to date"

サンプルWEBサイト用のIngressリソースの作成

Ingressリソースを作成して、ALBを作成します。以下のIngress用のマニフェストファイルを用意します。

ing-nginx.yml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
  namespace: sample
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-1:XXXXXXXXXX:certificate/ef62a474-e261-4039-a89a-d6955b6a384c
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=awslogs-elb-XXXXXXXXXX,access_logs.s3.prefix=sample-nginx
    alb.ingress.kubernetes.io/tags: TagKey=TagValue
  labels:
    app: ingress-nginx
spec:
  rules:
    - host: sample.goodbyegangster.com
      http:
        paths:
          - path: /*
            backend:
              serviceName: ssl-redirect
              servicePort: use-annotation
          - path: /*
            backend:
              serviceName: service-sample-nginx
              servicePort: 80

annotations で指定する値にて、ALBの各パラメータを細かく設定できます。

Ingress annotations

下記はHTTPSへのリダイレクトルールを作成する場合のサンプル・マニフェストファイルです。

Redirect Traffic from HTTP to HTTPS

kubectlを実行します。

$ kubectl apply -f ing-nginx.yml

これにてALBが作成されます。暫くしたらALBがActiveとなるので、以下のコマンドでALBのエンドポイント経由でWEBサイトにアクセスしてみます。

$ curl -k -H 'Host:goodbyegangster.com' https://<ALBのエンドポイント名>
deployment-sample-nginx-8c56d66c9-4pkqk

なおこの時に、EKS Worker Nodeにアタッチされたセキュリティグループに対して、必要なポリシー情報が自動的に追加されています。

ALBが作成されると同時に、Route53へもレコードが登録されています。ExternalDNSのpodのログを確認して、処理が正しく実行されている事を確認します。

$ kubectl logs external-dns-59d8d76b8c-dx8vm -n kube-system
...
time="2020-02-02T11:59:52Z" level=info msg="All records are already up to date"
time="2020-02-02T12:00:52Z" level=info msg="Desired change: CREATE sample.goodbyegangster.com A [Id: /hostedzone/xxxxxxxxxxxxxx]"
time="2020-02-02T12:00:52Z" level=info msg="Desired change: CREATE sample.goodbyegangster.com TXT [Id: /hostedzone/xxxxxxxxxxxxxx]"
time="2020-02-02T12:00:52Z" level=info msg="2 record(s) in zone goodbyegangster.com. [Id: /hostedzone/xxxxxxxxxxxxxx] were successfully updated"

最後に、実際にRoute53に登録されたDNS名でWEBサイトにアクセスしてみます。

$ curl https://sample.goodbyegangster.com/
deployment-sample-nginx-8c56d66c9-4pkqk