3sky's notes

Minimalistyczny blog o TI.

EKS na szybko

2021-08-01 3 min czytania 3sky

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?