Correzione dei buchi nel cluster Kubernetes. Report e trascrizione da DevOpsConf

Pavel Selivanov, Southbridge Solutions Architect e insegnante di Slurm, ha tenuto una presentazione alla DevOpsConf 2019. Questo intervento fa parte di uno degli argomenti del corso di approfondimento su Kubernetes “Slurm Mega”.

Slurm Basic: un'introduzione a Kubernetes si svolge a Mosca dal 18 al 20 novembre.
Slurm Mega: uno sguardo sotto il cofano di Kubernetes — Mosca, 22-24 novembre.
Slurm Online: entrambi i corsi Kubernetes sempre disponibile.

Sotto il taglio c'è una trascrizione del rapporto.

Buon pomeriggio, colleghi e coloro che simpatizzano con loro. Oggi parlerò di sicurezza.

Vedo che oggi ci sono molte guardie di sicurezza nella sala. Mi scuso con te in anticipo se utilizzo termini provenienti dal mondo della sicurezza non esattamente come per te è consuetudine.

È successo così che circa sei mesi fa mi sono imbattuto in un cluster Kubernetes pubblico. Pubblico significa che esiste un numero ennesimo di spazi dei nomi; in questi spazi dei nomi ci sono utenti isolati nel loro spazio dei nomi. Tutti questi utenti appartengono a società diverse. Ebbene, si presumeva che questo cluster dovesse essere utilizzato come CDN. Cioè, ti danno un cluster, ti danno un utente lì, vai lì nel tuo spazio dei nomi, distribuisci i tuoi fronti.

La mia azienda precedente ha provato a vendere un servizio del genere. E mi è stato chiesto di dare un'occhiata al cluster per vedere se questa soluzione era adatta o meno.

Sono arrivato a questo cluster. Mi sono stati concessi diritti limitati, spazio dei nomi limitato. I ragazzi lì hanno capito cosa fosse la sicurezza. Hanno letto del controllo degli accessi basato sui ruoli (RBAC) in Kubernetes e lo hanno distorto in modo che non potessi avviare i pod separatamente dalle distribuzioni. Non ricordo il problema che stavo cercando di risolvere avviando un pod senza distribuzione, ma volevo davvero avviare solo un pod. Per fortuna, ho deciso di vedere quali diritti ho nel cluster, cosa posso fare, cosa non posso fare e cosa hanno combinato lì. Allo stesso tempo, ti dirò cosa hanno configurato in modo errato in RBAC.

È successo così che in due minuti ho ricevuto un amministratore nel loro cluster, ho guardato tutti gli spazi dei nomi vicini, ho visto lì i fronti di produzione in corso delle aziende che avevano già acquistato il servizio e implementato. Riuscivo a malapena a trattenermi dall'andare davanti a qualcuno e mettere qualche parolaccia sulla pagina principale.

Ti dirò con esempi come ho fatto questo e come proteggerti da questo.

Ma prima, lasciatemi presentarmi. Mi chiamo Pavel Selivanov. Sono un architetto a Southbridge. Capisco Kubernetes, DevOps e ogni sorta di cose fantasiose. Io e gli ingegneri di Southbridge stiamo costruendo tutto questo e io mi sto consultando.

Oltre alle nostre attività principali, abbiamo recentemente lanciato progetti chiamati Slurms. Stiamo cercando di portare un po' alle masse la nostra capacità di lavorare con Kubernetes, per insegnare ad altre persone a lavorare anche con K8.

Di cosa parlerò oggi? L'argomento del rapporto è ovvio: la sicurezza del cluster Kubernetes. Ma voglio dire subito che questo argomento è molto ampio - e quindi voglio chiarire subito di cosa sicuramente non parlerò. Non parlerò di termini banali che sono già stati utilizzati centinaia di volte su Internet. Tutti i tipi di RBAC e certificati.

Parlerò di ciò che preoccupa me e i miei colleghi riguardo alla sicurezza in un cluster Kubernetes. Vediamo questi problemi sia tra i fornitori che forniscono cluster Kubernetes sia tra i clienti che si rivolgono a noi. E anche da clienti che si rivolgono a noi da altre società di consulenza amministrativa. Cioè, la portata della tragedia è in realtà molto grande.

