Gaten in het Kubernetes-cluster repareren. Rapport en transcriptie van DevOpsConf

Pavel Selivanov, Southbridge solutions architect en Slurm docent, gaf een presentatie op DevOpsConf 2019. Deze lezing is onderdeel van een van de onderwerpen van de verdiepingscursus over Kubernetes “Slurm Mega”.

Slurm Basic: een inleiding tot Kubernetes vindt plaats in Moskou op 18-20 november.
Slurm Mega: kijken onder de motorkap van Kubernetes — Moskou, 22-24 november.
Slurm Online: beide Kubernetes-cursussen altijd beschikbaar.

Onder de uitsnede vindt u een transcriptie van het rapport.

Goedemiddag collega's en degenen die met hen sympathiseren. Vandaag zal ik het hebben over veiligheid.

Ik zie dat er vandaag veel bewakers in de hal zijn. Bij voorbaat bied ik u mijn excuses aan als ik termen uit de veiligheidswereld niet precies gebruik zoals voor u gebruikelijk is.

Het gebeurde zo dat ik ongeveer zes maanden geleden één openbaar Kubernetes-cluster tegenkwam. Openbaar betekent dat er een zoveelste aantal naamruimten is; in deze naamruimten bevinden zich gebruikers die geïsoleerd zijn in hun naamruimte. Al deze gebruikers behoren tot verschillende bedrijven. Welnu, er werd aangenomen dat dit cluster als CDN zou moeten worden gebruikt. Dat wil zeggen, ze geven je een cluster, ze geven je daar een gebruiker, je gaat daar naar je naamruimte, zet je fronten in.

Mijn vorige bedrijf probeerde een dergelijke dienst te verkopen. En mij werd gevraagd om in het cluster te porren om te zien of deze oplossing geschikt was of niet.

Ik kwam naar dit cluster. Ik kreeg beperkte rechten en een beperkte naamruimte. De jongens daar begrepen wat veiligheid was. Ze lazen over op rollen gebaseerde toegangscontrole (RBAC) in Kubernetes - en ze verdraaiden het zo dat ik pods niet los van implementaties kon lanceren. Ik kan me het probleem niet herinneren dat ik probeerde op te lossen door een pod te lanceren zonder inzet, maar ik wilde eigenlijk alleen maar een pod lanceren. Voor veel succes besloot ik te kijken welke rechten ik heb in het cluster, wat ik kan doen, wat ik niet kan doen en wat ze daar hebben verpest. Tegelijkertijd zal ik je vertellen wat ze verkeerd hebben geconfigureerd in RBAC.

Het gebeurde zo dat ik binnen twee minuten een beheerder bij hun cluster ontving, naar alle aangrenzende naamruimten keek en daar de lopende productiefronten zag van bedrijven die de dienst al hadden gekocht en geïmplementeerd. Ik kon mezelf er nauwelijks van weerhouden om naar iemands front te gaan en een scheldwoord op de hoofdpagina te zetten.

Ik zal je met voorbeelden vertellen hoe ik dit deed en hoe je jezelf hiertegen kunt beschermen.

Maar eerst zal ik mezelf voorstellen. Mijn naam is Pavel Selivanov. Ik ben architect bij Southbridge. Ik begrijp Kubernetes, DevOps en allerlei mooie dingen. De Southbridge-ingenieurs en ik bouwen dit allemaal, en ik geef advies.

Naast onze hoofdactiviteiten zijn wij onlangs projecten gestart onder de naam Slurms. We proberen ons vermogen om met Kubernetes te werken een beetje onder de aandacht van de massa te brengen, om andere mensen te leren ook met K8's te werken.

Waar zal ik het vandaag over hebben? Het onderwerp van het rapport ligt voor de hand: over de veiligheid van het Kubernetes-cluster. Maar ik wil meteen zeggen dat dit onderwerp erg groot is - en daarom wil ik meteen duidelijk maken waar ik het zeker niet over zal hebben. Ik zal het niet hebben over afgezaagde termen die al honderd keer op internet zijn gebruikt. Allerlei RBAC en certificaten.

Ik zal het hebben over wat mij en mijn collega’s pijn doet aan de beveiliging in een Kubernetes-cluster. Deze problemen zien we zowel bij aanbieders die Kubernetes-clusters aanbieden als bij klanten die bij ons komen. En zelfs van klanten die bij ons komen via andere adviesbureaus. Dat wil zeggen dat de omvang van de tragedie eigenlijk heel groot is.

