Stiamo riparando le falle nel cluster Kubernetes. Relazione e trascrizione da DevOpsConf

Pavel Selivanov, architetto delle soluzioni Southbridge e docente di Slurm, ha tenuto una relazione al DevOpsConf 2019. Questa relazione fa parte di uno degli argomenti del corso avanzato su Kubernetes "Slurm Mega".

Slurm Base: introduzione a Kubernetes si svolge a Mosca dal 18 al 20 novembre.
Slurm Mega: diamo un'occhiata sotto il cofano di Kubernetes — Mosca, dal 22 al 24 novembre.
Slurm Online: entrambi i corsi su Kubernetes sono sempre disponibili.

Guarda il video

Dopo il salto — trascrizione della relazione.

Buongiorno colleghi e simpatizzanti. Oggi parlerò di sicurezza.

Vedo che oggi in sala ci sono molti esperti di sicurezza. Vi chiedo scusa in anticipo se utilizzerò termini dal mondo della sicurezza in modo non convenzionale.

È successo che circa sei mesi fa ho avuto accesso a un cluster Kubernetes pubblico. Pubblico significa che ci sono n namespace, in questi namespace ci sono utenti, isolati nel loro namespace. Tutti questi utenti appartengono a diverse aziende. E si prevedeva che questo cluster fosse utilizzato come CDN. Cioè ti danno un cluster, ti danno un utente, e tu accedi nel tuo namespace per fare il deploy delle tue interfacce.

Alla mia azienda precedente hanno provato a vendere un servizio simile. E mi è stato chiesto di testare il cluster per vedere se una soluzione del genere fosse adatta.

Sono andato in questo cluster. Mi hanno dato diritti limitati e un namespace ristretto. Lì i ragazzi sapevano cosa significasse sicurezza. Avevano studiato cosa fosse il controllo degli accessi basato su ruoli (RBAC) di Kubernetes e l'avevano impostato in modo tale che non potessi avviare pod separatamente dai deployment. Non ricordo il compito che stavo cercando di risolvere avviando un pod senza deployment, ma volevo davvero avviare semplicemente un pod. Ho deciso di controllare un po' quali diritti avevo nel cluster, cosa potevo fare, cosa non potevo fare, quali limitazioni avevano impostato. Inoltre, racconterò cosa avevano impostato male in RBAC.

È successo che dopo due minuti ho ottenuto i diritti di admin nel loro cluster, ho esaminato tutti i namespace vicini e ho visto che c'erano deployment di interfacce di produzione di aziende che avevano già acquistato il servizio e si erano già deployati. Ho faticato a trattenermi dal venire da qualcuno e piazzare una parola volgare sulla loro homepage.

Racconterò con esempi come ho fatto e come proteggersi da esso.

Ma per iniziare, mi presento. Mi chiamo Pavel Selivanov. Sono un architetto della Southbridge. Ho esperienza in Kubernetes, DevOps e in varie tecnologie all'avanguardia. Insieme ai miei ingegneri di Southbridge, realizziamo tutto questo e io fornisco consulenza.

Oltre all'attività principale, recentemente abbiamo lanciato dei progetti chiamati Slёrmy. Stiamo cercando di portare le nostre competenze su Kubernetes a un pubblico più ampio, per insegnare ad altre persone a lavorare con K8s.

Di cosa parlerò oggi. Il tema della mia presentazione è chiaro: la sicurezza del cluster Kubernetes. Ma voglio subito dire che questo argomento è molto ampio, e quindi voglio chiarire subito cosa non tratterò. Non parlerò di termini inflazionati che sono stati già discussi mille volte su internet. Tipo RBAC e certificati.

Parlerò di quali siano le problematiche relative alla sicurezza nel cluster Kubernetes che io e i miei colleghi incontriamo. Questi problemi li vediamo sia dai fornitori che forniscono cluster Kubernetes, sia dai clienti che si rivolgono a noi. Anche dai clienti che provengono da altre aziende di consulenza. Quindi, l'entità del problema è in realtà molto grande.

Tre punti di cui parlerò oggi:

  1. Diritti degli utenti vs diritti dei pod. I diritti degli utenti e i diritti dei pod non sono la stessa cosa.
  2. Raccolta di informazioni sul cluster. Mostrerò come sia possibile raccogliere tutte le informazioni necessarie da un cluster, senza avere diritti particolari in quel cluster.
  3. Attacco DoS al cluster. Se non possiamo raccogliere informazioni, saremo comunque in grado di compromettere il cluster. Parlerò degli attacchi DoS sugli elementi di gestione del cluster.

