Mbyllim boshllëqet në klasterin Kubernetes. Raporti dhe shënimi nga DevOpsConf

Pavel Selivanov, arkitekt i zgjidhjeve në Southbridge dhe lektori i Slyrm, mbajti një raport në DevOpsConf 2019. Ky raport është pjesë e një nga temat e kursit të thelluar për Kubernetes "Slyrm Mega".

Slyrm Baza: hyrje në Kubernetes ndodh në Moskë nga 18-20 Nëntor.
Slyrm Mega: hedhim një sy nën kapakun e Kubernetes — Moskë, 22-24 Nëntor.
Slyrm Online: të dy kurset për Kubernetes kanë qasje gjithmonë.

Luaj videon

Poshtë—shënimi i raportit.

Mirëdita, kolegëve dhe atyre që ndajnë shqetësimin. Sot do të flas për sigurinë.

Vërej se në sallë sot janë shumë ekspertë të sigurisë. Më vjen keq nëse terminologji nga bota e sigurisë do ta përdor jo ashtu siç është e zakonshme për ju.

Enë ndodhi që diku gjysmë viti më parë më ra në dorë një klasër publik Kubernetes. Publik — do të thotë që ka një sasi n-nesh namespaces, ku në këto namespace ka përdorues, të izoluar në namespace e tyre. Të gjithë këta përdorues i përkasin kompanive të ndryshme. Kështu, parashikohej që ky klasër të përdorej si CDN. Kjo do të thotë se ju jepet një klasër, ju jepet një përdorues për atë, ju hyni në namespace tuaj, dhe vendosni aplikacionet tuaja.

Kompania ime e mëparshme përpiqej të më shiste një shërbim të tillë. Dhe më kërkuan të testoja klasrin për të parë nëse një zgjidhje e tillë është e përshtatshme apo jo.

Arrita në këtë klaster. Më dhanë të drejta të kufizuara, një namespace të kufizuar. Atje, djemtë e dinin se çfarë është siguria. Kishin lexuar për kontrollet e aksesit të bazuara në role (RBAC) të Kubernetes — dhe e kishin vendosur në mënyrë që nuk mund të nisja podë pa drithërime. Nuk e mbaj mend detyrën që po përpiqesha të zgjidhja, duke nisur një pod pa drithërim, por isha shumë i interesuar për ta nisur thjesht një pod. Vendosa të shoh me fat se çfarë të drejtash kisha në klaster, çfarë mundesha, çfarë nuk mundesha, çfarë kishin vendosur atje. Po ashtu, do të tregoj se çfarë është vendosur gabimisht në RBAC-në e tyre.

Ishte një rast që pas dy minutash morava admin në klasterin e tyre, shikoja në të gjitha namespaces fqinje, pashë atje fronte prodhimi të kompanive që kishin blerë shërbimin dhe ishin deployuar. E pata shumë të vështirë të ndalesha që të mos shkoja te dikush në front dhe në faqen kryesore të vendosja ndonjë fjalë të pahijshme.

Do të tregoj me shembuj se si e bëra këtë dhe si duhet mbrojtur nga ajo.

Por fillim, lejoni të prezantohem. Emri im është Pavel Selivanov. Jam arkitekt i kompanisë Southbridge. Kam njohuri në Kubernetes, DevOps dhe gjëra të tjera moderne. Ne me inxhinierët e Southbridge po e ndërtojmë këtë, ndërsa unë ofroj këshilla.

Përveç aktivitetit tonë kryesor, ne sapo kemi lançuar projekte që quhen Slerms. Ne po përpiqemi të ndihmojmë njerëzit të punojnë me Kubernetes dhe t’i mësojmë ata si të përdorin K8s.

Çfarë do të flas sot. Tema e prezantimit është e qartë — siguria e klasterit Kubernetes. Por dua të theksoj se kjo temë është shumë e gjerë — dhe prandaj dua të sqaroj se për çfarë nuk do të flas. Nuk do të flas për terma të zakonshëm që janë përsëritur aq shumë në internet. Të tilla si RBAC dhe certifikat.

