Lyukak kitöltése a Kubernetes-fürtben. Jelentés és átirat a DevOpsConf-ból

Pavel Selivanov, a Southbridge-i megoldások építésze és a Slurm tanára előadást tartott a 2019-es DevOpsConf-on. Ez az előadás a Kubernetes „Slurm Mega” elmélyült tanfolyam egyik témájának része.

Slurm Basic: Bevezetés a Kubernetesbe november 18-20-án kerül sor Moszkvában.
Slurm Mega: Kubernetes motorháztetője alá néz — Moszkva, november 22-24.
Slurm Online: mindkét Kubernetes tanfolyam mindig elérhető.

A vágás alatt a jelentés átirata látható.

Jó napot, kollégák és a velük együttérzők. Ma a biztonságról fogok beszélni.

Úgy látom, ma sok biztonsági őr van a teremben. Előre is elnézést kérek, ha a biztonság világából származó kifejezéseket nem pontosan úgy használom, ahogy az Önöknél megszokott.

Történt, hogy körülbelül hat hónappal ezelőtt egy nyilvános Kubernetes-klaszterre bukkantam. Nyilvános azt jelenti, hogy van egy n-edik számú névter; ezekben a névterekben a felhasználók el vannak különítve a névterükben. Mindezek a felhasználók különböző cégekhez tartoznak. Nos, azt feltételezték, hogy ezt a fürtöt CDN-ként kell használni. Vagyis adnak egy fürtöt, ott adnak egy felhasználót, odamész a névteredbe, telepíted a frontjaidat.

Előző cégem próbált ilyen szolgáltatást eladni. És megkértek, hogy bökjem meg a klasztert, hogy megnézzem, megfelelő-e ez a megoldás vagy sem.

ebbe a klaszterbe jutottam. Korlátozott jogokat, korlátozott névteret kaptam. Az ottani srácok megértették, mi a biztonság. Olvastak a szerepalapú hozzáférés-vezérlésről (RBAC) a Kubernetesben – és úgy csavarták ki, hogy ne tudjam elindítani a podokat a telepítésektől külön. Nem emlékszem arra a problémára, amelyet úgy próbáltam megoldani, hogy telepítés nélkül elindítottam egy pod-ot, de nagyon szerettem volna csak egy pod elindítását. A sok siker érdekében úgy döntöttem, hogy megnézem, milyen jogaim vannak a klaszterben, mit tehetek, mit nem, és mit rontottak el ott. Ugyanakkor elmondom, mit állítottak be rosszul az RBAC-ban.

Történt, hogy két perc múlva kaptam egy adminisztrátort a klaszterükhöz, megnéztem az összes szomszédos névteret, ott láttam a szolgáltatást már megvásárolt és telepített cégek futó termelési frontjait. Alig bírtam megállni, hogy ne menjek valaki elé, és ne tegyek valami szitokszót a főoldalra.

Példákkal fogom elmondani, hogyan csináltam ezt, és hogyan védekezhetsz ettől.

De először hadd mutatkozzam be. A nevem Pavel Selivanov. Építész vagyok a Southbridge-ben. Megértem a Kubernetes-t, a DevOps-t és mindenféle divatos dolgot. A Southbridge mérnökei és én mindezt építjük, én pedig tanácsot adok.

Fő tevékenységeink mellett a közelmúltban elindítottuk a Slurms nevű projekteket. Igyekszünk egy kicsit a tömegekhez eljuttatni a Kubernetes-szel való munkavégzés képességét, hogy másokat is megtanítsunk K8-al dolgozni.

Miről fogok ma beszélni? A riport témája kézenfekvő – a Kubernetes klaszter biztonságáról. De rögtön azt akarom mondani, hogy ez a téma nagyon nagy - és ezért azonnal tisztázni akarom, miről nem fogok beszélni. Nem beszélek az interneten már százszor használt elcsépelt kifejezésekről. Mindenféle RBAC és tanúsítvány.

Arról fogok beszélni, hogy mi fáj nekem és kollégáimnak a Kubernetes-klaszter biztonságával kapcsolatban. Ezeket a problémákat mind a Kubernetes-fürtöket biztosító szolgáltatók, mind a hozzánk forduló ügyfelek körében tapasztaljuk. És még olyan ügyfelektől is, akik más tanácsadó adminisztrációs cégektől érkeznek hozzánk. Vagyis a tragédia mérete valójában nagyon nagy.