Er zijn letterlijk drie punten waar ik het vandaag over zal hebben:

  1. Gebruikersrechten versus podrechten. Gebruikersrechten en podrechten zijn niet hetzelfde.
  2. Informatie verzamelen over het cluster. Ik zal laten zien dat je alle informatie die je nodig hebt uit een cluster kunt verzamelen zonder dat je speciale rechten hebt in dit cluster.
  3. DoS-aanval op het cluster. Als we geen informatie kunnen verzamelen, kunnen we in ieder geval een cluster plaatsen. Ik zal het hebben over DoS-aanvallen op clusterbesturingselementen.

Een ander algemeen ding dat ik zal vermelden is waar ik dit allemaal op heb getest, waarvan ik zeker kan zeggen dat het allemaal werkt.

Als basis nemen wij de installatie van een Kubernetes cluster met behulp van Kubespray. Als iemand het niet weet: dit zijn eigenlijk een reeks rollen voor Ansible. Wij gebruiken het voortdurend in ons werk. Het mooie is dat je het overal kunt rollen: je kunt het op stukjes ijzer rollen of ergens in een wolk. Eén installatiemethode werkt in principe voor alles.

In dit cluster heb ik Kubernetes v1.14.5. Het gehele Kubuscluster, dat we zullen beschouwen, is verdeeld in naamruimten, elke naamruimte behoort tot een afzonderlijk team en leden van dit team hebben toegang tot elke naamruimte. Ze kunnen niet naar verschillende naamruimten gaan, alleen naar hun eigen naamruimte. Maar er is een bepaald beheerdersaccount dat rechten heeft op het hele cluster.

Gaten in het Kubernetes-cluster repareren. Rapport en transcriptie van DevOpsConf

Ik heb beloofd dat het eerste wat we zullen doen het verkrijgen van beheerdersrechten voor het cluster is. We hebben een speciaal geprepareerde pod nodig die het Kubernetes-cluster zal breken. Het enige wat we hoeven te doen is het toepassen op het Kubernetes-cluster.

kubectl apply -f pod.yaml

Deze pod komt terecht bij een van de meesters van het Kubernetes-cluster. En hierna stuurt het cluster ons graag een bestand terug met de naam admin.conf. In Cube slaat dit bestand alle beheerderscertificaten op en configureert het tegelijkertijd de cluster-API. Zo gemakkelijk is het om beheerderstoegang te krijgen tot, denk ik, 98% van de Kubernetes-clusters.

Ik herhaal, deze pod is gemaakt door één ontwikkelaar in uw cluster die toegang heeft om zijn voorstellen in één kleine naamruimte te implementeren, het wordt allemaal vastgeklemd door RBAC. Hij had geen rechten. Maar toch werd het certificaat teruggegeven.

En nu over een speciaal voorbereide pod. We voeren het uit op elke afbeelding. Laten we debian:jessie als voorbeeld nemen.

Wij hebben dit ding:

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

Wat is tolerantie? Masters in een Kubernetes-cluster worden meestal gemarkeerd met iets dat 'taint' wordt genoemd. En de essentie van deze “infectie” is dat er staat dat pods niet aan masternodes kunnen worden toegewezen. Maar niemand neemt de moeite om in welke groep dan ook aan te geven dat deze tolerant is voor de “infectie”. In de sectie Toleratie staat alleen dat als een knooppunt NoSchedule heeft, ons knooppunt tolerant is voor een dergelijke infectie - en er zijn geen problemen.

Verder zeggen we dat ons onder niet alleen tolerant is, maar zich ook specifiek op de meester wil richten. Omdat de meesters het lekkerste hebben wat we nodig hebben: alle certificaten. Daarom zeggen we nodeSelector - en we hebben een standaardlabel op masters, waarmee je uit alle knooppunten in het cluster precies die knooppunten kunt selecteren die masters zijn.

Met deze twee secties zal hij zeker bij de meester komen. En hij mag daar wonen.

Maar alleen naar de meester komen is voor ons niet genoeg. Dit levert ons niets op. Dus vervolgens hebben we deze twee dingen:

hostNetwork: true 
hostPID: true 

