Amazon EKS mit ALB und External DNS für Route 53


Bicycle

Amazon EKS mit ALB und External DNS für Route 53

Was ist Amazon EKS?

Amazon Elastic Kubernetes Service (Amazon EKS) ist ein verwalteter Service auf AWS, der die manuelle Installation und Wartung einer Kubernetes Control Plane und Kubernetes-Knoten überflüssig macht. Es gewährleistet eine hohe Verfügbarkeit, indem es die Control Plane über mehrere AWS Availability Zones ausführt und skaliert. Der Service übernimmt automatisch die Skalierung der Control Plane-Instanz, den Austausch ungesunder Instanzen und bietet Versions-Updates und Patches. Amazon EKS lässt sich in verschiedene AWS-Services integrieren, darunter Amazon ECR, Elastic Load Balancing, IAM und Amazon VPC, um Skalierbarkeit und Sicherheit zu gewährleisten. Es unterstützt die Verwendung bestehender Kubernetes-Plugins und -Werkzeuge, was eine nahtlose Migration von Anwendungen ohne Codeänderung ermöglicht. Anwendungen auf Amazon EKS sind mit Standard-Kubernetes-Umgebungen kompatibel, unabhängig von der Infrastruktur.

Warum sollten Sie diesen Beitrag lesen?

Als Entwickler suche ich ständig nach Möglichkeiten, meine Deployments zu automatisieren und zu vereinfachen.

Das Einrichten eines Amazon EKS-Clusters mit automatisierten Konfigurationen ermöglicht ein müheloses Management von containerisierten Anwendungen mit Skalierbarkeit und Sicherheit. Durch die Automatisierung wesentlicher Komponenten wie External DNS und Load Balancing können wir uns auf Innovation und schnelle Entwicklung konzentrieren und das volle Potenzial unserer Anwendungen in einer stabilen und effizienten Kubernetes-Umgebung freisetzen.

In diesem Beitrag möchte ich Ihnen zeigen, wie Sie einen Amazon EKS-Cluster einrichten und External DNS und den AWS Load Balancer Controller konfigurieren können, um DNS-Verwaltung und Lastausgleichsfunktionen innerhalb des Clusters zu aktivieren.

Was ist ALB?

Der AWS Load Balancer Controller vereinfacht die Verwaltung von AWS Elastic Load Balancers innerhalb eines Kubernetes-Clusters. Er stellt AWS Application Load Balancers (ALBs) für Kubernetes-Ingress und AWS Network Load Balancers (NLBs) für LoadBalancer-artige Services bereit.

Was ist External DNS?

External DNS für EKS ist ein Tool, das die Verwaltung von DNS-Einträgen für Ressourcen automatisiert, die in einem Amazon Elastic Kubernetes Service (EKS)-Cluster laufen. Es ermöglicht die Definition von DNS-Einträgen für Kubernetes-Services und Ingress-Ressourcen und erstellt oder aktualisiert automatisch DNS-Einträge in einem bestimmten DNS-Anbieter (z. B. AWS Route 53) auf der Grundlage von Änderungen im Cluster.

Was sind die Voraussetzungen?

Sie benötigen fünf Dinge:

  • Grundlegendes Verständnis von Kubernetes
  • Einen AWS Account
  • Ein VPC in AWS mit den folgenden Subnetz Tags:
    • kubernetes.io/cluster/<YOUR_CLUSTER_NAME> = shared
    • kubernetes.io/role/elb = 1
  • Ein Hosted Zone Eintrag in Route 53
  • Ein AWS Certificate Manager (ACM) Eintrag für den gewünschten Domänenname (z. B. *.example.com)

IAM-Policies erstellen

Damit External DNS und ALB ihre Arbeit machen können, benötigen sie einige Berechtigungen in AWS. Zum Glück für uns ist es einfach, diese zu erstellen. Kopieren wir einfach die folgende Berechtigung und erstellen eine Richtlinie mit dem Namen AllowExternalDNSUpdates und wir dürfen nicht vergessen, <YOUR_ROUTE_53_ZONE_ID> in die gehostete Zonen-ID unserer DNS-Zone in Route 53 zu ändern:

 1{
 2    "Version": "2012-10-17",
 3    "Statement": [
 4        {
 5            "Effect": "Allow",
 6            "Action": [
 7                "route53:ChangeResourceRecordSets"
 8            ],
 9            "Resource": [
10                "arn:aws:route53:::hostedzone/<YOUR_ROUTE_53_ZONE_ID>"
11            ]
12        },
13        {
14            "Effect": "Allow",
15            "Action": [
16                "route53:ListHostedZones",
17                "route53:ListResourceRecordSets"
18            ],
19            "Resource": [
20                "*"
21            ]
22        }
23    ]
24}