Do të flas për ato shqetësime që kam unë dhe kolegët e mi lidhur me sigurinë në klasterin Kubernetes. Ne i shohim këto probleme tek ofruesit që ofrojnë klastere Kubernetes dhe te klientët që vijnë tek ne. Edhe tek klientët që na vijnë nga kompani të tjera konsulente administratash. Pra, në të vërtetë, shkalla e tragjedisë është shumë e madhe.

Tre pika, për të cilat do të flas sot:

  1. Të drejtat e përdoruesve vs të drejtat e pod’ëve. Të drejtat e përdoruesve dhe të drejtat e pod’ëve nuk janë të njëjta.
  2. Grumbullimi i informacionit për klasterin. Do të tregoj se çfarë informacioni mund të grumbullojmë nga klasteri pa pasur të drejta të veçanta në të.
  3. Sulmi DoS ndaj klasterit. Nëse nuk arrijmë të grumbullojmë informacion, ne mund ta dështojmë klasterin në çdo rast. Do të flas për sulmet DoS ndaj elementeve menaxhuese të klasterit.

Një tjetër gjë e përgjithshme që do të përmend është se mbi çfarë kam testuar gjithçka dhe mbi çfarë mund të them me siguri se gjithçka funksionon.

Marrim si bazë instalimin e klasterit Kubernetes me anë të Kubespray. Nëse askush nuk e di, kjo është në thelb një grup rolesh për Ansible. Ne e përdorim atë vazhdimisht në punë. Është i mirë sepse mund të instalohet kudo — dhe në harduer, si edhe në ndonjë cloud. Një mënyrë instalimi është e përshtatshme për gjithçka.

Në këtë klasër do të kem Kubernetes v1.14.5. I gjithë klastri i Kubës, që do të shqyrtojmë, është ndarë në hapësira emri, secila hapësirë emri i takon një skuadre të veçantë, dhe anëtarët e kësaj skuadre kanë qasje në çdo hapësirë emri. Ata nuk mund të hyjnë në hapësira të tjera, vetëm në të tyre. Megjithatë, ekziston një llogari admini, e cila ka të drejta për të gjithë klastri.

Mbyllim boshllëqet në klasterin Kubernetes. Raporti dhe shënimi nga DevOpsConf

Premtova se e para që do të bëjmë është marrja e të drejtave admin në klasër. Na nevojitet një pod i përgatitur posaçërisht, i cili do të thyejë klastrin Kubernetes. E vetmja gjë që duhet të bëjmë është ta aplikojmë atë në klastrin Kubernetes.

kubectl apply -f pod.yaml

Ky pod do të arrijë në një nga masterat e klasit Kubernetes. Dhe klastri do të na kthejë me gëzim një skedar, i quajtur admin.conf. Në Kubë, në këtë skedar ruhen të gjithë certifikatat e adminit, dhe gjithashtu konfigurohet API i klasit. Kështu kaq thjeshtë mund të merret qasje administrative, mendoj, në 98% të klastrave Kubernetes.

Të përsëris, ky pod u krijua nga një zhvillues në klasrin tuaj, i cili ka akses për të shpërndarë propozimet e tij në një hapësirë të vogël emri, ai është plotësisht i kufizuar nga RBAC. Ai nuk kishte asnjë të drejtë. Por megjithatë, certifikata u kthye.

Tani për një pod të përgatitur posaçërisht. E fillojmë në çdo imazh. Për shembull, do të marrim debian:jessie.

Kemi një gjë të tillë:

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

Çfarë është tolerimi? Masterët në klusterin Kubernetes zakonisht shënohen me një gjë që quhet taint ("infeksion" në anglisht). Ideja e kësaj "infeksioni" është se pod-et nuk mund të emërohen në nodet master. Por askush nuk e ndalon caktimin e tolerancës ndaj "infeksionit" në çdo pod. Seksioni Toleration thotë se nëse në ndonjë nodë është vendosur NoSchedule, atëherë pod-i ynë është tolerues ndaj këtij infeksioni — dhe nuk ka asnjë problem.