Szó szerint három pontról fogok ma beszélni:

  1. Felhasználói jogok vs pod jogok. A felhasználói jogok és a pod-jogok nem ugyanazok.
  2. Információgyűjtés a klaszterről. Megmutatom, hogy minden szükséges információt összegyűjthet egy fürtről anélkül, hogy különleges jogokkal rendelkezne ebben a fürtben.
  3. DoS támadás a fürt ellen. Ha nem tudunk információt gyűjteni, akkor mindenképpen tudunk klasztert létrehozni. Szólok a fürtvezérlő elemek elleni DoS támadásokról.

Egy másik általános dolog, amit megemlítek, hogy miken teszteltem mindezt, ami alapján határozottan állíthatom, hogy minden működik.

A Kubernetes-fürt Kubespray használatával történő telepítését vesszük alapul. Ha valaki nem tudná, ez valójában az Ansible szerepei. Munkánk során folyamatosan használjuk. Az a jó, hogy bárhol feltekerheted - vasdarabokra vagy felhőbe tekerheted valahol. Egy telepítési módszer elvileg mindenre működik.

Ebben a fürtben Kubernetes v1.14.5 lesz. A teljes Cube-fürt, amelyet megvizsgálunk, névterekre van felosztva, minden névtér külön csapathoz tartozik, és ennek a csapatnak a tagjai minden névterhez hozzáférnek. Nem léphetnek különböző névterekre, csak a sajátjukba. De van egy bizonyos rendszergazdai fiók, amely a teljes fürthöz rendelkezik jogokkal.

Lyukak kitöltése a Kubernetes-fürtben. Jelentés és átirat a DevOpsConf-ból

Megígértem, hogy az első dolog, amit meg fogunk tenni, az adminisztrátori jogok megszerzése a fürthöz. Szükségünk van egy speciálisan előkészített podra, amely megtöri a Kubernetes-fürtöt. Mindössze annyit kell tennünk, hogy alkalmazzuk a Kubernetes-fürtre.

kubectl apply -f pod.yaml

Ez a pod a Kubernetes klaszter egyik mesteréhez érkezik. És ezek után a fürt boldogan visszaküldi nekünk az admin.conf nevű fájlt. A Cube-ban ez a fájl tárolja az összes rendszergazdai tanúsítványt, és egyúttal konfigurálja a fürt API-t. Így könnyű rendszergazdai hozzáférést szerezni a Kubernetes-fürtök 98%-ához.

Ismétlem, ezt a pod-ot a fürt egyik fejlesztője készítette, akinek hozzáférése van ahhoz, hogy javaslatait egyetlen kis névtérben helyezze üzembe. Mindezt az RBAC rögzíti. Nem voltak jogai. Ennek ellenére az igazolást visszaadták.

És most egy speciálisan elkészített hüvelyről. Bármilyen képen futtatjuk. Vegyük például a debian:jessie-t.

Nálunk ez a dolog:

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

Mi a tolerancia? A Kubernetes-klaszterben lévő mestereket általában foltnak nevezett jelöléssel látják el. Ennek a „fertőzésnek” pedig az a lényege, hogy kimondja, hogy a podokat nem lehet főcsomópontokhoz rendelni. De senki sem veszi a fáradságot, hogy bármelyik hüvelyben jelezze, hogy toleráns a „fertőzéssel” szemben. A Tűrés rész csak azt írja, hogy ha valamelyik csomópont rendelkezik NoSchedule-val, akkor a mi csomópontunk toleráns egy ilyen fertőzéssel szemben - és nincs probléma.

Továbbá azt mondjuk, hogy alánk nem csak toleráns, hanem kifejezetten a mestert is meg akarja célozni. Mert a mestereknél van a legfinomabb, amire szükségünk van – minden bizonyítványt. Ezért azt mondjuk, hogy nodeSelector - és van egy szabványos címkénk a mestereken, amely lehetővé teszi, hogy a fürt összes csomópontja közül pontosan azokat a csomópontokat válassza ki, amelyek mesterek.

Ezzel a két szakasszal biztosan a mesterhez fog jutni. És megengedik, hogy ott éljen.

De nekünk nem elég, ha csak a mesterhez jönünk. Ez nem ad nekünk semmit. Tehát a következő két dolog áll előttünk:

hostNetwork: true 
hostPID: true 