Ci sono letteralmente tre punti di cui parlerò oggi:

  1. Diritti utente e diritti pod. I diritti utente e i diritti pod non sono la stessa cosa.
  2. Raccolta di informazioni sul cluster. Mostrerò che puoi raccogliere tutte le informazioni di cui hai bisogno da un cluster senza avere diritti speciali in questo cluster.
  3. Attacco DoS al cluster. Se non possiamo raccogliere informazioni, potremo comunque inserire un cluster. Parlerò degli attacchi DoS sugli elementi di controllo del cluster.

Un'altra cosa generale che menzionerò è ciò su cui ho testato tutto questo, sul quale posso sicuramente dire che funziona tutto.

Prendiamo come base l'installazione di un cluster Kubernetes utilizzando Kubespray. Se qualcuno non lo sa, questo è in realtà un insieme di ruoli per Ansible. Lo usiamo costantemente nel nostro lavoro. La cosa buona è che puoi arrotolarlo ovunque: puoi arrotolarlo su pezzi di ferro o in una nuvola da qualche parte. Un metodo di installazione funziona in linea di principio per tutto.

In questo cluster avrò Kubernetes v1.14.5. L'intero cluster Cube, che prenderemo in considerazione, è diviso in namespace, ogni namespace appartiene a un team separato e i membri di questo team hanno accesso a ciascun namespace. Non possono accedere a spazi dei nomi diversi, ma solo al proprio. Ma esiste un determinato account amministratore che dispone dei diritti sull'intero cluster.

Correzione dei buchi nel cluster Kubernetes. Report e trascrizione da DevOpsConf

Ho promesso che la prima cosa che faremo sarà ottenere i diritti di amministratore per il cluster. Abbiamo bisogno di un pod appositamente preparato che rompa il cluster Kubernetes. Tutto quello che dobbiamo fare è applicarlo al cluster Kubernetes.

kubectl apply -f pod.yaml

Questo pod arriverà a uno dei master del cluster Kubernetes. E dopo questo il cluster ci restituirà felicemente un file chiamato admin.conf. In Cube, questo file archivia tutti i certificati dell'amministratore e allo stesso tempo configura l'API del cluster. Ecco quanto è facile ottenere l'accesso amministrativo, credo, al 98% dei cluster Kubernetes.

Ripeto, questo pod è stato creato da uno sviluppatore nel tuo cluster che ha accesso per distribuire le sue proposte in un piccolo spazio dei nomi, è tutto bloccato da RBAC. Non aveva diritti. Tuttavia il certificato è stato restituito.

E ora riguardo a un pod appositamente preparato. Lo eseguiamo su qualsiasi immagine. Prendiamo debian:jessie come esempio.

Abbiamo questa cosa:

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

Cos'è la tolleranza? I master in un cluster Kubernetes sono solitamente contrassegnati con qualcosa chiamato taint. E l'essenza di questa "infezione" è che dice che i pod non possono essere assegnati ai nodi master. Ma nessuno si preoccupa di indicare in nessun pod che sia tollerante all’“infezione”. La sezione Tolleranza dice semplicemente che se qualche nodo ha NoSchedule, allora il nostro nodo è tollerante a tale infezione e non ci sono problemi.

Inoltre, diciamo che il nostro sotto non solo è tollerante, ma vuole anche prendere di mira specificamente il padrone. Perché i maestri hanno la cosa più deliziosa di cui abbiamo bisogno: tutti i certificati. Pertanto, diciamo nodeSelector - e abbiamo un'etichetta standard sui master, che ti consente di selezionare da tutti i nodi nel cluster esattamente quei nodi che sono master.

Con queste due sezioni arriverà sicuramente al maestro. E gli sarà permesso di vivere lì.

Ma venire al maestro non ci basta. Questo non ci darà nulla. Quindi poi abbiamo queste due cose:

hostNetwork: true 
hostPID: true 

Specifichiamo che il nostro pod, che lanciamo, vivrà nello spazio dei nomi del kernel, nello spazio dei nomi della rete e nello spazio dei nomi PID. Una volta avviato il pod sul master, sarà in grado di vedere tutte le interfacce reali e live di questo nodo, ascoltare tutto il traffico e vedere il PID di tutti i processi.

Poi è questione di piccole cose. Prendi etcd e leggi quello che vuoi.

La cosa più interessante è questa funzionalità di Kubernetes, che è presente lì per impostazione predefinita.

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

E la sua essenza è che possiamo dire nel pod che lanciamo, anche senza diritti su questo cluster, che vogliamo creare un volume di tipo hostPath. Ciò significa prendere il percorso dall'host su cui verrà avviato e considerarlo come volume. E poi lo chiamiamo nome: host. Montiamo l'intero hostPath all'interno del pod. In questo esempio, nella directory /host.

Lo ripeterò ancora. Abbiamo detto al pod di raggiungere il master, ottenere lì hostNetwork e hostPID e montare l'intera root del master all'interno di questo pod.

Capisci che in Debian abbiamo bash in esecuzione e questa bash viene eseguita sotto root. Cioè, abbiamo appena ricevuto il root sul master, senza avere alcun diritto nel cluster Kubernetes.

Quindi l'intero compito è andare nella sottodirectory /host /etc/kubernetes/pki, se non sbaglio, raccogliere lì tutti i certificati principali del cluster e, di conseguenza, diventare l'amministratore del cluster.

Se lo guardi in questo modo, questi sono alcuni dei diritti più pericolosi nei pod, indipendentemente dai diritti di cui dispone l'utente:
Correzione dei buchi nel cluster Kubernetes. Report e trascrizione da DevOpsConf

Se ho i diritti per eseguire un pod in uno spazio dei nomi del cluster, allora questo pod avrà questi diritti per impostazione predefinita. Posso eseguire pod privilegiati e questi sono generalmente tutti i diritti, praticamente root sul nodo.

Il mio preferito è l'utente Root. E Kubernetes ha questa opzione Esegui come non root. Questo è un tipo di protezione da un hacker. Sapete cos’è il “virus Moldavo”? Se all'improvviso sei un hacker e vieni nel mio cluster Kubernetes, allora noi, poveri amministratori, chiediamo: “Per favore, indica nei tuoi pod con cui hackererai il mio cluster, esegui come non root. Altrimenti, succederà che eseguirai il processo nel tuo pod sotto root, e sarà molto facile per te hackerarmi. Per favore, proteggiti da te stesso."

Il volume del percorso host è, a mio avviso, il modo più veloce per ottenere il risultato desiderato da un cluster Kubernetes.

Ma cosa fare con tutto questo?

Il pensiero che dovrebbe venire a ogni normale amministratore che incontra Kubernetes è: “Sì, te l’ho detto, Kubernetes non funziona. Ci sono dei buchi. E l’intero Cubo è una stronzata.” In effetti, esiste qualcosa come la documentazione e, se guardi lì, c'è una sezione Politica di sicurezza dei pod.

Si tratta di un oggetto yaml - possiamo crearlo nel cluster Kubernetes - che controlla gli aspetti di sicurezza specificatamente nella descrizione dei pod. Cioè, in effetti, controlla i diritti per utilizzare qualsiasi hostNetwork, hostPID e alcuni tipi di volume presenti nei pod all'avvio. Con l'aiuto della politica di sicurezza dei pod, tutto questo può essere descritto.

La cosa più interessante della Pod Security Policy è che nel cluster Kubernetes tutti i programmi di installazione PSP non solo non sono descritti in alcun modo, ma sono semplicemente disabilitati per impostazione predefinita. La policy di sicurezza dei pod viene abilitata utilizzando il plug-in di ammissione.