Un'altra cosa generale di cui menzionerò è su cosa ho effettuato tutti questi test, su cosa posso affermare con certezza che funziona.

Come base, prendiamo l'installazione del cluster Kubernetes utilizzando Kubespray. Se qualcuno non lo sa, è fondamentalmente un insieme di ruoli per Ansible. Nella nostra attività lo utilizziamo costantemente. È comodo perché può essere implementato ovunque: lo si può installare su hardware fisico o in un cloud. Un metodo di installazione si adatta praticamente a tutto.

In questo cluster avrò Kubernetes v1.14.5. L'intero cluster di Kubernetes che esamineremo è suddiviso in namespace, ciascun namespace appartiene a un team separato, e solo i membri di quel team hanno accesso a quel namespace. Non possono accedere ad altri namespace, solo al proprio. Ma c'è un account admin che ha diritti su tutto il cluster.

Stiamo riparando le falle nel cluster Kubernetes. Relazione e trascrizione da DevOpsConf

Ho promesso che la prima cosa sarà ottenere i diritti admin sul cluster. Abbiamo bisogno di un pod appositamente preparato che romperà il cluster Kubernetes. Tutto ciò che dobbiamo fare è applicarlo nel cluster Kubernetes.

kubectl apply -f pod.yaml

Questo pod arriverà su uno dei nodi master del cluster Kubernetes. E il cluster ci restituirà felicemente un file chiamato admin.conf. In questo file di Kubernetes sono presenti tutti i certificati admin, e inoltre è configurato l'API del cluster. È così semplice ottenere l'accesso admin, penso, per il 98% dei cluster Kubernetes.

Ripeto, questo pod è stato creato da uno sviluppatore nel tuo cluster, che ha accesso per distribuire le proprie proposte in un piccolo namespace, tutto vincolato da RBAC. Non aveva alcun diritto. Eppure il certificato è tornato.

Ora parliamo del pod appositamente preparato. Lo avviamo su qualsiasi immagine. Per esempio, prendiamo debian:jessie.

Abbiamo questa cosa:

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

Cos'è una toleration? I master nel cluster Kubernetes sono solitamente contrassegnati da una cosa chiamata taint ("contaminazione" in inglese). E il punto di questa "contaminazione" è che sui nodi master non possono essere assegnati pod. Ma nulla impedisce a qualunque pod di dichiarare che è tollerante alla "contaminazione". La sezione Toleration dice proprio che se su qualche nodo è impostato NoSchedule, allora il nostro pod è tollerante a tale contaminazione — e non ci sono problemi.

In seguito, diciamo che il nostro pod non è solo tollerante, ma vuole anche entrare specificamente nel nodo master. Perché sui master ci sono le risorse più preziose di cui abbiamo bisogno: tutti i certificati. Quindi diciamo nodeSelector — e abbiamo un'etichetta standard sui master, che consente di selezionare tra tutti i nodi del cluster solo i nodi che sono master.

Con queste due sezioni, il pod arriverà sicuramente sul nodo master. E gli sarà consentito di risiedere lì.

Ma semplicemente arrivare sul master non è sufficiente. Non ci darà nulla. Quindi ora abbiamo queste due cose:

hostNetwork: true 
hostPID: true 

Indichiamo che il nostro pod, che stiamo avviando, vivrà nello spazio dei nomi del kernel, nello spazio dei nomi di rete e nello spazio dei nomi PID. Una volta che il pod è avviato sul master, potrà vedere tutte le interfacce attive e reali di questo nodo, intercettare tutto il traffico e vedere il PID di tutti i processi.

Poi, è una questione semplice. Prendete etcd e leggete ciò che desiderate.

La cosa più interessante è questa funzionalità di Kubernetes, che è presente di default.

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

E la sostanza di tutto ciò è che possiamo, nel pod che stiamo lanciando, anche senza diritti su questo cluster, dire che vogliamo creare un volume di tipo hostPath. Questo significa prendere un percorso dall'host su cui siamo in esecuzione e usarlo come volume. E poi lo chiamiamo name: host. Interamente questo hostPath viene montato all'interno del pod. In questo esempio nella directory /host.

Ripeto ancora una volta. Abbiamo detto al pod di venire sul master, ottenere lì hostNetwork e hostPID, e montare l'intero root del master all'interno di questo pod.