Pastaj, ne themi që pod-i ynë jo vetëm që është tolerues, por edhe dëshiron të emërohet në mënyrë specifike në master. Sepse në mastera ndodhen gjërat më interesante që na duhen — të gjitha certifikatat. Prandaj ne themi nodeSelector — dhe kemi një etiketë standarde në mastera, e cila lejon të zgjedhim nga të gjitha nodet e klusterit ato nodet që janë master.

Me këto dy seksione, pod-i do të arrijë me siguri në master. Dhe atij do t’i lejohet të jetojë aty.

Por t'u mbërritur vetëm në master, nuk mjafton. Kjo nuk na sjell asgjë. Prandaj, kemi këto dy gjëra për të vazhduar:

hostNetwork: true 
hostPID: true 

Ne tregojmë se pods që po e ekzekutojmë, do të jetojë në hapësirën emërore të bërthamës, në hapësirën e rrjetit dhe në hapësirën e PID. Pasi podi të fillojë ekzekutimin në master, ai do të mund të shikojë të gjitha ndërfaqet e vërteta, të gjalla të kësaj node, të dëgjojë të gjithë trafikun dhe të shohë PID-të e të gjithë proceseve.

Më pas, është një çështje e thjeshtë. Merrni etcd dhe lexoni atë që dëshironi.

Më e interesante është se kjo është një mundësi e Kubernetes, e cila është aty si vendosje default.

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

Dhe thelbi i saj është se ne mund të themi në podin që po e ekzekutojmë, madje pa të drejta në këtë klasër, se duam të krijojmë një volume të tipit hostPath. Kjo do të thotë të marrim një rrugë nga hosti, ku do të ekzekutojmë — dhe ta marrim atë si volume. Më pas e quajmë name: host. E gjithë ky hostPath montohen brenda podit. Në këtë shembull në direktorine /host.

Përsëri, e përsëris. I thamë podit të vijë në master, të marrë hostNetwork dhe hostPID — dhe të montojë të gjithë root-in e masterit brenda këtij podi.

Ju e kuptoni se në Debian ne kemi hapur bash-in, dhe ky bash po punon nën rolin e root-it. Kjo do të thotë se sapo morëm të drejtat e root në master, edhe pa pasur ndonjë të drejtë në klasterin Kubernetes.

Pas kësaj, detyra e gjithë është të hyjë në pod në direktorinë /host/etc/kubernetes/pki, nëse nuk gaboj, të marrë atje të gjitha certifikat e master-it të klasterit dhe, për pasojë, të bëhet administrator i klasterit.

Nëse e shohim kështu, këto janë disa nga të drejtat më të rrezikshme në pod-e — pavarësisht se çfarë të drejtash ka përdoruesi:
Mbyllim boshllëqet në klasterin Kubernetes. Raporti dhe shënimi nga DevOpsConf

Nëse kam të drejta për të nisur një pod në ndonjë namespace të klasterit, atëherë ky pod ka këto të drejta në mënyrë të paracaktuar. Mund të nis pod-e me privilegje, dhe kjo është pothuajse si të kem të drejta të plota në nod.

Preferenca ime është përdoruesi Root. Ndërsa Kubernetes ka një opsion të tillë Run As Non-Root. Kjo është një lloj mbrojtjeje nga hakerët. A dini çfarë është "virusi moldavis"? Nëse ndonjë haker ka ardhur në klasterin tim Kubernetes, ne, administratorët e varfër, kërkojmë: "Ju lutemi, tregoni në pod-et tuaja, me të cilat do të hakeroni klasterin tim, run as non-root. Nëse jo, atëherë ka gjasa që të filloni procesin në pod-in tuaj nën root dhe do të keni shumë lehtësi për të më hakuar. Mbrohuni, ju lutem, nga vetja juaj."

Volume i rrugës së hostit - sipas mendimit tim, mënyra më e shpejtë për të marrë rezultatin e dëshiruar nga klasteri Kubernetes.