Meghatározzuk, hogy az általunk elindított pod a kernel névtérben, a hálózati névtérben és a PID névtérben fog élni. Miután a pod elindult a mesteren, képes lesz látni ennek a csomópontnak az összes valós, élő interfészét, figyelni fogja az összes forgalmat, és láthatja az összes folyamat PID-jét.

Aztán apró dolgokról van szó. Vedd az etcd-t és olvasd el, amit akarsz.

A legérdekesebb dolog ez a Kubernetes funkció, amely alapértelmezés szerint ott van.

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

A lényege pedig az, hogy a podban azt mondhatjuk, hogy elindítjuk, még ha ehhez a fürthöz nincs is jogosultságunk, hogy egy hostPath típusú kötetet szeretnénk létrehozni. Ez azt jelenti, hogy el kell hagyni az utat attól a gazdagéptől, amelyen elindítjuk – és kötetnek tekintjük. És akkor nevezzük: host. Ezt a teljes hostPath-et a pod belsejébe csatoljuk. Ebben a példában a /host könyvtárba.

Megismétlem még egyszer. Azt mondtuk a podnak, hogy jöjjön a mesterhez, szerezze be a hostNetwork-t és a hostPID-t – és csatlakoztassa a master teljes gyökerét ebbe a podba.

Tudod, hogy a Debianban fut a bash, és ez a bash root alatt fut. Vagyis csak rootot kaptunk a mesteren, anélkül, hogy a Kubernetes-fürtben bármilyen jogosultságunk lenne.

Ezután az egész feladat az, hogy menjen a /host /etc/kubernetes/pki alkönyvtárba, ha nem tévedek, ott vegye fel a fürt összes főtanúsítványát, és ennek megfelelően legyen a fürt adminisztrátora.

Ha így nézzük, ezek a legveszélyesebb jogok a podokban – függetlenül attól, hogy milyen jogokkal rendelkezik a felhasználó:
Lyukak kitöltése a Kubernetes-fürtben. Jelentés és átirat a DevOpsConf-ból

Ha rendelkezem jogosultságokkal egy pod futtatására valamely fürt névtérben, akkor ez a pod alapértelmezés szerint rendelkezik ezekkel a jogokkal. Futtathatok privilegizált podokat, és ezek általában minden jog, gyakorlatilag root a csomóponton.

A kedvencem a Root felhasználó. És a Kubernetes rendelkezik ezzel a Futtatás nem gyökérként opcióval. Ez egyfajta védelem a hackerekkel szemben. Tudod, mi az a „moldvai vírus”? Ha hirtelen hacker lesz, és eljön a Kubernetes-fürtömhöz, akkor mi, szegény rendszergazdák azt kérdezzük: „Kérjük, jelölje meg a podokban, amellyel feltöri a fürtömet, és nem rootként fut. Ellenkező esetben előfordulhat, hogy root alatt futtatod a folyamatot a podban, és nagyon könnyen feltörhetsz engem. Kérlek, védd meg magad magadtól."

Véleményem szerint a gazdagép elérési út mennyisége a leggyorsabb módja annak, hogy a Kubernetes-fürtből a kívánt eredményt érjük el.

De mit kezdjünk ezzel az egésszel?

A Kubernetestel találkozó normál rendszergazdák gondolata a következő: „Igen, mondtam, hogy a Kubernetes nem működik. Lyukak vannak benne. És az egész kocka egy baromság." Sőt, van olyan, hogy dokumentáció, és ha ott nézel, akkor van egy szakasz Pod biztonsági szabályzat.

Ez egy yaml objektum - a Kubernetes fürtben hozhatjuk létre -, amely kifejezetten a pod-ok leírásában szabályozza a biztonsági szempontokat. Vagyis valójában ez szabályozza a jogokat bármely hostNetwork, hostPID és bizonyos kötettípusok használatára, amelyek az indításkor a podokban vannak. A Pod Security Policy segítségével mindez leírható.

A legérdekesebb dolog a Pod biztonsági házirendben, hogy a Kubernetes-fürtben az összes PSP-telepítő nincs leírva, hanem alapértelmezés szerint egyszerűen le van tiltva. A Pod Security Policy engedélyezve van a belépési beépülő modul használatával.

Rendben, helyezzük üzembe a Pod Security Policy-t a fürtben, tegyük fel, hogy van néhány szolgáltatási pod a névtérben, amelyekhez csak a rendszergazdák férhetnek hozzá. Tegyük fel, hogy minden más esetben a podoknak korlátozott jogai vannak. Mert valószínűleg a fejlesztőknek nem kell privilegizált podokat futtatniuk a fürtben.