Ok, distribuiamo la policy di sicurezza dei pod nel cluster, supponiamo di avere alcuni pod di servizio nello spazio dei nomi, a cui hanno accesso solo gli amministratori. Diciamo che in tutti gli altri casi i pod hanno diritti limitati. Perché molto probabilmente gli sviluppatori non hanno bisogno di eseguire pod privilegiati nel tuo cluster.

E a noi sembra che vada tutto bene. E il nostro cluster Kubernetes non può essere violato in due minuti.

C'è un problema. Molto probabilmente, se disponi di un cluster Kubernetes, il monitoraggio viene installato sul tuo cluster. Arriverei addirittura a prevedere che se il tuo cluster dispone di monitoraggio, si chiamerà Prometheus.

Ciò che sto per dirti sarà valido sia per l’operatore Prometeo che per Prometeo consegnato nella sua forma pura. La domanda è che se non riesco a inserire un amministratore nel cluster così rapidamente, significa che devo cercare di più. E posso effettuare ricerche con l'aiuto del tuo monitoraggio.

Probabilmente tutti leggono gli stessi articoli su Habré e il monitoraggio si trova nello spazio dei nomi di monitoraggio. Il grafico del timone si chiama più o meno lo stesso per tutti. Immagino che se esegui helm install stable/prometheus, ti ritroverai con più o meno gli stessi nomi. E molto probabilmente non dovrò nemmeno indovinare il nome DNS nel tuo cluster. Perché è standard.

Correzione dei buchi nel cluster Kubernetes. Report e trascrizione da DevOpsConf

Successivamente abbiamo un certo dev ns, in cui puoi eseguire un certo pod. E poi da questo pod è molto facile fare qualcosa del genere:

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

prometheus-kube-state-metrics è uno degli esportatori Prometheus che raccoglie parametri dall'API Kubernetes stessa. Ci sono molti dati lì, cosa è in esecuzione nel tuo cluster, di cosa si tratta, quali problemi hai con esso.

Come semplice esempio:

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

Effettuando una semplice richiesta curl da un pod non privilegiato, puoi ottenere le seguenti informazioni. Se non sai quale versione di Kubernetes stai utilizzando, te lo dirà facilmente.

E la cosa più interessante è che oltre ad accedere a kube-state-metrics, puoi altrettanto facilmente accedere direttamente a Prometheus stesso. Puoi raccogliere metriche da lì. Puoi anche creare parametri da lì. Anche in teoria, puoi creare una query di questo tipo da un cluster in Prometheus, che semplicemente la disattiverà. E il tuo monitoraggio smetterà del tutto di funzionare dal cluster.

E qui sorge la domanda se qualche monitoraggio esterno monitora il tuo monitoraggio. Ho appena avuto l'opportunità di operare in un cluster Kubernetes senza alcuna conseguenza per me. Non saprai nemmeno che opero lì, visto che non c’è più alcun monitoraggio.

Proprio come con la PSP, sembra che il problema sia che tutte queste fantasiose tecnologie - Kubernetes, Prometheus - semplicemente non funzionano e sono piene di buchi. Non proprio.

C'è una cosa del genere - Politica di rete.

Se sei un normale amministratore, molto probabilmente sai dei criteri di rete che questo è solo un altro yaml, di cui ce ne sono già molti nel cluster. E alcuni criteri di rete non sono assolutamente necessari. E anche se leggi cos'è la Network Policy, che è un firewall yaml di Kubernetes, che ti permette di limitare i diritti di accesso tra namespace, tra pod, allora hai sicuramente deciso che il firewall in formato yaml in Kubernetes si basa sulle prossime astrazioni ...No, no. Questo non è assolutamente necessario.

Anche se non hai detto ai tuoi specialisti della sicurezza che utilizzando Kubernetes puoi creare un firewall molto semplice e facile, e molto granulare. Se non lo sanno ancora e non ti disturbano: "Bene, dammi, dammi..." Allora, in ogni caso, hai bisogno della Politica di rete per bloccare l'accesso ad alcuni luoghi di servizio che possono essere estratti dal tuo cluster senza alcuna autorizzazione.

