Comment configurer ExternalDNS avec Amazon EKS ?

Dernière mise à jour : 01-03-2022

Je souhaite configurer ExternalDNS avec mon Amazon Elastic Kubernetes Service (Amazon EKS).

Brève description

ExternalDNS est un pod qui s'exécute dans votre cluster Amazon EKS. Pour utiliser ExternalDNS en tant que plugin avec votre Amazon EKS, vous devez configurer les autorisations AWS Identity and Access Management (IAM) afin d'autoriser Amazon EKS à accéder à Amazon Route 53.

Remarque : Assurez-vous qu'un nom de domaine et une zone hébergée Route 53 existent.

Résolution

Configurer les autorisations IAM et déployer ExternalDNS

1.    Configurez les autorisations IAM pour donner au pod ExternalDNS les autorisations nécessaires pour créer, mettre à jour et supprimer des registres Route 53 dans votre compte AWS.

Politique IAM :

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

Remarque : Vous pouvez également ajuster la politique précédente pour autoriser les mises à jour des ID de zone hébergée explicites.

2.    Créez un rôle IAM pour le compte de service à l'aide de la politique précédente :

eksctl create iamserviceaccount --name SERVICE_ACCOUNT_NAME --namespace NAMESPACE --cluster CLUSTER_NAME --attach-policy-arn IAM_POLICY_ARN --approve

Remarque : remplacez SERVICE_ACCOUNT_NAME par le nom de votre compte de service, NAMESPACE par votre espace de noms, CLUSTER_NAME par le nom de votre cluster et IAM_POLICY_ARN par l'ARN de votre politique IAM.

Pour vérifier le nom de votre compte de service, exécutez la commande suivante :

kubectl get sa

Exemple de résultat :

NAME           SECRETS   AGE
default        1         23h
external-dns   1         23h

Dans l'exemple de sortie précédent, external-dns est le nom qui a été donné au compte de service lors de sa création.

3.    Déployez ExternalDNS.

Vérifiez si le RBAC est activé dans votre cluster Amazon EKS :

kubectl api-versions | grep rbac.authorization.k8s.io

Remarque : Avant d'appliquer les manifestes suivants, recherchez ladernière version d'ExternalDNS (sur le site internet GitHub).

Exécutez la commande suivante :

kubectl apply DEPLOYMENT_MANIFEST_FILE_NAME.yaml

Remarque : remplacez DEPLOYMENT_MANIFEST_FILE_NAME par le nom de votre fichier votre manifeste de déploiement.

Si RBAC est activé, utilisez le manifeste suivant pour déployer 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 RBAC n'est pas activé, utilisez le manifeste suivant pour déployer 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.    Vérifiez que le déploiement a été réalisé avec succès :

kubectl get deployments

Exemple de résultat :

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
external-dns   1/1     1            1           85m

Vous pouvez également consulter les journaux pour vérifier que les registres sont à jour :

kubectl logs external-dns-9f85d8d5b-sx5fg

Exemple de résultat :

....
....
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"
....
....

Vérifiez que ExternalDNS fonctionne

1.    Créez un service exposé en tant queLoadBalancer et qui peut être acheminé en externe via le nom de domaine hébergé sur Route 53 :

kubectl apply SERVICE_MANIFEST_FILE_NAME.yaml

Remarque : RemplacezSERVICE_MANIFEST_FILE_NAME par le nom de fichier manifeste de votre service.

Manifeste :

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

Remarque : remplacez DOMAIN_NAME par votre nom de domaine.

2.    Vérifiez que le service NGINX a été créé avec le type LoadBalancer :

kubectl get svc

Exemple de résultat :

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

Remarque : Le service crée automatiquement un registre Route 53 pour la zone hébergée.

Consultez les journaux pour vérifier que le registre Route 53 a été créé :

kubectl logs external-dns-9f85d8d5b-sx5fg

Exemple de résultat :

...
...
...
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"
...
...
...

Pour en savoir plus sur comment configurer et vérifier ExternalDNS, consultezConfiguration d'ExternalDNS pour les services sur AWS (à partir du site internet GitHub).


Cet article vous a-t-il été utile ?


Besoin d'aide pour une question technique ou de facturation ?