Github Actions um Golden Images with HashiCorp Packer zu bauen
In früheren Beiträgen haben wir bereits verschiedene Möglichkeiten gezeigt, wie man mit HashiCorp Packer Golden Images erstellt. In diesem Beitrag zeigen wir,
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.
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.
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.
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.
Sie benötigen fünf Dinge:
kubernetes.io/cluster/<YOUR_CLUSTER_NAME> = shared
kubernetes.io/role/elb = 1
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}
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
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.
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.
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
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
Zusammenfassend haben wir in diesem Beitrag Folgendes gelernt:
alb.ingress.kubernetes.io
und external-dns.alpha.kubernetes.io
, bieten zusätzliche Konfigurationsoptionen für Load Balancer, SSL-Terminierung und DNS-Zuordnungen.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