Remedierea găurilor în clusterul Kubernetes. Raport și transcriere de la DevOpsConf

Pavel Selivanov, arhitect soluții Southbridge și profesor Slurm, a susținut o prezentare la DevOpsConf 2019. Această discuție face parte dintr-unul dintre subiectele cursului aprofundat despre Kubernetes „Slurm Mega”.

Slurm Basic: o introducere în Kubernetes are loc la Moscova în perioada 18-20 noiembrie.
Slurm Mega: privind sub capota Kubernetes — Moscova, 22-24 noiembrie.
Slurm Online: ambele cursuri Kubernetes mereu valabil.

Sub tăietură este o transcriere a raportului.

Bună ziua, colegi și cei care îi simpatizează. Astăzi voi vorbi despre siguranță.

Văd că astăzi sunt mulți securiști în sală. Îmi cer scuze în avans dacă folosesc termeni din lumea securității nu tocmai așa cum este obișnuit pentru tine.

S-a întâmplat că în urmă cu aproximativ șase luni am dat peste un cluster public Kubernetes. Public înseamnă că există un al n-lea număr de spații de nume; în aceste spații de nume există utilizatori izolați în spațiul lor de nume. Toți acești utilizatori aparțin unor companii diferite. Ei bine, s-a presupus că acest cluster ar trebui să fie folosit ca un CDN. Adică îți dau un cluster, îți dau un utilizator acolo, te duci acolo în spațiul tău de nume, îți desfășoară fronturile.

Compania mea anterioară a încercat să vândă un astfel de serviciu. Și mi s-a cerut să pun clusterul pentru a vedea dacă această soluție este potrivită sau nu.

Am ajuns la acest grup. Mi s-au oferit drepturi limitate, spațiu de nume limitat. Băieții de acolo au înțeles ce este siguranța. Au citit despre controlul accesului bazat pe roluri (RBAC) în Kubernetes - și l-au răsucit astfel încât să nu pot lansa pod-uri separat de implementări. Nu-mi amintesc problema pe care încercam să o rezolv lansând un pod fără implementare, dar îmi doream foarte mult să lansez doar un pod. Pentru noroc, m-am hotărât să văd ce drepturi am în cluster, ce pot face, ce nu pot face și ce au greșit acolo. În același timp, vă voi spune ce au configurat incorect în RBAC.

S-a întâmplat că în două minute am primit un administrator la clusterul lor, m-am uitat la toate spațiile de nume învecinate, am văzut acolo fronturile de producție care rulează ale companiilor care achiziționaseră deja serviciul și implementaseră. Abia m-am putut opri să merg în fața cuiva și să pun niște înjurături pe pagina principală.

Vă voi spune cu exemple cum am făcut asta și cum să vă protejați de asta.

Dar mai întâi, permiteți-mi să mă prezint. Numele meu este Pavel Selivanov. Sunt arhitect la Southbridge. Înțeleg Kubernetes, DevOps și tot felul de lucruri fanteziste. Inginerii Southbridge și cu mine construim toate acestea, iar eu consult.

Pe lângă activitățile noastre principale, recent am lansat proiecte numite Slurms. Încercăm să aducem un pic capacitatea noastră de a lucra cu Kubernetes în rândul maselor, să-i învățăm pe alți oameni să lucreze și cu K8.

Despre ce voi vorbi azi? Subiectul raportului este evident - despre securitatea clusterului Kubernetes. Dar vreau să spun imediat că acest subiect este foarte amplu - și, prin urmare, vreau să clarific imediat despre ce cu siguranță nu voi vorbi. Nu voi vorbi despre termeni năuciți care au fost deja folosiți de o sută de ori pe Internet. Tot felul de RBAC și certificate.

Voi vorbi despre ceea ce mă doare pe mine și pe colegii mei despre securitatea într-un cluster Kubernetes. Vedem aceste probleme atât în ​​rândul furnizorilor care furnizează clustere Kubernetes, cât și în rândul clienților care vin la noi. Și chiar și de la clienții care vin la noi de la alte companii admin de consultanță. Adică amploarea tragediei este de fapt foarte mare.

