Vi lagar hÄlen i Kubernetes-klustret. Rapport och avskrift frÄn DevOpsConf

Pavel Selivanov, lösningsarkitekt pÄ Southbridge och lÀrare pÄ Slyrm, höll en presentation pÄ DevOpsConf 2019. Denna presentation Àr en del av en av temi fördjupad kurs om Kubernetes "Slyrm Mega".

Slyrm GrundlÀggande: en introduktion till Kubernetes À skriven i Moskva 18-20 november.
Slyrm Mega: vi grĂ€ver djupare under huven pĂ„ Kubernetes — Moskva, 22-24 november.
Slyrm Online: bÄda kurserna om Kubernetes finns alltid tillgÀnglig.

Spela video

Under lÀsningen finns transkriptionen av presentationen.

God dag, kollegor och stödjande Ähörare. Idag kommer jag att prata om sÀkerhet.

Jag ser att det finns mÄnga sÀkerhetsproffs hÀr idag. Jag ber om ursÀkt i förvÀg om jag anvÀnder termer frÄn sÀkerhetsvÀrlden pÄ ett sÀtt som inte Àr helt standard för er.

För ungefÀr ett halvÄr sedan fick jag tillgÄng till ett offentligt Kubernetes-kluster. Offentligt betyder att det finns ett visst antal namnrymder dÀr anvÀndare Àr isolerade i sina egna namnrymder. Alla dessa anvÀndare tillhör olika företag. Tanken var att detta kluster skulle anvÀndas som CDN. Det vill sÀga, ni fÄr klustret, fÄr en anvÀndare in i ert namnrum, och ni kommer för att distribuera era frontend.

Mitt tidigare företag försökte sÀlja en sÄdan tjÀnst. Jag blev ombedd att undersöka klustret för att se om denna lösning var lÀmplig eller inte.

Jag gick in i detta kluster. Jag fick begrĂ€nsade rĂ€ttigheter, begrĂ€nsad namnrymd. DĂ€r förstod killarna vad sĂ€kerhet innebar. De hade lĂ€st om Rollbaserad Ă„tkomstkontroll (RBAC) i Kubernetes — och de hade konfigurerat det sĂ„ att jag inte kunde köra pods separat frĂ„n deployeringar. Jag minns inte uppgiften som jag försökte lösa genom att köra en pod utan en deployering, men jag ville verkligen bara köra en pod. Jag beslöt mig för att kolla vilka rĂ€ttigheter jag hade i klustret, vad jag kunde och inte kunde göra, och vad de hade stĂ€llt till med. Jag kommer ocksĂ„ att berĂ€tta att deras RBAC var felkonfigurerat.

Det hÀnde sig att efter tvÄ minuter hade jag blivit administratör för deras kluster, jag tittade i alla angrÀnsande namnrymder och sÄg aktiva produktionsfronter frÄn företag som redan köpt tjÀnsten och hade distribuerat sina system. Jag fick svÄrt att inte gÄ in pÄ nÄgon av sidorna och placera nÄgot olÀmpligt ord pÄ förstasidan.

Jag kommer att berÀtta med exempel hur jag gjorde detta och hur man skyddar sig mot det.

Men jag ska först presentera mig. Jag heter Pavel Selivanov. Jag Àr arkitekt pÄ Southbridge. Jag har kunskaper inom Kubernetes, DevOps och diverse moderna grejer. Tillsammans med ingenjörerna pÄ Southbridge bygger vi detta, och jag ger rÄdgivning.

Förutom vÄr huvudverksamhet har vi nyligen lanserat projekt som kallas Slërmy. Vi försöker sprida vÄr förmÄga att arbeta med Kubernetes och lÀra andra att ocksÄ arbeta med K8s.

