Amazon EKS で ExternalDNS を設定する方法
自分の Amazon Elastic Kubernetes サービス (Amazon EKS) で ExternalDNS を設定したいと考えています。
簡単な説明
ExternalDNS は Amazon EKS クラスターで実行されるポッドです。Amazon EKS で ExternalDNS をプラグインとして使用するには、AWS Identity and Access Management (IAM) のアクセス許可を設定します。これらのアクセス許可では、Amazon EKS に Amazon Route 53 へのアクセス許可を付与する必要があります。
注記: 次の解決方法を実施し始める前に、ドメイン名と Route 53 ホストゾーンが存在することを確認してください。
解決方法
IAM アクセス許可を設定して ExternalDNS をデプロイする
- AWS アカウント内に Route 53 レコードを作成、更新、削除するアクセス許可を ExternalDNS ポッドに付与するように、IAM アクセス許可を設定します。
IAM ポリシーは次のとおりです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/*" ] }, { "Effect": "Allow", "Action": [ "route53:ListHostedZones", "route53:ListResourceRecordSets" ], "Resource": [ "*" ] } ] }
注記: 前述のポリシーを調整して、明示的なホストゾーン ID の更新を許可することもできます。
- 前述のポリシーを使用して、サービスアカウントに IAM ロールを作成します。
eksctl create iamserviceaccount --name SERVICE_ACCOUNT_NAME --namespace NAMESPACE --cluster CLUSTER_NAME --attach-policy-arn IAM_POLICY_ARN --approve
注記: SERVICE_ACCOUNT_NAME をサービスアカウントの名前、NAMESPACE を名前空間、CLUSTER_NAME をクラスターの名前、そして IAM\ _POLICY\ _ARN を IAM ポリシーの ARN に置き換えてください。
サービスアカウントの名前を確認するには、次のコマンドを実行します。
kubectl get sa
出力例:
NAME SECRETS AGE default 1 23h external-dns 1 23h
上記の出力例では、external-dns はサービスアカウントにその作成時に付けられた名前です。
- ExternalDNS をデプロイします。
Amazon EKS クラスターで RBAC がオンになっているかどうかを確認します。
kubectl api-versions | grep rbac.authorization.k8s.io
注記: 次のマニフェストを適用する前に、 (GitHub のウェブサイトに) ExternalDNS の最新バージョンがあるかどうかを確認してください。
次のコマンドを実行します。
kubectl apply DEPLOYMENT_MANIFEST_FILE_NAME.yaml
注記: DEPLOYMENT_MANIFEST_FILE_NAME をデプロイマニフェストのファイル名に置き換えてください。
RBAC がオンになっている場合は、次のマニフェストを使用して ExternalDNS をデプロイします。
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services","endpoints","pods"] verbs: ["get","watch","list"] - apiGroups: ["extensions","networking.k8s.io"] resources: ["ingresses"] verbs: ["get","watch","list"] - apiGroups: [""] resources: ["nodes"] verbs: ["list","watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: external-dns-viewer roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: external-dns subjects: - kind: ServiceAccount name: external-dns namespace: default --- apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: serviceAccountName: external-dns containers: - name: external-dns image: k8s.gcr.io/external-dns/external-dns:v0.10.2 args: - --source=service - --source=ingress - --domain-filter=external-dns-test.my-org.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=my-hostedzone-identifier securityContext: fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes and AWS token files
RBAC がオンになっていない場合は、次のマニフェストを使用して ExternalDNS をデプロイします。
apiVersion: apps/v1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate selector: matchLabels: app: external-dns template: metadata: labels: app: external-dns spec: containers: - name: external-dns image: k8s.gcr.io/external-dns/external-dns:v0.10.2 args: - --source=service - --source=ingress - --domain-filter= <Your_R53_Domain_Name> # 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=<Your_R53_HostedZone_Id>
- デプロイが成功したことを確認します。
kubectl get deployments
出力例:
NAME READY UP-TO-DATE AVAILABLE AGE external-dns 1/1 1 1 85m
また、ログをチェックすれば、レコードが最新であることを確認することもできます。
kubectl logs external-dns-9f85d8d5b-sx5fg
出力例:
.... .... time="2022-02-10T20:22:02Z" level=info msg="Instantiating new Kubernetes client" time="2022-02-10T20:22:02Z" level=info msg="Using inCluster-config based on serviceaccount-token" time="2022-02-10T20:22:02Z" level=info msg="Created Kubernetes client https://10.100.0.1:443" time="2022-02-10T20:22:09Z" level=info msg="Applying provider record filter for domains: [<yourdomainname>.com. .<yourdomainname>.com.]" time="2022-02-10T20:22:09Z" level=info msg="All records are already up to date" .... ....
ExternalDNS が機能していることを確認
- LoadBalancer として公開されるサービスであると同時に、Route 53 でホストされているドメイン名を介して外部にルーティングできるサービスを作成します。
kubectl apply SERVICE_MANIFEST_FILE_NAME.yaml
注記: SERVICE_MANIFEST_FILE_NAME をサービスマニフェストのファイル名に置き換えてください。
マニフェストは次のとおりです。
apiVersion: v1 kind: Service metadata: name: nginx annotations: external-dns.alpha.kubernetes.io/hostname: DOMAIN_NAME spec: ports: - port: 80 targetPort: 80 protocol: TCP type: LoadBalancer selector: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx ports: - containerPort: 80 name: http
注記: DOMAIN_NAME を自身のドメイン名に置き換えてください。
- NGINX サービスが LoadBalancer タイプで作成されていることを確認します。
kubectl get svc
出力例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 26h nginx LoadBalancer 10.100.234.77 a1ef09255d52049f487e05b4f74faea6-954147917.us-west-1.elb.amazonaws.com 80:30792/TCP 74m
注記: このサービスは、Route 53 ホストゾーンレコードを自動的に作成します。
ログをチェックして、Route 53 レコードが作成されたことを確認します。
kubectl logs external-dns-9f85d8d5b-sx5fg
出力例:
... ... ... time="2022-02-10T21:22:43Z" level=info msg="Applying provider record filter for domains: [<domainname>.com. .<domainname>.com.]" time="2022-02-10T21:22:43Z" level=info msg="Desired change: CREATE <domainname>.com A [Id: /hostedzone/Z01155763Q6AN7CEI3AP6]" time="2022-02-10T21:22:43Z" level=info msg="Desired change: CREATE <domainname>.com TXT [Id: /hostedzone/Z01155763Q6AN7CEI3AP6]" time="2022-02-10T21:22:43Z" level=info msg="2 record(s) in zone xxx.com. [Id: /hostedzone/Z01155763Q6AN7CEI3AP6] were successfully updated" time="2022-02-10T21:23:43Z" level=info msg="Applying provider record filter for domains: [<domainname>.com. .<domainname>.com.]" time="2022-02-10T21:23:43Z" level=info msg="All records are already up to date" ... ... ...
ExternalDNS の詳細と例については、「AWS 上のサービス用の ExternalDNS の設定」(GitHub ウェブサイト) および「ExternalDNS の設定」(Kubernetes ウェブサイト) を参照してください。
関連するコンテンツ
- 質問済み 4年前lg...
- 質問済み 1年前lg...
- 質問済み 1年前lg...
- 質問済み 5ヶ月前lg...
- AWS公式更新しました 3ヶ月前
- AWS公式更新しました 2年前
- AWS公式更新しました 1年前
- AWS公式更新しました 1年前