AllowExternalDNSUpdates Policy

Jetzt fehlt nur noch die Richtlinie AWSLoadBalancerControllerIAMPolicy. Wir können die Richtlinie abrufen und erstellen, indem wir die folgenden Befehle in der AWS-CLI ausführen:

1$ curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.7/docs/install/iam_policy.json
2
3$ aws iam create-policy \
4    --policy-name AWSLoadBalancerControllerIAMPolicy \
5    --policy-document file://iam_policy.json

Einrichten des EKS-Clusters

Nun, da wir unsere Richtlinien haben, müssen wir nur noch unseren EKS-Cluster einrichten und ein einziges Skript ausführen, um alles für die Deployments vorzubereiten.

Amazon EKS

AWS führt uns durch die Erstellung des Clusters. Wir sollten jedoch darauf achten, dass wir den Cluster als öffentlichen Cluster erstellen, da dies die Einrichtung erheblich vereinfacht.

Nachdem die Erstellung des Clusters abgeschlossen ist, wählen wir den Cluster aus und wechseln zum Compute-Tap und fahren mit der Erstellung einer Node Group fort.

Compute Tap

Sobald alles fertig ist, führen wir unser Skript auf der AWS-CLI desselben Kontos aus, das den Cluster erstellt hat, und warten einfach, bis es fertig ist! Wir dürfen allerdings nicht vergessen, die Variablen CLUSTER_NAME, REGION und NAMESPACE auf die richtigen Werte für unsere Anwendung zu ändern.

  1#!/bin/bash
  2set -e
  3
  4# Sets up variables for the cluster name, region, namespace and account ID.
  5CLUSTER_NAME=mycluster
  6REGION=eu-central-1
  7NAMESPACE=demo
  8ACCOUNT_ID=$(aws sts get-caller-identity | python3 -c "import sys,json; print (json.load(sys.stdin)['Account'])")
  9
 10# Updates the kubeconfig for the specified EKS cluster.
 11aws eks --region $REGION update-kubeconfig --name $CLUSTER_NAME
 12
 13# Installs OpenSSL, downloads Helm 3, and makes it executable.
 14sudo yum install openssl -y
 15curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
 16chmod 700 get_helm.sh
 17./get_helm.sh
 18
 19# Creates a Kubernetes namespace.
 20kubectl create namespace $NAMESPACE
 21
 22# for ARM systems, set ARCH to: `arm64`, `armv6` or `armv7`
 23ARCH=amd64
 24PLATFORM=$(uname -s)_$ARCH
 25
 26# Downloads and extracts the eksctl utility.
 27curl -sLO "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
 28
 29# (Optional) Verify checksum
 30curl -sL "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_checksums.txt" | grep $PLATFORM | sha256sum --check
 31
 32tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
 33
 34sudo mv /tmp/eksctl /usr/local/bin
 35
 36# Associates the IAM OIDC provider with the EKS cluster.
 37eksctl utils associate-iam-oidc-provider \
 38    --region=$REGION \
 39    --cluster=$CLUSTER_NAME \
 40    --approve
 41
 42# Creates IAM service accounts for external-dns and aws-load-balancer-controller, attaching the appropriate IAM policies.
 43eksctl create iamserviceaccount \
 44    --name external-dns \
 45    --cluster $CLUSTER_NAME \
 46    --attach-policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates \
 47    --approve \
 48    --override-existing-serviceaccounts \
 49    --namespace $NAMESPACE
 50
 51eksctl create iamserviceaccount \
 52    --name aws-load-balancer-controller \
 53    --cluster $CLUSTER_NAME \
 54    --attach-policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy \
 55    --region $REGION \
 56    --approve \
 57    --override-existing-serviceaccounts \
 58    --namespace=kube-system
 59
 60# Adds the EKS Helm repository and updates the repositories.
 61helm repo add eks https://aws.github.io/eks-charts
 62helm repo update eks
 63
 64# Installs the aws-load-balancer-controller using Helm, specifying the cluster name and service account details.
 65helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
 66  -n kube-system \
 67  --set clusterName=$CLUSTER_NAME \
 68  --set serviceAccount.create=false \
 69  --set serviceAccount.name=aws-load-balancer-controller
 70
 71# Applies Kubernetes resources (ClusterRole, ClusterRoleBinding, and Deployment) for external-dns.
 72# Configures the external-dns Deployment with necessary parameters, including the domain filter, AWS provider, and AWS zone type.
 73kubectl apply -f - <<EOF
 74apiVersion: rbac.authorization.k8s.io/v1
 75kind: ClusterRole
 76metadata:
 77  name: external-dns
 78  namespace: $NAMESPACE
 79rules:
 80- apiGroups: [""]
 81  resources: ["services"]
 82  verbs: ["get","watch","list"]
 83- apiGroups: [""]
 84  resources: ["pods"]
 85  verbs: ["get","watch","list"]
 86- apiGroups: ["networking","networking.k8s.io"]
 87  resources: ["ingresses"]
 88  verbs: ["get","watch","list"]
 89- apiGroups: [""]
 90  resources: ["nodes"]
 91  verbs: ["get","watch","list"]
 92- apiGroups: [""]
 93  resources: ["endpoints"]
 94  verbs: ["get","watch","list"]
 95---
 96apiVersion: rbac.authorization.k8s.io/v1
 97kind: ClusterRoleBinding
 98metadata:
 99  name: external-dns-viewer