We specificeren dat onze pod, die we lanceren, in de kernelnaamruimte, in de netwerknaamruimte en in de PID-naamruimte zal leven. Zodra de pod op de master is gelanceerd, kan deze alle echte, live interfaces van dit knooppunt zien, naar al het verkeer luisteren en de PID van alle processen zien.

Dan is het een kwestie van kleine dingen. Neem etcd en lees wat je wilt.

Het meest interessante is deze Kubernetes-functie, die daar standaard aanwezig is.

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

En de essentie ervan is dat we in de pod die we lanceren, zelfs zonder rechten op dit cluster, kunnen zeggen dat we een volume van het type hostPath willen creëren. Dit betekent dat we het pad moeten nemen van de host waarop we zullen lanceren - en dit als volume moeten nemen. En dan noemen we het naam: host. We monteren dit hele hostPath in de pod. In dit voorbeeld naar de map /host.

Ik zal het nog een keer herhalen. We vertelden de pod om naar de master te komen, het hostNetwork en de hostPID daar op te halen - en de volledige root van de master in deze pod te mounten.

Je begrijpt dat we in Debian bash draaien, en deze bash draait onder root. Dat wil zeggen, we hebben zojuist root op de master ontvangen, zonder enige rechten in het Kubernetes-cluster.

Dan is de hele taak om naar de submap /host /etc/kubernetes/pki te gaan, als ik me niet vergis, daar alle hoofdcertificaten van het cluster op te halen en dienovereenkomstig de clusterbeheerder te worden.

Als je het op deze manier bekijkt, zijn dit enkele van de gevaarlijkste rechten in pods, ongeacht welke rechten de gebruiker heeft:
Gaten in het Kubernetes-cluster repareren. Rapport en transcriptie van DevOpsConf

Als ik de rechten heb om een ​​pod in een bepaalde naamruimte van het cluster uit te voeren, heeft deze pod standaard deze rechten. Ik kan bevoorrechte pods uitvoeren, en dit zijn over het algemeen alle rechten, praktisch root op het knooppunt.

Mijn favoriet is Root-gebruiker. En Kubernetes heeft deze Run As Non-Root-optie. Dit is een vorm van bescherming tegen een hacker. Weet jij wat het “Moldavische virus” is? Als je ineens een hacker bent en naar mijn Kubernetes-cluster komt, dan vragen wij, arme beheerders: “Geef in je pods aan waarmee je mijn cluster gaat hacken, draai als non-root. Anders zal het gebeuren dat je het proces in je pod onder root uitvoert, en het zal heel gemakkelijk voor je zijn om mij te hacken. Bescherm jezelf alsjeblieft tegen jezelf."

Het hostpadvolume is naar mijn mening de snelste manier om het gewenste resultaat uit een Kubernetes-cluster te halen.

Maar wat te doen met dit alles?

De gedachte die bij elke normale beheerder die Kubernetes tegenkomt zou moeten opkomen is: “Ja, ik zei het toch, Kubernetes werkt niet. Er zitten gaten in. En de hele Kubus is onzin.” In feite bestaat er zoiets als documentatie, en als je daar kijkt, is er een sectie Pod-beveiligingsbeleid.

Dit is een yaml-object – we kunnen het maken in het Kubernetes-cluster – dat beveiligingsaspecten specifiek regelt in de beschrijving van de pods. Dat wil zeggen dat het in feite de rechten beheert om elk hostNetwork, hostPID en bepaalde volumetypen te gebruiken die zich bij het opstarten in de pods bevinden. Met behulp van Pod Security Policy kan dit allemaal worden beschreven.

Het meest interessante aan het Pod-beveiligingsbeleid is dat in het Kubernetes-cluster alle PSP-installatieprogramma's niet alleen op geen enkele manier worden beschreven, maar gewoon standaard zijn uitgeschakeld. Pod-beveiligingsbeleid wordt ingeschakeld met behulp van de toelatingsplug-in.

Oké, laten we Pod Security Policy in het cluster implementeren. Laten we zeggen dat we een aantal servicepods in de naamruimte hebben, waartoe alleen beheerders toegang hebben. Laten we zeggen dat in alle andere gevallen pods beperkte rechten hebben. Omdat ontwikkelaars hoogstwaarschijnlijk geen bevoorrechte pods in uw cluster hoeven uit te voeren.

