Kubernetes beste praksis

Jeg chatte med en tidligere Googler SRE som (riktig) påpekte at Kubernetes utvikler seg veldig raskt (for raskt for å opprettholde valuta), bruker (mange) nye konsepter og at det er (for) mange måter å løse det samme problemet.

Mye av dette er sant og ikke nødvendigvis en dårlig ting og heller ikke nødvendigvis annerledes enn noen annen teknologi. Hvor jeg er uenig er at disse faktorene har frarådet hans adopsjon av Kubernetes. Jeg vil oppmuntre deg til å dykke i. Kubernetes er suksessen det er * til tross for * disse (rimelige) bekymringene fordi det er så veldig veldig bra.

I dette innlegget skal jeg gi deg noen rudimentære beste fremgangsmåter som jeg håper vil hjelpe deg å ta tak i denne teknologien ved containere og dykke inn.

I ingen spesiell rekkefølge:

  1. La noen andre gjøre det!

Bruk en Kubernetes-tjeneste som Kubernetes Engine. Med mindre du er intellektuelt nysgjerrig, kan en utvikler som jobber med Kubernetes eller du er en plattformleverandør som har kunder som ber om Kubernetes-tjenester, redde bryet og bruke en Kubernetes-tjeneste. Bygde du ditt eget hjem og bilen din? Eller liker du å sove på et sted ulven ikke kan blåse ned og kjøre en bil som pålitelig tar deg fra A-til-B?

Så hvis du har lest noen av mine andre innlegg, anbefaler jeg også å evaluere regionale klynger, og så ser du på noe som:

gcloud beta-containerklynger oppretter $ {CLUSTER} ...
gcloud beta-containerklynger få-legitimasjon $ {CLUSTER} ...

Og så er du klar til å gå med:

kubectl Apply - filnavn = marvels.yaml

2. Prøv å tenke “Kubernetes”

Dette * kan * være mer en utfordring med Kubernetes Engine enn på andre plattformer, men på Google Cloud Platform blir du tvunget til å opprettholde en forståelse av tilstanden til ressursene dine i Kubernetes (f.eks. Noder, Ingresses) og samtidig , de underliggende ressursene i Compute Engine (f.eks. VM-er, HTTP / S Load Balancers). Dette partikkelbølgedualitetsproblemet er uheldig. Takk til Dale H. for først å artikulere dette for meg.

Der det er mulig, prøv å holde deg til tankene når det gjelder Kubernetes ressurser og se bort fra de underliggende GCE-ressursene. Etter å ha brukt mer enn ett år på å skjemme arbeidet mitt til Kubernetes, har det blitt lettere å tenke rent i form av "et antall" pods utsatt av Services (og Ingresses).

3. Navneområder, Navnearealer, Navnearealer

Oppdatering: Takk til Michael Hausenblas for å ha opplært meg til en god praksis for * ikke * med henvisning til navneområder fra Kubernetes YAML-filer. Selv om du alltid bør bruke navnefelt, gir spesifisering av disse når du bruker filen mer fleksibilitet og muligheten til å bruke de samme YAML-filene mot, f.eks. forskjellige landskap. Se Michaels artikkel her.

Mike Altarace og jeg blogget måner siden om navneområder i Kubernetes og hvor du skulle bruke dem. Siden den gang ignorerte jeg ganske godt mine egne råd og trodde at brukssakene mine var så små at brukernavnsområdene ville bli overarbeidet. Jeg tok feil. Bruk alltid navneområder.

Som containere skal prosesser, er navneområdene Kubernetes prosjekter. Bortsett fra sikkerhetsgrensen som navneområdene formidler, er de en utmerket måte å dele opp arbeidet ditt på, og de gir en utmerket måte å tilbakestille eller slette:

kubectl slette navneareal / $ WORKING_PROJECT

