Come posso configurare ExternalDNS con Amazon EKS?

6 minuti di lettura
0

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 plugin con Amazon EKS, configura le autorizzazioni AWS Identity and Access Management (IAM). Queste autorizzazioni devono consentire ad Amazon EKS di accedere ad Amazon Route 53.

Nota: prima di iniziare la seguente risoluzione, assicurati che esistano un nome di dominio e una zona ospitata sulla 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 è attivo 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 è attivo, 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 è attivo, 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 ed esempi di DNS esterno, consulta Configurazione di DNS esterni per i servizi su AWS (sul sito Web di GitHub) e Configurazione di DNS esterni (sul sito Web di Kubernetes).


AWS UFFICIALE
AWS UFFICIALEAggiornata un anno fa