Există literalmente trei puncte despre care voi vorbi astăzi:

  1. Drepturile utilizatorului vs drepturile la pod. Drepturile utilizatorului și drepturile podului nu sunt același lucru.
  2. Colectarea de informații despre cluster. Voi arăta că puteți colecta toate informațiile de care aveți nevoie dintr-un cluster fără a avea drepturi speciale în acest cluster.
  3. Atac DoS asupra clusterului. Dacă nu putem colecta informații, vom putea pune un cluster în orice caz. Voi vorbi despre atacurile DoS asupra elementelor de control ale clusterului.

Un alt lucru general pe care îl voi menționa este pe ce am testat toate acestea, pe care pot spune cu siguranță că totul funcționează.

Luăm ca bază instalarea unui cluster Kubernetes folosind Kubespray. Dacă cineva nu știe, acesta este de fapt un set de roluri pentru Ansible. Îl folosim constant în munca noastră. Lucrul bun este că îl puteți rula oriunde - îl puteți rula pe bucăți de fier sau într-un nor undeva. O singură metodă de instalare funcționează în principiu pentru orice.

În acest cluster voi avea Kubernetes v1.14.5. Întregul cluster Cube, pe care îl vom lua în considerare, este împărțit în spații de nume, fiecare spațiu de nume aparține unei echipe separate, iar membrii acestei echipe au acces la fiecare spațiu de nume. Ei nu pot merge în spații de nume diferite, ci doar în spațiile lor. Dar există un anumit cont de administrator care are drepturi asupra întregului cluster.

Remedierea găurilor în clusterul Kubernetes. Raport și transcriere de la DevOpsConf

Am promis că primul lucru pe care îl vom face este să obținem drepturi de administrator pentru cluster. Avem nevoie de un pod special pregătit care va sparge cluster-ul Kubernetes. Tot ce trebuie să facem este să-l aplicăm clusterului Kubernetes.

kubectl apply -f pod.yaml

Acest pod va ajunge la unul dintre stăpânii clusterului Kubernetes. Și după aceasta clusterul ne va returna cu plăcere un fișier numit admin.conf. În Cube, acest fișier stochează toate certificatele de administrator și, în același timp, configurează API-ul cluster. Acesta este cât de ușor este să obțineți acces de administrator la, cred, 98% din clusterele Kubernetes.

Repet, acest pod a fost realizat de un dezvoltator din clusterul dvs. care are acces pentru a-și implementa propunerile într-un spațiu de nume mic, totul este blocat de RBAC. Nu avea drepturi. Dar, cu toate acestea, certificatul a fost returnat.

Și acum despre o pastă special pregătită. Îl rulăm pe orice imagine. Să luăm ca exemplu debian:jessie.

Avem chestia asta:

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

Ce este toleranța? Maeștrii dintr-un cluster Kubernetes sunt de obicei marcați cu ceva numit pată. Și esența acestei „infecții” este că spune că podurile nu pot fi alocate nodurilor principale. Dar nimeni nu se deranjează să indice în orice păstăi că este tolerant la „infecție”. Secțiunea Tolerație spune doar că, dacă un nod are NoSchedule, atunci nodul nostru este tolerant la o astfel de infecție - și nu există probleme.

Mai mult, spunem că sub-ul nostru nu este doar tolerant, ci și dorește să-l vizeze în mod specific pe stăpân. Pentru că maeștrii au cel mai delicios lucru de care avem nevoie - toate certificatele. Prin urmare, spunem nodeSelector - și avem o etichetă standard pe master, care vă permite să selectați din toate nodurile din cluster exact acele noduri care sunt master.

Cu aceste două secțiuni va ajunge cu siguranță la maestru. Și i se va permite să locuiască acolo.

Dar doar venirea la stăpân nu este suficientă pentru noi. Asta nu ne va da nimic. Deci în continuare avem aceste două lucruri:

hostNetwork: true 
hostPID: true 

