Come posso configurare ExternalDNS con Amazon EKS?

Ultimo aggiornamento: 01/03/2022

Voglio configurare ExternalDNS con il mio Amazon Elastic Kubernetes Service (Amazon EKS).

Breve descrizione

ExternalDNS è un pod che viene eseguito nel cluster Amazon EKS. Per utilizzare ExternalDNS come plug-in con Amazon EKS, devi configurare le autorizzazioni di AWS Identity and Access Management (IAM) per permettere ad Amazon EKS l'accesso ad Amazon Route 53.

Nota: assicurati che esistano un nome di dominio e una zona ospitata Route 53.

Risoluzione

Configura le autorizzazioni IAM e implementa ExternalDNS

1.    Imposta le autorizzazioni IAM per concedere al pod di ExternalDNS le autorizzazioni per creare, aggiornare ed eliminare i record di Route 53 nel tuo account AWS.

Policy 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: puoi anche modificare la policy precedente per permettere gli aggiornamenti degli ID delle zone ospitate esplicite.

2.    Crea un ruolo IAM per l'account del servizio utilizzando la policy precedente:

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

Nota: sostituisci SERVICE_ACCOUNT_NAME con il nome del tuo account di servizio,NAMESPACE con il tuo spazio dei nomi,CLUSTER_NAME con il nome del cluster e IAM_POLICY_ARN con l'ARN della tua policy IAM.

Per controllare il nome del tuo account di servizio, esegui il seguente comando:

kubectl get sa

Output di esempio:

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

Nell'output di esempio precedente, external-dns è il nome che è stato dato all'account del servizio quando è stato creato.

3.    Implementa ExternalDNS.

Verifica se l'RBAC è abilitato nel tuo cluster Amazon EKS:

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

Nota: prima di applicare i seguenti manifesti, controlla la versione più recente di ExternalDNS (dal sito Web GitHub).

Esegui il seguente comando:

kubectl apply DEPLOYMENT_MANIFEST_FILE_NAME.yaml

Nota: sostituisci DEPLOYMENT_MANIFEST_FILE_NAME con il nome del file del manifesto di implementazione.

Se RBAC è abilitato, utilizza il seguente manifesto per implementare 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

Se RBAC non è abilitato, utilizza il seguente manifesto per implementare 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.    Verifica che l’implementazione sia andata a buon fine:

kubectl get deployments

Output di esempio:

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

Puoi anche controllare i registri per verificare che i record siano aggiornati:

kubectl logs external-dns-9f85d8d5b-sx5fg

Output di esempio:

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

Verifica che ExternalDNS funzioni

1.    Crea un servizio che sia esposto come LoadBalancer e che possa essere instradato esternamente tramite il nome di dominio ospitato su Route 53:

kubectl apply SERVICE_MANIFEST_FILE_NAME.yaml

Nota: sostituisci SERVICE_MANIFEST_FILE_NAME con il nome del file del manifesto del servizio.

Manifesto:

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: sostituisci DOMAIN_NAME con il nome del tuo dominio.

2.    Verifica che il servizio NGINX sia stato creato con il tipo LoadBalancer:

kubectl get svc

Output di esempio:

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: il servizio crea automaticamente un record Route 53 per la zona ospitata.

Controlla i registri per verificare che sia stato creato il record Route 53:

kubectl logs external-dns-9f85d8d5b-sx5fg

Output di esempio:

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

Per ulteriori informazioni su come configurare e verificare ExternalDNS, consulta Configurazione di ExternalDNS per i servizi in AWS (dal sito Web GitHub).


Questo articolo è stato utile?


Hai bisogno di supporto tecnico o per la fatturazione?