Vad jag kommer att prata om idag. Temat för presentationen Ă€r helt klart — sĂ€kerheten i Kubernetes-kluster. Men jag vill genast sĂ€ga att detta Ă€mne Ă€r mycket stort — och dĂ€rför vill jag direkt klargöra vad jag definitivt inte kommer att diskutera. Jag kommer inte att prata om klichĂ©er som redan har diskuterats hundratals gĂ„nger pĂ„ internet. SĂ„dana saker som RBAC och certifikat.

Jag kommer att berÀtta om de saker som mig och mina kollegor bekymrar inom sÀkerheten i Kubernetes-kluster. Vi ser dessa problem hos bÄde leverantörer som tillhandahÄller Kubernetes-kluster och hos kunder som kommer till oss. Och till och med hos kunder som kommer till oss frÄn andra konsultadministrationsföretag. Det vill sÀga, tragedins omfattning Àr faktiskt mycket stor.

Jag kommer idag att diskutera tre punkter:

  1. AnvÀndarrÀttigheter vs pod-rÀttigheter. AnvÀndarrÀttigheter och pod-rÀttigheter Àr inte samma sak.
  2. Informationsinsamling om klustret. Jag kommer att visa vad som kan samlas in frÄn klustret, som kan behövas utan sÀrskilda rÀttigheter i detta kluster.
  3. DoS-attack mot klustret. Om vi inte kan samla in information kan vi ÀndÄ slÄ ut klustret. Jag kommer att berÀtta om DoS-attacker mot klusterhanteringskomponenterna.

En annan allmĂ€n sak som jag kommer att nĂ€mna — vad jag testade detta pĂ„, vad jag definitivt kan sĂ€ga fungerar.

Vi baserar oss pĂ„ installationen av Kubernetes-klustret med Kubespray. Om nĂ„gon inte vet, sĂ„ Ă€r detta i princip ett set av roller för Ansible. Vi anvĂ€nder det konstant i vĂ„rt arbete. Det Ă€r bra eftersom det kan anvĂ€ndas överallt — bĂ„de pĂ„ fysiska serverar och i molnet. En installationsmetod passar i princip för allt.

I detta kluster kommer jag att ha Kubernetes v1.14.5. Hela klustret av Kubernetes, som vi ska titta pÄ, Àr uppdelat i namnomrÄden, dÀr varje namnomrÄde tillhör ett separat team och endast medlemmarna i det teamet har tillgÄng till sitt eget namnomrÄde. De kan inte gÄ in i andra namnomrÄden. Men det finns ett administratörskonto som har rÀttigheter för hela klustret.

Vi lagar hÄlen i Kubernetes-klustret. Rapport och avskrift frÄn DevOpsConf

Jag lovade att det första vi ska göra Àr att fÄ administrativa rÀttigheter till klustret. Vi behöver en speciellt förberedd pod som kommer att bryta klustret Kubernetes. Det enda vi behöver göra Àr att tillÀmpa den i klustret Kubernetes.

kubectl apply -f pod.yaml

Denna pod kommer att landa pÄ en av masternoderna i klustret Kubernetes. Klustret kommer glatt att returnera en fil som heter admin.conf. I denna fil lagras alla certifikat för administratören, och dessutom Àr API:et för klustret konfigurerat. SÄ enkelt kan man fÄ administrativ Ätkomst, jag tror till 98% av Kubernetes-kluster.

Jag upprepar, denna pod skapades av en utvecklare i ert kluster, som har tillgÄng att distribuera sina förslag i ett litet namnomrÄde, dÀr allt Àr begrÀnsat av RBAC. Han hade inga rÀttigheter. Men ÀndÄ kom certifikatet tillbaka.

Nu, om den specialförberedda podden. LÄt oss köra den pÄ valfri bild. Som exempel tar vi debian:jessie.

Vi har nÄgot sÄdant hÀr:

tolerations:
-   effect: NoSchedule 
    operator: Exists 
nodeSelector: 
    node-role.kubernetes.io/master: "" 