Specificăm că podul nostru, pe care îl lansăm, va locui în spațiul de nume kernel, în spațiul de nume de rețea și în spațiul de nume PID. Odată ce pod-ul este lansat pe master, acesta va putea să vadă toate interfețele reale, live ale acestui nod, să asculte tot traficul și să vadă PID-ul tuturor proceselor.

Atunci este o chestiune de lucruri mărunte. Ia etcd și citește ce vrei.

Cel mai interesant lucru este această caracteristică Kubernetes, care este prezentă acolo în mod implicit.

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

Și esența sa este că putem spune în pod că lansăm, chiar și fără drepturi asupra acestui cluster, că vrem să creăm un volum de tip hostPath. Aceasta înseamnă să luăm calea de la gazda pe care ne vom lansa – și să o luăm ca volum. Și apoi îi spunem nume: gazdă. Montăm toată această cale de host în interiorul podului. În acest exemplu, în directorul /host.

O voi repeta din nou. Am spus podului să vină la master, să obțină hostNetwork și hostPID acolo - și să monteze întreaga rădăcină a masterului în interiorul acestui pod.

Înțelegeți că în Debian avem bash care rulează, iar acest bash rulează sub root. Adică tocmai am primit root pe master, fără a avea drepturi în clusterul Kubernetes.

Apoi întreaga sarcină este să mergi în subdirectorul /host /etc/kubernetes/pki, dacă nu mă înșel, ridică toate certificatele master ale clusterului de acolo și, în consecință, devin administratorul clusterului.

Dacă te uiți în acest fel, acestea sunt unele dintre cele mai periculoase drepturi din poduri - indiferent de drepturile pe care le are utilizatorul:
Remedierea găurilor în clusterul Kubernetes. Raport și transcriere de la DevOpsConf

Dacă am drepturile de a rula un pod într-un spațiu de nume al clusterului, atunci acest pod are aceste drepturi în mod implicit. Pot rula poduri privilegiate, iar acestea sunt în general toate drepturile, practic root pe nod.

Preferatul meu este utilizatorul Root. Și Kubernetes are această opțiune Run As Non-Root. Acesta este un tip de protecție împotriva unui hacker. Știți ce este „virusul moldovenesc”? Dacă dintr-o dată ești un hacker și vii la clusterul meu Kubernetes, atunci noi, administratorii săraci, întrebăm: „Vă rugăm să indicați în pod-urile dvs. cu care îmi veți sparge clusterul, rulați ca non-root. În caz contrar, se va întâmpla să rulați procesul în pod sub root și vă va fi foarte ușor să mă piratați. Vă rugăm să vă protejați de voi înșivă.”

Volumul căii gazdei este, în opinia mea, cea mai rapidă modalitate de a obține rezultatul dorit dintr-un cluster Kubernetes.

Dar ce să faci cu toate astea?

Gândul care ar trebui să vină oricărui administrator normal care întâlnește Kubernetes este: „Da, ți-am spus, Kubernetes nu funcționează. Sunt găuri în el. Și tot Cubul este o prostie.” De fapt, există documentație și, dacă te uiți acolo, există o secțiune Politica de securitate a podului.

Acesta este un obiect yaml - îl putem crea în clusterul Kubernetes - care controlează aspectele de securitate în mod specific în descrierea podurilor. Adică, de fapt, controlează drepturile de utilizare a oricărui hostNetwork, hostPID, anumite tipuri de volum care se află în pod-uri la pornire. Cu ajutorul Politicii de securitate Pod, toate acestea pot fi descrise.

Cel mai interesant lucru despre politica de securitate a podului este că, în clusterul Kubernetes, toate instalatoarele PSP nu sunt descrise în niciun fel, ci sunt pur și simplu dezactivate implicit. Politica de securitate a podului este activată folosind pluginul de admitere.

Bine, să implementăm politica de securitate a podului în cluster, să presupunem că avem câteva poduri de servicii în spațiul de nume, la care doar administratorii au acces. Să presupunem că, în toate celelalte cazuri, podurile au drepturi limitate. Deoarece, cel mai probabil, dezvoltatorii nu trebuie să ruleze poduri privilegiate în clusterul dvs.