És úgy tűnik, minden rendben van velünk. A Kubernetes-fürtünket pedig nem lehet két perc alatt feltörni.

Van egy probléma. Valószínűleg, ha van Kubernetes-fürtje, akkor a figyelés telepítve van a fürtre. Még azt is megjósolnám, hogy ha a klaszternek van felügyelete, akkor Prometheusnak fogják hívni.

Amit most elmondok, az mind a Prometheus operátorra, mind a tiszta formában szállított Prometheusra érvényes lesz. A kérdés az, hogy ha nem tudok ilyen gyorsan bejuttatni egy adminisztrátort a fürtbe, akkor ez azt jelenti, hogy többet kell keresnem. És tudok keresni a monitorozásod segítségével.

Valószínűleg mindenki ugyanazokat a cikkeket olvassa Habréról, és a monitorozás a figyelő névtérben található. A kormánydiagramot nagyjából mindenki számára azonosnak nevezik. Feltételezem, hogy ha telepíted a stable/prometheust, akkor nagyjából ugyanazokat a neveket kapod. És valószínűleg nem is kell kitalálnom a DNS-nevet a fürtben. Mert szabványos.

Lyukak kitöltése a Kubernetes-fürtben. Jelentés és átirat a DevOpsConf-ból

Ezután van egy bizonyos dev ns, amelyben futtathat egy bizonyos pod. És akkor ebből a podból nagyon könnyű valami ilyesmit csinálni:

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

A prometheus-kube-state-metrics egyike azon Prometheus exportőröknek, amelyek magából a Kubernetes API-ból gyűjtik a mutatókat. Nagyon sok adat van ott, mi fut a fürtben, mi az, milyen problémái vannak vele.

Egyszerű példaként:

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

Ha egyszerű hajcsavarási kérelmet ad elő egy nem privilegizált podból, akkor a következő információkat kaphatja meg. Ha nem tudja, hogy a Kubernetes melyik verzióját futtatja, könnyen megmondja.

A legérdekesebb pedig az, hogy a kube-state-metrics elérése mellett ugyanolyan könnyen elérheti magát a Prometheust is közvetlenül. Onnan gyűjtheti a mutatókat. Akár mérőszámokat is építhetsz onnan. Még elméletileg is létrehozhat egy ilyen lekérdezést a Prometheus fürtjéből, amely egyszerűen kikapcsolja. És a figyelése teljesen leáll a fürtről.

És itt felmerül a kérdés, hogy bármilyen külső felügyelet felügyeli-e az Ön felügyeletét. Most kaptam a lehetőséget, hogy egy Kubernetes klaszterben működjek anélkül, hogy bármilyen következményekkel járna a magam számára. Nem is fogja tudni, hogy ott tevékenykedem, hiszen már nincs felügyelet.

Csakúgy, mint a PSP-vel, itt is az a probléma, hogy ezek a divatos technológiák – Kubernetes, Prometheus – egyszerűen nem működnek, és tele vannak lyukakkal. Nem igazán.

Van ilyen - Hálózati szabályzat.

Ha Ön normál adminisztrátor, akkor valószínűleg tudja a Network Policyről, hogy ez csak egy újabb yaml, amelyből már sok van a fürtben. És bizonyos hálózati házirendekre biztosan nincs szükség. És még ha elolvassa is, mi az a Network Policy, hogy ez a Kubernetes yaml tűzfala, lehetővé teszi a hozzáférési jogok korlátozását a névterek, a podok között, akkor biztosan úgy döntött, hogy a Kubernetes yaml formátumú tűzfala a következő absztrakciókon alapul. ... Nem nem . Ez határozottan nem szükséges.

Még akkor is, ha nem mondta el a biztonsági szakértőknek, hogy a Kubernetes használatával nagyon könnyű és egyszerű tűzfalat hozhat létre, és egy nagyon részletes tűzfalat. Ha ezt még nem tudják, és nem zavarnak: „Na, add, add...” Akkor mindenesetre a Hálózati házirendre van szükség, hogy blokkolja a hozzáférést néhány szolgáltatási helyhez, amelyeket ki lehet húzni a klaszterből. minden felhatalmazás nélkül.