Por çfarë të bëjmë me të gjitha këto?

Mendimet që duhet të vijnë në kokën e çdo administratori normal që përballet me Kubernetes: "Ah, po, e thashë, Kubernetes nuk punon. Ka vrima. Dhe e gjithë kjo është e kotë". Në të vërtetë, ekziston një gjë e tillë si dokumentacioni, dhe nëse e shikoni, ka një seksion. Politika e Sigurisë së Pod.

Ky është një objekt YAML — mund ta krijojmë atë në klasterin Kubernetes — që kontrollon aspektet e sigurisë, saktësisht në përshkrimin e pod-ëve. Pra, në thelb kontrollon ato të drejta për përdorimin e hostNetwork, hostPID, dhe disa lloje volume që ekzistojnë në pod-et gjatë ekzekutimit. Me ndihmën e Pod Security Policy, çdo gjë mund të përshkruhet.

Më e rëndësishmja për Pod Security Policy është që në klasterin Kubernetes, të gjithë instaluesit e PSP nuk janë vetëm të papërshkruar, ata janë thjesht të çaktivizuar si parazgjedhje. Pod Security Policy aktivizohet me ndihmën e një plugin-i admission.

Okej, do ta dërgojmë Pod Security Policy në klaster, duke thënë që kemi disa pod-e shërbimi në një namespace, të cilin e kanë akses vetëm administratorët. Le të themi, në të gjitha pod-et e tjera, të drejtat janë të kufizuara. Sepse ndoshta zhvilluesit nuk kanë nevojë të ekzekutojnë pod-e me privilegje në klasterin tuaj.

Dhe duket se gjithçka është mirë. Klasteri ynë Kubernetes nuk mund të thyhet për dy minuta.

Ka një problem. Ndoshta, nëse keni një klaster Kubernetes, atëherë në klasterin tuaj është instaluar monitorimi. Madje më guxim, parashikoj që në klasterin tuaj ka monitorim, dhe ai quhet Prometheus.

Ajo që do të tregoj tani do të jetë i vlefshëm si për operatorin Prometheus, ashtu edhe për Prometheus-in e instaluar në mënyrë të pastër. Problemi është se nëse nuk mund të siguroj një administrator në kluster kaq shpejt, atëherë do të thotë se duhet të kërkoj më shumë. Dhe mund të kërkoj përmes monitorimit tuaj.

Padyshim, të gjithë janë lexuar të njëjtat artikuj në Habrë, dhe monitorimi ndodhet në hapësirën e emrave monitoring. Helm chart të gjithë i quajnë më ose më pak njësoj. Unë përfytyroj se nëse bëni helm install stable/prometheus, do të keni emra përafërsisht të njëjtë. Dhe edhe me shumë mundësi, emri DNS në klusterin tuaj nuk do të duhet ta gjej. Sepse është standard.

Mbyllim boshllëqet në klasterin Kubernetes. Raporti dhe shënimi nga DevOpsConf

Më pas kemi një dev ns, në të cilin mund të fillojmë një pod. Dhe pastaj nga ky pod është shumë e lehtë të bëhet kështu:

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

prometheus-kube-state-metrics është një nga eksportuesit e Prometheus-it, i cili mbledh metrika nga API i Kubernetes vetë. Ekziston shumë informacion se çfarë është e aktivizuar në klusterin tuaj, si është ajo, çfarë probleme keni me të.

Si një shembull i thjeshtë:

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

Duke një kërkesë të thjeshtë curl nga një pod jo privilegjuar, mund të merrni këto informacion. Nëse nuk e dini se në cilën version të Kubernetes jeni, ai do t'ju tregojë lehtësisht.

Dhe më interesante është se, përveç faktit që po i qaseni kube-state-metrics, ju gjithashtu mund ta qaseni direkt Prometheus. Mund të mbledhni metrika nga ai. Mund të krijoni metrika nga atje. Teori siç është, mund të ndiheni të lirë të ndërtoni një kërkesë nga klasteri te Prometheus që thjesht do ta shuajë. Dhe monitorimi juaj gjithashtu do të ndalojë së funksionuari.