Capite che in Debian abbiamo bash in esecuzione, e questa bash lavora come root. Quindi, abbiamo appena ottenuto i diritti di root sul master, senza avere diritti nel cluster Kubernetes.

La prossima sfida è entrare nel pod nella directory /host/etc/kubernetes/pki, se non sbaglio, prelevare tutti i certificati master del cluster e, di conseguenza, diventare l'amministratore del cluster.

Se ci pensate, questi sono alcuni dei diritti più pericolosi nei pod - indipendentemente dai diritti che ha l'utente:
Stiamo riparando le falle nel cluster Kubernetes. Relazione e trascrizione da DevOpsConf

Se ho i diritti di avviare un pod in qualche spazio dei nomi del cluster, allora questo pod ha di default questi diritti. Posso avviare pod privilegiati, e questo significa praticamente tutti i diritti, quasi come root sul nodo.

La mia preferita è l'Utente root. E Kubernetes ha un'opzione chiamata 'Run As Non-Root'. È una forma di protezione contro gli hacker. Sapete cosa è il 'virus moldavo'? Se siete hacker e siete entrati nel mio cluster Kubernetes, noi, poveri amministratori, chiediamo: 'Per favore, indicate nei vostri pod, con cui hackererete il mio cluster, run as non-root. Altrimenti succederà che lancerete un processo nel vostro pod come root e sarà molto semplice hackerarmi. Proteggetevi, per favore, da voi stessi.'

L'host path volume è, secondo me, il modo più veloce per ottenere il risultato desiderato dal cluster Kubernetes.

Ma cosa fare con tutto questo?

Pensieri che dovrebbero venire a qualsiasi amministratore normale che si confronta con Kubernetes: «Aha, lo sapevo, Kubernetes non funziona. Ha delle falle. E tutto il resto è spazzatura». In realtà, c'è qualcosa chiamato documentazione, e se ci si guarda, c'è una sezione Pod Security Policy.

Questo è un oggetto yaml – che possiamo creare nel cluster Kubernetes – che controlla gli aspetti di sicurezza proprio nella descrizione dei pod. Quindi, di fatto, controlla i permessi per l'uso di vari hostNetwork, hostPID, e determinati tipi di volume che ci sono nei pod al momento del lancio. Con la Pod Security Policy, tutto ciò può essere descritto.

La cosa più interessante della Pod Security Policy è che nel cluster Kubernetes, nessun installatore di PSP è descritto in alcun modo, sono semplicemente disabilitati per impostazione predefinita. La Pod Security Policy viene attivata tramite un plugin di ammissione.

Ok, nel cluster implementiamo la Pod Security Policy, diciamo che abbiamo alcuni pod di servizio nello namespace, a cui hanno accesso solo gli amministratori. Diciamo che negli altri pod i permessi sono limitati. Perché è probabile che gli sviluppatori non abbiano bisogno di avviare pod privilegiati nel vostro cluster.

E a quanto pare tutto va bene. E il nostro cluster Kubernetes non può essere compromesso in due minuti.

C'è un problema. È probabile che, se avete un cluster Kubernetes, ci sia un monitoraggio installato. Mi azzardo a prevedere che se nel vostro cluster c'è un monitoraggio, si chiama Prometheus.

Quello che sto per raccontare sarà valido sia per l'operatore Prometheus che per Prometheus installato in modo standard. Il problema è che se non riesco a ottenere rapidamente un amministratore nel cluster, significa che devo cercare di più. E posso cercare utilizzando il vostro monitoraggio.

Probabilmente, tutti hanno letto gli stessi articoli su Habr, e il monitoraggio si trova nello namespace monitoring. Il chart di Helm per tutti si chiama più o meno allo stesso modo. Suppongo che se fate helm install stable/prometheus, otterrete nomi più o meno identici. E molto probabilmente non dovrò neanche indovinare il nome DNS nel vostro cluster. Perché è standard.

Stiamo riparando le falle nel cluster Kubernetes. Relazione e trascrizione da DevOpsConf

Poi abbiamo un certo dev ns, in cui è possibile avviare un certo pod. E da questo pod è molto facile fare così:

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

prometheus-kube-state-metrics è uno degli exporter di Prometheus che raccoglie metriche dall'API di Kubernetes stesso. Ci sono molti dati su cosa è in esecuzione nel tuo cluster, 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:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a9638ee634989",container_id="docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2853397d7daf08e72c22d3cf8b"} 1