Den eneste ulempen er at når du bruker ikke-standard navneområdet, må du spesifisere arbeidsområdet ditt - navnspace = $ WORKING_PROJECT på kubectl-kommandoer som etter min mening kan være en god beskyttelsespraksis. Du kan imidlertid alltid - alle navnefelt eller angi et annet navneområde som standard (lenke).

4. For mange måter å løse et problem på

Dette er en nedslående bekymring. Jeg tror det sannsynligvis er usant, men fraværende god veiledning og beste praksis, ser det ut til at det er for mange lignende måter å løse det samme problemet på. Jeg har et vanlig mønster som jeg bruker som jeg vil oppsummere her for å oppmuntre til diskusjon:

  • YAML-filer er kunnskap innen kjølerom (se nr. 5)
  • Beholderne dine skal gjøre en ting godt (se "mistillit")
  • Distribuer alltid distribusjoner (se nr. 6)
  • Hvis du vil ha L7 aka HTTP / S Load-Balancing, bruk Ingress (se nr. 7 - ha!)
  • Administrer legitimasjon sikkert ved å bruke Secrets (lenke)

5. Skjevhet til kubectl gjelder - filnavn over alternativer

Det er lett å få en rask hit med kubectl create namespace / $ {WORKING_DIR}, men etter flere slike kommandoer lurer du kanskje på hvordan du nådde gjeldende tilstand og - enda viktigere - hvordan du gjenskaper denne tilstanden. Jeg oppfordrer deg til å lage YAML-filer for å beskrive ressursene dine i stedet for den tilsvarende kub ectl create-kommandoen.

Jeg oppfordrer deg til å bli kjent med * utmerket * Kubernetes API-dokumentasjon (link, link og 1.10) som er uttømmende, nøyaktige og enkle å navigere (kanskje den perfekte dokumentasjonen !?). Men selv med dette kraftige verktøyet er det noen ganger litt utfordrende å ta en kubectl-kommando som fungerer for deg og konvertere den til YAML. Det er ikke:

kubectl get distribution / $ {MY_DEPLOYMENT} --output = yaml
kubectl get service / $ {MY_SERVICE} --output = yaml
kubectl få alt / $ {MY_ANYTHING} --output = yaml

Rør resultatene til en fil hvis du vil, men bruk disse som grunnlag for ekvivalent (!) YAML-fil. Du må slippe alle forekomstreferanser.

Når du har laget mesterverk.yaml, oppfordrer jeg deg til alltid å søke om å lage den opprinnelige opprettelsen, søke om å gjøre eventuelle etterfølgende oppdateringer, og hvis du må slette. Det er det!

kubectl Apply - filnavn = mesterverk.yaml
kubectl delete - filnavn = mesterverk.yaml

Mindre innsikt: du trenger ikke å trekke YAML-filer lokale for å distribuere. Du kan også gi kubectl Apply - filnavn med URLer, og så lenge avhengige filer er lokale referanser, vil distribusjonen fungere.

Mindre innsikt: det eneste stedet jeg ser dette ble brukt er i Kubernetes-land, men det er en legitim praksis. Du kan kombinere flere YAML-filer i en YAML-fil med --- og ... filskillere. Så i stedet for et navneområde YAML, en distribusjon YAML og en service YAML, kan det hende du har en mega-YAML som konsoliderer alle tre filene til en.

Dette er gyldig YAML (kopier og lim det inn i f.eks. YAML Lint). Det er * ugyldig * Kubernetes spec | YAML fordi hver spesifikasjon er ufullstendig, men hvis hver ble fullført, er dette helt greit YAML og en god måte å holde ressursene tilknyttet.

Se #B (Xsonnet) for en kritikk.

6. Bruk distribusjoner

Det er en haug med kraft i distribusjoner. Det er nok min veiledning å si: bruk distribusjoner hele tiden, hver gang. Selv når du distribuerer din første singel podnginx. Distribusjoner er “First Class” -reiser for prisen på Coach, du kan falle i rullende distribusjoner, du gjør en feil, søke på nytt og Kubernetes tar seg av å drepe de frekke belgene og erstatte dem med veloppdragne.