En alles lijkt goed te gaan met ons. En ons Kubernetes-cluster is niet in twee minuten te hacken.

Er is een probleem. Als u een Kubernetes-cluster heeft, is monitoring hoogstwaarschijnlijk op uw cluster geïnstalleerd. Ik zou zelfs zo ver willen gaan om te voorspellen dat als je cluster monitoring heeft, het Prometheus zal heten.

Wat ik u ga vertellen, geldt voor zowel de Prometheus-operator als voor Prometheus die in zijn pure vorm wordt geleverd. De vraag is dat als ik niet zo snel een beheerder in het cluster kan krijgen, dit betekent dat ik verder moet zoeken. En ik kan zoeken met behulp van jouw monitoring.

Waarschijnlijk heeft iedereen dezelfde artikelen over Habré gelezen en bevindt de monitoring zich in de monitoring-naamruimte. Helmdiagram wordt voor iedereen ongeveer hetzelfde genoemd. Ik vermoed dat als je stable/prometheus installeert, je ongeveer dezelfde namen zult krijgen. En hoogstwaarschijnlijk hoef ik de DNS-naam in uw cluster niet eens te raden. Omdat het standaard is.

Gaten in het Kubernetes-cluster repareren. Rapport en transcriptie van DevOpsConf

Vervolgens hebben we een bepaalde dev ns, waarin je een bepaalde pod kunt draaien. En vanuit deze pod is het heel eenvoudig om zoiets als dit te doen:

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

prometheus-kube-state-metrics is een van de Prometheus-exporteurs die statistieken verzamelt van de Kubernetes API zelf. Er zit daar veel data, wat draait er in je cluster, wat is het, welke problemen heb je ermee.

Als eenvoudig voorbeeld:

kube_pod_container_info{namespace=“kube-systeem”,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:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a96 38ee634989″,container_id=»docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2 853397d7daf08e72c22d3cf8b»} 1

Door een eenvoudig curlverzoek in te dienen vanuit een niet-bevoorrechte pod, kunt u de volgende informatie verkrijgen. Als u niet weet welke versie van Kubernetes u gebruikt, kan dit u gemakkelijk worden verteld.

En het meest interessante is dat je naast toegang tot kube-state-metrics, net zo gemakkelijk rechtstreeks toegang hebt tot Prometheus zelf. Van daaruit kunt u statistieken verzamelen. U kunt van daaruit zelfs statistieken samenstellen. Zelfs theoretisch kun je zo'n query bouwen vanuit een cluster in Prometheus, waardoor deze eenvoudigweg wordt uitgeschakeld. En uw monitoring werkt helemaal niet meer vanuit het cluster.

En hier rijst de vraag of er externe monitoring is die jouw monitoring monitort. Ik heb zojuist de kans gekregen om in een Kubernetes-cluster te opereren, zonder enige gevolgen voor mezelf. Je zult niet eens weten dat ik daar opereer, omdat er geen toezicht meer is.

Net als bij de PSP voelt het alsof het probleem is dat al deze mooie technologieën – Kubernetes, Prometheus – gewoon niet werken en vol gaten zitten. Niet echt.

Er bestaat zoiets- Netwerkbeleid.

Als u een normale beheerder bent, weet u waarschijnlijk van Network Policy dat dit gewoon weer een yaml is, waarvan er al veel in het cluster zijn. En sommige netwerkbeleidsregels zijn absoluut niet nodig. En zelfs als je leest wat Netwerkbeleid is, dat het een yaml-firewall van Kubernetes is, waarmee je de toegangsrechten tussen naamruimten, tussen pods kunt beperken, dan heb je zeker besloten dat de firewall in yaml-formaat in Kubernetes gebaseerd is op de volgende abstracties ... Nee nee . Dit is absoluut niet nodig.

Zelfs als u uw beveiligingsspecialisten niet heeft verteld dat u met uw Kubernetes een zeer gemakkelijke en eenvoudige firewall kunt bouwen, en nog een zeer gedetailleerde firewall. Als ze dit nog niet weten en je niet lastig vallen: "Nou, geef me, geef me..." Dan heb je in ieder geval Network Policy nodig om de toegang tot sommige serviceplaatsen te blokkeren die uit je cluster kunnen worden gehaald zonder enige toestemming.

