This is the multi-page printable view of this section. Click here to print.
Architettura di Kubernetes
- 1: Nodi
- 2: Comunicazione Control Plane - Nodo
- 3: Concetti alla base del Cloud Controller Manager
- 4: Controller
1 - Nodi
Un nodo è una macchina worker in Kubernetes, precedentemente noto come minion
. Un nodo
può essere una VM o una macchina fisica, a seconda del cluster. Ogni nodo contiene
i servizi necessari per eseguire pods ed è gestito dal master
componenti. I servizi su un nodo includono il container runtime, kubelet e kube-proxy. Vedere
The Kubernetes Node sezione in
documento di progettazione dell'architettura per maggiori dettagli.
Node Status
Lo stato di un nodo contiene le seguenti informazioni:
Ogni sezione è descritta in dettaglio di seguito.
Addresses
L'utilizzo di questi campi varia a seconda del provider cloud o della configurazione bare metal.
- HostName: il nome host riportato dal kernel del nodo. Può essere sovrascritto tramite il parametro kubelet
--hostname-override
. - ExternalIP: in genere l'indirizzo IP del nodo che è esternamente instradabile (disponibile dall'esterno del cluster).
- InternalIP: in genere l'indirizzo IP del nodo che è instradabile solo all'interno del cluster.
Condition
l campo conditions
descrive lo stato di tutti i nodi Running
.
Condizione del nodo | Descrizione |
---|---|
OutOfDisk |
True se lo spazio disponibile sul nodo non è sufficiente per aggiungere nuovi pod, altrimenti False |
Pronto |
True se il nodo è integro e pronto ad accettare i pod, False se il nodo non è integro e non accetta i pod e Sconosciuto se il controller del nodo non è stato ascoltato dal nodo nell'ultimo nodo-monitor -grace-periodo (il valore predefinito è 40 secondi) |
MemoryPressure |
Vero se la pressione esiste sulla memoria del nodo, ovvero se la memoria del nodo è bassa; altrimenti False |
PIDPressure |
True se la pressione esiste sui processi, ovvero se ci sono troppi processi sul nodo; altrimenti False |
DiskPressure |
True se esiste una pressione sulla dimensione del disco, ovvero se la capacità del disco è bassa; altrimenti False |
NetworkUnavailable |
True se la rete per il nodo non è configurata correttamente, altrimenti False |
La condizione del nodo è rappresentata come un oggetto JSON. Ad esempio, la seguente risposta descrive un nodo sano.
"conditions": [
{
"type": "Ready",
"status": "True"
}
]
Se lo stato della condizione Ready rimane Unknown
o False
per un tempo superiore a pod-eviction-timeout
, viene passato un argomento al gestore-kube-controller e tutti i pod sul nodo sono programmati per la cancellazione dal controller del nodo. La durata predefinita del timeout di sfratto è di ** cinque minuti **. In alcuni casi, quando il nodo non è raggiungibile, l'apiserver non è in grado di comunicare con kubelet sul nodo. La decisione di eliminare i pod non può essere comunicata al kubelet fino a quando non viene ristabilita la comunicazione con l'apiserver. Nel frattempo, i pod che sono programmati per la cancellazione possono continuare a funzionare sul nodo partizionato.
Nelle versioni di Kubernetes precedenti alla 1.5, il controllore del nodo forzerebbe la cancellazione
questi pod non raggiungibili dall'apiserver. Tuttavia, in 1.5 e versioni successive, il controller del nodo non impone l'eliminazione dei pod finché non lo è
confermato che hanno smesso di funzionare nel cluster. Puoi vedere i pod che potrebbero essere in esecuzione su un nodo irraggiungibile
lo stato Terminating
o Unknown
. Nei casi in cui Kubernetes non può dedurre dall'infrastruttura sottostante se ha un nodo
lasciato permanentemente un cluster, potrebbe essere necessario che l'amministratore del cluster elimini manualmente l'oggetto nodo. Cancellare l'oggetto nodo da
Kubernetes fa sì che tutti gli oggetti Pod in esecuzione sul nodo vengano eliminati dal server apis e libera i loro nomi.
Nella versione 1.12, la funzione TaintNodesByCondition
è promossa in versione beta, quindi il controller del ciclo di vita del nodo crea automaticamente
taints che rappresentano le condizioni.
Allo stesso modo lo schedulatore ignora le condizioni quando si considera un nodo; anziché
guarda le tinte del Nodo e le tolleranze di un Pod.
Ora gli utenti possono scegliere tra il vecchio modello di pianificazione e un nuovo modello di pianificazione più flessibile. Un pod che non ha tolleranze viene pianificato in base al vecchio modello. Ma un baccello quello tollera che i nodi di un nodo particolare possano essere programmati su quel nodo.
Attenzione:
ESe si disabilita questa funzione si crea un leggero ritardo tra il tempo in cui una condizione viene osservata e quando viene creata una contaminazione. Questo ritardo è in genere inferiore a un secondo, ma può aumentare il numero di pod pianificati correttamente ma rifiutati dal kubelet.Capacity
Descrive le risorse disponibili sul nodo: CPU, memoria e il massimo numero di pod che possono essere programmati sul nodo.
Info
Informazioni generali sul nodo, come la versione del kernel, la versione di Kubernetes (versione kubelet e kube-proxy), versione Docker (se utilizzata), nome del sistema operativo. Le informazioni sono raccolte da Kubelet dal nodo.
Management
Unlike pods and services, a node is not inherently created by Kubernetes: it is created externally by cloud providers like Google Compute Engine, or it exists in your pool of physical or virtual machines. So when Kubernetes creates a node, it creates an object that represents the node. After creation, Kubernetes checks whether the node is valid or not. For example, if you try to create a node from the following content:
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
Kubernetes crea un oggetto nodo internamente (la rappresentazione), e
convalida il nodo tramite il controllo dello stato in base al campo metadata.name
. Se il nodo è valido - cioè, se necessario
i servizi sono in esecuzione, è idoneo per l'esecuzione di un pod. Altrimenti, lo è
ignorato per qualsiasi attività del cluster finché non diventa valido.
Nota:
Kubernetes mantiene l'oggetto per il nodo non valido e continua a verificare se diventa valido. È necessario eliminare esplicitamente l'oggetto Nodo per interrompere questo processo.Attualmente, ci sono tre componenti che interagiscono con il nodo di Kubernetes interfaccia: controller del nodo, kubelet e kubectl.
Node Controller
Il controller del nodo è un componente master di Kubernetes che gestisce vari aspetti dei nodi.
Il controller del nodo ha più ruoli nella vita di un nodo. Il primo sta assegnando a Blocco CIDR sul nodo quando è registrato (se l'assegnazione CIDR è attivata).
Il secondo è mantenere aggiornato l'elenco interno dei nodi del controller del nodo l'elenco delle macchine disponibili del provider cloud. Quando si corre in una nuvola ambiente, ogni volta che un nodo non è sano, il controller del nodo chiede al cloud fornitore se la VM per quel nodo è ancora disponibile. Altrimenti, il nodo controller cancella il nodo dalla sua lista di nodi.
Il terzo è il monitoraggio della salute dei nodi. Il controller del nodo è responsabile dell'aggiornamento della condizione NodeReady di NodeStatus a Condizione Notata quando un nodo diventa irraggiungibile (ad esempio, il controller del nodo si arresta ricevere heartbeat per qualche motivo, ad es. a causa del fatto che il nodo si trova in basso), e poi in seguito sfratto tutti i pod dal nodo (usando una terminazione elegante) se il nodo continua essere irraggiungibile. (I timeout predefiniti sono 40 secondi per iniziare la segnalazione ConditionUnknown e 5m dopo di ciò per iniziare a sfrattare i pod.)
Il controller del nodo controlla lo stato di ogni nodo ogni --node-monitor-period
secondi.
Nelle versioni di Kubernetes precedenti alla 1.13, NodeStatus è l'heartbeat di
nodo. A partire da Kubernetes 1.13, la funzionalità di lease del nodo viene introdotta come un
funzione alfa (porta caratteristica NodeLease
,
KEP-0009).
Quando la funzione di lease del nodo è abilitata, ogni nodo ha un oggetto Lease
associato in
spazio dei nomi kube-node-lease
che viene rinnovato periodicamente dal nodo ed entrambi
NodeStatus e lease del nodo vengono considerati heartbeat dal nodo. Locazioni di nodi
si rinnovano frequentemente mentre NodeStatus viene segnalato solo dal nodo al master
quando c'è qualche cambiamento o è passato abbastanza tempo (il default è 1 minuto, che
è più lungo del timeout predefinito di 40 secondi per i nodi non raggiungibili). Da
il lease del nodo è molto più leggero di NodeStatus, questa caratteristica rende nodo
battito cardiaco significativamente più economico sia per la scalabilità che per le prestazioni
prospettive.
In Kubernetes 1.4, abbiamo aggiornato la logica del controller del nodo per gestire meglio casi in cui un numero elevato di nodi ha problemi con il raggiungimento del master (ad esempio perché il master ha problemi di rete). A partire da 1.4, il nodo controller controlla lo stato di tutti i nodi nel cluster quando si effettua un decisione sullo sfratto del pod.
Nella maggior parte dei casi, il controller del nodo limita il tasso di sfratto a
--node-eviction-rate
(default 0.1) al secondo, il che significa che non eliminerà i pod
da più di 1 nodo per 10 secondi.
Il comportamento di sfratto del nodo cambia quando un nodo in una determinata zona di disponibilità
diventa malsano. Il controller del nodo controlla quale percentuale di nodi nella zona
sono malsani (la condizione NodeReady è ConditionUnknown o ConditionFalse) a
lo stesso tempo. Se la frazione di nodi malsani è almeno
--unhealthy-zone-threshold
(default 0.55) quindi il tasso di sfratto è ridotto:
se il cluster è piccolo (cioè ha meno o uguale a
--large-cluster-size-threshold
nodes - default 50) quindi gli sfratti sono
fermato, altrimenti il tasso di sfratto è ridotto a
--secondary-node-eviction-rate
(default 0.01) al secondo.
La ragione per cui le politiche sono implementate per zona di disponibilità è perché una zona di disponibilità potrebbe divenire partizionato dal master mentre gli altri rimangono connessi. Se il tuo cluster non si estende su più zone di disponibilità del provider cloud, quindi c'è solo una zona di disponibilità (l'intero cluster).
Un motivo chiave per diffondere i nodi tra le zone di disponibilità è che
il carico di lavoro può essere spostato in zone sane quando un'intera zona viene interrotta.
Pertanto, se tutti i nodi in una zona non sono sani, il controller del nodo viene sottratto a
la normale frequenza --node-eviction-rate
. Il caso d'angolo è quando tutte le zone sono
completamente malsano (cioè non ci sono nodi sani nel cluster). In tale
caso, il controller del nodo presuppone che ci sia qualche problema con il master
connettività e interrompe tutti gli sfratti fino a quando non viene ripristinata la connettività.
A partire da Kubernetes 1.6, il NodeController è anche responsabile della rimozione
i pod che sono in esecuzione sui nodi con NoExecute
, quando i pod non tollerano
i taints. Inoltre, come caratteristica alfa che è disabilitata per impostazione predefinita, il
NodeController è responsabile per l'aggiunta di taints corrispondenti ai problemi del nodo come
nodo irraggiungibile o non pronto. Vedi questa documentazione
per i dettagli su NoExecute
taints e la funzione alpha.
partire dalla versione 1.8, il controller del nodo può essere reso responsabile della creazione di taints che rappresentano le condizioni del nodo. Questa è una caratteristica alfa della versione 1.8.
Self-Registration of Nodes
Quando il flag kubelet --register-node
è vero (il default), il kubelet tenterà di farlo
registrarsi con il server API. Questo è il modello preferito, utilizzato dalla maggior parte delle distro.
Per l'autoregistrazione, il kubelet viene avviato con le seguenti opzioni:
--kubeconfig
- Percorso delle credenziali per autenticarsi sull'apiserver.--cloud-provider
- Come parlare con un provider cloud per leggere i metadati su se stesso.--register-node
- Si registra automaticamente con il server API.--register-with-taints
- Registra il nodo con la lista data di taints (separati da virgola<chiave> = <valore>: <effetto>
). No-op seregister-node
è falso.--node-ip
- Indirizzo IP del nodo.--node-labels
- Etichette da aggiungere quando si registra il nodo nel cluster (vedere le restrizioni dell'etichetta applicate dal plugin di accesso NodeRestriction in 1.13+).--node-status-update-frequency
- Specifica la frequenza con cui kubelet invia lo stato del nodo al master
Quando Node authorization mode e NodeRestriction admission plugin sono abilitati, kubelets è autorizzato solo a creare / modificare la propria risorsa nodo.
Manual Node Administration
Un amministratore di cluster può creare e modificare oggetti nodo.
Se l'amministratore desidera creare manualmente oggetti nodo, imposta il flag kubelet
--Register nodo = false
.
L'amministratore può modificare le risorse del nodo (indipendentemente dall'impostazione di --register-node
).
Le modifiche includono l'impostazione di etichette sul nodo e la marcatura non programmabile.
Le etichette sui nodi possono essere utilizzate insieme ai selettori di nodo sui pod per controllare la pianificazione, per esempio. vincolare un pod per poter essere eseguito solo su un sottoinsieme di nodi.
Contrassegnare un nodo come unschedulable impedisce a nuovi pod di essere programmati per quello nodo, ma non ha alcun effetto sui pod esistenti sul nodo. Questo è utile come fase preparatoria prima del riavvio del nodo, ecc. Ad esempio, per contrassegnare un nodo unschedulable, esegui questo comando:
kubectl cordon $NODENAME
Nota:
I pod creati da un controller DaemonSet bypassano lo scheduler di Kubernetes e non rispettare l'attributo unschedulable su un nodo. Questo presuppone che i demoni appartengano la macchina anche se viene scaricata dalle applicazioni mentre si prepara per un riavvio.Node capacity
La capacità del nodo (numero di cpu e quantità di memoria) è parte dell'oggetto nodo. Normalmente, i nodi si registrano e segnalano la loro capacità durante la creazione dell'oggetto nodo. Se stai facendo amministrazione manuale del nodo, quindi devi impostare il nodo capacità quando si aggiunge un nodo.
Lo scheduler di Kubernetes garantisce che ci siano risorse sufficienti per tutti i pod su un nodo. esso controlla che la somma delle richieste di container sul nodo non sia maggiore della capacità del nodo. esso include tutti i contenitori avviati da kubelet, ma non i contenitori avviati direttamente dal contenitore runtime né qualsiasi processo eseguito all'esterno dei contenitori.
Se si desidera riservare esplicitamente risorse per processi non Pod, seguire questo tutorial su riserva risorse per i demoni di sistema.
API Object
Il nodo è una risorsa di livello superiore nell'API REST di Kubernetes. Maggiori dettagli su L'oggetto API può essere trovato a: Node API object.
2 - Comunicazione Control Plane - Nodo
Questo documento cataloga le connessioni tra il piano di controllo (control-plane), in realtà l'apiserver, e il cluster Kubernetes. L'intento è di consentire agli utenti di personalizzare la loro installazione per rafforzare la configurazione di rete affinché il cluster possa essere eseguito su una rete pubblica (o su IP completamente pubblici resi disponibili da un fornitore di servizi cloud).
Dal Nodo al control-plane
Kubernetes adotta un pattern per le API di tipo "hub-and-spoke". Tutte le chiamate delle API eseguite sui vari nodi sono effettuate verso l'apiserver (nessuno degli altri componenti principali è progettato per esporre servizi remoti). L'apiserver è configurato per l'ascolto di connessioni remote su una porta HTTPS protetta (443) con una o più forme di autenticazioni client abilitate. Si dovrebbero abilitare una o più forme di autorizzazioni, in particolare nel caso in cui siano ammesse richieste anonime o token legati ad un account di servizio (service account).
Il certificato pubblico (public root certificate) relativo al cluster corrente deve essere fornito ai vari nodi di modo che questi possano connettersi in modo sicuro all'apiserver insieme alle credenziali valide per uno specifico client. Ad esempio, nella configurazione predefinita di un cluster GKE, le credenziali del client fornite al kubelet hanno la forma di un certificato client. Si veda inizializzazione TLS del kubelet TLS per la fornitura automatica dei certificati client al kubelet.
I Pod che desiderano connettersi all'apiserver possono farlo in modo sicuro sfruttando un account di servizio in modo che Kubernetes inserisca automaticamente il certificato pubblico di radice e un token valido al portatore (bearer token) all'interno Pod quando questo viene istanziato.
In tutti i namespace è configurato un Service con nome kubernetes
con un indirizzo IP virtuale che viene reindirizzato (tramite kube-proxy) all'endpoint HTTPS dell'apiserver.
Anche i componenti del piano d controllo comunicano con l'apiserver del cluster su di una porta sicura esposta da quest'ultimo.
Di conseguenza, la modalità operativa predefinita per le connessioni dai nodi e dai Pod in esecuzione sui nodi verso il control-plane è protetta da un'impostazione predefinita e può essere eseguita su reti non sicure e/o pubbliche.
Dal control-plane al nodo
Esistono due percorsi di comunicazione principali dal control-plane (apiserver) verso i nodi. Il primo è dall'apiserver verso il processo kubelet in esecuzione su ogni nodo nel cluster. Il secondo è dall'apiserver a ciascun nodo, Pod, o servizio attraverso la funzionalità proxy dell'apiserver.
Dall'apiserver al kubelet
Le connessioni dall'apiserver al kubelet vengono utilizzate per:
- Prendere i log relativi ai vari Pod.
- Collegarsi (attraverso kubectl) ai Pod in esecuzione.
- Fornire la funzionalità di port-forwarding per i kubelet.
Queste connessioni terminano all'endpoint HTTPS del kubelet. Di default, l'apiserver non verifica il certificato servito dal kubelet, il che rende la connessione soggetta ad attacchi man-in-the-middle, e tale da essere considerato non sicuro (unsafe) se eseguito su reti non protette e/o pubbliche.
Per verificare questa connessione, si utilizzi il parametro --kubelet-certificate-authority
al fine di fornire all'apiserver un insieme di certificati radice da utilizzare per verificare il
il certificato servito dal kubelet.
Se questo non è possibile, si usi un tunnel SSH tra l'apiserver e il kubelet, se richiesto, per evitare il collegamento su una rete non protetta o pubblica.
In fine, l'autenticazione e/o l'autorizzazione del kubelet dovrebbe essere abilitate per proteggere le API esposte dal kubelet.
Dall'apiserver ai nodi, Pod, e servizi
Le connessioni dall'apiserver verso un nodo, Pod o servizio avvengono in modalità predefinita su semplice connessione HTTP e quindi non sono né autenticate né criptata. Queste connessioni possono essere eseguite su una connessione HTTPS sicura mediante il prefisso https:
al nodo, Pod o nome del servizio nell'URL dell'API, ma non valideranno il certificato fornito dall'endpoint HTTPS né forniranno le credenziali del client così anche se la connessione verrà criptata, non fornirà alcuna garanzia di integrità. Non è attualmente sicuro eseguire queste connessioni su reti non protette e/o pubbliche.
I tunnel SSH
Kubernetes supporta i tunnel SSH per proteggere la comunicazione tra il control-plane e i nodi. In questa configurazione, l'apiserver inizializza un tunnel SSH con ciascun nodo del cluster (collegandosi al server SSH in ascolto sulla porta 22) e fa passare tutto il traffico verso il kubelet, il nodo, il Pod, o il servizio attraverso questo tunnel. Questo tunnel assicura che il traffico non sia esposto al di fuori della rete su cui sono in esecuzioni i vari nodi.
I tunnel SSH sono al momento deprecati ovvero non dovrebbero essere utilizzati a meno che ci siano delle esigenze particolari. Il servizio Konnectivity
è pensato per rimpiazzare questo canale di comunicazione.
Il servizio Konnectivity
Kubernetes v1.18 [beta]
Come rimpiazzo dei tunnel SSH, il servizio Konnectivity fornisce un proxy a livello TCP per la comunicazione tra il control-plane e il cluster. Il servizio Konnectivity consiste in due parti: il Konnectivity server e gli agenti Konnectivity, in esecuzione rispettivamente sul control-plane e sui vari nodi. Gli agenti Konnectivity inizializzano le connessioni verso il server Konnectivity e mantengono le connessioni di rete. Una volta abilitato il servizio Konnectivity, tutto il traffico tra il control-plane e i nodi passa attraverso queste connessioni.
Si può fare riferimento al tutorial per il servizio Konnectivity per configurare il servizio Konnectivity all'interno del cluster
3 - Concetti alla base del Cloud Controller Manager
Il concetto di CCM (cloud controller manager), da non confondere con il binario, è stato originariamente creato per consentire di sviluppare Kubernetes indipendentemente dall'implementazione dello specifico cloud provider. Il cloud controller manager viene eseguito insieme ad altri componenti principali come il Kubernetes controller manager, il server API e lo scheduler. Può anche essere avviato come addon di Kubernetes, nel qual caso viene eseguito su Kubernetes.
Il design del cloud controller manager è basato su un meccanismo di plug-in che consente ai nuovi provider cloud di integrarsi facilmente con Kubernetes creando un plug-in. Sono in atto programmi per l'aggiunta di nuovi provider di cloud su Kubernetes e per la migrazione dei provider che usano il vecchio metodo a questo nuovo metodo.
Questo documento discute i concetti alla base del cloud controller manager e fornisce dettagli sulle funzioni associate.
Ecco l'architettura di un cluster Kubernetes senza il gestore del controller cloud:
Architettura
Nel diagramma precedente, Kubernetes e il provider cloud sono integrati attraverso diversi componenti:
- Kubelet
- Kubernetes controller manager
- Kubernetes API server
Il CCM consolida tutta la logica dipendente dal cloud presente nei tre componenti precedenti, per creare un singolo punto di integrazione con il cloud. La nuova architettura con il CCM si presenta così:
Componenti del CCM
Il CCM divide alcune funzionalità del Kubernetes controller manager (KCM) e le esegue in un differente processo. In particolare, toglie dal KCM le integrazioni con il cloud specifico. Il KCM ha i seguenti controller che dipendono dal cloud specifico:
- Node controller
- Volume controller
- Route controller
- Service controller
Nella versione 1.9, il CCM esegue i seguenti controller dall'elenco precedente:
- Node controller
- Route controller
- Service controller
Nota:
È stato deliberatamente deciso di non spostare il Volume controller nel CCM. Data la complessità del Volume controller e gli sforzi già fatti per astrarre le logiche specifiche dei singoli fornitori, è stato deciso che il Volume controller non verrà spostato nel CCM.Il piano originale per supportare i volumi utilizzando il CCM era di utilizzare Flex per supportare volumi collegabili. Tuttavia, una implementazione parallela, nota come CSI è stata designata per sostituire Flex.
Considerando queste evoluzioni, abbiamo deciso di adottare un approccio intermedio finché il CSI non è pronto.
Funzioni del CCM
Il CCM eredita le sue funzioni da componenti di Kubernetes che dipendono da uno specifico provider di cloud. Questa sezione è strutturata sulla base di tali componenti.
1. Kubernetes controller manager
La maggior parte delle funzioni del CCM deriva dal KCM. Come menzionato nella sezione precedente, CCM esegue i seguenti cicli di controllo:
- Node controller
- Route controller
- Service controller
Node controller
Il Node controller è responsabile per l'inizializzazione di un nodo ottenendo informazioni sui nodi in esecuzione nel cluster dal provider cloud. Il controller del nodo esegue le seguenti funzioni:
- Inizializzare un nodo con le label zone/region specifiche per il cloud in uso.
- Inizializzare un nodo con le specifiche, ad esempio, tipo e dimensione specifiche del cloud in uso.
- Ottenere gli indirizzi di rete del nodo e l'hostname.
- Nel caso in cui un nodo non risponda, controlla il cloud per vedere se il nodo è stato cancellato dal cloud. Se il nodo è stato eliminato dal cloud, elimina l'oggetto Nodo di Kubernetes.
Route controller
Il Route controller è responsabile della configurazione delle route nel cloud in modo che i container su nodi differenti del cluster Kubernetes possano comunicare tra loro. Il Route controller è utilizzabile solo dai cluster su Google Compute Engine.
Service Controller
Il Service Controller rimane in ascolto per eventi di creazione, aggiornamento ed eliminazione di servizi. In base allo stato attuale dei servizi in Kubernetes, configura i bilanciatori di carico forniti dal cloud (come gli ELB, i Google LB, o gli Oracle Cloud Infrastructure LB) per riflettere lo stato dei servizi in Kubernetes. Inoltre, assicura che i back-end dei bilanciatori di carico forniti dal cloud siano aggiornati.
2. Kubelet
Il Node Controller contiene l'implementazione dipendente dal cloud della kubelet. Prima dell'introduzione del CCM, la kubelet era responsabile dell'inizializzazione di un nodo con dettagli dipendenti dallo specifico cloud come gli indirizzi IP, le label region/zone e le informazioni sul tipo di istanza. L'introduzione del CCM ha spostato questa operazione di inizializzazione dalla kubelet al CCM.
In questo nuovo modello, la kubelet inizializza un nodo senza informazioni specifiche del cloud. Tuttavia, aggiunge un blocco al nodo appena creato che rende il nodo non selezionabile per eseguire container finché il CCM non inizializza il nodo con le informazioni specifiche del cloud. Il CCM rimuove quindi questo blocco.
Sistema a plug-in
Il cloud controller manager utilizza le interfacce di Go per consentire l'implementazione di implementazioni di qualsiasi cloud. In particolare, utilizza l'interfaccia CloudProvider definita qui.
L'implementazione dei quattro controller generici evidenziati sopra, alcune strutture, l'interfaccia cloudprovider condivisa rimarranno nel core di Kubernetes. Le implementazioni specifiche per i vari cloud saranno costruite al di fuori del core e implementeranno le interfacce definite nel core.
Per ulteriori informazioni sullo sviluppo di plug-in, consultare Developing Cloud Controller Manager.
Autorizzazione
Questa sezione dettaglia l'accesso richiesto dal CCM sui vari API objects per eseguire le sue operazioni.
Node controller
Il Node controller funziona solo con oggetti di tipo Node. Richiede l'accesso completo per ottenere, elencare, creare, aggiornare, applicare patch, guardare ed eliminare oggetti di tipo Node.
v1/Node:
- Get
- List
- Create
- Update
- Patch
- Watch
- Delete
Route controller
Il Route controller ascolta la creazione dell'oggetto Node e configura le rotte in modo appropriato. Richiede l'accesso in lettura agli oggetti di tipo Node.
v1/Node:
- Get
Service controller
Il Service controller resta in ascolto per eventi di creazione, aggiornamento ed eliminazione di oggetti di tipo Servizi, e configura gli endpoint per tali Servizi in modo appropriato.
Per accedere ai Servizi, è necessario il permesso per list e watch. Per aggiornare i Servizi, sono necessari i permessi patch e update.
Per impostare gli endpoint per i Servizi, richiede i permessi create, list, get, watch, e update.
v1/Service:
- List
- Get
- Watch
- Patch
- Update
Others
L'implementazione del core di CCM richiede l'accesso per creare eventi e, per garantire operazioni sicure, richiede l'accesso per creare ServiceAccounts.
v1/Event:
- Create
- Patch
- Update
v1/ServiceAccount:
- Create
L'RBAC ClusterRole per il CCM ha il seguente aspetto:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cloud-controller-manager
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- '*'
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- ""
resources:
- services
verbs:
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- get
- list
- watch
- update
Vendor Implementations
I seguenti fornitori di cloud hanno una implementazione di CCM:
Cluster Administration
Le istruzioni complete per la configurazione e l'esecuzione del CCM sono fornite qui.
4 - Controller
Nella robotica e nell'automazione, un circuito di controllo (control loop) è un un'iterazione senza soluzione di continuità che regola lo stato di un sistema.
Ecco un esempio di un circuito di controllo: il termostato di una stanza.
Quando viene impostata la temperatura, si definisce attraverso il termostato lo stato desiderato. L'attuale temperatura nella stanza è invece lo stato corrente. Il termostato agisce per portare lo stato corrente il più vicino possibile allo stato desiderato accendendo e spegnendo le apparecchiature.
In Kubernetes, i controller sono circuiti di controllo che osservano lo stato del cluster, e apportano o richiedono modifiche quando necessario. Ogni controller prova a portare lo stato corrente del cluster verso lo stato desiderato.Il modello del controller
Un controller monitora almeno una tipo di risorsa registrata in Kubernetes. Questi oggetti hanno una proprietà chiamata spec (specifica) che rappresenta lo stato desiderato. Il o i controller per quella risorsa sono responsabili di mantenere lo stato corrente il più simile possibile rispetto allo stato desiderato.
Il controller potrebbe eseguire l'azione relativa alla risorsa in questione da sé; più comunemente, in Kubernetes, un controller invia messaggi all'API server che a sua volta li rende disponibili ad altri componenti nel cluster. Di seguito troverete esempi per questo scenario.
Controllo attraverso l'API server
Il Job controller è un esempio di un controller nativo in Kubernetes. I controller nativi gestiscono lo stato interagendo con l'API server presente nel cluster.
Il Job è una risorsa di Kubernetes che lancia uno o più Pod per eseguire un lavoro (task) e poi fermarsi.
(Una volta che è stato schedulato, un oggetto Pod diventa parte dello stato desisderato di un dato kubelet).
Quando il Job controller vede un nuovo lavoro da svolgere si assicura che, da qualche parte nel cluster, i kubelet anche sparsi su più nodi eseguano il numero corretto di Pod necessari per eseguire il lavoro richiesto. Il Job controller non esegue direttamente alcun Pod o container bensì chiede all'API server di creare o rimuovere i Pod. Altri componenti appartenenti al control plane reagiscono in base alle nuove informazioni (ci sono nuovi Pod da creare e gestire) e cooperano al completamento del job.
Dopo che un nuovo Job è stato creato, lo stato desiderato per quel Job è il suo completamento. Il Job controller fa sì che lo stato corrente per quel Job sia il più vicino possibile allo stato desiderato: creare Pod che eseguano il lavoro che deve essere effettuato attraverso il Job, così che il Job sia prossimo al completamento.
I controller aggiornano anche gli oggetti che hanno configurato. Ad esempio: una volta che il lavoro relativo ad un dato Job è stato completato, il Job controller aggiorna l'oggetto Job segnandolo come Finished
.
(Questo è simile allo scenario del termostato che spegne un certo led per indicare che ora la stanza ha raggiungo la temperatura impostata)
Controllo diretto
A differenza del Job, alcuni controller devono eseguire delle modifiche a parti esterne al cluster.
Per esempio, se viene usato un circuito di controllo per assicurare che ci sia un numero sufficiente di Nodi nel cluster, allora il controller ha bisogno che qualcosa al di fuori del cluster configuri i nuovi Nodi quando sarà necessario.
I controller che interagiscono con un sistema esterno trovano il loro stato desiderato attraverso l'API server, quindi comunicano direttamente con un sistema esterno per portare il loro stato corrente più in linea possibile con lo stato desiderato
(In realtà c'è un controller che scala orizzontalmente i nodi nel cluster. Vedi Cluster autoscaling).
Stato desiderato versus corrente
Kubernetes ha una visione cloud-native dei sistemi, ed è in grado di gestire continue modifiche.
Il cluster viene modificato continuamente durante la sua attività ed il circuito di controllo è in grado di risolvere automaticamente i possibili guasti.
Fino a che i controller del cluster sono in funzione ed in grado di apportare le dovute modifiche, non è rilevante che lo stato complessivo del cluster sia o meno stabile.
Progettazione
Come cardine della sua progettazione, Kubernetes usa vari controller ognuno dei quali è responsabile per un particolare aspetto dello stato del cluster. Più comunemente, un dato circuito di controllo (controller) usa un tipo di risorsa per il suo stato desiderato, ed utilizza anche risorse di altro tipo per raggiungere questo stato desiderato. Per esempio il Job controller tiene traccia degli oggetti di tipo Job (per scoprire nuove attività da eseguire) e degli oggetti di tipo Pod (questi ultimi usati per eseguire i Job, e quindi per controllare quando il loro lavoro è terminato). In questo caso, qualcos'altro crea i Job, mentre il Job controller crea i Pod.
È utile avere semplici controller piuttosto che un unico, monolitico, circuito di controllo. I controller possono guastarsi, quindi Kubernetes è stato disegnato per gestire questa eventualità.
Nota:
Ci possono essere diversi controller che creato o aggiornano lo stesso tipo di oggetti. Dietro le quinte, i controller di Kubernetes si preoccupano esclusivamente delle risorse (di altro tipo) collegate alla risorsa primaria da essi controllata.
Per esempio, si possono avere Deployment e Job; entrambe creano Pod. Il Job controller non distrugge i Pod creati da un Deployment, perché ci sono informazioni (labels) che vengono usate dal controller per distinguere i Pod.
I modi per eseguire i controller
Kubernetes annovera un insieme di controller nativi che sono in esecuzione all'interno del kube-controller-manager. Questi controller nativi forniscono importanti funzionalità di base.
Il Deployment controller ed il Job controller sono esempi di controller che vengono forniti direttamente da Kubernetes stesso (ovvero controller "nativi"). Kubernetes consente di eseguire un piano di controllo(control plane) resiliente, di modo che se un dei controller nativi dovesse fallire, un'altra parte del piano di controllo si occuperà di eseguire quel lavoro.
Al fine di estendere Kubernetes, si possono avere controller in esecuzione al di fuori del piano di controllo. Oppure, se si desidera, è possibile scriversi un nuovo controller. È possibile eseguire il proprio controller come una serie di Pod, oppure esternamente rispetto a Kubernetes. Quale sia la soluzione migliore, dipende dalla responsabilità di un dato controller.
Voci correlate
- Leggi in merito Kubernetes control plane
- Scopri alcune delle basi degli oggetti di Kubernetes
- Per saperne di più riguardo alle API di Kubernetes
- Se vuoi creare un tuo controller, guarda i modelli per l'estensibilità in Estendere Kubernetes.