loading...
Cover image for ExternalDNS, Istio y AWS Route 53

ExternalDNS, Istio y AWS Route 53

samcre profile image Sam ・4 min read

En el anterior artículo dejaste configurado Istio y cert-manager para que trabajaran juntos sirviendo pods del service mesh sobre HTTPS. Menuda gozada, ¿verdad? Pero hasta que no configurasteis el registro DNS en vuestro proveedor, evidentemente, no se podía acceder. Hacer cosas a mano, ¿qué año es este? ¿2017?

En este artículo vamos a dejar instalado y configurado en el clúster la utilidad ExternalDNS, que se encargará de actualizar automáticamente nuestro proveedor de DNS basándose en los hosts configurados en los Gateways de Istio.

ExternalDNS es compatible con más de 15 proveedores de DNS, aunque solo dos de manera estable (GCloud y AWS Route 53), y es relativamente fácil de instalar y configurar en nuestro clúster. En esta parte, seguiremos con el ejemplo del artículo anterior, y vamos a integrarlo con AWS Route 53, para que cree automáticamente en Route 53 los hosts que activemos en los Gateways de Istio.

Configuración previa

Al igual que con cert-manager, y con todo en AWS, necesitamos crear una policy de IAM que otorgue al clúster o los pods que ejecuten ExternalDNS los permisos necesarios para trabajar con Route 53. En la propia documentación de ExternalDNS podemos encontrar el JSON que la define, pero básicamente es esta:

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

Creo que es importante señalar que la línea "Resource": ["arn:aws:route53:::hostedzone/*"] otorga permisos demasiado abiertos, y deberíamos modificarla indicando única y exclusivamente el ZONE_ID de las zonas que queremos que ExternalDNS gestione por nosotros.

Evidentemente, ya deberemos tener creada una zona DNS en AWS para que sea gestionada por ExternalDNS, porque esta utilidad no las crea.

Instalando y configurando ExternalDNS

Para instalar ExternalDNS tenemos disponible un chart de Helm, pero su fichero YAML de despliegue es tan sencillo, que nos vamos a limitar a copiarlo, y modificar los parámetros que integrarán ExternalDNS con Route 53. Si lo instaláis con el chart, podéis compartir la configuración a seguir en los comentarios.

Guardamos en un fichero local el YAML anterior, y pasamos a editar la parte del Deployment. En concreto, los valores para args:

[...]
        args:
        - --source=service
        - --source=ingress
        - --source=istio-gateway
        - --istio-ingress-gateway=custom-istio-namespace/custom-istio-ingressgateway # load balancer service to be used; can be specified multiple times. Omit to use the default (istio-system/istio-ingressgateway)
        - --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-identifier
  • --source: Indicamos a ExternalDNS qué tipo de recursos dentro del clúster debe analizar para actualizar el DNS. Si solo vamos a usar istio-gateway, podemos dejar únicamente este.
  • --istio-ingress-gateway: Este flag solo es obligatorio si hemos creado o usamos un ingressgateway distintio al que Istio crea por defecto (istio-ingressgateway). De ser así, eliminamos o comentamos esta línea.
  • --domain-filter: Restringimos la actualización de DNS de ExternalDNS a uno o varios dominios. Si eliminamos este flag, actualizará cualquier dominio que encuentre. Esto va muy relacionado con crear un política de IAM con los permisos necesarios.
  • --provider: En este caso, aws, ya que lo queremos integrar con Route 53.
  • --policy: Por defecto usa el valor sync, que elimina registros DNS cuando no los encuentra en ninguno de los source configurados. El valor upsert-only simplemente añade nuevos registros al DNS.
  • --aws-zone-type: Indicamos que la(s) zona(s) que ha de gestionar tienen carácter privado o público en Route 53.

Una vez que hayáis modificado estas opciones a vuestras necesidades, aplicáis al clúster. Podéis instalarlo en su propio namespace:

kubectl apply -n externaldns -f externaldns.yaml

Cuando el pod esté en estado Running, si tenemos algún Gateway de Istio configurado, ExternalDNS empezará a crear registros DNS en Route 53. En caso de no tener aún nada, aplicamos nuestro Gateway y VirtualService, y en unos pocos minutos veremos en los logs del pod cómo empieza a añadir los registros:

time="2019-06-10T15:51:33Z" level=info msg="Desired change: CREATE nginx.example.com A"
time="2019-06-10T15:51:33Z" level=info msg="Desired change: CREATE nginx.example.com TXT"
time="2019-06-10T15:51:36Z" level=info msg="2 record(s) in zone example.com. were successfully updated"

Con estas opciones conseguiremos despreocuparnos de la configuración DNS, que ExternalDNS se encargará de gestionar por nosotros. Esta configuración puede sernos tremendamente útil para presentar en endpoints temporales, mediante Integración Continua, una nueva feature de nuestra web y, combinándolo con cert-manager, en un perfecto HTTPS.

Posted on by:

samcre profile

Sam

@samcre

I have no idea what I'm doing.

Discussion

pic
Editor guide