Net als in het voorbeeld dat ik gaf, kunt u kube-statusstatistieken ophalen uit elke naamruimte in het Kubernetes-cluster zonder dat u daarvoor de rechten hebt. Netwerkbeleid heeft de toegang van alle andere naamruimten tot de monitoringnaamruimte gesloten en dat is alles: geen toegang, geen problemen. In alle grafieken die er bestaan, zowel de standaard Prometheus als de Prometheus die in de operator zit, zit simpelweg een optie in de roerwaarden om er eenvoudigweg netwerkbeleid voor in te schakelen. Je hoeft het alleen maar aan te zetten en ze zullen werken.

Er is hier eigenlijk één probleem. Als normale, bebaarde beheerder heeft u waarschijnlijk besloten dat netwerkbeleid niet nodig is. En na het lezen van allerlei artikelen over bronnen als Habr, besloot je dat flanel, vooral met de host-gateway-modus, het beste is wat je kunt kiezen.

Wat te doen?

U kunt proberen de netwerkoplossing die u in uw Kubernetes-cluster heeft, opnieuw te implementeren en deze te vervangen door iets functionelers. Voor dezelfde Calico bijvoorbeeld. Maar ik wil meteen zeggen dat de taak van het veranderen van de netwerkoplossing in een Kubernetes-werkcluster nogal niet triviaal is. Ik heb het twee keer opgelost (beide keren echter theoretisch), maar we hebben bij Slurms zelfs laten zien hoe het moet. Voor onze studenten lieten we zien hoe je de netwerkoplossing in een Kubernetes-cluster kunt veranderen. In principe kun je proberen ervoor te zorgen dat er geen downtime is op het productiecluster. Maar het zal je waarschijnlijk niet lukken.

En het probleem is eigenlijk heel eenvoudig opgelost. Er bevinden zich certificaten in het cluster en u weet dat uw certificaten over een jaar verlopen. Nou ja, en meestal een normale oplossing met certificaten in het cluster - waarom maken we ons zorgen, we zullen een nieuw cluster in de buurt oprichten, de oude laten rotten en alles opnieuw implementeren. Het is waar dat als het verrot gaat, we een dag moeten blijven zitten, maar hier is een nieuw cluster.

Wanneer je een nieuwe tros grootbrengt, gebruik dan tegelijkertijd Calico in plaats van flanel.

Wat moet u doen als uw certificaten voor honderd jaar worden uitgegeven en u het cluster niet opnieuw gaat inzetten? Er bestaat zoiets als Kube-RBAC-Proxy. Dit is een hele coole ontwikkeling; je kunt jezelf hiermee als zijspancontainer in elke pod in het Kubernetes-cluster inbedden. En het voegt feitelijk autorisatie toe aan deze pod via RBAC van Kubernetes zelf.

Er is één probleem. Voorheen werd deze Kube-RBAC-Proxy-oplossing ingebouwd in de Prometheus van de operator. Maar toen was hij weg. Moderne versies vertrouwen er nu op dat u een netwerkbeleid heeft en sluit dit met behulp daarvan. En daarom zullen we de grafiek een beetje moeten herschrijven. Sterker nog, als je naar toe gaat deze opslagplaats, er zijn voorbeelden van hoe je dit als zijspannen kunt gebruiken, en de kaarten zullen minimaal herschreven moeten worden.

Er is nog een klein probleem. Prometheus is niet de enige die zijn statistieken aan iedereen uitdeelt. Al onze Kubernetes-clustercomponenten kunnen ook hun eigen statistieken retourneren.

Maar zoals ik al zei: als je geen toegang hebt tot het cluster en geen informatie kunt verzamelen, kun je op zijn minst wat schade aanrichten.

Ik zal dus snel twee manieren laten zien hoe een Kubernetes-cluster kan worden geruïneerd.

Je zult lachen als ik je dit vertel, dit zijn twee echte gevallen.

Methode één. Uitputting van hulpbronnen.

Laten we nog een speciale pod lanceren. Het zal een sectie als deze hebben.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Zoals u weet, zijn verzoeken de hoeveelheid CPU en geheugen die op de host is gereserveerd voor specifieke pods met verzoeken. Als we een host met vier kernen in een Kubernetes-cluster hebben en daar vier CPU-pods aankomen met verzoeken, betekent dit dat er geen pods met verzoeken meer naar deze host kunnen komen.