100  namespace: $NAMESPACE
101roleRef:
102  apiGroup: rbac.authorization.k8s.io
103  kind: ClusterRole
104  name: external-dns
105subjects:
106- kind: ServiceAccount
107  name: external-dns
108  namespace: wherebear
109---
110apiVersion: apps/v1
111kind: Deployment
112metadata:
113  name: external-dns
114  namespace: $NAMESPACE
115spec:
116  strategy:
117    type: Recreate
118  selector:
119    matchLabels:
120      app: external-dns
121  template:
122    metadata:
123      labels:
124        app: external-dns
125    spec:
126      serviceAccountName: external-dns
127      containers:
128      - name: external-dns
129        image: k8s.gcr.io/external-dns/external-dns:v0.13.4
130        args:
131        - --source=service
132        - --source=ingress
133        - --domain-filter=wherebear.app # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
134        - --provider=aws
135        #- --policy=upsert-only # would prevent ExternalDNS from deleting any records, omit to enable full synchronization
136        - --aws-zone-type=public # only look at public hosted zones (valid values are public, private or no value for both)
137        - --registry=txt
138        - --txt-owner-id=wherebear-eks-cluster-external-dns
139      securityContext:
140        fsGroup: 65534 # For ExternalDNS to be able to read Kubernetes and AWS token files
141EOF

Jetzt können wir unsere Anwendung bereitstellen und unter dem gewünschten Domänennamen darauf zugreifen, indem wir den Ingress für das jeweilige Deployment wie folgt einstellen. Bitte beachten Sie, dass Sie den Domänennamen, den Zertifikat-ARN, den Name des Dienstes, den Namensraum und den Name des Ingress entsprechend Ihren Anforderungen ändern müssen:

 1apiVersion: networking.k8s.io/v1
 2kind: Ingress
 3metadata:
 4  name: "<NAME_OF_INGRESS>"
 5  namespace: "<NAMESPACE>"
 6  annotations:
 7    # Below annotation is to specify if the loadbalancer is "internal" or "internet-facing"
 8    alb.ingress.kubernetes.io/scheme: internet-facing
 9    # TODO: Fill in with the ARN of your certificate.
10    alb.ingress.kubernetes.io/certificate-arn: <YOUR_CERTIFICATE_ARN>
11    # TODO: Fill in the listening ports.
12    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
13    # Set HTTP to HTTPS redirects. Every HTTP listener configured will be redirected to below mentioned port over HTTPS.
14    alb.ingress.kubernetes.io/ssl-redirect: '443'
15    alb.ingress.kubernetes.io/target-type: ip
16    external-dns.alpha.kubernetes.io/hostname: www.example.com
17spec:
18  ingressClassName: alb
19  rules:
20    - http:
21        paths:
22          - path: /
23            pathType: Prefix
24            backend:
25              service:
26                name: "<SERVICE_NAME>"
27                port:
28                  number: 80