Az általam megadott példához hasonlóan a Kubernetes-fürt bármely névteréből előhívhat kube állapotmérőket anélkül, hogy ehhez bármilyen joga lenne. A hálózati házirendek lezárták az összes többi névtér hozzáférését a figyelő névtérhez, és ennyi: nincs hozzáférés, nincs probléma. Az összes létező diagramon, mind a szabványos Prometheusban, mind a Prometheusban, amely az operátorban található, egyszerűen van egy lehetőség a kormányértékekben, hogy egyszerűen engedélyezze számukra a hálózati házirendeket. Csak be kell kapcsolni és működni fognak.

Itt tényleg egy probléma van. Normál szakállas adminisztrátorként valószínűleg úgy döntött, hogy nincs szükség hálózati szabályzatra. És miután elolvasott mindenféle cikket olyan forrásokról, mint a Habr, úgy döntött, hogy a flanel, különösen a host-gateway módban, a legjobb választás.

Mit kell tenni?

Megpróbálhatja újratelepíteni a Kubernetes-fürtben lévő hálózati megoldást, és megpróbálhatja lecserélni valami funkcionálisabbra. Ugyanarra a Calico-ra például. De rögtön azt akarom mondani, hogy a hálózati megoldás megváltoztatása egy Kubernetes működő fürtben meglehetősen nem triviális. Kétszer megoldottam (mindkét alkalommal azonban elméletileg), de még a Slurms-ban is megmutattuk, hogyan kell csinálni. Diákjainknak megmutattuk, hogyan lehet megváltoztatni a hálózati megoldást egy Kubernetes-fürtben. Elvileg megpróbálhatja megbizonyosodni arról, hogy nincs leállás a termelési klaszteren. De valószínűleg nem fog sikerülni.

És a probléma valójában nagyon egyszerűen megoldódik. Vannak tanúsítványok a fürtben, és Ön tudja, hogy a tanúsítványai egy év múlva lejárnak. Nos, és általában egy normál megoldás tanúsítványokkal a fürtben - miért aggódunk, új klasztert hozunk létre a közelben, hagyjuk, hogy a régi tönkremenjen, és mindent újratelepítünk. Igaz, ha elromlik, egy napot kell ülnünk, de itt egy új klaszter.

Amikor új fürtöt emel, ezzel egyidejűleg illessze be a Calico-t a flanel helyett.

Mi a teendő, ha a tanúsítványait száz évre adják ki, és nem kívánja újratelepíteni a klasztert? Van olyan, hogy Kube-RBAC-Proxy. Ez egy nagyon klassz fejlesztés, lehetővé teszi, hogy oldalkocsis konténerként beágyazza magát a Kubernetes-fürt bármelyik podjába. És tulajdonképpen engedélyt ad ehhez a podhoz magának a Kubernetes RBAC-ján keresztül.

Egy probléma van. Korábban ez a Kube-RBAC-Proxy megoldás az üzemeltető Prometheus-jába volt beépítve. De aztán elment. Most a modern verziók arra támaszkodnak, hogy rendelkezik hálózati házirenddel, és bezárja azokat. Ezért egy kicsit át kell írnunk a diagramot. Sőt, ha arra jársz ezt az adattárat, van példa arra, hogyan lehet ezt oldalkocsiként használni, és a grafikonokat minimálisan át kell majd írni.

Van még egy apró probléma. Nem a Prometheus az egyetlen, aki bárkinek átadja a mérőszámait. Minden Kubernetes-fürt-összetevőnk képes visszaadni saját mérőszámait.

De ahogy már mondtam, ha nem fér hozzá a fürthöz és nem gyűjt információt, akkor legalább árthat.

Tehát gyorsan bemutatok két módot, hogyan lehet tönkretenni egy Kubernetes-klasztert.

Nevetni fogsz, ha elmondom, ez két valós eset.

XNUMX. módszer. Erőforrások kimerülése.

Indítsunk el egy másik különleges pod. Lesz benne egy ilyen szakasz.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Mint tudják, a kérések a CPU és a memória mennyisége, amely a gazdagépen le van foglalva a kéréseket tartalmazó adott podokhoz. Ha van egy négymagos gazdagépünk egy Kubernetes-fürtben, és négy CPU pod érkezik oda kéréssel, az azt jelenti, hogy erre a gazdagépre nem érkezhet több kéréssel rendelkező pod.

