¿Cómo configuro ExternalDNS con Amazon EKS?
Quiero configurar ExternalDNS con mi Amazon Elastic Kubernetes Service (Amazon EKS).
Descripción breve
ExternalDNS es un pod que se ejecuta en el clúster de Amazon EKS. Para usar ExternalDNS como complemento con Amazon EKS, configure los permisos de AWS Identity and Access Management (IAM). Estos permisos deben permitir el acceso de Amazon EKS a Amazon Route 53.
Nota: Antes de iniciar la siguiente resolución, asegúrese de que exista un nombre de dominio y una zona alojada de Route 53.
Resolución
Configure los permisos de IAM e implemente ExternalDNS
1. Configure los permisos de IAM para otorgar al pod ExternalDNS permisos para crear, actualizar y eliminar registros de Route 53 en su cuenta de AWS.
Política de IAM:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "route53:ChangeResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/*" ] }, { "Effect": "Allow", "Action": [ "route53:ListHostedZones", "route53:ListResourceRecordSets" ], "Resource": [ "*" ] } ] }
Nota: También puede ajustar la política anterior para permitir las actualizaciones de los ID de zona alojada explícitos.
2. Utilice la política anterior para crear un rol de IAM para la cuenta de servicio:
eksctl create iamserviceaccount --name SERVICE_ACCOUNT_NAME --namespace NAMESPACE --cluster CLUSTER_NAME --attach-policy-arn IAM_POLICY_ARN --approve
Nota: Reemplace SERVICE_ACCOUNT_NAME por el nombre de su cuenta de servicio, NAMESPACE por su espacio de nombres, CLUSTER_NAME por el nombre de su clúster e IAM_POLICY_ARN por el ARN de su política de IAM.
Para comprobar el nombre de su cuenta de servicio, ejecute el siguiente comando:
kubectl get sa
Resultado de ejemplo:
NAME SECRETS AGE default 1 23h external-dns 1 23h
En el resultado del ejemplo anterior, external-dns es el nombre que se le dio a la cuenta de servicio cuando se creó.
3. Implemente ExternalDNS.
Compruebe si el control de acceso basado en roles (RBAC) está activado en su clúster de Amazon EKS:
kubectl api-versions | grep rbac.authorization.k8s.io
Nota: Antes de aplicar los siguientes manifiestos, busque la última versión de ExternalDNS (desde el sitio web de GitHub).
Ejecute el siguiente comando:
kubectl apply DEPLOYMENT_MANIFEST_FILE_NAME.yaml
Nota: Reemplace DEPLOYMENT_MANIFEST_FILE_NAME por el nombre del archivo de manifiesto de implementación.
Si el RBAC está activado, utilice el siguiente manifiesto para implementar 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
Si el RBAC no está activado, utilice el siguiente manifiesto para implementar 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>
4. Compruebe que la implementación se haya realizado correctamente:
kubectl get deployments
Resultado de ejemplo:
NAME READY UP-TO-DATE AVAILABLE AGE external-dns 1/1 1 1 85m
También puede revisar los registros para comprobar que estén actualizados:
kubectl logs external-dns-9f85d8d5b-sx5fg
Resultado de ejemplo:
.... .... 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" .... ....
Compruebe que ExternalDNS esté funcionando
1. Cree un servicio que se exponga como LoadBalancer y que se pueda dirigir externamente a través del nombre de dominio que se aloja en Route 53:
kubectl apply SERVICE_MANIFEST_FILE_NAME.yaml
Nota: Reemplace SERVICE_MANIFEST_FILE_NAME por el nombre del archivo de manifiesto de servicio.
Manifiesto:
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
Nota: Reemplace DOMAIN_NAME por el nombre de su dominio.
2. Compruebe que el servicio NGINX se haya creado con el tipo LoadBalancer:
kubectl get svc
Resultado de ejemplo:
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
Nota: El servicio crea automáticamente un registro de Route 53 para la zona alojada.
Revise los registros para comprobar que se haya creado el registro de Route 53:
kubectl logs external-dns-9f85d8d5b-sx5fg
Resultado de ejemplo:
... ... ... 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" ... ... ...
Para obtener más información y ejemplos de ExternalDNS, consulte Configuración de ExternalDNS para servicios en AWS (en el sitio web de GitHub) y Configuración de ExternalDNS (en el sitio web de Kubernetes).

Contenido relevante
- OFICIAL DE AWSActualizada hace 4 meses
- OFICIAL DE AWSActualizada hace 7 meses