Și totul pare să fie în regulă la noi. Și clusterul nostru Kubernetes nu poate fi spart în două minute.

Există o problemă. Cel mai probabil, dacă aveți un cluster Kubernetes, atunci monitorizarea este instalată pe clusterul dvs. Aș merge chiar atât de departe încât să prezic că dacă clusterul tău are monitorizare, se va numi Prometheus.

Ceea ce urmează să vă spun va fi valabil atât pentru operatorul Prometheus, cât și pentru Prometheus livrat în forma sa pură. Întrebarea este că, dacă nu pot introduce un administrator în cluster atât de repede, atunci asta înseamnă că trebuie să caut mai mult. Și pot căuta cu ajutorul monitorizării dvs.

Probabil că toată lumea citește aceleași articole despre Habré, iar monitorizarea se află în spațiul de nume de monitorizare. Diagrama Helm se numește aproximativ la fel pentru toată lumea. Bănuiesc că, dacă helm install stable/prometheus, vei ajunge cu aproximativ aceleași nume. Și, cel mai probabil, nici nu va trebui să ghicesc numele DNS din clusterul tău. Pentru că este standard.

Remedierea găurilor în clusterul Kubernetes. Raport și transcriere de la DevOpsConf

În continuare avem un anumit dev ns, în care puteți rula un anumit pod. Și apoi din acest pod este foarte ușor să faci ceva de genul acesta:

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

prometheus-kube-state-metrics este unul dintre exportatorii Prometheus care colectează valori din API-ul Kubernetes în sine. Există o mulțime de date acolo, ce rulează în clusterul dvs., ce este, ce probleme aveți cu el.

Ca exemplu simplu:

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:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a96 38ee634989″,container_id=»docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2 853397d7daf08e72c22d3cf8b»} 1

Făcând o cerere simplă de curl de la un pod neprivilegiat, puteți obține următoarele informații. Dacă nu știți ce versiune de Kubernetes rulați, vă va spune cu ușurință.

Și cel mai interesant lucru este că, pe lângă accesarea kube-state-metrics, puteți accesa la fel de ușor și direct Prometheus. Puteți colecta valori de acolo. Puteți chiar să construiți valori de acolo. Chiar și teoretic, puteți construi o astfel de interogare dintr-un cluster din Prometheus, care pur și simplu o va dezactiva. Și monitorizarea dvs. nu va mai funcționa din cluster.

Și aici apare întrebarea dacă vreo monitorizare externă vă monitorizează monitorizarea. Tocmai am avut ocazia de a opera într-un cluster Kubernetes fără consecințe pentru mine. Nici nu veți ști că operez acolo, deoarece nu mai există nicio monitorizare.

La fel ca în cazul PSP, se pare că problema este că toate aceste tehnologii elegante - Kubernetes, Prometheus - pur și simplu nu funcționează și sunt pline de găuri. Nu chiar.

Există așa ceva - Politica de rețea.

Dacă sunteți un administrator normal, atunci cel mai probabil știți despre politica de rețea că acesta este doar un alt yaml, dintre care există deja o mulțime de ei în cluster. Și unele politici de rețea cu siguranță nu sunt necesare. Și chiar dacă ai citit ce este Network Policy, că este un firewall yaml al Kubernetes, îți permite să limitezi drepturile de acces între spații de nume, între poduri, atunci cu siguranță ai decis că firewall-ul în format yaml în Kubernetes se bazează pe următoarele abstracții ... Nu, nu . Acest lucru cu siguranță nu este necesar.

Chiar dacă nu le-ați spus specialiștilor în securitate că folosind Kubernetes puteți construi un firewall foarte ușor și simplu și unul foarte granular. Dacă nu știu acest lucru încă și nu vă deranjează: „Ei bine, dă-mi, dă-mi...” Atunci, în orice caz, ai nevoie de Politica de rețea pentru a bloca accesul la unele locuri de servicii care pot fi extrase din clusterul tău. fara nicio autorizatie.