Ha ilyen pod futtatok, akkor a következő parancsot fogom futtatni:

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

Akkor senki más nem tudja majd telepíteni a Kubernetes-fürtbe. Mert minden csomópont elfogy a kérésekből. Így leállítom a Kubernetes klaszteredet. Ha ezt este megteszem, elég hosszú időre leállíthatom a bevetéseket.

Ha újra megnézzük a Kubernetes dokumentációját, látni fogjuk ezt a Limit Range nevű dolgot. Erőforrásokat állít be a fürtobjektumokhoz. A yaml-ben írhatsz egy Limit Range objektumot, alkalmazhatod bizonyos névterekre - majd ebben a névtérben elmondhatod, hogy van alapértelmezett, maximális és minimális erőforrásod a podokhoz.

Egy ilyen dolog segítségével korlátozhatjuk a felhasználókat a csapatok konkrét terméknévtereiben abban, hogy mindenféle kellemetlen dolgot jelezzenek a podokon. De sajnos, még ha azt mondod is a felhasználónak, hogy nem indíthatnak el több CPU-ra vonatkozó kérelmet tartalmazó podokat, van egy ilyen csodálatos skálázási parancs, vagy a műszerfalon keresztül is méretezhetnek.

És innen ered a kettes számú módszer. 11 111 111 111 111 hüvelyt dobunk piacra. Ez tizenegy milliárd. Ez nem azért van, mert kitaláltam egy ilyen számot, hanem mert magam láttam.

Igazi történet. Késő este ki akartam menni az irodából. Látom, hogy egy csoport fejlesztő ül a sarokban, és kétségbeesetten csinálnak valamit a laptopjaikkal. Odamegyek a srácokhoz, és megkérdezem: "Mi történt veled?"

Valamivel korábban, este kilenc körül az egyik fejlesztő hazafelé készült. És úgy döntöttem: "Most egyre csökkentem a jelentkezésemet." Nyomtam egyet, de kicsit lelassult az internet. Megint megnyomta az egyest, megnyomta az egyet, és az Enter-re kattintott. Megböktem mindent, amit tudtam. Aztán életre kelt az internet – és minden kezdett lecsökkenteni erre a számra.

Igaz, ez a történet nem a Kubernetesen játszódik, akkoriban a Nomad volt. Ez azzal a ténnyel végződött, hogy miután egy órán keresztül megpróbáltuk megakadályozni Nomadot a folyamatos méretezési kísérletekben, Nomad azt válaszolta, hogy nem hagyja abba a méretezést, és nem tesz mást. – Fáradt vagyok, elmegyek. És összegömbölyödött.

Természetesen a Kubernetesen is megpróbáltam ugyanezt megtenni. Kubernetes nem volt elégedett a tizenegymilliárd hüvelyekkel, azt mondta: „Nem tehetem. Meghaladja a belső szájvédőt." De 1 000 000 000 hüvely képes.

Egymilliárdra válaszul a Kocka nem vonult vissza önmagába. Tényleg elkezdett skálázni. Minél tovább haladt a folyamat, annál több időbe telt új hüvelyek létrehozása. De a folyamat továbbra is folytatódott. A gond csak az, hogy ha korlátlanul tudok podokat elindítani a névteremben, akkor kérések és korlátok nélkül is annyi pod-ot tudok elindítani néhány feladattal, hogy ezeknek a feladatoknak a segítségével a csomópontok elkezdenek összeadni a memóriában, a CPU-ban. Amikor ennyi podot indítok el, a belőlük származó információknak a tárhelyre kell kerülniük, azaz stb. És amikor túl sok információ érkezik oda, a tároló túl lassan kezd visszatérni - és a Kubernetes kezd unalmassá válni.

És még egy probléma... Tudniillik a Kubernetes vezérlőelemei nem egy központi dolog, hanem több komponens. Különösen van egy vezérlő menedzser, ütemező stb. Mindezek a srácok egyszerre kezdenek el szükségtelen, ostoba munkát végezni, ami idővel egyre több időt vesz igénybe. A vezérlő menedzser új podokat hoz létre. Az ütemező megpróbál új csomópontot találni számukra. Valószínűleg hamarosan elfogynak az új csomópontok a fürtben. A Kubernetes-fürt egyre lassabban kezd el működni.

De úgy döntöttem, hogy még tovább megyek. Mint tudják, a Kubernetesben van egy szolgáltatás, amit szolgáltatásnak hívnak. Nos, alapértelmezés szerint a fürtökben a szolgáltatás valószínűleg IP-táblázatokkal működik.