Dhe këtu lind pyetja, a monitoron ndonjë monitorim i jashtëm monitorimin tuaj. Para pak çastesh, pata mundësinë të veproj në klasterin Kubernetes pa asnjë pasojë për veten time. Ju madje nuk do të kuptoni se unë po veproj aty, pasi nuk ka asnjë monitorim më.

Njësoj si me PSP, krijohet përshtypja se problemi qëndron te këto teknologji të modës — Kubernetes, Prometheus — që thjesht nuk funksionojnë dhe janë plot boshllëqe. Në të vërtetë, nuk është ashtu.

Ekziston një gjë — Politika e Rrjetit.

Nëse jeni një administrator normal, ndoshta e dini se Politika e Rrjetit është një yaml tjetër, të cilët ka mjaft në klasër. Dhe Politikat e Rrjetit ndoshta nuk janë të nevojshme. Por edhe nëse e keni lexuar se çfarë është Politika e Rrjetit, se është një firewall yaml i Kubernetesit, i cili lejon të kufizoni të drejtat e aksesit midis emërhapësirave, midis pod-ëve, ju patjetër keni vendosur se firewall-i në formatin yaml në Kubernetes është një nga ato abstraksione… Jo, jo. Kjo qartë nuk është e nevojshme.

Edhe nëse specialistët tuaj për sigurinë nuk janë informuar se me ndihmën e Kubernetesit tuaj mund të ndërtoni shumë lehtë dhe thjeshtë një firewall dhe madje shumë të detajuar. Nëse ata nuk e dinë dhe nuk ju shqetësojnë: "Më jepni, më jepni..." Ai do të jetë gjithsesi e nevojshme Politika e Rrjetit për të bllokuar qasjen në disa vende shërbyese, të cilat mund të tërhiqen nga klasfiku, pa pasur asnjë autorizim.

Si në shembullin që kam dhënë, mund të tërheqësh kube state metrics nga çdo namespace në klasterin Kubernetes, pa pasur asnjë të drejtë për këtë. Politikat e rrjetit e kufizojnë aksesin nga të gjithë namespaces e tjera në namespace-in e monitorimit dhe siç duket, asnjë akses, asnjë problem. Në të gjitha chart-et që ekzistojnë, dhe prometheus standard dhe prometheus që është në operator, thjesht ka një opsion në values e helm për të aktivizuar politikat e rrjetit për ta. Thjesht duhet të aktivizosh, dhe ato do të punojnë.

Ka një problem këtu. Duke qenë një admin normal me mjekër, është e mundur që keni vendosur se politikat e rrjetit nuk janë të nevojshme. Dhe duke lexuar artikuj të ndryshëm në burime si Habr, keni vendosur se flannel, veçanërisht me mënyrën host-gateway, është më e mira që mund të zgjidhni.

Çfarë të bëjmë?

Mund të provoni të ri-deploy një zgjidhje rrjeti që është në klasterin tuaj Kubernetes, ose të provoni ta ndryshoni me diçka më funksionale. Për shembull, me të njëjtën Calico. Por dua të them menjëherë, se detyra e ndryshimit të zgjidhjes rrjeti në një klaster Kubernetes në funksion është mjaft e komplikuar. E kam zgjidhur dy herë (të dyja herët, megjithatë, në mënyrë teorike), por madje ne në Slërma kemi treguar si ta bëjmë këtë. për ata që mësojmë, ne kemi treguar se si të ndryshohet zgjidhja rrjeti në klasterin Kubernetes. Në princip mund të provoni të bëni kështu, në mënyrë që të mos ketë ndërprerje në klasterin e prodhimit. Por ndoshta nuk do t'ju rezultojë asgjë.