7. LoadBalancer og Ingress

Disse forårsaker forvirring. Når jeg oppretter tjenester ved å bruke --type = LoadBalancer, vil jeg i hodet mitt (og jeg kan ta feil) ønske | få et nettverk LB. Hvis jeg vil ha HTTP / S (nivå 7) Load-Balancing, må jeg opprette en Ingress. Ingress er en forvirrende ressurs fra Kubernetes. Det er nok å si, L7 == Ingress (og mye konfigurasjonseffekt som et resultat).

Kubernetes Engine manifesterer Ingress-ressurser som GCE HTTP / S Load-Balancers. Christopher Grant gjør en veldig god jobb med å avmystifisere Ingress i innleggene sine (her og her).

8. NodePorts

Jeg har ikke (noen gang?) Laget noen ClusterIP direkte. Jeg har gjort ting mot Kubernetes som resulterte i at tjenester ble utsatt av ClusterIPs. Stort sett (!) Opprettet jeg NodePorts eller jeg gjør ting (f.eks. Oppretter Ingress-ressurser) som bruker NodePorts.

NodePorts er tilknyttet Kubernetes Nodes, og de er porter. Det kraftige anlegget de tilbyr er at * hver * node i klyngen (eller er det denne NodePool? [[TODO]]) utsetter den samme tjenesten på den samme porten.

Hvis jeg oppretter en tjeneste som er eksponert på NodePort X, kan jeg være trygg på at hvis jeg får tilgang til porten på * hvilken som helst * node i klyngen, får jeg tilgang til tjenesten. Dette danner grunnlaget for Kubernetes 'belastningsbalanseringsfunksjoner fordi klyngen er i stand til å rute innkommende forespørsler om tjenesten til denne porten på hvilken som helst node.

Google Cloud SDK (også kjent som gcloud) inkluderer en ssh-klient som gjør det trivielt å koble til Compute Engine VMs (som du husker Kubernetes Cluster Nodes). ssh-klienten har en port-videresending evne. Så hvis vi vil koble til en Kubernetes-tjeneste og kan slå opp tjenestens NodePort, så kan vi trivielt (!) Port-forward til den tjenesten ved port-videresending (ved hjelp av gcloud eller hvilken som helst ssh-klient) til porten på hvilken som helst node.