Ha például egymilliárd pod-ot futtat, majd egy szkript segítségével kényszeríti a Kubernetis-t új szolgáltatások létrehozására:

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

A fürt összes csomópontján egyre több új iptables szabály jön létre hozzávetőlegesen egyszerre. Ezenkívül minden szolgáltatáshoz egymilliárd iptables-szabályt állítanak elő.

Megnéztem ezt az egészet több ezeren, tízig. És az a probléma, hogy már ennél a küszöbnél elég problémás ssh-t csinálni a csomóponton. Mert a csomagok, amelyek oly sok láncon mennek keresztül, kezdenek nem túl jól érezni magukat.

És ezt is mind a Kubernetes segítségével oldják meg. Van egy ilyen erőforrás-kvóta objektum. Beállítja a rendelkezésre álló erőforrások és objektumok számát a fürt névterében. A Kubernetes-fürt minden névterében létrehozhatunk egy yaml objektumot. Ezzel az objektummal azt mondhatjuk, hogy ehhez a névtérhez van hozzárendelve bizonyos számú kérés és korlát, majd azt mondhatjuk, hogy ebben a névtérben 10 szolgáltatás és 10 pod létrehozása lehetséges. Egyetlen fejlesztő pedig legalább esténként megfojthatja magát. Kubernetes azt fogja mondani neki: "Nem méretezheti a készleteit erre az összegre, mert az erőforrás meghaladja a kvótát." Ennyi, probléma megoldva. Dokumentáció itt.

Ezzel kapcsolatban felmerül egy problémás pont. Érzi, milyen nehéz lesz névteret létrehozni a Kubernetesben. Létrehozásához sok mindent figyelembe kell vennünk.

Erőforráskvóta + Határtartomány + RBAC
• Hozzon létre egy névteret
• Hozzon létre egy határtartományt belül
• Hozzon létre erőforráskvótán belül
• Hozzon létre egy szervizfiókot a CI számára
• Szerepkötés létrehozása a CI és a felhasználók számára
• Opcionálisan indítsa el a szükséges szervizegységeket

Ezért szeretném megragadni az alkalmat, hogy megosszam a fejleményeket. Van egy olyan dolog, amit SDK operátornak hívnak. Így a Kubernetes-fürt operátorokat írhat hozzá. Az Ansible segítségével állításokat írhat.

Először Ansible-ben írták, aztán láttam, hogy van SDK operátor, és átírtam az Ansible szerepkört operátorrá. Ez az utasítás lehetővé teszi egy parancsnak nevezett objektum létrehozását a Kubernetes-fürtben. A parancson belül lehetővé teszi a parancs környezetének leírását yaml nyelven. A csapatkörnyezeten belül pedig lehetővé teszi számunkra, hogy leírjuk, hogy olyan sok erőforrást allokálunk.

kicsi megkönnyítve ezt az egész összetett folyamatot.

És befejezésül. Mit kezdjünk ezzel az egésszel?
Első. A pod biztonsági szabályzata jó. És annak ellenére, hogy a Kubernetes telepítői a mai napig nem használják őket, továbbra is használnia kell őket a fürtökben.

A hálózati házirend nem csupán egy újabb szükségtelen funkció. Ez az, amire igazán szükség van egy klaszterben.

LimitRange/ResourceQuota – ideje használni. Nagyon régen kezdtük el használni, és sokáig biztos voltam benne, hogy mindenki használja. Kiderült, hogy ez ritka.

A jelentésben említetteken kívül vannak olyan nem dokumentált szolgáltatások, amelyek lehetővé teszik a fürt megtámadását. Nemrég jelent meg a Kubernetes sebezhetőségeinek kiterjedt elemzése.

Néhány dolog olyan szomorú és bántó. Például bizonyos feltételek mellett a Kubernetes-fürtben lévő kockák átadhatják a warlocks könyvtár tartalmát egy jogosulatlan felhasználónak.

Itt Vannak utasítások arra vonatkozóan, hogyan reprodukálhat mindent, amit mondtam. Vannak olyan fájlok, amelyek gyártási példákat tartalmaznak a ResourceQuota és a Pod Security Policy kinézetére. És mindezt megérintheti.

Köszönet mindenkinek.

Forrás: will.com

Hozzászólás