
Prosjekt – Proof of concept med Amazon Web Services og Kafka. #1
I vår bransje har det de siste årene blitt veldig populært med Event Driven Architecture, Mikroservices og Kafka. Følg oss i utviklingen av en slik løsning med AWS, Kafka, Kubernetes, Kotlin og mer
Artikkelnummer | Andre artikler i denne serien |
---|---|
1 | Prosjekt – Proof of concept med Amazon Web Services og Kafka. #1 |
2 | Prosjekt – Proof of concept med Amazon Web Services og Kafka. #2 |
I Item ønsker vi å være oppdatert på hvordan markedet beveger seg. Vi strever etter kompetanse på løsninger og teknologier våre kunder allerede benytter, og som de ser for seg å bruke i framtiden.
Derfor har vi satt to av våre konsulenter til å utvikle et proof of concept for Event Driven Architecture-fremgangsmåten for å se på hvordan man kan utvikle en slik løsning, hvilke fallgruver som finnes, og gjøre oss opp noen tanker rundt hvordan vi best kan hjelpe våre kunder med å utvikle for Event Driven Architecture og spesielt Kafka. Utviklingen av denne løsningen vil i de kommende ukene bli omgjort til blogg-poster, og dette er nr. 1 av disse.
Første steg i prosessen var å avgjøre hvordan vi ville bygge opp strukturen og få en overordnet plan for prosjektet. Her finnes det en rekke teorier på best practice, men siden våre utviklere i dette prosjektet mer eller mindre står fritt til å velge uten kundepåvirkning falt valget på Amazon Web Services, Kafka, og Kotlin med Gradle. En overordnet idé ble skissert opp veldig grovt til disse TO DO-punktene:
- Kubernetes-cluster i AWS EKS for å hoste applikasjonene våre.
- Kafka-cluster i AWS MKS
- Skrive mest mulig av infrastruktur i Cloudformation så vi kan ha Infrastructure as Code.
- Utvikle applikasjoner som kaller Entur's API'er, for så å pushe dette ut til Kafka, en Kafka-producer med andre ord.
- Der det plukkes opp av en Kafka-consumer og behandles videre. (Hva som skal skje videre her er fortsatt ikke bestemt, men det funderes på å dytte data inn i Apache Druid, for så å vise data i HighCharts eller lignende)
(Endringer kan forekomme etter erfaringer er gjort)
I denne posten vil vi gå gjennom de to første punktene i prosessen, dvs. sette opp tjenestene vi ønsker å bruke fra AWS. Her falt valget på AWS EKS(Amazon Elastic Kubernetes Service) for hosting av applikasjonene vi skal utvikle, og AWS MSK (Amazon Managed Streaming for Kafka) for Kafka-bussen.
Hvis du lurer på hva kafka er kan du lese mer om det her.
Det aller første vi fant ut man måtte gjøre var å sette opp en Virtual Private Cloud for de to AWS-tjenestene.
Amazon Virtual Private Cloud (Amazon VPC) lar deg starte AWS-ressurser i et virtuelt nettverk som du har definert. Dette virtuelle nettverket ligner et tradisjonelt nettverk som man opererer i eget datasenter der man har kontroll over det virtuelle nettverksmiljøet, inkludert valg av ditt eget IP-adresseområde, oppretting av undernett og konfigurasjon av rutetabeller og nettverksgateways.
Vi ønsket et eget VPC for både MSK og EKS, med 3 subnets i hver, og med routing og peering mellom de to så tjenestene kan kommunisere. Første gang vi forsøkte dette gikk vi via AWS Console for å bli kjent med logikken, men ønsket om IaC resulterte i at vi kodet dette i CludFormation. Her finner du vår VPC.yaml fil i GitHub
Denne produserer en VPC med et navn som input og en "VPC cidr block" som parameter.
En klar fordel med å bruke CloudFormation viser seg allerede her; du slipper å først lage et VPC, for så å lage tre unike subnets for dette, for så å sette opp route-table fra subnets til VPC'en. Her gjøres alt i 73 linjer kode som er gjenbrukbar og lettleselig.
Andre steg i oppsett er å åpne for kommunikasjon mellom disse VPC'er. Dette viste seg å være nærmest røske-i-håret-type frustrerende å gjøre i AWS-console, så igjen kommer CloudFormation godt med. Det mest brukbare aspektet med CloudFormation her er at man kan eksportere og importere variabler mellom CloudFormation-filene og ende opp med riktige verdier på riktig sted. Se på hvor elegant det kan gjøres i yaml-filen VPCPeering.yaml, på linjene 37, 51, 64 og 72:
VpcId:
Fn::ImportValue:
!Sub ${VPCKubeStackName}-VPCID
Her bruker vi verdien av VPCKubeStackName som variabel, da vi forsøkte å gjøre samme operasjoner gjennom console gikk vi mange ganger og dobbeltsjekket verdier da man skal ha tungen rett i munnen for ikke å bruke feil verdi et sted.
Nå er vi klare til å sette opp Kubernetes. Valget falt på Kubernetes da vi ønsket at applikasjonene våre skal kunne skalere om nødvendig. Pluss at muligheten for å dra ned hele AWS-stacken når den ikke var i bruk for å spare penger er smart når man utvikler for konsept.
Ved første gjennomgang brukte vi guiden man finner her AWS getting started guide
Og fikk det hele opp ganske smertefritt, men, igjen ønsket vi å kunne bruke CloudFormation da det er generelt mye enklere å ha med å gjøre i det lange løp.Etter mange timer med prøving og feiling endte vi opp med filen Kubernetes.yaml
Denne CloudFormation filen lager selve EKS-clusteret, som er kontrollinstanser som kjører Kubernetes programvaren og eksponerer Kubernetes api’et. Dermed kan vi bruke “kubectl” for å kontrollere Kubernetes senere.
Deretter lager den en node-gruppe som kobles til EKS-clusteret. Dette er EC2-maskinene der applikasjonene skal kjøre. EC2-maskiner er Amazons virtuelle datamaskiner. Denne node-gruppen kommer med en auto-scaling policy som øker eller minker antallet noder basert på behovet. Her har vi satt den til å være 3 maskiner som default, med mulighet til å skalere opp til 5 hvis det trengs.
Når dette er gjort kan vi koble oss til Kubernetes-clusteret og sjekke at det er oppe og fungerer. Dette gjør man først ved å oppdatere kubectl-configen lokalt på egen maskin:
aws eks –region #regionen-du-bruker update-kubeconfig –name #navnet-på-clusteret –profile #profilen-din
(“profile” er kun relevant hvis du har flere aws profiler på maskinen, ellers er den “default” og kan droppes)
Deretter kan vi sjekke at det fungerer:
kubectl get svc –kubeconfig=$HOME/.kube/config
Den skal returnere noe som:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 1m
Nå er vi klare til å fyre opp Kafka gjennom AWS MSK. Amazon MSK er en fullstendig administrert tjeneste som gjør det enkelt for deg å bygge og kjøre applikasjoner som bruker Apache Kafka til å behandle strømningsdata. MSK gjør det enkelt å bygge og kjøre applikasjoner på Apache Kafka uten å trenge infrastrukturkompetanse for Kafka, som provisjonering av servere, konfigurering, server-patching etc. Man kan også bruke standard Apache Kafka API'er.
Vår cloudformation fil for Kafka clusteret kan du se her.
Den lager et Kafka-cluster bestående av 3 EC2-maskiner (brokers), som befinner seg i hver sin availability zone. Zookeeper nodene lages av AWS automatisk.
For å kunne lage “topics”, laget vi også en EC2-maskin i samme VPC, og installerte Kafka på denne. Den er tilgjengelig via SSH. Alt dette er beskrevet i CloudFormation filen, og kan tas opp og ned etter behov.
Å lage “topics” krever også at man kobler seg til Zookeeper fra EC2-maskinen. Det gjør vi ved å først finne ZookeeperConnectString:
aws kafka describe-cluster --region #regionen --cluster-arn #MSKClusterArn’en
For deretter å kunne lage “topics” fra terminalen:
bin/kafka-topics.sh --create --zookeeper #ZookeeperConnectString --replication-factor 3 --partitions 3 --topic #Hva-du-vil-kalle-topicen
(“replication-factor” og “partitions” kan velges etter hva man har behov for)
Med dette er Kafka oppe og kjører i AWS og vi er klare til å bruke den.
Dette er da vår foreløpige stack, og i teorien skal den gjøre og inneholde alt vi trenger til senere; men vi tør ikke kalle den "ferdig" riktig enda. Som alltid i utvikling så er det en del testing som gjenstår, og det er ikke noe vi får gjort før vi har applikasjoner å teste. Men, vi håper at det er et godt grunnlag for videre progresjon i prosjektet vårt.
Så summert med noen korte punkter, hva vi har lært så langt:
- Det kan være lurt å sette seg inn i AWS Console før man begynner med CloudFormation
- CloudFormation for infrastruktur er enklere, men krever innsikt
- Dokumentasjonen til CloudFormation er derfor praktisk å bruke (der er også gode eksempler)
- VPC'ene for de to clusterne må kunne kommunisere med hverandre, det var noe vi ikke forsto på lang tid. Derfor har vi lagt til peering mellom de to.
- Man lærer veldig mye rundt AWS, veldig fort, ved å kaste seg på et prosjekt som dette, men det krever et par grå hår i offer
Bli med I neste blogg-post der vi skal:
- Programmere en svært enkel producer, og en consumer, i Kotlin
- Compilere dem til Docker-images med Gradle
- Pushe disse imagene til git, og publisere dem i Kubernetes-clusteret vårt.
- Få producer og consumer til å utveksle data.