Dhe problemi në të vërtetë zgjidhet shumë lehtë. Në klaster ka certifikata, dhe ju e dini se certifikatave tuaja do t'u skadojë afati pas një viti. Në përgjithësi, zgjidhja normale me certifikatat në klaster është — pse të shqetësohemi, do të ngremë një klaster të ri afër, le të skadojë e vjetra, dhe gjithçka do të ri-deplojohet. Megjithatë, kur të skadojë, do të kemi një ditë që do të qëndrojë, por do të kemi një klaster të ri.

Kur të ngrini klasterin e ri, njëherësh vendosni Calico në vend të flannel.

Çfarë duhet të bëni nëse keni certifikata të lëshuara për njëqind vjet dhe nuk planifikoni të ridispononi klasterin? Ka një gjë që quhet Kube-RBAC-Proxy. Kjo është një zhvillim shumë i bukur, që lejon të integrohet si një container sidecar në çdo pod në klasterin Kubernetes. Dhe në fakt, ajo shton autorizimin për këtë pod përmes RBAC të Kubernetesit.

Ka një problem. Më parë, në operatorin Prometheus, kjo zgjidhje Kube-RBAC-Proxy ishte e integruar. Por më vonë u hoq. Tani versionet moderne mbështeten në atë që keni një politikë rrjeti dhe e mbyllni duke e përdorur atë. Prandaj do t'ju duhet të rishkruani pak kartën. Në të vërtetë, nëse hyni në ky repo, ka shembuj se si të përdoret si sidecars, dhe kartat do të duhet të rishkruhen minimalisht.

Ka edhe një problem të vogël. Jo vetëm Prometheus i jep metrikat e tij kujtdo. Të gjithë komponentët e klasterit Kubernetes gjithashtu dinë të japin metrikat e tyre.

Por siç e thashë më parë, nëse nuk mund të aksesoni klasterin dhe të mbledhni informacion, mund të dëmtoni pak.

Tani do të tregoj shpejt dy mënyra se si mund ta dëmtoni shëndetin e klasterit Kubernetes.

Do të qeshni kur ta dëgjoni këtë, janë dy raste nga jeta reale.

Shtimi i parë. Shterja e burimeve.

Po fillojmë një pod special tjetër. Ai do të ketë një seksion të tillë.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Siç e dini, kërkesat janë sasia e CPU-së dhe memories që rezervohen në host për pod-et specifike me kërkesa. Nëse kemi një host me katër bërthama në klasterin Kubernetes, dhe aty vjen një pod me kërkesa për katër CPU, atëherë do të thotë se asnjë pod tjetër me kërkesa nuk mund të hyjë në këtë host.

Nëse e filloj një pod të tillë, më pas do të jap urdhrin:

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

Asnjë tjetër nuk do të mund të deplohet në klasterin Kubernetes. Sepse në të gjitha nodet do të përfundojnë kërkesat. Dhe kështu do ta ndaloj klasterin tuaj Kubernetes. Nëse e bëj këtë në mbrëmje, mund t'i ndaloj deploimet për një kohë të gjatë.

Nëse ne e shohim përsëri dokumentacionin e Kubernetes, do të shohim një gjë që quhet Limit Range. Ai përcakton burimet për objektet e klasterit. Ju mund të shkruani një objekt Limit Range në formatin yaml, ta zbatoni në hapësira të caktuara emërtimi — dhe më pas në këtë hapësirë emërtimi mund të thoni se keni burime për pod-ët që janë me default, maksimale dhe minimale.

Me një gjë të tillë ne mund të kufizojmë përdoruesit në hapësira të caktuara produktesh në komandat për të specifikuar gjëra të padëshiruara në pod-ët e tyre. Por fatkeqësisht, edhe nëse i thoni përdoruesit që nuk mund të krijoni pod-ë me kërkesa më të mëdha se një CPU, ka një komandë të shkëlqyer scale, ose përmes panelit ata mund të bëjnë shkallëzim.

Dhe nga kjo rrjedh mënyra e dytë. Aktivizojmë 11 111 111 111 111 pod-ë. Këto janë njëmbëdhjetë miliardë. Nuk është se e kam shpikur këtë numër, por sepse vetë e kam parë.