Følgende eksempel bruker kubectl til å ta tak i den 0de noden i klyngen. Kubernetes Engine Node-navnet er det samme som Compute Engine VM-navnet. Gitt en tjeneste kalt $ {MY_SERVICE} i et navneområde kalt $ {MY_NAMESPACE}, bestemmer vi tjenestens NodePort. Deretter bytter vi til gcloud og bruker den innebygde sshen for å portover-fremover (ved å bruke --ssh-flag = "- L XXXX: localhost: XXXX).

NODE_HOST = $ (\
  kubectl få noder \
  Output = jsonpath = "{. eks [0]} .metadata.name")
NODE_PORT = $ (\
  kubectl get services / $ {MY_SERVICE} \
  --namespace = $ {MY_NAMESPACE} \
  Output = jsonpath = "{. spec.ports [0]} .nodePort")
ekko $ {NODE_PORT}
gcloud beregne ssh $ {NODE_HOST} \
--ssh-flag = "- L $ {NODE_PORT}: localhost: $ {NODE_PORT}" \
--project = $ {} YOUR_PROJECT

Hva er så kraftig med dette? Nå har du kanskje tilgang til tjenesten som om den var lokal og uten å måtte slå hull i en brannmur.

NodePorts er høyt nummererte porter (~ 30.000–32.767).

9. Hacking av kubectl bruk JSON

Googles Cloud SDK (aka gcloud) er virkelig utmerket, men kubectl (Kubernetes CLI) er mer bedre (sic). En kraftig funksjon er formatering og filtrering av output. Dette tillater ikke-koding (ikke-API-krangel) måter å utvide skript og andre verktøy med informasjon fra Kubernetes klynger på.

All Kubernetes ressurstilstand er tilgjengelig gjennom f.eks. kubectl get (etter min erfaring mer nyttig for dette formålet enn kubectl beskriver) kommandoer. Så er det bare igjen å finne nålen i det som kan være en høystakk av JSON.

Trikset er å:

kubectl get [resource] / [resource-name] --output = JSON

Og deretter øyeeplet resultatene for å begynne å bygge en spørringsstreng:

kubectl get [resource] / [resource-name] --output = jsonpath = ". elementer [*]"

og iterativt avgrense resultatet som er satt ned til du har varen (e) du søker. Her er et eksempel som skal fungere med hvilken som helst klynge:

kubectl få noder --output = json
kubectl få noder --output = jsonpath = "{. elementer [*]}
kubectl få noder --output = jsonpath = "{. elementer [0]}
kubectl få noder --output = jsonpath = "{. elementer [0] .metadata.name}

Til slutt er det et anstendig argument (og en grunntale i * nix) for å lære ett JSON-parsingverktøy og bruke det verktøyet på alle JSON-analyseringsbehov. Er det i dette tilfellet noen rimelig konkurrent til å jq? Jeg mistenker ikke.

Plus jq har en utmerket lekeplass (jqplay.org).

A. Bruk etiketter

Det har vært en lang tid, men all slags programvaretjenester støtter nå konseptet med vilkårlig merking av ressurser (vanligvis nøkkelverdipar). Årsaken til at dette er kraftig er at disse metadataene gir en åpen, fullstendig brukerdefinert måte å spørre ressurser på. Kubernetes bruker dette prinsippet iboende; det er en iboende evne og ikke en ettertanke | bolt-on.

En Kubernetes-tjeneste eksponerer et vilkårlig antall Kubernetes Pods. A Services eksponerer ikke * pods som kalles “Henry” eller Pods som inneholder et ReplicaSet. I stedet eksponerer en tjeneste Pods hvis etiketter oppfyller kriterier som er definert under tjenestens spesifikasjon og disse etikettene, selvfølgelig, brukerdefinerte.

OBS. I eksemplet over bruker vi et navneområde kalt project-x, og dette navneromspesifikasjonen vises i navnefeltet (når det opprettes), distribusjonen for å definere hvor distribusjonen eksisterer, og i tjenesten. Distribusjonen (som kalles microservice-y) vil opprette et ReplicaSet (implisitt spesifisert her; det er det Deployments oppretter) som vil opprettholde 100 Pods. Hver pod har en etikett-app: publicname-a og inneholder en beholder kalt grpc-proxy basert på et bilde som heter image-grpc-proxy. Tjenesten kalles service-p. Avgjørende velger tjenesten (!) Pods (bare i prosjekt-x navnefelt) som har en etikett-app: publicname-a. Tjenesten vil velge hvilken som helst Pod (i prosjekt-x-navneområdet) som har denne etiketten (nøkkel: verdi) -paret * ikke * bare de Podene som er opprettet i denne distribusjonen. Tjenesten refererer ikke til pods med deres navn (som er basert på distribusjonsnavnet), beholdernavnet eller beholderbildets navn, bare etikettene som er tilknyttet poden.

NB Dette er * ikke * en god praksis, men det beviser poenget. Hvis du skulle kjøre en konfigurasjon som ligner på ovenfor og deretter opprette for eksempel en pod som kjører Nginx (i prosjekt-x navneområdet), og deretter la du etiketten app: publicname-a til den, vil den raskt bli integrert i settet med pods som er samlet av service-p-tjenesten. Hvis du skulle fjerne etiketten fra en eller annen Pods samlet av tjenesten, ville Pod ikke slutte å bli inkludert.

Denne funksjonen er eksemplifisert ved å rulle oppdateringer der distribusjonen oppretter en ny ReplicaSet som inneholder nye Pods for versjon X ', forskjellig fra ReplicaSet og Pods for versjon X. Tjenesten kan defineres for å avsløre skjæringspunktet mellom Pods som kjører over begge disse versjonene fordi det er ikke definert i form av ReplicaSets eller spesifikke Pods, men av brukerdefinerte etiketter ("selectors") som brukes av deg når Pods opprettes.

Det er veldig kraftig!

B. Bruk Jsonnet, muligens Ksonnet

To utfordringer med alle (!?) Strukturerte formater (YAML, JSON, XML, CSV ;-) er selvreferanser og variabler. Når du lager spesifikasjoner for marvellous.yaml for implementeringen av Kubernetes, vil du lett få dette problemet. Du finner deg selv å bruke bokstaver (f.eks. For bildenavn og fordøyelser), og selv med de anerkjente distribusjonene, gjenta navn og velgere.

Det er ingen løsning på disse problemene hvis du begrenser deg til YAML og JSON. Google opprettet Jsonnet delvis for å løse disse problemene. De smarte Heptio-menneskene har utvidet Jsonnet til Kubernetes med ... Ksonnet.

Begge er templatespråk som løser problemene som er skissert over (og mer). Jeg oppfordrer deg til å vurdere Jsonnet. Som med min anbefaling om å vurdere å bruke jq, lær deg Jsonnet en gang og bruk den overalt du bruker JSON. Ksonnet er spesifikt for Kubernetes, og - i min begrensede (!) Erfaring - fant jeg fordelene som ble oppnådd ved denne spesifisiteten, ikke å oppveies av læringskurven.

C. YAML eller JSON

Kubernetes behandler YAML og JSON stort sett likt. Personlig synes jeg YAML er å foretrekke for konfigurasjonsfiler som jeg kubectl - gjelder fordi YAML er mer kortfattet enn JSON. Selv om jeg synes YAML er vanskeligere å skrive.

Når det gjelder forståelse av struktur og parsing, foretrekker jeg imidlertid å --output = JSON og også fordi - output = JSONPATH. Jeg er en stor Golang-fan, men Go-maler er ikke så intuitive og jeg bruker ikke dem.

mindre innsikt: YAML er et supersett av JSON (lenke)… vent! hva?

D. Downward Dog API og config

“Nedadgående API” for å gi det sitt riktige, om enn ikke mindre forvirrende navn, er et anlegg i Kubernetes der Pods kan få en følelse av klyngen rundt seg. Jeg antar at den normale strømmen er fra omverdenen opp i Pod og dens containere * men * det er tider hvor det er nyttig for en container (!) Å få informasjon om omgivelsene, f.eks. dens Nodenavn | IP, Podens navn (mellomrom) | IP.

Verdiene for nedadgående API blir presentert for beholderen gjennom miljøvariabler. Miljøvariabler brukes (som andre steder) for å gi config eller annen tilstand til containere. En veldig fin konsekvens av å bruke miljøvariabler og implementeringen av Downward API (med et mindre forbehold) er at beholderen forblir koblet fra Kubernetes.

Her er et eksempel fra kompisen min - Sal Rashid - som bruker Downward API for å samle Node og Pod-tilstand og presentere disse for brukeren:

https://github.com/salrashid123/istio_helloworld/blob/master/all-istio.yaml

NB Se seksjonene som begynner på linje 76, 80, 84, 88 der Pod-navn, navneområde, IP og Nodenavn blir gitt ved kjøretid av Downward API til beholderen som heter myapp-container.

Downward API er den eneste, praktiske måten å samle disse dataene på for en container. Så det er mer en "eneste praksis" i stedet for "beste praksis".

I mange av innleggene mine, mens jeg bygger løsninger for Kubernetes, tester jeg prosessen lokalt og utenfor en container, deretter i en container (spesifiserer miljøvariabler), deretter på en Kubernetes-klynge. De containeriserte mekanismene er konsistente (se nedenfor), selv om en vanligvis kjører på Docker og en på Kubernetes.

I et innlegg jeg nylig skrev på Googles Container-Optimized OS, demonstrerer jeg en container som kjører lokalt under Docker, eksternt under Container-Optimized OS og deretter på Kubernetes.

Her kjører lokalt under Docker. Legg merke til hvordan miljøvariablene (- env) brukes til å gi konfigurasjon til gcr.io/${PROJECT}/datastore.

docker run \
- interaktiv \
- kjekt \
--publish = 127.0.0.1: 8080: 8080 \
--env = GCLOUD_DATASET_ID = $ {PROJECT} \
--env = GOOGLE_APPLICATION_CREDENTIALS = / tmp / $ {ROBOT} .key.json \
- volume = $ PWD / $ {ROBOT} .key.json: / tmp / $ {ROBOT} .key.json \
gcr.io/${PROJECT}/datastore

Her er det samme resultatet som pakker distribusjonen inn i etableringen av en Container-optimalisert VM. Denne gangen sjekk ut verdiene som er gitt til beholder-env-flagget:

gcloud beta-beregne forekomster create-with-container $ {INSTANCE} \
--zone = $ {ZONE} \
- image-family = cos-stable \
--image-project = cos-sky \
--container-image=gcr.io/${PROJECT}/${IMAGE}@${DIGEST} \
--container-restart-policy = alltid \
--container-env = \
GCLOUD_DATASET_ID = $ {PROJECT}, \
GOOGLE_APPLICATION_CREDENTIALS = / tmp / $ {ROBOT} .key.json \
--container-mount-host-path = \
mount-path = / tmp \
host-path = / tmp \
modus = rw \
--project = $ {} PROJECT

Og til slutt, her er YAML-utdraget for distribusjonen for Kubernetes:

beholdere:
      - navn: datastore
        image: gcr.io/${PROJECT}/datastore
        imagePullPolicy: Alltid
        volumeMounts:
          - navn: datastore
            mountPath: / var / secrets / google
        env:
        - navn: GOOGLE_APPLICATION_CREDENTIALS
          verdi: /var/secrets/google/datastore.key.json
        - navn: GCLOUD_DATASET_ID
          verdi: $ {PROJECT}
        porter:
        - navn: http
          containerPort: 8080

Jeg synes dermed bruk av miljøvariabler for at config er ganske klønete. Det er ingen klar intensjonell binding av spesifikke miljøvariabler til spesifikke prosesser, og du skjønner bare at de ikke er konfigurert riktig når ting går i stykker. Det er lett å forestille seg miljøvariabler som er i konflikt i et ikke-containert miljø, selv om dette er et mindre problem med containere fordi vi som ovenfor angir eksplisitt verdier for en bestemt container.

Alt som sagt er det å bruke miljøvariabler på denne måten.

E. Sidevogner og hvorfor Pods ikke alltid er synonyme med containere

5 cl cognac
2 cl trippel sek
2 cl sitronsaft
Forberedelse Hell alle ingrediensene i cocktail shaker fylt med is. Rist godt og sil i cocktailglass.

Mye av tiden lager du Kubernetes Pods som inneholder enkelt containere, og du lurer på hvorfor det er all overhead til en Pod når du bare trenger en container. Pods er mer analogt med et vertsmiljø som kan kjøre mange containere. Det er mange ganger du vil vurdere å kjøre flere containere i en pod ...

... og bare en gang du skal :-)