Facendo una semplice richiesta curl da un pod non privilegiato, puoi ottenere queste informazioni. Se non sai in quale versione di Kubernetes sei in esecuzione, te lo dirà facilmente.

E la cosa più interessante è che oltre a contattare kube-state-metrics, puoi contattare direttamente anche Prometheus. Puoi raccogliere metriche da lì. Puoi anche costruire metriche da lì. Anche teoricamente, puoi formulare una richiesta dal cluster a Prometheus che lo spegnerà semplicemente. E la tua monitorizzazione smetterà completamente di funzionare nel cluster.

E qui sorge la domanda, se qualche monitoraggio esterno stia monitorando il tuo monitoraggio. Ho appena ottenuto la possibilità di agire nel cluster Kubernetes senza alcuna conseguenza per me. Non ti accorgerai nemmeno che sto agendo lì, poiché non c'è più monitoraggio.

Proprio come con PSP, c'è la sensazione che il problema sia che tutte queste tecnologie alla moda — Kubernetes, Prometheus — semplicemente non funzionano e siano piene di falle. In realtà non è così.

Esiste una cosa — Network Policy.

Se sei un admin normale, probabilmente sai che per Network Policy si tratta di un altro yaml, ce ne sono già tanti nel cluster. E alcune Network Policies non sono affatto necessarie. E anche se hai letto cosa sia una Network Policy, ovvero un firewall yaml di Kubernetes, che consente di limitare i diritti di accesso tra namespace e tra pod, certamente hai già deciso che un firewall in formato yaml in Kubernetes è sull'ennesima astrazione... No, no. Questo non è affatto necessario.

Anche se ai vostri esperti di sicurezza non è stato detto che con il vostro Kubernetes si può creare un firewall in modo molto semplice e diretto, e se non lo sanno ancora e non vi importunano: «Dai, dai...». In ogni caso, vi serve una Network Policy per chiudere l'accesso ad alcune aree di servizio che possono essere richiamate dal vostro cluster senza alcuna autorizzazione.

Come nell'esempio che ho fornito, è possibile richiamare kube state metrics da qualsiasi namespace nel cluster Kubernetes, senza avere alcun permesso. Le politiche di rete hanno bloccato l'accesso da tutti gli altri namespace al namespace di monitoraggio e, in pratica, è tutto: nessun accesso, nessun problema. In tutti i chart disponibili, sia del prometeo standard che di quello incluso nell'operatore, c'è semplicemente un'opzione in values di helm per abilitare le politiche di rete. Basta attivarle e funzioneranno.

C'è però un problema. Essendo un normale amministratore con la barba, probabilmente hai pensato che le politiche di rete non siano necessarie. E dopo aver letto vari articoli su risorse come Habr, hai concluso che flannel, soprattutto in modalità host-gateway, sia la migliore opzione che puoi scegliere.

Cosa fare?

Puoi provare a ridistribuire la soluzione di rete che hai nel tuo cluster Kubernetes, tentando di sostituirla con qualcosa di più funzionale. Ad esempio, Calico. Ma voglio subito dirti che cambiare la soluzione di rete in un cluster Kubernetes attivo è un compito piuttosto non triviale. L'ho affrontato due volte (entrambe le volte, però, teoricamente), ma abbiamo anche mostrato su Slurm come farlo. Per i nostri corsisti abbiamo dimostrato come cambiare la soluzione di rete in un cluster Kubernetes. In linea di massima, puoi provare a farlo senza downtime nel cluster di produzione, ma probabilmente non ci riuscirai.

E il problema, in realtà, si risolve molto facilmente. Nel cluster ci sono certificati, e tu sai che questi certificati scadranno dopo un anno. E di solito, la soluzione standard con i certificati in un cluster è: perché preoccuparsi, alziamo un nuovo cluster accanto, lasciamo scadere il vecchio e ridistribuiamo tutto. A dire il vero, quando scadrà, il sistema resterà inattivo per un giorno, ma avremo un nuovo cluster.

Quando alzerai il nuovo cluster, inserisci Calico al posto di flannel.

Cosa fare se i vostri certificati sono emessi per cento anni e non avete intenzione di ridistribuire il cluster? Esiste uno strumento chiamato Kube-RBAC-Proxy. È uno sviluppo molto interessante, in quanto permette di integrarsi come container sidecar a qualsiasi pod nel cluster Kubernetes. E in effetti aggiunge autorizzazione a questo pod tramite RBAC di Kubernetes stesso.