Një histori e vërtetë. Vonë në mbrëmje po përgatitesha të largohem nga zyrja. Shikoj, në një qoshe janë disa zhvillues dhe po bëjnë diçka nervoze me laptopët e tyre. Po i afrohem dhe e pyes: «Çfarë po ndodh me ju?»

Pak më herët, rreth orës nëntë të mbrëmjes, një nga zhvilluesit po përgatitej të shkonte në shtëpi. Ai vendosi: "Tani do ta përmirësoj aplikacionin tim deri në një." Shtypi një, por interneti u ngadalësua pak. Ai e shtypi sërish numrin një, e pati të vështirë ta shtypte, dhe e klikoi Enter. E provokoi çdo gjë që mundi. Atëherë interneti u zgjuan — dhe gjithçka filloi të përmirësohej deri në atë numër.

Megjithatë, kjo histori nuk ndodhi në Kubernetes, atëherë ishte Nomad. Kjo përfundoi me përpjekjet tona për të ndaluar Nomad nga përpjekjet e tij të vazhdueshme për të përmirësuar, Nomad u përgjigj se nuk do të ndalte dhe nuk do të bënte asgjë tjetër. "Jam lodhur, po largohem." Dhe u tërhoq.

Natyrisht, unë provova të bëj të njëjtën gjë në Kubernetes. Njëzet e një miliard podash Kubernetes nuk u kënaqën, ai tha: "Nuk mundem. Tejkalon kapacitetet e brendshme." Por 1 000 000 000 podash ia doli.

Në përgjigje të një miliard kub, ai nuk u hodh në vete. Ai me të vërtetë filloi të bëjë skalimin. Sa më shumë që procesi përparonte, aq më shumë kohë i duhej për të krijuar pods të rinj. Por prapë procesi po ndodhte. Problemi i vetëm është se nëse unë mund të filloj pods pa kufij në hapësirën time emrin, edhe pa kërkesat dhe kufizimet, mund të filloj me disa detyra një numër të tillë pods, sa që me këto detyra nodet do të fillojnë të grumbullojnë në kujtesë dhe CPU. Kur unë filloj kaq shumë pods, informacioni nga ata duhet të shkojë në depo, domethënë në etcd. Dhe kur shumë informacion arrin atje, depoja fillon të japë shumë ngadalë — dhe Kubernetes fillon të ketë vonesa.

Dhe një problem tjetër... Siç e dini, elementët menaxhues të Kubernetes-it nuk janë një gjë e vetme qendrore, por disa komponentë. Atje veçanërisht ka një menaxher kontrolli, një programues dhe kështu me radhë. Të gjithë këta do fillojnë të kryejnë punë të panevojshme paralelisht, e cila me kalimin e kohës do të marrë gjithnjë e më shumë dhe më shumë kohë. Menaxher kontrolli do të krijojë pod-e të reja. Programuesi do të përpiqet t'u gjejë atyre një nod të ri. Probabiliteti është që nodet e reja në klasterin tuaj do të përfundojnë së shpejti. Klasteri i Kubernetes-it do të fillojë të punojë gjithnjë e më ngadalë.

Por unë krijova një hap më shumë. Siç e dini, në Kubernetes ka një gjë që quhet shërbim. Po ashtu, në mënyrë standarde në klasterat tuaj, shërbimi, me siguri, punon me ndihmën e IP tables.

Nëse lançoni një miliard pod-e, për shembull, dhe pastaj me ndihmën e një skripti e detyroni Kubernetes-in të krijojë shërbime të reja:

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

Në të gjitha nodet e klasterit, gjithmonë do të generehen rregulla të reja iptables pothuajse njëkohësisht. Në fakt, për çdo shërbim do të krijohet nga një miliard rregullash iptables.

E kam kontrolluar këtë me disa mijëra, deri në disa dhjetëra. Problemi është se në këtë prag, është mjaft e vështirë të lidhesh me SSH në nod. Sepse pakot, duke kaluar nëpër një numër të tillë të zinxhirëve, fillojnë të ndihen keq.