Ca și în exemplul pe care l-am dat, puteți extrage valorile stării kube din orice spațiu de nume din clusterul Kubernetes fără a avea niciun drept pentru a face acest lucru. Politicile de rețea au închis accesul de la toate celelalte spații de nume la spațiul de nume de monitorizare și atât: fără acces, fără probleme. În toate diagramele care există, atât Prometheus standard, cât și Prometheus care se află în operator, există pur și simplu o opțiune în valorile cârmei pentru a activa politicile de rețea pentru ele. Trebuie doar să-l porniți și vor funcționa.

Există într-adevăr o problemă aici. Fiind un administrator normal cu barbă, cel mai probabil ați decis că politicile de rețea nu sunt necesare. Și după ce ați citit tot felul de articole despre resurse precum Habr, ați decis că flanela, în special cu modul gazdă-gateway, este cel mai bun lucru pe care îl puteți alege.

Ce să fac?

Puteți încerca să redistribuiți soluția de rețea pe care o aveți în clusterul dvs. Kubernetes, încercați să o înlocuiți cu ceva mai funcțional. Pentru același Calico, de exemplu. Dar vreau să spun imediat că sarcina de a schimba soluția de rețea într-un cluster de lucru Kubernetes este destul de netrivială. Am rezolvat-o de două ori (de ambele ori, totuși, teoretic), dar chiar am arătat cum se face la Slurms. Pentru studenții noștri, am arătat cum să schimbăm soluția de rețea într-un cluster Kubernetes. În principiu, puteți încerca să vă asigurați că nu există timpi de nefuncționare pe clusterul de producție. Dar probabil că nu vei reuși.

Și problema este de fapt rezolvată foarte simplu. Există certificate în cluster și știți că certificatele dvs. vor expira într-un an. Ei bine, și, de obicei, o soluție normală cu certificate în cluster - de ce ne facem griji, vom ridica un nou cluster în apropiere, îl vom lăsa pe cel vechi să putrezească și vom redistribui totul. Adevărat, când devine putrezit, va trebui să stăm o zi, dar iată un nou grup.

Când ridicați un grup nou, introduceți în același timp Calico în loc de flanel.

Ce trebuie să faceți dacă certificatele dvs. sunt emise pentru o sută de ani și nu veți redistribui clusterul? Există așa ceva ca Kube-RBAC-Proxy. Aceasta este o dezvoltare foarte interesantă, vă permite să vă încorporați ca container sidecar în orice pod din clusterul Kubernetes. Și de fapt adaugă autorizare acestui pod prin RBAC al Kubernetes însuși.

Există o problemă. Anterior, această soluție Kube-RBAC-Proxy a fost încorporată în Prometheus al operatorului. Dar apoi a plecat. Acum, versiunile moderne se bazează pe faptul că aveți o politică de rețea și o închideți folosindu-le. Și, prin urmare, va trebui să rescriem puțin diagrama. De fapt, dacă mergi la acest depozit, există exemple despre cum să utilizați acest lucru ca sidecar-uri, iar diagramele vor trebui rescrise minim.

Mai este o mică problemă. Prometheus nu este singurul care oferă valorile oricui. Toate componentele clusterului nostru Kubernetes sunt, de asemenea, capabile să returneze propriile valori.

Dar, așa cum am spus deja, dacă nu puteți accesa clusterul și nu puteți colecta informații, atunci puteți măcar să faceți ceva rău.

Așa că voi arăta rapid două moduri în care un cluster Kubernetes poate fi ruinat.

O să râzi când îți voi spune asta, acestea sunt două cazuri din viața reală.

Metoda unu. Epuizarea resurselor.

Să lansăm un alt pod special. Va avea o secțiune ca aceasta.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

După cum știți, solicitările reprezintă cantitatea de CPU și memorie care este rezervată pe gazdă pentru anumite poduri cu solicitări. Dacă avem o gazdă cu patru nuclee într-un cluster Kubernetes și patru pod-uri CPU sosesc acolo cu solicitări, înseamnă că nu mai vor mai putea ajunge la această gazdă.

