Comment configurer ExternalDNS avec Amazon EKS ?

Lecture de 6 minute(s)
0

Je souhaite configurer ExternalDNS avec 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 Amazon EKS, configurez les autorisations Identity and Access Management (IAM) d'AWS. Ces autorisations doivent permettre à Amazon EKS d'accéder à Amazon Route 53.

Remarque : Avant de commencer la résolution suivante, assurez-vous qu'un nom de domaine et une zone hébergée par 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 de créer, mettre à jour et supprimer les enregistrements de la 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.    Utilisez la politique précédente pour créer un rôle IAM pour le compte de service :

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 sortie :

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, vérifiez la dernière version d'ExternalDNS (depuis le site Web GitHub).

Exécutez la commande suivante :

kubectl apply DEPLOYMENT_MANIFEST_FILE_NAME.yaml

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

Si le 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 le 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 s'est bien déroulé :

kubectl get deployments

Exemple de sortie :

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 enregistrements sont à jour :

kubectl logs external-dns-9f85d8d5b-sx5fg

Exemple de sortie :

....
....
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 qui s'affiche en tant que LoadBalancer et qui peut être routé de manière externe via le nom de domaine hébergé sur Route 53 :

kubectl apply SERVICE_MANIFEST_FILE_NAME.yaml

Remarque : Remplacez SERVICE_MANIFEST_FILE_NAME par le nom de fichier de votre manifeste de 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 le nom de votre domaine.

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

kubectl get svc

Exemple de sortie :

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 enregistrement Route 53 pour la zone hébergée.

Consultez les journaux pour vérifier que l'enregistrement Route 53 a été créé :

kubectl logs external-dns-9f85d8d5b-sx5fg

Exemple de sortie :

...
...
...
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 plus d'informations et d'exemples sur ExternalDNS, consultez Configuration d'ExternalDNS pour les services sur AWS (sur le site Web GitHub) et Configurer ExternalDNS (sur le site Web de Kubernetes).


AWS OFFICIEL
AWS OFFICIELA mis à jour il y a un an