Come nell'esempio che ho fornito, puoi recuperare i parametri dello stato di Kube da qualsiasi spazio dei nomi nel cluster Kubernetes senza avere alcun diritto per farlo. Le policy di rete hanno chiuso l'accesso da tutti gli altri spazi dei nomi allo spazio dei nomi di monitoraggio e basta: nessun accesso, nessun problema. In tutti i grafici esistenti, sia il Prometheus standard che il Prometheus presente nell'operatore, c'è semplicemente un'opzione nei valori helm per abilitare semplicemente le politiche di rete per loro. Devi solo accenderlo e funzioneranno.

C'è davvero un problema qui. Essendo un normale amministratore barbuto, molto probabilmente hai deciso che le politiche di rete non sono necessarie. E dopo aver letto tutti i tipi di articoli su risorse come Habr, hai deciso che la flanella, soprattutto con la modalità gateway host, è la cosa migliore che puoi scegliere.

Cosa fare?

Puoi provare a ridistribuire la soluzione di rete che hai nel tuo cluster Kubernetes, provare a sostituirla con qualcosa di più funzionale. Per lo stesso Calico, per esempio. Ma voglio dire subito che il compito di cambiare la soluzione di rete in un cluster di lavoro Kubernetes non è affatto banale. L'ho risolto due volte (entrambe le volte, però, in teoria), ma abbiamo anche mostrato come farlo a Slurms. Ai nostri studenti abbiamo mostrato come modificare la soluzione di rete in un cluster Kubernetes. In linea di principio, puoi provare a assicurarti che non vi siano tempi di inattività nel cluster di produzione. Ma probabilmente non ci riuscirai.

E il problema in realtà è risolto in modo molto semplice. Sono presenti certificati nel cluster e sai che i tuoi certificati scadranno tra un anno. Bene, e di solito una soluzione normale con certificati nel cluster: perché preoccuparci, creeremo un nuovo cluster nelle vicinanze, lasceremo marcire quello vecchio e ridistribuiremo tutto. È vero, quando va a male, dovremo aspettare un giorno, ma ecco un nuovo ammasso.

Quando si solleva un nuovo grappolo, contemporaneamente inserire il calicò al posto della flanella.

Cosa fare se i tuoi certificati vengono emessi per cento anni e non ridistribuirai il cluster? Esiste una cosa come Kube-RBAC-Proxy. Questo è uno sviluppo molto interessante, ti consente di incorporarti come contenitore sidecar in qualsiasi pod nel cluster Kubernetes. E in realtà aggiunge l'autorizzazione a questo pod tramite RBAC di Kubernetes stesso.

C'è un problema. In precedenza, questa soluzione Kube-RBAC-Proxy era integrata nel Prometheus dell'operatore. Ma poi se n'era andato. Ora le versioni moderne si basano sul fatto che si dispone di criteri di rete e li si chiude utilizzandoli. E quindi dovremo riscrivere un po’ il grafico. In effetti, se vai a questo deposito, ci sono esempi di come utilizzarlo come sidecar e i grafici dovranno essere riscritti minimamente.

C'è un altro piccolo problema. Prometheus non è l'unico a distribuire i suoi parametri a chiunque. Tutti i nostri componenti del cluster Kubernetes sono anche in grado di restituire i propri parametri.

Ma come ho già detto, se non puoi accedere al cluster e raccogliere informazioni, puoi almeno causare qualche danno.

Quindi mostrerò rapidamente due modi in cui un cluster Kubernetes può essere rovinato.

Riderai quando te lo dico, questi sono due casi di vita reale.

Metodo uno. Esaurimento delle risorse.

Lanciamo un altro pod speciale. Avrà una sezione come questa.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Come sai, le richieste rappresentano la quantità di CPU e memoria riservata sull'host per pod specifici con richieste. Se abbiamo un host a quattro core in un cluster Kubernetes e quattro pod CPU arrivano lì con richieste, significa che nessun altro pod con richieste potrà arrivare a questo host.

Se eseguo un pod di questo tipo, eseguirò il comando:

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