C'è un problema però. In passato, nella versione dell'operatore Prometheus, questa soluzione Kube-RBAC-Proxy era integrata. Ma poi è stata rimossa. Ora le versioni moderne si basano sul fatto che avete una network policy e chiudete l'accesso utilizzando essa. Pertanto, sarà necessario riscrivere un po' il chart. In realtà, se andate a questo repository, troverete esempi su come utilizzarlo come sidecars, e sarà necessario riscrivere il chart il meno possibile.

C'è anche un altro piccolo problema. Non solo Prometheus fornisce le sue metriche a chiunque. Anche tutti i componenti del cluster Kubernetes possono fornire le proprie metriche.

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

Quindi vi mostrerò rapidamente due modi in cui puoi compromettere la salute di un cluster Kubernetes.

Scommetto che riderete quando vi racconterò di questo, sono due casi della vita reale.

Primo metodo. Esaurimento delle risorse.

Avviamo un altro pod speciale. Avrà una sezione simile a questa.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

Come sapete, le richieste sono la quantità di CPU e memoria riservata per specifici pod con richieste. Se abbiamo un host quad-core nel cluster Kubernetes, e arriva un pod con una richiesta di quattro CPU, significa che non può arrivare nessun altro pod con richieste su questo host.

Se avviassi un pod di questo tipo, poi eseguirei il comando:

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

Allora nessun altro potrà essere distribuito nel cluster Kubernetes. Perché tutte le nodi esauriranno le richieste. E così facendo fermerò il vostro cluster Kubernetes. Se facessi questo la sera, potrei fermare i deploy per un bel po' di tempo.

Se diamo un'altra occhiata alla documentazione di Kubernetes, vedremo una cosa chiamata Limit Range. Essa stabilisce le risorse per gli oggetti del cluster. Puoi scrivere un oggetto Limit Range in yaml, applicarlo a specifici namespace — e poi in quel namespace puoi dire che hai risorse per i pod di tipo predefinito, massimo e minimo.

Con questa cosa possiamo limitare gli utenti in specifici namespace di prodotto delle squadre nelle loro possibilità di indicare le loro porcherie nei pod. Ma sfortunatamente, anche se dici all'utente che non può avviare i pod con richieste superiori a una CPU, esiste un comando meraviglioso chiamato scale, o tramite dashboard possono fare scale.

E da qui deriva il secondo modo. Avviamo 11 111 111 111 111 pod. Sono undici miliardi. Non perché io abbia inventato un numero del genere, ma perché l'ho visto io stesso.

Una storia reale. Tardi la sera stavo per lasciare l'ufficio. Vedo un gruppo di sviluppatori che sta facendo qualcosa di frenetico con i portatili in un angolo. Mi avvicino ai ragazzi e chiedo: «Cosa è successo?»

Poco prima, intorno alle nove di sera, uno degli sviluppatori stava per andare a casa. E ha pensato: «Adesso scalerò la mia applicazione a uno». Ha premuto uno, ma internet ha rallentato un po'. Ha premuto di nuovo su uno, ha schiacciato uno, ha cliccato su Invio. Ha provato a toccare tutto ciò che poteva. A quel punto, internet si è ripreso — e tutto ha iniziato a scalare verso quel numero.

D'altronde, questa storia non stava accadendo su Kubernetes, in quel momento era Nomad. È finita così, che dopo un'ora dei nostri tentativi di fermare Nomad dalle persistenti tentativi di scalare, Nomad ha risposto che non avrebbe smesso di scalare e non avrebbe fatto nient'altro. «Sono stanco, me ne vado». E si è chiuso.

Naturalmente ho provato a fare lo stesso su Kubernetes. Undici miliardi di pod non hanno fatto felice Kubernetes, ha detto: «Non posso. Supera i limiti interni». Ma 1 000 000 000 pod ce l'ha fatta.

In risposta a un miliardo di pod, Kubernetes non è andato in crash. Ha davvero iniziato a scalare. Più il processo avanzava, più tempo impiegava per creare nuovi pod. Tuttavia, il processo continuava. L'unico problema è che, se posso lanciare pod senza limiti nel mio namespace, anche senza richieste e limiti, posso lanciare un numero tale di pod con determinate attività che le risorse delle nodi iniziano a saturarsi in termini di memoria e CPU. Quando avvio così tanti pod, le informazioni da essi devono arrivare allo storage, ovvero etcd. E quando troppe informazioni arrivano lì, lo storage inizia a restituire dati troppo lentamente — e Kubernetes subisce dei rallentamenti.