Vad Ă€r tolerans? Masternoderna i Kubernetes-klustret Ă€r vanligtvis markerade med nĂ„got som kallas taint ("smitta" pĂ„ engelska). PoĂ€ngen med denna "smitta" Ă€r att poddar inte fĂ„r tilldelas till masternoder. Men ingen hindrar en pod frĂ„n att ange att den Ă€r tolerant mot "smittan". Sektionen Toleration sĂ€ger just att om det finns NoSchedule pĂ„ en nod, sĂ„ Ă€r vĂ„r pod tolerant mot denna smitta — och inga problem uppstĂ„r.

Vidare sĂ€ger vi att vĂ„r pod inte bara Ă€r tolerant, utan ocksĂ„ vill hamna speciellt pĂ„ mastern. För pĂ„ mastern finns det det mest attraktiva som vi behöver — alla certifikat. SĂ„ vi specificerar nodeSelector — och vi har en standardetikett pĂ„ mastern som gör att vi kan vĂ€lja just de noder i klustret som Ă€r masters.

Med dessa tvÄ sektioner kommer podden garanterat att hamna pÄ mastern. Och den kommer att fÄ bo dÀr.

Men det Àr inte tillrÀckligt att bara komma till mastern. Det kommer inte att ge oss nÄgot. SÄ hÀr följer tvÄ saker:

hostNetwork: true 
hostPID: true 

Vi anger att vÄr podd, som vi kör, kommer att leva i kÀrnans namnutrymme, i nÀtverksnamnutrymmet och i PID-namnutrymmet. SÄ snart podden startar pÄ mastern, kommer den att kunna se alla riktiga, levande grÀnssnitt pÄ denna nod, lyssna pÄ all trafik och se PID för alla processer.

DÀrefter Àr det enkelt. Ta etcd och lÀs vad du vill.

Det mest intressanta Àr denna funktion i Kubernetes, som Àr dÀr som standard.

volumeMounts:
- mountPath: /host 
  name: host 
volumes:
- hostPath: 
    path: / 
    type: Directory 
  name: host 

Och poĂ€ngen Ă€r att vi kan i podden, som vi kör, Ă€ven utan rĂ€ttigheter i denna kluster, sĂ€ga att vi vill skapa ett volume av typen hostPath. Det betyder att vi tar vĂ€gen frĂ„n vĂ€rden vi kommer att docka — och tar det som ett volume. Vi kallar det sedan name: host. Hela denna hostPath monteras inuti podden. I detta exempel i katalogen /host.

Jag upprepar. Vi har sagt till podden att Ă„ka till mastern, fĂ„ hostNetwork och hostPID — och montera hela root pĂ„ mastern inuti denna pod.

Du förstÄr att vi har bash igÄng i Debian, och denna bash körs under root. SÄ vi har just fÄtt root pÄ mastern, utan att ha nÄgra rÀttigheter i Kubernetes-klustret.

DÀrefter Àr hela uppgiften att gÄ in i podden i katalogen /host /etc/kubernetes/pki, om jag inte minns fel, ta alla mastercertifikat frÄn klustret och dÀrmed bli administratör av klustret.

Om man ser det sĂ„ hĂ€r, Ă€r dessa en av de mest farliga rĂ€ttigheterna i poddar — oavsett vilka rĂ€ttigheter anvĂ€ndaren har:
Vi lagar hÄlen i Kubernetes-klustret. Rapport och avskrift frÄn DevOpsConf

Om jag har rÀtt att köra en podd i nÄgot namnutrymme i klustret, sÄ har denna podd dessa rÀttigheter som standard. Jag kan köra privilegierade poddar, och det betyder i princip alla rÀttigheter, nÀstan root pÄ noden.

Min favorit — Root-anvĂ€ndare. Och Kubernetes har en sĂ„dan alternativ Run As Non-Root. Detta Ă€r en sorts skydd mot hackare. Vet du vad en "moldavisk virus" Ă€r? Om du plötsligt Ă€r en hackare och har kommit in i mitt Kubernetes-kluster, sĂ„ ber vi, de stackars administratörerna: "Ange snĂ€lla i dina poddar, med vilka du planerar att hacka mitt kluster, run as non-root. Annars kan det hĂ€nda att du kör en process i din podd som root, och det blir vĂ€ldigt enkelt för dig att hacka mig. Skydda dig sjĂ€lv, snĂ€lla."