Sannsynligvis mer enn én, men la oss holde oss til bare én gang.

Antimønsteret (ikke gjør dette) er å se for deg den nåværende konfigurasjonen (la oss anta en webserver og en database backend) og papirstopp begge i en Pod. Dette er * ikke * en god idé * med mindre * hver web-serverforekomst må være uløselig og for alltid være knyttet til en spesifikk databaseforekomst. Dette er usannsynlig.

Det som er mer sannsynlig er at webserverforekomstene skal skaleres etter den samlede frontendbelastningen, og at databaseforekomstene skal skaleres (uavhengig av dette og) basert på deres samlede evne til å takle frontendbelastningen. Når du ser samlet, tenke Tjeneste og når du tenker Tjeneste, kan du prøve å se for deg et vilkårlig antall Pods (fordi det betyr noe for regningen din, men for de fleste andre formål spiller det ingen rolle hvor mange Pods som trengs, så lenge nummeret er riktig for servering av arbeidsmengden).

Når bør du vurdere flere containere per Pod? Den ene gangen når dette * alltid * er fornuftig, er når du ønsker å komplementere, utvide eller berike oppførselen til den primære Pod i en container. La oss se på webserveren og databaseeksemplet ovenfra. I dette scenariet er du forhåpentligvis overbevist om at du vil distribuere to tjenester (og to distribusjoner), en for frontend og en for backend.

Det er en god og vanlig praksis å fronta webserverforekomsten selv med en omvendt proxy. Vanligvis vil dette være enten Nginx eller HAProxy, og det blir stadig mer vanlig å bruke Envoy (jeg anbefaler, hvis du ser på fullmakter, å vurdere utsending; se #F Istio). En omvendt proxy gir konsistens (vi bruker bare f.eks. Utsending) selv om du bruker forskjellige webservere (f.eks. Apache, Tomcat m / Java osv.), Selv om du har en blanding av HTTP, gRPC, websockets osv. Trafikk. , selv om du ønsker å dirigere litt trafikk til web-serveren din og litt trafikk til en cache (f.eks. lakk).

I alle de foregående scenariene ville det være fornuftig å bruke "sidevogn" -modellen. I denne modellen har den primære beholderen (webserveren din) tilleggsutstyr, komplementære containere (utsending-proxy, lakkbuffer osv.). Disse må være tett koblet til en spesifikk webserverforekomst * og * funksjonelt, kombinasjonen er "enheten".

Det er veldig vanlig å se logging, overvåking, spor og andre infrastrukturelle komponenter levert som sidevogner også. En motivasjon her er å skille bekymringer. For å gi utviklere et konsistent krav som produserer kode som er 'håndterbar' og gir SRE fleksibilitet til å velge foretrukne verktøy, vel vitende om at all kode på tvers av flåten vil logge, avgi målinger, være sporbar, bruke autoristisk osv. Dette er et mønster som danner grunnlaget for servicenettverk (se #F Istio). Dette er den endelige beste, om enn begynnende praksis.

F. Bruk Istio

Bruk Istio nøye.

Istio (og andre servicenettverk) er relativt begynnende teknologier født fra selskaper (inkludert Google) som har kjørt containere i stor skala. Tjeneste nettverk plasserer en universal (i Istios tilfelle, utsending) proxy i hver Pod i hver distribusjon i hvert navneområde i hver klynge.

Resultatet er et konsistent styringsunderlag som tillater løs kobling av ledelse (vi bruker Stackdriver Trace i dag, men det er planer om å migrere til Jaeger, vi har rullet vår Prometheus-overvåking) og kontrolltjenester (vi vet at alle tjenestene våre er sikre, vi dirigerer 10% av trafikken til kanaribygging av tjenester A, B og C).

Jeg anbefaler “nøye” fordi disse teknologiene er nye, har grove kanter og utvikler seg raskt. Men fordelene (fleksibilitet, smidighet, fremtidssikring) metodikken gir deg sannsynligvis langt større enn kostnadene. Det viktigste er at du bruker servicemesh som din modell med Kubernetes, selv om du ennå ikke ønsker å ta i bruk en av servicemesh-teknologiene.

Det var alt folkens!