Dacă rulez un astfel de pod, atunci voi rula comanda:

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

Atunci nimeni altcineva nu se va putea implementa în clusterul Kubernetes. Pentru că toate nodurile vor rămâne fără solicitări. Și astfel voi opri clusterul tău Kubernetes. Dacă fac asta seara, pot opri implementările pentru o perioadă destul de lungă.

Dacă ne uităm din nou la documentația Kubernetes, vom vedea acest lucru numit Limit Range. Setează resurse pentru obiectele cluster. Puteți scrie un obiect Limit Range în yaml, îl puteți aplica anumitor spații de nume - și apoi în acest spațiu de nume puteți spune că aveți resurse implicite, maxime și minime pentru poduri.

Cu ajutorul unui astfel de lucru, putem limita utilizatorii din spațiile de nume de produse specifice ale echipelor în capacitatea de a indica tot felul de lucruri urâte pe podurile lor. Dar, din păcate, chiar dacă îi spui utilizatorului că nu poate lansa pod-uri cu solicitări pentru mai mult de un CPU, există o comandă de scalare atât de minunată sau poate face scala prin tabloul de bord.

Și de aici vine metoda numărul doi. Lansăm 11 capsule. Adică unsprezece miliarde. Asta nu pentru că am venit cu un astfel de număr, ci pentru că l-am văzut și eu.

Poveste adevarata. Seara târziu eram pe punctul de a pleca de la birou. Văd un grup de dezvoltatori stând în colț, făcând frenetic ceva cu laptopurile lor. Mă duc la băieți și îi întreb: „Ce s-a întâmplat cu tine?”

Puțin mai devreme, pe la nouă seara, unul dintre dezvoltatori se pregătea să plece acasă. Și am decis: „Acum îmi voi reduce cererea la una.” Am apăsat pe una, dar internetul a încetinit puțin. A apăsat din nou pe cel, l-a apăsat pe cel și a dat clic pe Enter. Am bătut tot ce am putut. Apoi internetul a prins viață - și totul a început să se reducă la acest număr.

Adevărat, această poveste nu a avut loc pe Kubernetes; la acea vreme era Nomad. S-a încheiat cu faptul că, după o oră de încercări de a-l opri pe Nomad de la încercările persistente de scalare, Nomad a răspuns că nu se va opri din escaladare și nu va face nimic altceva. — Sunt obosit, plec. Și s-a ghemuit.

Desigur, am încercat să fac același lucru pe Kubernetes. Kubernetes nu a fost mulțumit de unsprezece miliarde de capsule, el a spus: „Nu pot. Depășește apărătoarele interne.” Dar 1 de păstăi ar putea.

Ca răspuns la un miliard, Cubul nu s-a retras în sine. Chiar a început să crească. Cu cât procesul a mers mai departe, cu atât i-a luat mai mult timp să creeze noi păstăi. Dar tot procesul a continuat. Singura problemă este că dacă pot lansa pod-uri nelimitat în spațiul meu de nume, atunci chiar și fără solicitări și limite pot lansa atât de multe pod-uri cu unele sarcini încât cu ajutorul acestor sarcini nodurile vor începe să se adune în memorie, în CPU. Când lansez atât de multe pod-uri, informațiile de la ele ar trebui să intre în stocare, adică etcd. Și când sosesc prea multe informații acolo, spațiul de stocare începe să revină prea încet - iar Kubernetes începe să devină plictisitor.

Și încă o problemă... După cum știți, elementele de control Kubernetes nu sunt un lucru central, ci mai multe componente. În special, există un manager de controler, un planificator și așa mai departe. Toți acești tipi vor începe să facă o muncă inutilă, stupidă în același timp, care în timp va începe să dureze din ce în ce mai mult timp. Managerul controlerului va crea poduri noi. Scheduler va încerca să găsească un nou nod pentru ei. Cel mai probabil, veți rămâne fără noduri noi în cluster în curând. Clusterul Kubernetes va începe să funcționeze din ce în ce mai lent.

Dar am decis să merg și mai departe. După cum știți, în Kubernetes există așa ceva numit serviciu. Ei bine, în mod implicit, în clusterele dvs., cel mai probabil, serviciul funcționează folosind tabele IP.

Dacă rulați un miliard de poduri, de exemplu, și apoi utilizați un script pentru a forța Kubernetis să creeze servicii noi:

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

Pe toate nodurile clusterului, din ce în ce mai multe reguli iptables noi vor fi generate aproximativ simultan. Mai mult, un miliard de reguli iptables vor fi generate pentru fiecare serviciu.

Am verificat toată chestia asta cu câteva mii, până la zece. Și problema este că deja la acest prag este destul de problematic să faci ssh la nod. Pentru că pachetele, care trec prin atâtea lanțuri, încep să nu se simtă prea bine.

Și asta, de asemenea, totul este rezolvat cu ajutorul Kubernetes. Există un astfel de obiect de cotă de resurse. Setează numărul de resurse și obiecte disponibile pentru spațiul de nume din cluster. Putem crea un obiect yaml în fiecare spațiu de nume al clusterului Kubernetes. Folosind acest obiect, putem spune că avem un anumit număr de cereri și limite alocate pentru acest namespace, iar apoi putem spune că în acest namespace este posibil să creăm 10 servicii și 10 pod-uri. Și un singur dezvoltator se poate sufoca cel puțin seara. Kubernetes îi va spune: „Nu vă puteți scala podurile la această sumă, deoarece resursa depășește cota.” Gata, problema rezolvata. Documentatie aici.

Un punct problematic apare în acest sens. Simți cât de dificil devine să creezi un spațiu de nume în Kubernetes. Pentru a-l crea, trebuie să luăm în considerare o mulțime de lucruri.

Cotă de resurse + Interval limită + RBAC
• Creați un spațiu de nume
• Creați un interval limită în interior
• Creați o cotă de resurse în interior
• Creați un cont de service pentru CI
• Creați legături de rol pentru CI și utilizatori
• Opțional lansați podurile de service necesare

Prin urmare, aș dori să profit de această ocazie pentru a împărtăși evoluțiile mele. Există așa ceva numit operator SDK. Aceasta este o modalitate prin care un cluster Kubernetes poate scrie operatori pentru el. Puteți scrie declarații folosind Ansible.

La început a fost scris în Ansible, apoi am văzut că există un operator SDK și am rescris rolul Ansible într-un operator. Această declarație vă permite să creați un obiect în clusterul Kubernetes numit comandă. În interiorul unei comenzi, vă permite să descrieți mediul pentru această comandă în yaml. Și în mediul de echipă, ne permite să descriem că alocam atât de multe resurse.

minion ușurând întreg acest proces complex.

Și în concluzie. Ce să faci cu toate astea?
Primul. Politica de securitate a podului este bună. Și, în ciuda faptului că niciunul dintre instalatorii Kubernetes nu le folosește până în prezent, trebuie totuși să le folosiți în clustere.

Politica de rețea nu este doar o altă caracteristică inutilă. Acesta este ceea ce este cu adevărat necesar într-un cluster.

LimitRange/ResourceQuota - este timpul să-l folosiți. Am început să-l folosim cu mult timp în urmă și mult timp am fost sigur că toată lumea îl folosește. S-a dovedit că acest lucru este rar.

Pe lângă ceea ce am menționat în timpul raportului, există caracteristici nedocumentate care vă permit să atacați clusterul. Lansat recent analiză amplă a vulnerabilităților Kubernetes.

Unele lucruri sunt atât de triste și rănitoare. De exemplu, în anumite condiții, cubeletele dintr-un cluster Kubernetes pot oferi conținutul directorului warlocks unui utilizator neautorizat.

Aici Există instrucțiuni despre cum să reproduc tot ce ți-am spus. Există fișiere cu exemple de producție despre cum arată ResourceQuota și Pod Security Policy. Și poți atinge toate acestea.

Mulțumiri tuturor.

Sursa: www.habr.com

Adauga un comentariu