Host path volume — enligt min Ă„sikt, det snabbaste sĂ€ttet att fĂ„ det önskade resultatet frĂ„n Kubernetes-klustret.

Men vad ska man göra med allt detta?

Tankar som varje normal administratör som stöter pÄ Kubernetes bör ha: "Aha, jag sa ju att Kubernetes inte fungerar. Den har hÄl. Och hela Kubernetes Àr skrÀp." I verkligheten finns det nÄgot som heter dokumentation, och om man tittar dit sÄ finns det ett avsnitt. Pod Security Policy.

Detta Àr ett yaml-objekt - vi kan skapa det i Kubernetes-klustret - som kontrollerar sÀkerhetsaspekter specifikt i beskrivningen av poddar. Det innebÀr att den faktiskt kontrollerar rÀttigheter för anvÀndning av olika hostNetwork, hostPID, vissa typer av volymer som finns i poddar vid start. Med hjÀlp av Pod Security Policy kan allt detta beskrivas.

Det mest intressanta med Pod Security Policy Àr att i Kubernetes-klustret Àr alla PSP-installationer egentligen inte beskrivna pÄ nÄgot sÀtt, de Àr helt enkelt avstÀngda som standard. Pod Security Policy aktiveras med hjÀlp av en admission plugin.

Okej, vi ska deploya Pod Security Policy i klustret och sÀga att vi har vissa tjÀnstepoddar i ett namespace som bara administratörer har Ätkomst till. LÄt oss sÀga att i alla andra poddar har man begrÀnsade rÀttigheter. Eftersom det troligen inte Àr nödvÀndigt för utvecklarna att köra privilegierade poddar i ert kluster.

Och vi har tydligen allt i ordning. Och vÄrt Kubernetes-kluster kan inte hackas pÄ tvÄ minuter.

Det finns ett problem. Troligen om ni har ett Kubernetes-kluster, sÄ har ni ocksÄ övervakning installerad. Jag vÄgar till och med förutspÄ att om det finns övervakning i ert kluster sÄ kallas den Prometheus.

Det jag nu ska berÀtta gÀller bÄde Prometheus-operatören och Prometheus installerad i sin rena form. FrÄgan Àr att om jag inte kan fÄ en administratör sÄ snabbt i klustret, betyder det att jag mÄste leta mer. Och jag kan leta med hjÀlp av er övervakning.

Förmodligen har alla lÀst samma artiklar pÄ Habré, och övervakningen finns i namespace monitoring. Helm-diagrammet heter ungefÀr detsamma för alla. Jag antar att om ni gör helm install stable/prometheus, sÄ fÄr ni ungefÀr samma namn. Och det Àr till och med troligt att DNS-namnet i ert kluster inte behöver gissas. Eftersom det Àr standard.

Vi lagar hÄlen i Kubernetes-klustret. Rapport och avskrift frÄn DevOpsConf

Sedan har vi ett visst dev-namespac, i vilket man kan starta en viss pod. Och dÀrifrÄn Àr det mycket lÀtt att göra sÄ hÀr:

$ curl http://prometheus-kube-state-metrics.monitoring 

prometheus-kube-state-metrics Àr en av Prometheus-exportörerna som samlar in mÀtdata frÄn Kubernetes API:et. Det finns en mÀngd information om vad som körs i din kluster, hur det ser ut och vilka problem du har med det.

Som ett enkelt exempel:

kube_pod_container_info{namespace="kube-system",pod="kube-apiserver-k8s-1",container="kube-apiserver",image=

"gcr.io/google-containers/kube-apiserver:v1.14.5"

,image_id="docker-pullable://gcr.io/google-containers/kube-apiserver@sha256:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a9638ee634989",container_id="docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2853397d7daf08e72c22d3cf8b"} 1

Genom att göra en enkel curl-förfrÄgan frÄn en icke-privilegerad pod kan du fÄ sÄdan information. Om du inte vet vilken version av Kubernetes du kör sÄ kan den enkelt berÀtta det för dig.

Och det mest intressanta Àr att förutom att du kontaktar kube-state-metrics kan du lika gÀrna nÄ sjÀlva Prometheus direkt. Du kan samla in mÀtdata dÀrifrÄn. Du kan till och med bygga mÀtdata dÀrifrÄn. Teoretiskt sett kan du konstruera en sÄdan förfrÄgan frÄn klustret till Prometheus som helt enkelt slÄr av det. Och din övervakning kommer helt att sluta fungera.

Och hÀr uppstÄr frÄgan, övervakar nÄgon extern övervakning din övervakning? Jag fick just möjligheten att agera i Kubernetes-klustret helt utan konsekvenser för mig sjÀlv. Du kommer inte ens att veta att jag Àr dÀr eftersom övervakningen redan Àr borttagen.

Precis som med PSP finns kĂ€nslan av att problemet Ă€r att alla dessa trendiga teknologier — Kubernetes, Prometheus — helt enkelt inte fungerar och Ă€r fyllda med hĂ„l. Det Ă€r faktiskt inte sĂ„.

Det finns nĂ„got som kallas — Network Policy.

Om du Ă€r en vanlig admin vet du sannolikt att Network Policy Ă€r Ă€nnu en yaml, av vilka det redan finns gott om i klustret. Och vissa Network Policies Ă€r verkligen inte nödvĂ€ndiga. Även om du har lĂ€st vad en Network Policy Ă€r, att den Ă€r en yaml-brandvĂ€gg för Kubernetes, som gör det möjligt att begrĂ€nsa Ă„tkomstrĂ€ttigheter mellan namespaces, mellan pods, sĂ„ har du sĂ€kert kommit fram till att en brandvĂ€gg i yaml-format i Kubernetes Ă€r ytterligare en abstraktion
 Nej, det behövs verkligen inte.

Även om era sĂ€kerhetsspecialister inte har berĂ€ttat att ni kan bygga en mycket enkel och granulĂ€r brandvĂ€gg med hjĂ€lp av er Kubernetes, behöver ni i alla fall Network Policy för att stĂ€nga Ă„tkomst till vissa kĂ€nsliga platser som kan nĂ„s frĂ„n er kluster utan nĂ„gon autentisering.

Som i exemplet jag nÀmnde kan man nÄ kube state metrics frÄn vilket namnrum som helst i Kubernetes-klustret utan att ha nÄgra rÀttigheter. Network policies stÀngde Ätkomst frÄn alla andra namnrum till övervakningsnamnrymden, och sÄ Àr det: ingen Ätkomst, inga problem. I alla diagram som finns, bÄde i standard Prometheus och det Prometheus som finns i operatören, finns det helt enkelt ett alternativ att aktivera nÀtverkspolicys för dem i values-filen i Helm. Det Àr bara att aktivera, sÄ fungerar de.

Det finns dock ett problem med detta. Som en erfaren administratör har ni förmodligen kommit fram till att nÀtverkspolicys inte Àr nödvÀndiga. Och efter att ha lÀst olika artiklar pÄ resurser som Habr, har ni beslutat att flannel, sÀrskilt i host-gateway-lÀget, Àr det bÀsta alternativet ni kan vÀlja.

Vad göra?

Ni kan försöka omdeplaera den nÀtverkslösning som ni har i ert Kubernetes-kluster och byta ut den mot nÄgot mer funktionellt. Kanske Calico, till exempel. Men jag vill genast pÄpeka att det Àr en ganska komplicerad uppgift att byta nÀtverkslösning i ett aktivt Kubernetes-kluster. Jag har löst det tvÄ gÄnger (bÄda gÄngerna, faktiskt, teoretiskt), men vi visade till och med pÄ Slurm hur man gör. För vÄra studenter visade vi hur man byter nÀtverkslösning i ett Kubernetes-kluster. Ni kan i princip försöka göra det sÄ att det inte blir nÄgon driftstopp i produktionsklustret. Men det Àr troligt att ni misslyckas.