Ma c'è un altro problema… Come sapete, gli elementi di controllo di Kubernetes non sono un'unica entità centrale, ma diversi componenti. Ci sono in particolare il controller manager, lo scheduler e così via. Tutti questi componenti inizieranno a eseguire simultaneamente lavoro inutile e confuso, che col tempo inizierà a richiedere sempre più tempo. Il controller manager creerà nuovi pod. Lo scheduler cercherà di trovare loro un nuovo nodo. È probabile che nuovi nodi nel vostro cluster finiscano presto. Il cluster Kubernetes inizierà a funzionare sempre più lentamente.

Ma ho deciso di spingermi oltre. Come sapete, in Kubernetes esiste una cosa chiamata servizio. Beh, di default nei vostri cluster, molto probabilmente, il servizio funziona tramite IP tables.

Ad esempio, se lanciate un miliardo di pod, e poi con uno script costringete Kubernetes 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 verranno generati tutto il tempo nuovi e nuovi regole iptables. In particolare, per ogni servizio verranno generati un miliardo di regole iptables.

Ho testato tutto questo su diverse migliaia, fino a decine. E il problema è che già a questo livello è piuttosto problematico fare ssh su un nodo. Perché i pacchetti, passando attraverso così tante catene, iniziano a comportarsi male.

E anche questo si risolve grazie a Kubernetes. C'è un oggetto chiamato Resource quota. Imposta il numero di risorse e oggetti disponibili per uno specifico namespace nel cluster. Possiamo creare un oggetto yaml in ogni namespace del cluster Kubernetes. Con questo oggetto possiamo indicare che per questo namespace è riservata una certa quantità di richieste, limiti, e poi possiamo dire che in questo namespace possono essere creati 10 servizi e 10 pod. E il developer può divertirsi anche la sera. Kubernetes gli dirà: "Non puoi scalare i tuoi pod a quel numero, perché supera la quota delle risorse". Ecco, il problema è risolto. Documentazione qui.

Un problema sorge in relazione a questo. Senti quanto sia difficile creare un namespace in Kubernetes. Per crearlo, dobbiamo considerare un sacco di cose.

Resource quota + Limit Range + RBAC
• Creiamo il namespace
• Creiamo all'interno limitrange
• Creiamo all'interno resourcequota
• Creiamo serviceaccount per CI
• Creiamo rolebinding per CI e utenti
• Facoltativamente avviamo i pod di servizio necessari

Quindi, cogliendo l'occasione, vorrei condividere le mie realizzazioni. C'è una cosa chiamata operatore SDK. È un modo per scrivere operatori per Kubernetes all'interno del cluster. Puoi scrivere operatori usando Ansible.

Inizialmente avevamo scritto in Ansible, poi ho visto che esisteva l'operatore SDK e ho riscritto il ruolo Ansible in un operatore. Questo operatore consente di creare nel cluster Kubernetes un oggetto chiamato comando. All'interno del comando, permette di descrivere in yaml l'ambiente per questo comando. E all'interno dell'ambiente del comando permette di descrivere che stiamo riservando un certo numero di risorse.

Piccola semplificazione di tutto questo processo complesso.

E in conclusione. Cosa fare con tutto questo?
Primo. La Pod Security Policy è buona. E nonostante nessuno dei fornitori di Kubernetes li utilizzi ancora oggi, è comunque necessario usarli nei tuoi cluster.

La Network Policy non è un'altra funzione superflua. È qualcosa di realmente necessario nel cluster.

LimitRange/ResourceQuota — è tempo di usarli. Abbiamo iniziato a usarli tempo fa, e sono stato a lungo convinto che tutti li adottassero. Si è rivelato che è raro.

Oltre a quanto ho menzionato durante la presentazione, ci sono funzionalità non documentate che consentono di attaccare il cluster. È uscito recentemente una grande analisi delle vulnerabilità di Kubernetes.

Alcune cose sono così tristi e fastidiose. Come, ad esempio, in alcune condizioni le kubelet nel cluster Kubernetes possono restituire il contenuto della directory dei warlocks a un utente non autorizzato.

Qui ci sono istruzioni su come riprodurre tutto ciò di cui ho parlato. Ci sono file con esempi di produzione, come appare ResourceQuota, Pod Security Policy. E tutto questo può essere toccato.

Grazie a tutti.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster