EKS na szybko
Witam
Zbudujmy trochę rzeczy. Dzisiaj na AWS(EKS). Dzisiaj z popularnymi narzędziami, i prawie bez programowania(w YAMLu). Dziś ze szczególnym uwzględnieniem szybkości i prostoty. Dadatkowo nie ma CI/CD.
Komponenty
Zachowam tą listę prostą.
Budowania infrastruktury
Organizacja
Pierwsze kroki. Potrzebuję zbudować jakąś infrastrukturę. Prawię każdy używa Terraforma do budowania i zarządzania zasobami, użyję go więc i ja. Na bazie Terraformowego modułu dla EKS zbudowałem prosty manifest. Dodatkowo zdecydowałem się na dodanie ECR i konfigurację outputów w specyficzny sposób.
# chciałem dostać endpoint control planu
output "cluster_endpoint" {
description = "Endpoint for EKS control plane."
value = module.eks.cluster_endpoint
}
# cluster_name jest potrzebny do uzyskania kubeconfigu
output "cluster_name" {
description = "Name of created cluster"
value = local.cluster_name
}
# nazwa ECR'a generowanego dynamicznie
output "ecr_url" {
description = "URL of ECR registry"
value = aws_ecr_repository.ecr.repository_url
}
# region również może być dynamiczny
output "region" {
description = "AWS region."
value = var.region
}
Variables.tf
oraz main.tf
nie są zbyt interesujące, w związku z tym wylądują w repozytorium.
Przepływ komend
# pobranie modulów
terraform init
# spojrzenie na plan
terraform plan | less
# ten krok może chwilę potrwać (9:33.03 total)
# jeżeli plan jest poprawny wprowadź yes, lub użyj falgi -auto-approve
terraform apply
Kubectl i ECR
Czy jest tam ktoś?
Po zbudowaniu klastra, chcemy sprawdzić czy owy klaster działa. W tym celu muszę uaktualnić mój kubeconfig na potrzeby autentykacji. Aby to uzyskać potrzebuję AWS CLI oraz kubectl.
# zmienne oparte na wyniku terraforma
aws eks update-kubeconfig \
--region $(terraform output -raw region) \
--name $(terraform output -raw cluster_name)
kubectl get pod
Docker login
Teraz muszę zalogować się do ECR.
aws ecr get-login-password \
--region $(terraform output -raw region) \
| docker login --username AWS \
--password-stdin $(terraform output -raw ecr_url | cut -d'/' -f1)
Nastepnie mogę umieścić fantastyczny obraz Nginx’a w ECR.
docker tag nginx:latest $(terraform output -raw ecr_url):1.0.0
docker push $(terraform output -raw ecr_url):1.0.0
Helming
Po tych wszystkich przygotowaniach, moge finalnie wdrożyć moją aplikację. W ramach tego procesu zdecydowałem się użyć helma. Jest to standardowe, bardzo popularne i elastyczne rozwjązanie. Po raz kolejny Helmowy Chart zostanie dołączony do repozytorium. Nie zawiera żadnych haków, badź magii - po prostu nudne szablony.
Przepływ komend
# wywołanie testowe
helm template <app name> -f <file with values> --dry-run <chart name>
# dla przykładu
# helm template example-app -f example-app.yaml --dry-run ./example-app
# zainstalowanie chartu
helm install <app name> -f <file with values> --namespace <namespace> <chart name>
# dla przykładu
# helm install example-app -f example-app.yaml --namespace example ./example-app
# aktualizacja aplikacji
helm upgrade <app name> <chart> --set.image=<tag>
# dla przykładu
# helm upgrade example-app ./example-app --set=image.tag=2.0.0
DNS
Teraz jedyne co muszę zmienić to rekord DNS. Ah, zapomniałem o LoadBalancerze. Na potrzeby
tego artykułu używam typu LoadBalancer
. Po dodaniu takiego serwisu ELB dostarcza AWSowy
endpoint naszej aplikacji. Moją główną domeną jest 3sky.dev
, oddelegowałem ją do
CloudFlare, dlatego dodam rekord typy CNAME przez API.
Żeby to zrobić potrzebuję 4 komend i czasu(na propagację DNS)
# token
TOKEN=my-private-token
ZONE=my-domain-zone
ELB=$(kubectl get svc example-app -n example --output jsonpath='{.status.loadBalancer.ingress[0].hostname}')
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
--data '{"type":"CNAME","name":"app","content":"'"$ELB"'","ttl":1,"proxied":true}' | jq .
W końcu mogę sprawdzić moją aplikację na app.3sky.dev
. Uwiercie mi,
działała(aplikacja została zatrzymana po testach).
Podsumowanie
W przypadku podsumowania. Całe przedsięwzięcie było szybsze, niż napisanie tego postu z gotowego pliku README.md. Około 10 minut EKS, 30 minut propagacja DNS. Wywołanie komend było szybkie - mam szybką klawiaturę. Coż mogę powiedzieć więcej? Testowanie i implementacja rzeczy to wciąż zabawa. Co będzie kolejne? Nie mam pojęcia. Znowu zacząłem Elixira, więc może jakieś wyrafinowane CI/CD dla funkcyjnego języka?
- Repozytorium: GitHub