Quindi nessun altro potrà eseguire la distribuzione nel cluster Kubernetes. Perché tutti i nodi esauriranno le richieste. E così fermerò il tuo cluster Kubernetes. Se lo faccio la sera, posso interrompere le implementazioni per un periodo piuttosto lungo.

Se esaminiamo nuovamente la documentazione di Kubernetes, vedremo questa cosa chiamata Limit Range. Imposta le risorse per gli oggetti del cluster. Puoi scrivere un oggetto Limit Range in yaml, applicarlo a determinati spazi dei nomi e quindi in questo spazio dei nomi puoi dire di avere risorse predefinite, massime e minime per i pod.

Con l'aiuto di una cosa del genere, possiamo limitare gli utenti in spazi dei nomi di prodotti specifici dei team nella capacità di indicare ogni sorta di cose brutte sui loro pod. Ma sfortunatamente, anche se dici all'utente che non può avviare pod con richieste per più di una CPU, esiste un comando di ridimensionamento così meraviglioso oppure può eseguire il ridimensionamento tramite la dashboard.

Ed è da qui che nasce il metodo numero due. Lanciamo 11 pod. Sono undici miliardi. Questo non è perché ho inventato un numero del genere, ma perché l'ho visto io stesso.

Storia vera. A tarda sera stavo per uscire dall'ufficio. Vedo un gruppo di sviluppatori seduti in un angolo, che fanno freneticamente qualcosa con i loro laptop. Vado dai ragazzi e chiedo: "Cosa ti è successo?"

Un po' prima, verso le nove di sera, uno degli sviluppatori si stava preparando per tornare a casa. E ho deciso: “Ora ridurrò la mia domanda a una”. Ne ho premuto uno, ma Internet ha rallentato leggermente. Lo premette di nuovo, lo premette e fece clic su Invio. Ho fatto tutto quello che potevo. Poi Internet ha preso vita e tutto ha cominciato a ridursi a questo numero.

È vero, questa storia non è avvenuta su Kubernetes; a quel tempo era Nomad. Si è concluso con il fatto che dopo un'ora dei nostri tentativi di fermare Nomad dai persistenti tentativi di ridimensionamento, Nomad ha risposto che non avrebbe smesso di ridimensionare e non avrebbe fatto nient'altro. "Sono stanco, me ne vado." E si rannicchiò.

Naturalmente ho provato a fare lo stesso su Kubernetes. Kubernetes non era contento di undici miliardi di pod, ha detto: “Non posso. Supera i paradenti interni." Ma 1 di pod potrebbero farlo.

In risposta a un miliardo, il Cubo non si è chiuso in se stesso. Ha davvero iniziato a ridimensionarsi. Più andava avanti il ​​processo, più tempo gli occorreva per creare nuovi pod. Ma il processo continuava comunque. L'unico problema è che se posso avviare pod illimitatamente nel mio spazio dei nomi, anche senza richieste e limiti posso avviare così tanti pod con alcune attività che con l'aiuto di queste attività i nodi inizieranno ad accumularsi in memoria, in CPU. Quando lancio così tanti pod, le informazioni da essi contenuti dovrebbero essere archiviate, ovvero ecc. E quando arrivano troppe informazioni, lo spazio di archiviazione inizia a ritornare troppo lentamente e Kubernetes inizia a diventare noioso.

E ancora un problema... Come sapete, gli elementi di controllo di Kubernetes non sono una cosa centrale, ma diversi componenti. In particolare, c'è un controller manager, uno scheduler e così via. Tutti questi ragazzi inizieranno a svolgere contemporaneamente un lavoro inutile e stupido, che col tempo inizierà a richiedere sempre più tempo. Il gestore del controller creerà nuovi pod. Lo Scheduler proverà a trovare un nuovo nodo per loro. Molto probabilmente presto esaurirai i nuovi nodi nel tuo cluster. Il cluster Kubernetes inizierà a funzionare sempre più lentamente.

Ma ho deciso di andare ancora oltre. Come sai, in Kubernetes esiste una cosa chiamata servizio. Bene, per impostazione predefinita nei tuoi cluster, molto probabilmente, il servizio funziona utilizzando le tabelle IP.

Se esegui un miliardo di pod, ad esempio, e poi utilizzi uno script per forzare Kubernetis a creare nuovi servizi:

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

Su tutti i nodi del cluster, sempre più nuove regole iptables verranno generate approssimativamente simultaneamente. Inoltre, per ciascun servizio verranno generate un miliardo di regole iptables.

Ho controllato l'intera faccenda su diverse migliaia, fino a dieci. E il problema è che già a questa soglia è abbastanza problematico eseguire ssh sul nodo. Perché i pacchetti, attraversando così tante catene, iniziano a non sentirsi molto bene.

E anche questo è tutto risolto con l’aiuto di Kubernetes. Esiste un oggetto quota di risorse di questo tipo. Imposta il numero di risorse e oggetti disponibili per lo spazio dei nomi nel cluster. Possiamo creare un oggetto yaml in ogni spazio dei nomi del cluster Kubernetes. Utilizzando questo oggetto, possiamo dire che abbiamo un certo numero di richieste e limiti allocati per questo namespace, e quindi possiamo dire che in questo namespace è possibile creare 10 servizi e 10 pod. E un singolo sviluppatore può almeno soffocarsi la sera. Kubernetes gli dirà: “Non puoi ridimensionare i tuoi pod a quella quantità, perché la risorsa supera la quota”. Questo è tutto, problema risolto. Documentazione qui.

A questo proposito si pone un punto problematico. Senti quanto sta diventando difficile creare uno spazio dei nomi in Kubernetes. Per crearlo, dobbiamo tenere conto di molte cose.

Quota di risorse + Intervallo limite + RBAC
• Creare uno spazio dei nomi
• Creare un intervallo limite all'interno
• Creare una quota di risorse interna
• Creare un account di servizio per CI
• Creare associazioni di ruoli per CI e utenti
• Facoltativamente, avviare i pod di servizio necessari

Pertanto, vorrei cogliere l’occasione per condividere i miei sviluppi. Esiste una cosa chiamata operatore SDK. Questo è un modo in cui un cluster Kubernetes può scrivere gli operatori. Puoi scrivere istruzioni usando Ansible.

All'inizio era scritto in Ansible, poi ho visto che c'era un operatore SDK e ho riscritto il ruolo Ansible in un operatore. Questa istruzione ti consente di creare un oggetto nel cluster Kubernetes chiamato comando. All'interno di un comando, ti consente di descrivere l'ambiente per questo comando in yaml. E all'interno dell'ambiente del team, ci consente di descrivere che stiamo assegnando così tante risorse.

petite semplificando l'intero processo complesso.

E in conclusione. Cosa fare con tutto questo?
Primo. La politica di sicurezza dei pod è buona. E nonostante il fatto che nessuno dei programmi di installazione di Kubernetes li utilizzi fino ad oggi, è comunque necessario utilizzarli nei tuoi cluster.

I criteri di rete non sono solo un'altra funzionalità non necessaria. Questo è ciò che serve veramente in un cluster.

LimitRange/ResourceQuota: è ora di usarlo. Abbiamo iniziato a usarlo molto tempo fa e per molto tempo sono stato sicuro che tutti lo usassero. Si è scoperto che questo è raro.

Oltre a quanto menzionato durante il report, esistono funzionalità non documentate che consentono di attaccare il cluster. Rilasciato di recente analisi approfondita delle vulnerabilità di Kubernetes.

Alcune cose sono così tristi e dolorose. Ad esempio, in determinate condizioni, i cubelet in un cluster Kubernetes possono fornire il contenuto della directory warlocks a un utente non autorizzato.

Qui Ci sono le istruzioni su come riprodurre tutto quello che ti ho detto. Sono presenti file con esempi di produzione dell'aspetto di ResourceQuota e della policy di sicurezza dei pod. E puoi toccare tutto questo.

Grazie a tutti.

Fonte: habr.com

Aggiungi un commento