Als ik zo'n pod uitvoer, voer ik de opdracht uit:

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

Dan kan niemand anders in het Kubernetes-cluster implementeren. Omdat alle knooppunten geen aanvragen meer hebben. En dus stop ik jouw Kubernetes-cluster. Als ik dit 's avonds doe, kan ik de inzet een hele tijd stilleggen.

Als we nog eens naar de Kubernetes-documentatie kijken, zien we iets dat Limit Range heet. Het stelt bronnen in voor clusterobjecten. U kunt een Limit Range-object in yaml schrijven, het op bepaalde naamruimten toepassen - en vervolgens in deze naamruimte kunt u zeggen dat u standaard-, maximale en minimale bronnen voor de pods heeft.

Met behulp van zoiets kunnen we gebruikers in specifieke productnaamruimten van teams beperken in de mogelijkheid om allerlei nare dingen op hun pods aan te duiden. Maar helaas, zelfs als je de gebruiker vertelt dat ze geen pods kunnen starten met verzoeken voor meer dan één CPU, is er zo'n prachtig schaalcommando, of ze kunnen via het dashboard schalen.

En dit is waar methode nummer twee vandaan komt. We lanceren 11 pods. Dat is elf miljard. Dit is niet omdat ik zo’n getal heb bedacht, maar omdat ik het zelf heb gezien.

Echt verhaal. Laat in de avond stond ik op het punt het kantoor te verlaten. Ik zie een groep ontwikkelaars in de hoek zitten, verwoed iets met hun laptops doen. Ik ga naar de jongens toe en vraag: "Wat is er met je gebeurd?"

Iets eerder, rond negen uur 's avonds, maakte een van de ontwikkelaars zich klaar om naar huis te gaan. En ik besloot: “Ik ga mijn applicatie nu terugbrengen naar één.” Ik drukte op één, maar het internet vertraagde een beetje. Hij drukte nogmaals op de ene, hij drukte op de ene en klikte op Enter. Ik porde in alles wat ik kon. Toen kwam het internet tot leven - en alles begon zich te beperken tot dit aantal.

Toegegeven, dit verhaal speelde zich niet af op Kubernetes; destijds was het Nomad. Het eindigde met het feit dat Nomad, na een uur van onze pogingen om Nomad te weerhouden van aanhoudende pogingen om te schalen, antwoordde dat hij niet zou stoppen met schalen en niets anders zou doen. "Ik ben moe, ik ga weg." En hij krulde zich op.

Uiteraard probeerde ik hetzelfde te doen op Kubernetes. Kubernetes was niet blij met elf miljard pods, zei hij: “Dat kan ik niet. Overtreft de interne mondbeschermers." Maar 1 peulen zouden dat wel kunnen.

Als reactie op één miljard trok de Kubus zich niet in zichzelf terug. Hij begon echt te schalen. Hoe verder het proces vorderde, hoe meer tijd het hem kostte om nieuwe pods te maken. Maar toch ging het proces door. Het enige probleem is dat als ik onbeperkt pods in mijn naamruimte kan starten, ik zelfs zonder verzoeken en limieten zoveel pods met sommige taken kan starten dat met behulp van deze taken de knooppunten zich in het geheugen, in de CPU, gaan optellen. Wanneer ik zoveel pods lanceer, zou de informatie ervan in de opslag moeten gaan, dat wil zeggen, etcd. En als daar te veel informatie binnenkomt, begint de opslag te langzaam terug te keren - en begint Kubernetes saai te worden.

En nog een probleem... Zoals u weet, zijn de Kubernetes-besturingselementen niet één centraal ding, maar meerdere componenten. In het bijzonder is er een controllermanager, planner, enzovoort. Al deze jongens zullen tegelijkertijd onnodig, stom werk gaan doen, wat na verloop van tijd steeds meer tijd zal gaan kosten. De controllermanager zal nieuwe pods maken. De planner zal proberen een nieuw knooppunt voor hen te vinden. Waarschijnlijk zijn er binnenkort geen nieuwe knooppunten meer in uw cluster. Het Kubernetes-cluster zal steeds langzamer gaan werken.

Maar ik besloot nog verder te gaan. Zoals u weet bestaat er in Kubernetes zoiets als een service. Welnu, in uw clusters werkt de service hoogstwaarschijnlijk standaard met behulp van IP-tabellen.