Wie wird aufgeräumt?

Wenn wir unseren Cluster löschen und die erstellten Ressourcen bereinigen möchten, können wir dies tun, indem wir das folgende Skript in der AWS-CLI ausführen und den Cluster anschließend löschen:

 1#!/bin/bash
 2set -e
 3
 4CLUSTER_NAME=mycluster
 5REGION=eu-central-1
 6NAMESPACE=demo
 7ACCOUNT_ID=$(aws sts get-caller-identity | python3 -c "import sys,json; print (json.load(sys.stdin)['Account'])")
 8
 9eksctl delete iamserviceaccount \
10    --name external-dns \
11    --cluster $CLUSTER_NAME \
12    --namespace $NAMESPACE
13
14eksctl delete iamserviceaccount \
15    --name aws-load-balancer-controller \
16    --cluster $CLUSTER_NAME \
17    --namespace kube-system
18
19aws iam list-open-id-connect-providers
20ACCOUNT_ID=$(aws sts get-caller-identity | python3 -c "import sys,json; print (json.load(sys.stdin)['Account'])")
21echo $ACCOUNT_ID
22
23OIDCURL=$(aws eks describe-cluster --name $CLUSTER_NAME --region $REGION --query "cluster.identity.oidc.issuer" --output text  | python3 -c "import sys; print (sys.stdin.readline().replace('https://',''))")
24echo $OIDCURL
25aws iam delete-open-id-connect-provider --open-id-connect-provider-arn arn:aws:iam::$ACCOUNT_ID:oidc-provider/$OIDCURL
26aws iam list-open-id-connect-providers

Prüfen Sie abschließend, ob die Lastverteiler gelöscht wurden. Falls nicht, müssen Sie sie manuell löschen. Wenn Ihr VPC getaggt ist, können Sie auch das folgende Skript ausführen:

 1#!/bin/bash
 2set -e
 3
 4vpc_id=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=<YOUR_TAG_VALUE>" --query 'Vpcs[0].VpcId' --output text)
 5load_balancer_arns=$(aws elbv2 describe-load-balancers --query 'LoadBalancers[?VpcId==`'"$vpc_id"'`].LoadBalancerArn' --output text)
 6for arn in $load_balancer_arns; do
 7  aws elbv2 delete-load-balancer --load-balancer-arn $arn
 8done
 9
10security_group_ids=$(aws ec2 describe-security-groups --filters "Name=vpc-id,Values=$vpc_id" --query 'SecurityGroups[?starts_with(GroupName, `k8s-`)].GroupId' --output text)
11
12for sg_id in $security_group_ids; do
13  aws ec2 delete-security-group --group-id $sg_id
14done

Die Lessons Learned

Zusammenfassend haben wir in diesem Beitrag Folgendes gelernt:

  1. Amazon Elastic Kubernetes Service (Amazon EKS) ist ein verwalteter Service, der das Deployment und die Verwaltung von Kubernetes-Clustern auf AWS vereinfacht, sodass Sie sich auf Ihre Anwendungen und nicht auf die Einrichtung der Infrastruktur konzentrieren können.
  2. Der AWS Load Balancer Controller und External DNS sind wertvolle Tools für die Verwaltung des Lastausgleichs und der DNS-Verwaltung innerhalb eines EKS-Clusters und bieten Automatisierung und Vereinfachung.
  3. Die richtige IAM-Konfiguration (Identity and Access Management) ist entscheidend für die Erteilung der erforderlichen Berechtigungen für Ressourcen und die Gewährleistung eines sicheren Zugangs zu AWS-Services und EKS-Clustern.
  4. Anmerkungen innerhalb der Ingress-Konfiguration, wie alb.ingress.kubernetes.io und external-dns.alpha.kubernetes.io, bieten zusätzliche Konfigurationsoptionen für Load Balancer, SSL-Terminierung und DNS-Zuordnungen.
Zurück Unsere Trainings entdecken

Wir sind für Sie da

Sie interessieren sich für unsere Trainings oder haben einfach eine Frage, die beantwortet werden muss? Sie können uns jederzeit kontaktieren! Wir werden unser Bestes tun, um alle Ihre Fragen zu beantworten.

Hier kontaktieren