Och problemet gÄr faktiskt att lösa ganska enkelt. I klustret finns det certifikat, och ni vet att certifikaten kommer att gÄ ut om ett Är. Det normala tillvÀgagÄngssÀttet med certifikat i klustret Àr att vi sÀtter upp ett nytt kluster bredvid, lÄter det gamla gÄ ut, och allt deployas om. Visserligen kommer det gamla klustret att ligga stilla i en hel dag nÀr det gÄr ut, men dÄ har vi Ätminstone det nya klustret.

NÀr ni sÀtter upp det nya klustret, se till att inkludera Calico istÀllet för flannel.

Vad ska man göra om dina certifikat Àr utfÀrdade pÄ hundra Är och du inte tÀnker omdeploya klustret? Det finns nÄgot som heter Kube-RBAC-Proxy. Det Àr en riktigt fantastisk lösning som lÄter dig integrera den som en sidecar-container i valfri podd i Kubernetes-klustret. Den tillför i praktiken autentisering via RBAC i sjÀlva Kubernetes.

Det finns ett problem. Tidigare var Kube-RBAC-Proxy integrerat i Prometheus-operatorn. Men det finns inte lÀngre. Nu kör moderna versioner pÄ att du har en nÀtverkspolicy som stÀnger av Ätkomst med hjÀlp av dem. DÀrför mÄste du Àndra diagrammet lite grann. Om du gÄr in i detta repository, hittar du exempel pÄ hur man anvÀnder det som sidecars, och diagrammen mÄste Àndras minimalt.

Det finns Àven ett litet problem till. Inte bara Prometheus levererar sina mÀtvÀrden till vem som helst. Alla komponenter i Kubernetes-klustret kan ocksÄ leverera sina egna mÀtvÀrden.

Men som jag redan har nÀmnt, om du inte kan fÄ Ätkomst till klustret och samla information, kan du Ätminstone skada det.

SÄ jag ska snabbt visa tvÄ sÀtt att förstöra hÀlsan pÄ ett Kubernetes-kluster.

Du kommer att skratta nÀr jag berÀttar detta, det Àr tvÄ fall frÄn verkliga livet.

Metod ett. Resursutarmning.

Vi startar en sÀrskild podd. Den kommer att ha en sektion som ser ut sÄ hÀr.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Som du vet Àr requests den mÀngd CPU och minne som reserveras pÄ vÀrden för specifika poddar med requests. Om vi har en fyrkÀrnig vÀrd i Kubernetes-klustret, och det finns en podd med fyra CPU i requests, betyder det att ingen annan podd med requests kan Äka dit.

Om jag startar en sÄdan podd och sedan kör kommandot:

$ kubectl scale special-pod --replicas=...

DÄ kan ingen annan deploya i Kubernetes-klustret. Eftersom alla noder fÄr slut pÄ requests. PÄ sÄ sÀtt kan jag stoppa ditt Kubernetes-kluster. Om jag gör detta pÄ kvÀllen kan jag stoppa deployerna ganska lÀnge.

Om vi tittar igenom Kubernetes-dokumentationen sĂ„ ser vi nĂ„got som kallas Limit Range. Det sĂ€tter resursgrĂ€nser för klusterobjekt. Du kan skriva ett Limit Range-objekt i yaml, tillĂ€mpa det pĂ„ specifika namespaces — och sedan kan du ange att du har standard-, maximal- och minimalresurser för pods i det namnet.

Med den hÀr funktionen kan vi begrÀnsa anvÀndare i specifika produktnamn för team nÀr det gÀller att ange oönskade resurser för sina pods. Men tyvÀrr, Àven om du informerar anvÀndaren att de inte fÄr starta pods med begÀrningar som överstiger en CPU, finns det en fantastisk skala-kommando, eller via dashboarden kan de utföra skalan.