Als u bijvoorbeeld een miljard pods uitvoert en vervolgens een script gebruikt om Kubernetis te dwingen nieuwe services te maken:

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

Op alle knooppunten van het cluster zullen steeds meer nieuwe iptables-regels ongeveer gelijktijdig worden gegenereerd. Bovendien zullen er voor elke dienst een miljard iptables-regels worden gegenereerd.

Ik heb dit hele ding gecontroleerd op enkele duizenden, tot tien. En het probleem is dat het al bij deze drempel behoorlijk problematisch is om ssh naar het knooppunt te doen. Omdat pakketten, die door zoveel ketens gaan, niet erg goed beginnen te voelen.

En ook dit wordt allemaal opgelost met behulp van Kubernetes. Er is zo'n Resourcequota-object. Stelt het aantal beschikbare bronnen en objecten in voor de naamruimte in het cluster. We kunnen een yaml-object maken in elke naamruimte van het Kubernetes-cluster. Met behulp van dit object kunnen we zeggen dat we een bepaald aantal verzoeken en limieten hebben toegewezen voor deze naamruimte, en dan kunnen we zeggen dat het in deze naamruimte mogelijk is om 10 services en 10 pods te maken. En een enkele ontwikkelaar kan zichzelf 's avonds op zijn minst stikken. Kubernetes zal tegen hem zeggen: “Je kunt je pods niet naar dat aantal schalen, omdat de bron het quotum overschrijdt.” Dat is alles, probleem opgelost. Documentatie hier.

In dit verband doet zich één problematisch punt voor. Je voelt hoe lastig het wordt om een ​​naamruimte te creëren in Kubernetes. Om het te creëren, moeten we met veel dingen rekening houden.

Resourcequotum + Limietbereik + RBAC
• Maak een naamruimte
• Creëer een limietbereik binnenin
• Creëer binnen resourcequota
• Maak een serviceaccount aan voor CI
• Creëer rolbinding voor CI en gebruikers
• Start eventueel de benodigde servicepods

Daarom wil ik graag van deze gelegenheid gebruik maken om mijn ontwikkelingen te delen. Er bestaat zoiets als de SDK-operator. Dit is een manier voor een Kubernetes-cluster om er operators voor te schrijven. U kunt verklaringen schrijven met Ansible.

In eerste instantie was het geschreven in Ansible, en toen zag ik dat er een SDK-operator was en herschreef ik de Ansible-rol in een operator. Met deze instructie kunt u een object in het Kubernetes-cluster maken dat een opdracht wordt genoemd. Binnen een opdracht kunt u de omgeving voor deze opdracht in yaml beschrijven. En binnen de teamomgeving kunnen we hiermee beschrijven dat we zoveel middelen inzetten.

Kleintje waardoor dit hele complexe proces eenvoudiger wordt.

En tot slot. Wat te doen met dit alles?
Eerst. Pod-beveiligingsbeleid is goed. En ondanks het feit dat geen van de Kubernetes-installatieprogramma's ze tot op de dag van vandaag gebruikt, moet je ze nog steeds in je clusters gebruiken.

Netwerkbeleid is niet zomaar een onnodige functie. Dit is wat echt nodig is in een cluster.

LimitRange/ResourceQuota - het is tijd om het te gebruiken. We zijn hier lang geleden mee begonnen en ik was er lange tijd zeker van dat iedereen het gebruikte. Het bleek dat dit zeldzaam is.

Naast wat ik tijdens het rapport heb genoemd, zijn er ongedocumenteerde functies waarmee u het cluster kunt aanvallen. Onlangs uitgebracht uitgebreide analyse van Kubernetes-kwetsbaarheden.

Sommige dingen zijn zo verdrietig en pijnlijk. Onder bepaalde omstandigheden kunnen cubelets in een Kubernetes-cluster bijvoorbeeld de inhoud van de warlocks-directory aan een ongeautoriseerde gebruiker geven.

Hier Er zijn instructies voor het reproduceren van alles wat ik je heb verteld. Er zijn bestanden met productievoorbeelden van hoe ResourceQuota en Pod Security Policy eruit zien. En je kunt dit allemaal aanraken.

Dank aan allen.

Bron: www.habr.com

Voeg een reactie