Dhe gjithashtu zgjidhet me ndihmën e Kubernetes. Ka një objekt që quhet 'Resource quota'. Përcakton numrin e burimeve të disponueshme dhe objekteve për një namespace në klaster. Ne mund të krijojmë një objekt YAML në çdo namespace të klasterit Kubernetes. Me anë të këtij objekti, mund të themi se për këtë namespace janë alokuar një numër i caktuar kërkesash, kufij, dhe më pas mund të themi se në këtë namespace është e mundur të krijohen 10 shërbime dhe 10 pod. Dhe zhvilluesi mund të kalojë orë të tëra gjatë mbrëmjeve. Kubernetes do t'i thotë: "Nuk mund të shkallëzoni podët tuaj në një kaq të madhe, sepse kalon kufizimin e burimeve". E gjitha, problemi zgjidhet. Dokumentacioni ndodhet këtu.

Një problem i mundshëm lidhur me këtë gjithashtu paraqitet. E ndjeni se sa e vështirë bëhet të krijoni një hapësirë në Kubernetes. Për ta krijuar atë, na nevojitet të merremi parasysh shumë gjëra.

Kota e burimeve + Kufiri i Rangut + RBAC
• Krijojmë hapësirën
• Krijojmë brenda kufirit të rangut
• Krijojmë brenda kotës së burimeve
• Krijojmë llogarinë e shërbimit për CI
• Krijojmë rolebinding për CI dhe përdoruesit
• Opsionale, nisnim pods e nevojshme

Prandaj, duke shfrytëzuar këtë rast, do të doja të ndaj zhvillimet e mia. Ka një gjë, e quajtur operator SDK. Kjo është një mënyrë për të shkruar operatorë në klasterin Kubernetes. Mund të shkruani operatorë me ndihmën e Ansible.

Fillimisht, ne kishim shkruar me Ansible, pastaj pashë se ekziston operator SDK dhe e kam ribërë rolin e Ansible në operator. Ky operator lejon krijimin e një objekti në klasterin Kubernetes, i cili quhet komandë. Brenda komandës, ai lejon të përshkruajmë ambientin në yaml për këtë komandë. Dhe brenda ambientit të komandës ai lejon të përcaktojmë se sa burime po alokojmë.

E vogël lehtësuese e gjithë këtij procesi të komplikuar.

Dhe për në fund. Çfarë të bëjmë me të gjithë këtë?
Në radhë të parë. Politika e Sigurisë së Pod-eve është e mirë. Dhe pavarësisht se asnjë nga instaluarët e Kubernetes deri më tani nuk i përdor ato, megjithatë, duhet t'i përdorni në klasteret tuaj.

Politika e Rrjetit nuk është ndonjë veçori tjetër e panevojshme. Kjo është ajo që në klaster është vërtet e nevojshme.

LimitRange/ResourceQuota — është koha ta përdorni. Ne e kemi filluar këtë prej kohësh, dhe mendova se të gjithë kështu e praktikojnë. Doli se është një rastësi.

Përveç asaj që përmenda gjatë prezantimit, ka veçori të papublikueshme që lejojnë sulmin ndaj klasterit. Së fundi doli një analizë e madhe e vulnerabiliteteve të Kubernetes.

Disa gjëra janë aq të pikëlluara dhe të dhimbshme. Siç është, nën disa kushte, uzurpatorët në klasterin e Kubernetes mund të japin përmbajtjen e direktorisë warlocks, madje për një përdorues të paautorizuar.

Këtu janë instrukcione për të riprodhuar gjithçka që kam folur. Ka skedarë me shembuj prodhimi, si duken ResourceQuota, Politika e Sigurisë së Pod-eve. Dhe gjithçka mund të provoni.

Faleminderit të gjithëve.

Burimi: habr.com

Bli një hosting të besueshëm për faqet me mbrojtje DDoS, VPS VDS serverë 🔥 Bli një hosting të besueshëm për faqet me mbrojtje DDoS, VPS VDS serverë | ProHoster