Och hÀrifrÄn kommer sÀtt nummer tvÄ. Vi startar 11 111 111 111 111 pods. Det Àr elva miljarder. Detta Àr inte för att jag hittade pÄ det numret, utan för att jag sjÀlv har sett det.

En sann historia. Sent pÄ kvÀllen var jag redo att lÀmna kontoret. Jag sÄg en grupp utvecklare sitta i ett hörn och göra nÄgot hektiskt med sina laptops. Jag gick fram till killarna och frÄgade: "Vad har hÀnt?"

Lite tidigare, vid nio pĂ„ kvĂ€llen, var en av utvecklarna pĂ„ vĂ€g hem. Han bestĂ€mde sig: "Jag ska skala min applikation till en." Han tryckte pĂ„ enan, men internet blev lite segt. Han tryckte en gĂ„ng till pĂ„ enan, han tryckte pĂ„ enan, klickade pĂ„ Enter. Han tryckte pĂ„ allt han kunde. DĂ„ blev internet snabbt igen — och allt började skala till det numret.

Men detta hÀnde inte pÄ Kubernetes, dÄ var det Nomad. Detta slutade med att efter en timmes försök att stoppa Nomad frÄn att insistera pÄ att skala, svarade Nomad att den inte skulle sluta skala och inte skulle göra nÄgot annat. "Jag Àr trött, jag gÄr". Och lÄg ner.

SjĂ€lvklart försökte jag göra detsamma pĂ„ Kubernetes. Elva miljarder pods gjorde Kubernetes besviken, den sa: "Jag kan inte. Överskrider interna grĂ€nser." Men 1 000 000 000 pods gick att skapa.

Som svar pĂ„ en miljard Pods har Kubernetes inte stĂ€ngt av sig sjĂ€lv. Det började verkligen skala. Ju lĂ€ngre processen fortskred, desto mer tid krĂ€vdes för att skapa nya Pods. Men processen fortsatte Ă€ndĂ„. Det enda problemet Ă€r att om jag kan starta Pods utan begrĂ€nsningar i mitt namnrymd, sĂ„ kan jag, Ă€ven utan requests och begrĂ€nsningar, starta sĂ„ mĂ„nga Pods med olika uppgifter att noderna börjar lagra minne och CPU-resurser. NĂ€r jag startar sĂ„ mĂ„nga Pods, mĂ„ste informationen frĂ„n dem lagras, det vill sĂ€ga i etcd. Och nĂ€r för mycket information nĂ„r lagringen, börjar den att ge ut data för lĂ„ngsamt — och Kubernetes fĂ„r problem.

Och en ytterligare problem
 Som ni vet, Ă€r Kubernetes kontrollkomponenter inte en enskild central enhet, utan flera komponenter. DĂ€r finns bland annat controller manager, scheduler och sĂ„ vidare. Alla dessa komponenter kommer att börja utföra onödigt arbete samtidigt, vilket med tiden kommer att ta mer och mer tid. Controller manager kommer att skapa nya Pods. Scheduler kommer att försöka hitta nya noder Ă„t dem. Nya noder i din kluster kommer sannolikt att ta slut snart. Kubernetes-klustret kommer att börja arbeta lĂ„ngsammare och lĂ„ngsammare.

Men jag bestÀmde mig för att gÄ Ànnu lÀngre. Som ni vet finns det nÄgot i Kubernetes som kallas en tjÀnst. Och som standard fungerar tjÀnsten i era kluster, sannolikt, med hjÀlp av IP-tables.

Om man startar en miljard Pods, till exempel, och sedan med hjÀlp av ett skript fÄr Kubernetes att skapa nya tjÀnster:

for i in {1..1111111}; do
    kubectl expose deployment test --port 80  
        --overrides="{"apiVersion": "v1", 
           "metadata": {"name": "nginx$i"}}"; 
done 

PÄ alla noder i klustret kommer nya IP-tables regler att genereras nÀstan samtidigt. Dessutom kommer en miljard IP-tables regler att genereras för varje tjÀnst.

Jag har testat detta med nÄgra tusen, upp till ett tiotal. Problemet Àr att det redan pÄ denna nivÄ Àr ganska problematiskt att göra en SSH-anslutning till en nod. Eftersom paketen, som passerar genom sÄ mÄnga kedjor, inte mÄr sÄ bra.

Och detta löses ocksÄ med hjÀlp av Kubernetes. Det finns ett objekt som heter Resource quota. Det faststÀller antalet tillgÀngliga resurser och objekt för namnomrÄdet i klustret. Vi kan skapa en yaml-objekt i varje namnomrÄde i Kubernetes-klustret. Med hjÀlp av detta objekt kan vi sÀga att vi har fÄtt ett visst antal förfrÄgningar och begrÀnsningar för detta namnomrÄde, och vidare kan vi sÀga att det Àr möjligt att skapa 10 tjÀnster och 10 pods i detta namnomrÄde. Och utvecklaren kan ge sig sjÀlv kvot för att experimentera pÄ kvÀllarna. Kubernetes kommer att sÀga: "Det gÄr inte att skala upp dina pods till den mÀngden, eftersom det överskrider resurskvoten." Problemet Àr löst. Dokumentation finns hÀr.

Ett problematiskt moment uppstÄr i samband med detta. Du kÀnner hur svÄrt det blir att skapa ett namnomrÄde i Kubernetes. För att skapa det behöver vi ta hÀnsyn till en massa olika faktorer.

Resource quota + Limit Range + RBAC
‱ Skapa namnomrĂ„de
‱ Skapa en limit range inuti
‱ Skapa en resource quota inuti
‱ Skapa ett service account för CI
‱ Skapa role binding för CI och anvĂ€ndare
‱ Eventuellt starta nödvĂ€ndiga service pods

SÄ jag vill gÀrna passa pÄ att dela med mig av mina projekt. Det finns en sak som kallas operator SDK. Det Àr ett sÀtt att skriva operatörer för Kubernetes-klustret. Du kan skriva operatörer med hjÀlp av Ansible.

Först hade vi skrivit det i Ansible, och sen sÄg jag att det finns en operator SDK och skrev om Ansible-rollen till en operator. Denna operator gör det möjligt att skapa ett objekt i Kubernetes-klustret som kallas kommando. Inuti kommandot kan den beskriva miljön för detta kommando i yaml. Och inom kommando-miljön kan den beskriva hur mycket resurser vi tilldelar.

Liten för att förenkla hela denna komplicerade process.

Och slutligen. Vad ska man göra med allt detta?
Första. Pod Security Policy - det Àr bra. Trots att ingen av Kubernetes-installatörerna anvÀnder dem till denna dag, bör de ÀndÄ anvÀndas i era kluster.

Network Policy - det Àr ingen annan onödig funktion. Det Àr nÄgot som verkligen behövs i klustret.

LimitRange/ResourceQuota - det Àr dags att anvÀnda. Vi har anvÀnt detta lÀnge, och jag var lÀnge övertygad om att alla gjorde det. Det visade sig vara ganska sÀllsynt.

Förutom det jag nÀmnde under presentationen finns det odeklarerade funktioner som gör det möjligt att attackera klustret. Nyligen kom ut en stor analys av sÄrbarheter i Kubernetes.

Vissa saker Àr sÄ sorgliga och upprörande. Som till exempel, under vissa förhÄllanden kan kubeletar i Kubernetes-klustret ge obehöriga anvÀndare Ätkomst till innehÄllet i warlocks-katalogen.

HÀr finns instruktioner om hur man Äterskapar allt jag pratat om. Det finns filer med produktions exempel, som visar hur ResourceQuota och Pod Security Policy ser ut. Och allt detta kan man ta pÄ.

Tack alla.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster