Questo sito contiene la documentazione della versione attuale di Kubernetes e delle quattro versioni precedenti di Kubernetes.
La sezione Concetti ti aiuta a conoscere le parti del sistema Kubernetes e le astrazioni utilizzate da Kubernetes per rappresentare il tuo cluster e ti aiuta ad ottenere una comprensione più profonda di come funziona Kubernetes.
Per lavorare con Kubernetes, usi gli oggetti API Kubernetes per descrivere lo stato desiderato del tuo cluster: quali applicazioni o altri carichi di lavoro vuoi eseguire, quali immagini del contenitore usano, numero di repliche, quali risorse di rete e disco vuoi rendere disponibile e altro ancora. Puoi impostare lo stato desiderato creando oggetti usando l'API di Kubernetes, in genere tramite l'interfaccia della riga di comando, kubectl. Puoi anche utilizzare direttamente l'API di Kubernetes per interagire con il cluster e impostare o modificare lo stato desiderato.
Una volta impostato lo stato desiderato, il Kubernetes Control Plane funziona per fare in modo che lo stato corrente del cluster corrisponda allo stato desiderato. Per fare ciò, Kubernetes esegue automaticamente una serie di attività, come l'avvio o il riavvio dei contenitori, il ridimensionamento del numero di repliche di una determinata applicazione e altro ancora. Il piano di controllo di Kubernetes è costituito da una raccolta di processi in esecuzione sul cluster:
kubernetes contiene una serie di astrazioni che rappresentano lo stato del tuo sistema: applicazioni e carichi di lavoro distribuiti in container, le loro risorse di rete e disco associate e altre informazioni su ciò che sta facendo il tuo cluster. Queste astrazioni sono rappresentate da oggetti nell'API di Kubernetes; guarda la Panoramica degli oggetti di Kubernetes per maggiori dettagli.
Gli oggetti di base di Kubernetes includono:
209/5000 Inoltre, Kubernetes contiene una serie di astrazioni di livello superiore denominate Controllori. I controller si basano sugli oggetti di base e forniscono funzionalità aggiuntive e funzionalità di convenienza. Loro includono:
Le varie parti del Piano di controllo di Kubernetes, come i master Kubernetes e i processi di Kubelet, regolano il modo in cui Kubernetes comunica con il cluster. Il Piano di controllo mantiene un registro di tutti gli oggetti Kubernetes nel sistema e esegue cicli di controllo continui per gestire lo stato di tali oggetti. In qualsiasi momento, i loop di controllo di Control Plane risponderanno ai cambiamenti nel cluster e lavoreranno per fare in modo che lo stato effettivo di tutti gli oggetti nel sistema corrisponda allo stato desiderato che hai fornito.
Ad esempio, quando si utilizza l'API di Kubernetes per creare un oggetto di distribuzione, si fornisce un nuovo stato desiderato per il sistema. Il piano di controllo di Kubernetes registra la creazione dell'oggetto e svolge le tue istruzioni avviando le applicazioni richieste e pianificandole sui nodi del cluster, in modo che lo stato effettivo del cluster corrisponda allo stato desiderato.
Il master Kubernetes è responsabile della gestione dello stato desiderato per il tuo cluster. Quando interagisci con Kubernetes, ad esempio utilizzando l'interfaccia della riga di comando kubectl, stai comunicando con il master di Kubernetes del cluster.
Il "master" si riferisce a una raccolta di processi che gestiscono lo stato del cluster. In genere questi processi vengono eseguiti tutti su un singolo nodo nel cluster e questo nodo viene anche definito master. Il master può anche essere replicato per disponibilità e ridondanza.
I nodi di un cluster sono le macchine (VM, server fisici, ecc.) che eseguono i flussi di lavoro delle applicazioni e del cloud. Il master Kubernetes controlla ciascun nodo; raramente interagirai direttamente con i nodi.
Se vuoi scrivere una pagina concettuale, vedi Uso dei modelli di pagina per informazioni sul tipo di pagina di concetto e il modello di concetto.
Questa pagina è una panoramica generale su Kubernetes.
Kubernetes è una piattaforma portatile, estensibile e open-source per la gestione di carichi di lavoro e servizi containerizzati, in grado di facilitare sia la configurazione dichiarativa che l'automazione. La piattaforma vanta un grande ecosistema in rapida crescita. Servizi, supporto e strumenti sono ampiamente disponibili nel mondo Kubernetes .
Il nome Kubernetes deriva dal greco, significa timoniere o pilota. Google ha reso open-source il progetto Kubernetes nel 2014. Kubernetes unisce oltre quindici anni di esperienza di Google nella gestione di carichi di lavoro di produzione su scala mondiale con le migliori idee e pratiche della comunità.
Diamo un'occhiata alla ragione per cui Kubernetes è così utile facendo un piccolo salto indietro nel tempo.
L'era del deployment tradizionale: All'inizio, le organizzazioni eseguivano applicazioni su server fisici. Non c'era modo di definire i limiti delle risorse per le applicazioni in un server fisico e questo ha causato non pochi problemi di allocazione delle risorse. Ad esempio, se più applicazioni vengono eseguite sullo stesso server fisico, si possono verificare casi in cui un'applicazione assorbe la maggior parte delle risorse e, di conseguenza, le altre applicazioni non hanno le prestazioni attese. Una soluzione per questo sarebbe di eseguire ogni applicazione su un server fisico diverso. Ma questa non è una soluzione ideale, dal momento che le risorse vengono sottoutilizzate, inoltre, questa pratica risulta essere costosa per le organizzazioni, le quali devono mantenere numerosi server fisici.
L'era del deployment virtualizzato: Come soluzione venne introdotta la virtualizzazione. Essa consente di eseguire più macchine virtuali (VM) su una singola CPU fisica. La virtualizzazione consente di isolare le applicazioni in più macchine virtuali e fornisce un livello di sicurezza superiore, dal momento che le informazioni di un'applicazione non sono liberamente accessibili da un'altra applicazione.
La virtualizzazione consente un migliore utilizzo delle risorse riducendo i costi per l'hardware, permette una migliore scalabilità, dato che un'applicazione può essere aggiunta o aggiornata facilmente, e ha molti altri vantaggi.
Ogni VM è una macchina completa che esegue tutti i componenti, compreso il proprio sistema operativo, sopra all'hardware virtualizzato.
L'era del deployment in container: I container sono simili alle macchine virtuali, ma presentano un modello di isolamento più leggero, condividendo il sistema operativo (OS) tra le applicazioni. Pertanto, i container sono considerati più leggeri. Analogamente a una macchina virtuale, un container dispone di una segregazione di filesystem, CPU, memoria, PID e altro ancora. Poiché sono disaccoppiati dall'infrastruttura sottostante, risultano portabili tra differenti cloud e diverse distribuzioni.
I container sono diventati popolari dal momento che offrono molteplici vantaggi, ad esempio:
I container sono un buon modo per distribuire ed eseguire le tue applicazioni. In un ambiente di produzione, è necessario gestire i container che eseguono le applicazioni e garantire che non si verifichino interruzioni dei servizi. Per esempio, se un container si interrompe, è necessario avviare un nuovo container. Non sarebbe più facile se questo comportamento fosse gestito direttamente da un sistema?
È proprio qui che Kubernetes viene in soccorso! Kubernetes ti fornisce un framework per far funzionare i sistemi distribuiti in modo resiliente. Kubernetes si occupa della scalabilità, failover, distribuzione delle tue applicazioni. Per esempio, Kubernetes può facilmente gestire i rilasci con modalità Canary deployment.
Kubernetes ti fornisce:
Kubernetes non è un sistema PaaS (Platform as a Service) tradizionale e completo. Dal momento che Kubernetes opera a livello di container piuttosto che che a livello hardware, esso fornisce alcune caratteristiche generalmente disponibili nelle offerte PaaS, come la distribuzione, il ridimensionamento, il bilanciamento del carico, la registrazione e il monitoraggio. Tuttavia, Kubernetes non è monolitico, e queste soluzioni predefinite sono opzionali ed estensibili. Kubernetes fornisce gli elementi base per la costruzione di piattaforme di sviluppo, ma conserva le scelte dell'utente e la flessibilità dove è importante.
Kubernetes:
Facendo il deployment di Kubernetes, ottieni un cluster.
Un cluster Kubernetes è un'insieme di macchine, chiamate nodi, che eseguono container gestiti da Kubernetes. Un cluster ha almeno un Worker Node.
Il/I Worker Node ospitano i Pod che eseguono i workload dell'utente. Il/I Control Plane Node gestiscono i Worker Node e tutto quanto accade all'interno del cluster. Per garantire la high-availability e la possibilità di failover del cluster, vengono utilizzati più Control Plane Node.
Questo documento descrive i diversi componenti che sono necessari per avere un cluster Kubernetes completo e funzionante.
Questo è un diagramma di un cluster Kubernetes con tutti i componenti e le loro relazioni.

I componenti del Control Plane sono responsabili di tutte le decisioni globali sul cluster (ad esempio, lo scheduling) oltre che a rilevare e rispondere agli eventi del cluster (ad esempio, l'avvio di un nuovo pod quando il valore replicas di un deployment non è soddisfatto).
I componenti della Control Plane possono essere eseguiti su qualsiasi nodo del cluster stesso. Solitamente, per semplicità, gli script di installazione tendono a eseguire tutti i componenti della Control Plane sulla stessa macchina, separando la Control Plane dai workload dell'utente. Vedi creare un cluster in High-Availability per un esempio di un'installazione multi-master.
L'API server è un componente di Kubernetes control plane che espone le Kubernetes API. L'API server è il front end del control plane di Kubernetes.
La principale implementazione di un server Kubernetes API è kube-apiserver. kube-apiserver è progettato per scalare orizzontalmente, cioè scala aumentando il numero di istanze. Puoi eseguire multiple istanze di kube-apiserver e bilanciare il traffico tra queste istanze.
È un database key-value ridondato, che è usato da Kubernetes per salvare tutte le informazioni del cluster.
Se il tuo cluster utilizza etcd per salvare le informazioni, assicurati di avere una strategia di backup per questi dati.
Puoi trovare informazioni dettagliate su etcd sulla documentazione ufficiale.
Componente della Control Plane che controlla i pod appena creati che non hanno un nodo assegnato, e dopo averlo identificato glielo assegna.
I fattori presi in considerazioni nell'individuare un nodo a cui assegnare l'esecuzione di un Pod includono la richiesta di risorse del Pod stesso e degli altri workload presenti nel sistema, i vincoli delle hardware/software/policy, le indicazioni di affinity e di anti-affinity, requisiti relativi alla disponibilità di dati/Volumes, le interferenze tra diversi workload e le scadenze.
Componente della Control Plane che gestisce controllers.
Da un punto di vista logico, ogni controller è un processo separato, ma per ridurre la complessità, tutti i principali controller di Kubernetes vengono raggruppati in un unico container ed eseguiti in un singolo processo.
Alcuni esempi di controller gestiti dal kube-controller-manager sono:
Il cloud-controller-manager esegue dei controller specifici del tuo cloud provider. Se hai una installazione Kubernetes on premises, o un ambiente di laboratorio nel tuo PC, il cluster non ha un cloud-controller-manager.
Come nel kube-controller-manager, il cloud-controller-manager combina diversi control loop logicamente indipendenti in un singolo binario che puoi eseguire come un singolo processo. Tu puoi scalare orizzontalmente (eseguire più di una copia) per migliorare la responsività o per migliorare la tolleranza ai fallimenti.
I seguenti controller hanno dipendenze verso implementazioni di specifici cloud provider:
I componenti del nodo vengono eseguiti su ogni nodo, mantenendo i pod in esecuzione e fornendo l'ambiente di runtime Kubernetes.
Un agente che è eseguito su ogni nodo del cluster. Si assicura che i container siano eseguiti in un pod.
La kubelet riceve un set di PodSpecs che vengono forniti attraverso vari meccanismi, e si assicura che i container descritti in questi PodSpecs funzionino correttamente e siano sani. La kubelet non gestisce i container che non sono stati creati da Kubernetes.
kube-proxy è un proxy eseguito su ogni nodo del cluster, responsabile della gestione dei Kubernetes Service.
I kube-proxy mantengono le regole di networking sui nodi. Queste regole permettono la comunicazione verso gli altri nodi del cluster o l'esterno.
Il kube-proxy usa le librerie del sistema operativo quando possible; in caso contrario il kube-proxy gestisce il traffico direttamente.
Il container runtime è il software che è responsabile per l'esecuzione dei container.
Kubernetes supporta diversi container runtimes: Docker, containerd, cri-o, rktlet e tutte le implementazioni di Kubernetes CRI (Container Runtime Interface).
Gli Addons usano le risorse Kubernetes (DaemonSet, Deployment, etc) per implementare funzionalità di cluster.
Dal momento che gli addons forniscono funzionalità a livello di cluster, le risorse che necessitano di un namespace, vengono collocate nel namespace kube-system.
Alcuni addons sono descritti di seguito; mentre per una più estesa lista di addons, per favore vedere Addons.
Mentre gli altri addons non sono strettamente richiesti, tutti i cluster Kubernetes dovrebbero essere muniti di un DNS del cluster, dal momento che molte applicazioni lo necessitano.
Il DNS del cluster è un server DNS aggiuntivo rispetto ad altri server DNS presenti nella rete, e si occupa specificatamente dei record DNS per i servizi Kubernetes.
I container eseguiti da Kubernetes automaticamente usano questo server per la risoluzione DNS.
La Dashboard è una interfaccia web per i cluster Kubernetes. Permette agli utenti di gestire e fare troubleshooting delle applicazioni che girano nel cluster, e del cluster stesso.
Il Monitoraggio dei Container salva serie temporali di metriche generiche dei container in un database centrale e fornisce una interfaccia in cui navigare i dati stessi.
Un log a livello di cluster è responsabile per il salvataggio dei log dei container in un log centralizzato la cui interfaccia permette di cercare e navigare nei log.
Le convenzioni generali seguite dalle API sono descritte in API conventions doc.
Gli endpoints delle API, la lista delle risorse esposte ed i relativi esempi sono descritti in API Reference.
L'accesso alle API da remoto è discusso in Controllare l'accesso alle API.
Le API di Kubernetes servono anche come riferimento per lo schema dichiarativo della configurazione del sistema stesso. Il comando kubectl può essere usato per creare, aggiornare, cancellare ed ottenere le istanze delle risorse esposte attraverso le API.
Kubernetes assicura la persistenza del suo stato (al momento in etcd) usando la rappresentazione delle risorse implementata dalle API.
Kubernetes stesso è diviso in differenti componenti, i quali interagiscono tra loro attraverso le stesse API.
In base alla nostra esperienza, ogni sistema di successo ha bisogno di evolvere ovvero deve estendersi aggiungendo funzionalità o modificare le esistenti per adattarle a nuovi casi d'uso. Le API di Kubernetes sono quindi destinate a cambiare e ad estendersi. In generale, ci si deve aspettare che nuove risorse vengano aggiunte di frequente cosi come nuovi campi possano altresì essere aggiunti a risorse esistenti. L'eliminazione di risorse o di campi devono seguire la politica di deprecazione delle API.
In cosa consiste una modifica compatibile e come modificare le API è descritto dal API change document.
La documentazione completa e dettagliata delle API è fornita attraverso la specifica OpenAPI.
Dalla versione 1.10 di Kubernetes, l'API server di Kubernetes espone le specifiche OpenAPI attraverso il seguente endpoint /openapi/v2. Attraverso i seguenti headers HTTP è possibile richiedere un formato specifico:
| Header | Possibili Valori |
|---|---|
| Accept | application/json, application/com.github.proto-openapi.spec.v2@v1.0+protobuf (il content-type di default è application/json per */* ovvero questo header può anche essere omesso) |
| Accept-Encoding | gzip (questo header è facoltativo) |
Prima della versione 1.14, gli endpoints che includono il formato del nome all'interno del segmento (/swagger.json, /swagger-2.0.0.json, /swagger-2.0.0.pb-v1, /swagger-2.0.0.pb-v1.gz)
espongo le specifiche OpenAPI in formati differenti. Questi endpoints sono deprecati, e saranno rimossi dalla versione 1.14 di Kubernetes.
Esempi per ottenere le specifiche OpenAPI:
| Prima della 1.10 | Dalla versione 1.10 di Kubernetes |
|---|---|
| GET /swagger.json | GET /openapi/v2 Accept: application/json |
| GET /swagger-2.0.0.pb-v1 | GET /openapi/v2 Accept: application/com.github.proto-openapi.spec.v2@v1.0+protobuf |
| GET /swagger-2.0.0.pb-v1.gz | GET /openapi/v2 Accept: application/com.github.proto-openapi.spec.v2@v1.0+protobuf Accept-Encoding: gzip |
Kubernetes implementa per le sue API anche una serializzazione alternativa basata sul formato Protobuf che è stato pensato principalmente per la comunicazione intra-cluster, documentato nella seguente design proposal, e i files IDL per ciascun schema si trovano nei Go packages che definisco i tipi delle API.
Prima della versione 1.14, l'apiserver di Kubernetes espone anche un'endpoint, /swaggerapi, che può essere usato per ottenere
le documentazione per le API di Kubernetes secondo le specifiche Swagger v1.2 .
Questo endpoint è deprecato, ed è stato rimosso nella versione 1.14 di Kubernetes.
Per facilitare l'eliminazione di campi specifici o la modifica della rappresentazione di una data risorsa, Kubernetes supporta molteplici versioni della stessa API disponibili attraverso differenti indirizzi, come ad esempio /api/v1 oppure
/apis/extensions/v1beta1.
Abbiamo deciso di versionare a livello di API piuttosto che a livello di risorsa o di campo per assicurare che una data API rappresenti una chiara, consistente vista delle risorse di sistema e dei sui comportamenti, e per abilitare un controllo degli accessi sia per le API in via di decommissionamento che per quelle sperimentali.
Si noti che il versionamento delle API ed il versionamento del Software sono indirettamente collegati. La API and release versioning proposal descrive la relazione tra le versioni delle API ed le versioni del Software.
Differenti versioni delle API implicano differenti livelli di stabilità e supporto. I criteri per ciascuno livello sono descritti in dettaglio nella API Changes documentation. Queste modifiche sono qui ricapitolate:
alpha (e.g. v1alpha1).beta (e.g. v2beta3).vX dove X è un intero.Per facilitare l'estendibilità delle API di Kubernetes, sono stati implementati gli API groups.
L'API group è specificato nel percorso REST ed anche nel campo apiVersion di un oggetto serializzato.
Al momento ci sono diversi API groups in uso:
Il gruppo core, spesso referenziato come il legacy group, è disponibile al percorso REST /api/v1 ed utilizza apiVersion: v1.
I gruppi basati su un nome specifico sono disponibili attraverso il percorso REST /apis/$GROUP_NAME/$VERSION, ed usano apiVersion: $GROUP_NAME/$VERSION (e.g. apiVersion: batch/v1). La lista completa degli API groups supportati e' descritta nel documento Kubernetes API reference.
Vi sono due modi per supportati per estendere le API attraverso le custom resources:
Alcune risorse ed API groups sono abilitati di default. Questi posso essere abilitati o disabilitati attraverso il settaggio/flag --runtime-config
applicato sull'apiserver. --runtime-config accetta valori separati da virgola. Per esempio: per disabilitare batch/v1, usa la seguente configurazione --runtime-config=batch/v1=false, per abilitare batch/v2alpha1, utilizzate --runtime-config=batch/v2alpha1.
Il flag accetta set di coppie chiave/valore separati da virgola che descrivono la configurazione a runtime dell'apiserver.
--runtime-config abbiano effetto.DaemonSets, Deployments, StatefulSet, NetworkPolicies, PodSecurityPolicies e ReplicaSets presenti nel gruppo di API extensions/v1beta1 sono disabilitate di default.
Per esempio: per abilitare deployments and daemonsets, utilizza la seguente configurazione
--runtime-config=extensions/v1beta1/deployments=true,extensions/v1beta1/daemonsets=true.
extensions/v1beta1 per ragioni storiche.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.
Lo stato di un nodo contiene le seguenti informazioni:
Ogni sezione è descritta in dettaglio di seguito.
L'utilizzo di questi campi varia a seconda del provider cloud o della configurazione bare metal.
--hostname-override.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.
Descrive le risorse disponibili sul nodo: CPU, memoria e il massimo numero di pod che possono essere programmati sul nodo.
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.
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.
Attualmente, ci sono tre componenti che interagiscono con il nodo di Kubernetes interfaccia: controller del nodo, kubelet e kubectl.
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.
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 se register-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 masterQuando Node authorization mode e NodeRestriction admission plugin sono abilitati, kubelets è autorizzato solo a creare / modificare la propria risorsa nodo.
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
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.
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.
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).
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.
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.
Le connessioni dall'apiserver al kubelet vengono utilizzate per:
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.
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.
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.
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
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:

Nel diagramma precedente, Kubernetes e il provider cloud sono integrati attraverso diversi componenti:
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ì:

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:
Nella versione 1.9, il CCM esegue i seguenti controller dall'elenco precedente:
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.
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.
La maggior parte delle funzioni del CCM deriva dal KCM. Come menzionato nella sezione precedente, CCM esegue i seguenti cicli di controllo:
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:
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.
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.
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.
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.
Questa sezione dettaglia l'accesso richiesto dal CCM sui vari API objects per eseguire le sue operazioni.
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:
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:
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:
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:
v1/ServiceAccount:
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
I seguenti fornitori di cloud hanno una implementazione di CCM:
Le istruzioni complete per la configurazione e l'esecuzione del CCM sono fornite qui.
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.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.
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)
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).
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.
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à.
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.
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.
Ogni container che viene eseguito è riproducibile; la pratica di includere le dipendenze all'interno di ciascuno container permette di ottenere sempre lo stesso risultato ad ogni esecuzione del medesimo container.
I Container permettono di disaccoppiare le applicazioni dall'infrastruttura del host su cui vengono eseguite. Questo approccio rende più facile il deployment su cloud o sitemi operativi differenti tra loro.
L'immagine di un container e' un pacchetto software che contiene tutto ciò che serve per eseguire un'applicazione: il codice sorgente e ciascun runtime necessario, librerie applicative e di sistema, e le impostazioni predefinite per ogni configurazione necessaria.
Un container è immutabile per definizione: non è possibile modificare il codice di un container in esecuzione. Se si ha un'applicazione containerizzata e la si vuole modificare, si deve costruire un nuovo container che includa il cambiamento desiderato, e quindi ricreare il container partendo dalla nuova immagine aggiornata.
Il container runtime è il software che è responsabile per l'esecuzione dei container.
Kubernetes supporta diversi container runtimes: Docker, containerd, cri-o, rktlet e tutte le implementazioni di Kubernetes CRI (Container Runtime Interface).
L'immagine di un container rappresenta dati binari che incapsulano un'applicazione e tutte le sue dipendenze software. Le immagini sono costituite da pacchetti software eseguibili che possono essere avviati in modalità standalone e su cui si possono fare ipotesi ben precise circa l'ambiente in cui vengono eseguiti.
Tipicamente viene creata un'immagine di un'applicazione ed effettuato il push su un registry (un repository pubblico di immagini) prima di poterne fare riferimento esplicito in un Pod
Questa pagina va a delineare nello specifico il concetto di immagine di un container.
Alle immagini dei container vengono normalmente attribuiti nomi come pause, example/mycontainer, o kube-apiserver.
Le immagini possono anche contenere l'hostname del registry in cui le immagini sono pubblicate;
ad esempio: registro.fittizio.esempio/nomeimmagine,
ed è possibile che sia incluso nel nome anche il numero della porta; ad esempio: registro.fittizio.esempio:10443/nomeimmagine.
Se non si specifica l'hostname di un registry, Kubernetes assume che ci si riferisca al registry pubblico di Docker.
Dopo la parte relativa al nome dell'immagine si può aggiungere un tag (come comunemente avviene per comandi come docker e podman).
I tag permettono l'identificazione di differenti versioni della stessa serie di immagini.
I tag delle immagini sono composti da lettere minuscole e maiuscole, numeri, underscore (_),
punti (.), e trattini (-).
Esistono regole aggiuntive relative a dove i caratteri separatori (_, -, and .)
possano essere inseriti nel tag di un'immagine.
Se non si specifica un tag, Kubernetes assume il tag latest che va a definire l'immagine disponibile più recente.
Evitate di utilizzare il tag latest quando si rilasciano dei container in produzione,
in quanto risulta difficile tracciare quale versione dell'immagine sia stata avviata e persino più difficile
effettuare un rollback ad una versione precente.
Invece, meglio specificare un tag specifico come ad esempio v1.42.0.
Quando un Deployment,
StatefulSet, Pod, o qualsiasi altro
oggetto che includa un Pod template viene creato per la prima volta, la policy di default per il pull di tutti i container nel Pod
è impostata su IfNotPresent (se non presente) se non specificato diversamente.
Questa policy permette al
kubelet di evitare di fare il pull
di un'immagine se questa è già presente.
Se necessario, si può forzare il pull in ogni occasione in uno dei seguenti modi:
imagePullPolicy (specifica per il pull delle immagini) del container su Always (sempre).imagePullPolicy ed usando il tag :latest (più recente) per l'immagine da utilizzare;
Kubernetes imposterà la policy su Always (sempre).imagePullPolicy ed il tag per l'immagine da utilizzare.Il valore dell'impostazione imagePullPolicy del container è sempre presente quando l'oggetto viene creato per la prima volta
e non viene aggiornato se il tag dell'immagine dovesse cambiare successivamente.
Ad esempio, creando un Deployment con un'immagine il cui tag non è
:latest, e successivamente aggiornando il tag di quell'immagine a :latest, il campo
imagePullPolicy non cambierà su Always.
È necessario modificare manualmente la policy di pull di ogni oggetto dopo la sua creazione.
Quando imagePullPolicy è definito senza un valore specifico, esso è impostato su Always.
Oltre a fornire immagini binarie, un container registry può fornire un indice delle immagini disponibili per un container.
L'indice di un'immagine può puntare a più file manifest ciascuno per una versione specifica dell'architettura di un container.
L'idea è che si può avere un unico nome per una stessa immagine (ad esempio: pause, example/mycontainer, kube-apiserver) e permettere a diversi sistemi di recuperare l'immagine binaria corretta a seconda dell'architettura della macchina che la sta utilizzando.
Kubernetes stesso tipicamente nomina le immagini dei container tramite il suffisso -$(ARCH).
Per la garantire la retrocompatibilità è meglio generare le vecchie immagini con dei suffissi.
L'idea è quella di generare, ad esempio, l'immagine pause con un manifest che include tutte le architetture supportate,
affiancata, ad esempio, da pause-amd64 che è retrocompatibile per le vecchie configurazioni o per quei file YAML
in cui sono specificate le immagini con i suffissi.
I private registry possono richiedere l'utilizzo di chiavi per accedere alle immagini in essi contenute.
Le credenziali possono essere fornite in molti modi:
Di seguito la spiegazione dettagliata di queste opzioni.
Se si sta utilizzando Docker sui nodi, si può configurare il Docker container runtime per autenticare il nodo presso un private container registry.
Questo è un approccio possibile se si ha il controllo sulle configurazioni del nodo.
auths e HttpHeaders nelle configurazioni relative a Docker.
Eventuali helper per le credenziali di Docker (credHelpers o credsStore) non sono supportati.Docker salva le chiavi per i registri privati in $HOME/.dockercfg oppure nel file $HOME/.docker/config.json.
Inserendo lo stesso file nella lista seguente, kubelet lo utilizzerà per recuperare le credenziali quando deve fare il pull delle immagini.
{--root-dir:-/var/lib/kubelet}/config.json{cwd of kubelet}/config.json${HOME}/.docker/config.json/.docker/config.json{--root-dir:-/var/lib/kubelet}/.dockercfg{cwd of kubelet}/.dockercfg${HOME}/.dockercfg/.dockercfgHOME=/root esplicitamente come variabile d'ambiente del processo kubelet.Di seguito i passi consigliati per configurare l'utilizzo di un private registry da parte dei nodi del cluster. In questo esempio, eseguire i seguenti comandi sul proprio desktop/laptop:
docker login [server] per ogni set di credenziali che vuoi utilizzare. Questo comando aggiornerà $HOME/.docker/config.json sul tuo PC.$HOME/.docker/config.json in un editor di testo per assicurarti che contenga le credenziali che tu voglia utilizzare.nodes=$( kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}' )nodes=$( kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}' ).docker/config.json in uno dei path sopra riportati nella lista di ricerca.
for n in $nodes; do scp ~/.docker/config.json root@"$n":/var/lib/kubelet/config.json; donePuoi fare una verifica creando un Pod che faccia uso di un'immagine privata; ad esempio:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: private-image-test-1
spec:
containers:
- name: uses-private-image
image: $PRIVATE_IMAGE_NAME
imagePullPolicy: Always
command: [ "echo", "SUCCESS" ]
EOF
pod/private-image-test-1 created
Se tutto funziona correttamente, pochi istanti dopo, si può lanciare il comando:
kubectl logs private-image-test-1
e verificare che il comando restituisca in output:
SUCCESS
Qualora si sospetti che il comando sia fallito, si può eseguire:
kubectl describe pods/private-image-test-1 | grep 'Failed'
In caso di fallimento, l'output sarà simile al seguente:
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
Bisogna assicurarsi che tutti i nodi nel cluster abbiano lo stesso file .docker/config.json.
Altrimenti i pod funzioneranno correttamente su alcuni nodi ma falliranno su altri.
Ad esempio, se si utilizza l'autoscaling per i nodi, il template di ogni istanza
devono includere il file .docker/config.json oppure montare un disco che lo contenga.
Tutti i pod avranno accesso in lettura alle immagini presenti nel private registry
una volta che le rispettive chiavi di accesso siano state aggiunte nel file .docker/config.json.
Kubelet di default prova a fare il pull di ogni immagine dal registry specificato.
Tuttavia, qualora la proprietà imagePullPolicy (specifica di pull dell'immagine) del container sia impostata su IfNotPresent (vale a dire, se non è già presente) oppure su Never (mai),
allora l'immagine locale è utilizzata (in via preferenziale o esclusiva, rispettivamente).
Se si vuole fare affidamento a immagini pre-scaricate per non dover incorrere in una fase di autenticazione presso il registry, bisogna assicurarsi che tutti i nodi nel cluster abbiano scaricato le stesse versioni delle immagini.
Questa procedura può essere utilizzata per accelerare il processo di creazione delle istanze o come alternativa all'autenticazione presso un private registry.
Tutti i pod avranno accesso in lettura a qualsiasi immagine pre-scaricata.
Kubernetes da la possibilità di specificare le chiavi del container registry su un Pod.
Esegui il comando seguente, sostituendo i valori riportati in maiuscolo con quelli corretti:
kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
Se possiedi il file delle credenziali per Docker, anziché utilizzare il comando quì sopra
puoi importare il file di credenziali come un Kubernetes
Secrets.
Creare un Secret a partire da credenziali Docker fornisce la spiegazione dettagliata su come fare.
Ciò è particolarmente utile se si utilizzano più container registry privati,
in quanto il comando kubectl create secret docker-registry genera un Secret che
funziona con un solo private registry.
È possibile creare pod che referenzino quel Secret aggiungendo la sezione imagePullSecrets alla definizione del Pod.
Ad esempio:
cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: myregistrykey
EOF
cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF
Questo deve esser fatto per ogni Pod che utilizzi un private registry.
Comunque, le impostazioni relative a questo campo possono essere automatizzate inserendo la sezione imagePullSecrets nella definizione della risorsa ServiceAccount.
Visitare la pagina Aggiungere ImagePullSecrets ad un Service Account per istruzioni più dettagliate.
Puoi utilizzarlo in congiunzione al file .docker/config.json configurato per ogni nodo. In questo caso, si applicherà un merge delle credenziali.
Ci sono varie soluzioni per configurare i private registry. Di seguito, alcuni casi d'uso comuni e le soluzioni suggerite.
imagePullSecrets.Se si ha la necessità di accedere a più registri, si può generare un Secret per ognuno di essi.
Kubelet farà il merge di ogni imagePullSecrets in un singolo file virtuale .docker/config.json.
Questa pagina descrive le risorse disponibili nei Container eseguiti in Kubernetes.
Quando si esegue un Container in Kubernetes, le seguenti risorse sono rese disponibili:
L' hostname di un Container è il nome del Pod all'interno del quale è eseguito il Container.
È consultabile tramite il comando hostname o tramite la funzione
gethostname
disponibile in libc.
Il nome del Pod e il namespace possono essere resi disponibili come environment variables attraverso l'uso delle downward API.
Gli utenti possono aggiungere altre environment variables nella definizione del Pod; anche queste saranno disponibili nel Container come tutte le altre environment variables definite staticamente nella Docker image.
Al momento della creazione del Container è generata una serie di environment variables con la lista di servizi in esecuzione nel cluster. Queste environment variables rispettano la sintassi dei Docker links.
Per un servizio chiamato foo che è in esecuzione in un Container di nome bar, le seguenti variabili sono generate:
FOO_SERVICE_HOST=<host su cui il servizio è attivo>
FOO_SERVICE_PORT=<porta su cui il servizio è pubblicato>
I servizi hanno un indirizzo IP dedicato e sono disponibili nei Container anche via DNS se il DNS addon è installato nel cluster.
Questa pagina descrive come i Container gestiti con kubelet possono utilizzare il lifecycle hook framework dei Container per l'esecuzione di codice eseguito in corrispondenza di alcuni eventi durante il loro ciclo di vita.
Analogamente a molti framework di linguaggi di programmazione che hanno degli hooks legati al ciclo di vita dei componenti, come ad esempio Angular, Kubernetes fornisce ai Container degli hook legati al loro ciclo di vita dei Container. Gli hook consentono ai Container di essere consapevoli degli eventi durante il loro ciclo di gestione ed eseguire del codice implementato in un handler quando il corrispondente hook viene eseguito.
Esistono due tipi di hook che vengono esposti ai Container:
PostStart
Questo hook viene eseguito successivamente alla creazione del container. Tuttavia, non vi è garanzia che questo hook venga eseguito prima dell'ENTRYPOINT del container. Non vengono passati parametri all'handler.
PreStop
Questo hook viene eseguito prima della terminazione di un container a causa di una richiesta API o
di un evento di gestione, come ad esempio un fallimento delle sonde di liveness/startup, preemption,
risorse contese e altro. Una chiamata all'hook di PreStop fallisce se il container è in stato
terminated o completed e l'hook deve finire prima che possa essere inviato il segnale di TERM per
fermare il container. Il conto alla rovescia per la terminazione del Pod (grace period) inizia prima dell'esecuzione
dell'hook PreStop, quindi indipendentemente dall'esito dell'handler, il container terminerà entro
il grace period impostato. Non vengono passati parametri all'handler.
Una descrizione più dettagliata riguardante al processo di terminazione dei Pod può essere trovata in Terminazione dei Pod.
I Container possono accedere a un hook implementando e registrando un handler per tale hook. Ci sono due tipi di handler che possono essere implementati per i Container:
pre-stop.sh, all'interno dei cgroup e namespace del Container.
Le risorse consumate dal comando vengono contate sul Container.Quando viene richiamato l'hook legato al lifecycle del Container, il sistema di gestione di Kubernetes
esegue l'handler secondo l'azione dell'hook, httpGet e tcpSocket vengono eseguiti dal processo kubelet,
mentre exec è eseguito nel Container.
Le chiamate agli handler degli hook sono sincrone rispetto al contesto del Pod che contiene il Container.
Questo significa che per un hook PostStart, l'ENTRYPOINT e l'hook si attivano in modo asincrono.
Tuttavia, se l'hook impiega troppo tempo per essere eseguito o si blocca, il container non può raggiungere lo
stato di running.
Gli hook di PreStop non vengono eseguiti in modo asincrono dall'evento di stop del container; l'hook
deve completare la sua esecuzione prima che l'evento TERM possa essere inviato. Se un hook di PreStop
si blocca durante la sua esecuzione, la fase del Pod rimarrà Terminating finchè il Pod non sarà rimosso forzatamente
dopo la scadenza del suo terminationGracePeriodSeconds. Questo grace period si applica al tempo totale
necessario per effettuare sia l'esecuzione dell'hook di PreStop che per l'arresto normale del container.
Se, per esempio, il terminationGracePeriodSeconds è di 60, e l'hook impiega 55 secondi per essere completato,
e il container impiega 10 secondi per fermarsi normalmente dopo aver ricevuto il segnale, allora il container
verrà terminato prima di poter completare il suo arresto, poiché terminationGracePeriodSeconds è inferiore al tempo
totale (55+10) necessario perché queste due cose accadano.
Se un hook PostStart o PreStop fallisce, allora il container viene terminato.
Gli utenti dovrebbero mantenere i loro handler degli hook i più leggeri possibili. Ci sono casi, tuttavia, in cui i comandi di lunga durata hanno senso, come il salvataggio dello stato del container prima della sua fine.
La chiamata degli hook avviene almeno una volta, il che significa
che un hook può essere chiamato più volte da un dato evento, come per PostStart
o PreStop.
Sta all'implementazione dell'hook gestire correttamente questo aspetto.
Generalmente, vengono effettuate singole chiamate agli hook. Se, per esempio, la destinazione di hook HTTP non è momentaneamente in grado di ricevere traffico, non c'è alcun tentativo di re invio. In alcuni rari casi, tuttavia, può verificarsi una doppia chiamata. Per esempio, se un kubelet si riavvia nel mentre dell'invio di un hook, questo potrebbe essere chiamato per una seconda volta dopo che il kubelet è tornato in funzione.
I log di un handler di hook non sono esposti negli eventi del Pod.
Se un handler fallisce per qualche ragione, trasmette un evento.
Per il PostStart, questo è l'evento di FailedPostStartHook,
e per il PreStop, questo è l'evento di FailedPreStopHook.
Puoi vedere questi eventi eseguendo kubectl describe pod <pod_name>.
Ecco alcuni esempi di output di eventi dall'esecuzione di questo comando:
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined]
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567
38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1
37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1
38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1"
1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook
La ConfigMap è un oggetto API usato per memorizzare dati non riservati in coppie chiave-valore. I Pods possono utilizzare le ConfigMaps come variabili d'ambiente, argomenti da riga di comando, o come files di configurazione all'interno di un Volume.
La ConfigMap ti permette di disaccoppiare le configurazioni specifiche per ambiente dalle immagini del container, cosicchè le tue applicazioni siano facilmente portabili.
Usa una ConfigMap per tenere separati i dati di configurazione dal codice applicativo.
Per esempio, immagina che stai sviluppando un'applicazione che puoi eseguire sul tuo computer (per lo sviluppo) e sul cloud (per gestire il traffico reale). Puoi scrivere il codice puntando a una variabile d'ambiente chiamata DATABASE_HOST. Localmente, puoi settare quella variabile a localhost. Nel cloud, la puoi settare referenziando il Service di Kubernetes che espone la componente del database sul tuo cluster. Ciò ti permette di andare a recuperare l'immagine del container eseguita nel cloud e fare il debug dello stesso codice localmente se necessario.
La ConfigMap non è pensata per sostenere una gran mole di dati. I dati memorizzati su una ConfigMap non possono superare 1 MiB. Se hai bisogno di memorizzare delle configurazioni che superano questo limite, puoi considerare di montare un volume oppure usare un database o un file service separato.
La ConfigMap è un oggetto API che ti permette di salvare configurazioni per poi poter essere riutilizzate da altri oggetti. A differenza di molti oggetti di Kubernetes che hanno una spec, la ConfigMap ha i campi data e binaryData. Questi campi accettano le coppie chiave-valore come valori. Entrambi i campi data e binaryData sono opzionali. Il campo data è pensato per contenere le stringhe UTF-8 mentre il campo binaryData è pensato per contenere dati binari come le stringhe codificate in base64.
Il nome di una ConfigMap deve essere un nome valido per un sottodominio DNS.
Ogni chiave sotto il campo data o binaryData deve consistere di caratteri alfanumerici, -, _ o .. Le chiavi salvate sotto data non devono coincidere con le chiavi nel campo binaryData.
Partendo dalla versione 1.19, puoi aggiungere il campo immutable alla definizione di ConfigMap per creare una ConfigMap immutabile.
Puoi scrivere una spec del Pod che si riferisce a una ConfigMap e configurare il o i containers
in quel Pod sulla base dei dati presenti nella ConfigMap. Il Pod e la ConfigMap devono essere nello
stesso Namespace.
Questo è un esempio di una ConfigMap che ha alcune chiavi con valori semplici, e altre chiavi dove il valore ha il formato di un frammento di configurazione.
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
# chiavi simili a proprietà; ogni chiave mappa un valore semplice
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
# chiavi simili a files
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
user-interface.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
Ci sono quattro modi differenti con cui puoi usare una ConfigMap per configurare un container all'interno di un Pod:
Questi metodologie differenti permettono di utilizzare diversi metodi per modellare i dati che saranno consumati. Per i primi tre metodi, il kubelet utilizza i dati della ConfigMap quando lancia il container (o più) in un Pod.
Per il quarto metodo dovrai scrivere il codice per leggere la ConfigMap e i suoi dati. Comunque, poiché stai utilizzando l'API di Kubernetes direttamente, la tua applicazione può sottoscriversi per ottenere aggiornamenti ogniqualvolta la ConfigMap cambia, e reagire quando ciò accade. Accedendo direttamente all'API di Kubernetes, questa tecnica ti permette anche di accedere a una ConfigMap in namespace differenti.
Ecco un esempio di Pod che usa i valori da game-demo per configurare il container:
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: alpine
command: ["sleep", "3600"]
env:
# Definire la variabile d'ambiente
- name: PLAYER_INITIAL_LIVES # Notare che il case qui è differente
# dal nome della key nella ConfigMap.
valueFrom:
configMapKeyRef:
name: game-demo # La ConfigMap da cui proviene il valore.
key: player_initial_lives # La chiave da recuperare.
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# Settare i volumi al livello del Pod, in seguito montarli nei containers all'interno del Pod
- name: config
configMap:
# Fornire il nome della ConfigMap che vuoi montare.
name: game-demo
# Una lista di chiavi dalla ConfigMap per essere creata come file
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"
Una ConfigMap non differenzia tra le proprietà di una singola linea e un file con più linee e valori. L'importante è il modo in cui i Pods e gli altri oggetti consumano questi valori.
Per questo esempio, definire un volume e montarlo all'interno del container demo come /config crea
due files,
/config/game.properties e /config/user-interface.properties,
sebbene ci siano quattro chiavi nella ConfigMap. Ciò avviene perché la definizione del Pod
specifica una lista di items nella sezione dei volumes.
Se ometti del tutto la lista degli items, ogni chiave nella ConfigMap diventerà
un file con lo stesso nome della chiave, e otterrai 4 files.
Le ConfigMaps possono essere montate come volumi. Le ConfigMaps possono anche essere utilizzate da altre parti del sistema, senza essere direttamente esposte al Pod. Per esempio, le ConfigMaps possono contenere l'informazione che altre parti del sistema utilizzeranno per la loro configurazione.
La maniera più comune per usare le ConfigMaps è di configurare i containers che sono in esecuzione in un Pod nello stesso namespace. Puoi anche utilizzare una ConfigMap separatamente.
Per esempio, potresti incontrare addons o operators che adattano il loro comportamento in base a una ConfigMap.
Per utilizzare una ConfigMap in un volume all'interno di un Pod:
.spec.volumes[]. Nominare
il volume in qualsiasi modo, e avere un campo .spec.volumes[].configMap.name configurato per
referenziare il tuo oggetto ConfigMap..spec.containers[].volumeMounts[] a ogni container che necessiti di una
ConfigMap. Nello specifico .spec.containers[].volumeMounts[].readOnly = true e
.spec.containers[].volumeMounts[].mountPath in una cartella inutilizzata
dove vorresti che apparisse la ConfigMap.data della ConfigMap si converte in un file
sotto mountPath.Questo è un esempio di un Pod che monta una ConfigMap in un volume:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
configMap:
name: myconfigmap
Ogni ConfigMap che desideri utilizzare deve essere referenziata in .spec.volumes.
Se c'è più di un container nel Pod, allora ogni container necessita del suo
blocco volumeMounts, ma solamente un .spec.volumes è necessario ConfigMap.
Quando una ConfigMap è utilizzata in un volume ed è aggiornata, anche le chiavi vengono aggiornate.
Il kubelet controlla se la ConfigMap montata è aggiornata ad ogni periodo di sincronizzazione.
Ad ogni modo, il kubelet usa la sua cache locale per ottenere il valore attuale della ConfigMap.
Il tipo di cache è configurabile usando il campo ConfigMapAndSecretChangeDetectionStrategy nel KubeletConfiguration struct.
Una ConfigMap può essere propagata per vista (default), ttl-based, o redirigendo
tutte le richieste direttamente all'API server.
Come risultato, il ritardo totale dal momento in cui la ConfigMap è aggiornata al momento in cui nuove chiavi sono propagate al Pod può essere tanto lungo quanto il periodo della sincronizzazione del kubelet + il ritardo della propagazione della cache, dove il ritardo della propagazione della cache dipende dal tipo di cache scelta
(è uguale rispettivamente al ritardo della propagazione, ttl della cache, o zero).
Le ConfigMaps consumate come variabili d'ambiente non sono aggiornate automaticamente e necessitano di un riavvio del pod.
Kubernetes v1.21 [stable]
La funzionalità di Kubernetes Immutable Secrets and ConfigMaps fornisce un'opzione per configurare Secrets individuali e ConfigMaps come immutabili. Per clusters che usano le ConfigMaps come estensione (almeno decine o centinaia di ConfigMap uniche montate nel Pod), prevenire i cambiamenti nei loro dati ha i seguenti vantaggi:
Questa funzionalità è controllata dal ImmutableEphemeralVolumes
feature gate.
Puoi creare una ConfigMap immutabile settando il campo immutable a true.
Per esempio:
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
Una volta che una ConfigMap è segnata come immutabile, non è possibile invertire questo cambiamento né cambiare il contenuto del campo data o binaryData field. Puoi solamente cancellare e ricreare la ConfigMap. Poiché i Pods hanno un puntamento verso la ConfigMap eliminata, è raccomandato di ricreare quei Pods.
La panoramica dell'amministrazione del cluster è per chiunque crei o gestisca un cluster Kubernetes. Presuppone una certa dimestichezza con i core Kubernetes concetti.
Consulta le guide di Setup per avere degli esempi su come pianificare, impostare e configurare cluster Kubernetes. Le soluzioni elencate in questo articolo sono chiamate distribuzioni.
Prima di scegliere una guida, ecco alcune considerazioni:
Nota: non tutte le distro vengono mantenute attivamente. Scegli le distro che sono state testate con una versione recente di Kubernetes.
Gestione di un cluster descrive diversi argomenti relativi al ciclo di vita di un cluster: creazione di un nuovo cluster, aggiornamento dei nodi master e worker del cluster, esecuzione della manutenzione del nodo (ad esempio kernel aggiornamenti) e aggiornamento della versione dell'API di Kubernetes di un cluster in esecuzione.
Scopri come gestire i nodi.
Scopri come impostare e gestire la quota di risorse per i cluster condivisi.
Certificati descrive i passaggi per generare certificati utilizzando diverse catene di strumenti.
Kubernetes Container Environment descrive l'ambiente per i contenitori gestiti Kubelet su un nodo Kubernetes.
Controllo dell'accesso all'API di Kubernetes descrive come impostare le autorizzazioni per gli utenti e gli account di servizio.
Autenticazione spiega l'autenticazione in Kubernetes, incluse le varie opzioni di autenticazione.
Autorizzazione è separato dall'autenticazione e controlla come vengono gestite le chiamate HTTP.
Utilizzo dei controller di ammissione spiega i plug-in che intercettano le richieste al server API Kubernetes dopo l'autenticazione e l'autorizzazione.
Uso di Sysctls in un cluster Kubernetes descrive a un amministratore come utilizzare lo strumento da riga di comando sysctl per impostare i parametri del kernel.
Controllo descrive come interagire con i log di controllo di Kubernetes.
Integrazione DNS descrive come risolvere un nome DNS direttamente su un servizio Kubernetes.
Registrazione e monitoraggio delle attività del cluster spiega come funziona il logging in Kubernetes e come implementarlo.
Quando si utilizza l'autenticazione del certificato client, è possibile generare certificati
manualmente tramite easyrsa, openssl o cfssl.
** easyrsa ** può generare manualmente certificati per il tuo cluster.
curl -LO https://dl.k8s.io/easy-rsa/easy-rsa.tar.gz tar xzf easy-rsa.tar.gz cd easy-rsa-master / easyrsa3 ./easyrsa init-pki
--batch imposta la modalità automatica. --req-cn default CN da usare.) ./easyrsa --batch "--req-cn = $ {MASTER_IP} @ date +% s "build-ca nopass
--subject-alt-name imposta i possibili IP e nomi DNS del server API
accessibile con. Il MASTER_CLUSTER_IP è solitamente il primo IP dal servizio CIDR
che è specificato come argomento --service-cluster-ip-range per il server API e
il componente del controller controller. L'argomento --days è usato per impostare il numero di giorni
dopodiché scade il certificato.
L'esempio sotto riportato assume anche che tu stia usando cluster.local come predefinito
Nome di dominio DNS ./easyrsa --subject-alt-name = "IP: $ {MASTER_IP},"
"IP: $ {} MASTER_CLUSTER_IP,"
"DNS: kubernetes,"
"DNS: kubernetes.default,"
"DNS: kubernetes.default.svc,"
"DNS: kubernetes.default.svc.cluster,"
"DNS: kubernetes.default.svc.cluster.local"
--days = 10000
build-server-full server nopass
pki / ca.crt, pki / issued / server.crt e pki / private / server.key nella tua directory.--client-ca-file =/YourDirectory/ca.crt --tls-cert-file =/YourDirectory/server.crt --tls-chiave file privato=/YourDirectory/server.key
** openssl ** può generare manualmente certificati per il tuo cluster.
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/ CN = $ {MASTER_IP}" -days 10000 -out ca.crt
openssl genrsa -out server.key 2048
Creare un file di configurazione per generare una richiesta di firma del certificato (CSR).
Assicurati di sostituire i valori contrassegnati da parentesi angolari (ad esempio <MASTER_IP>)
con valori reali prima di salvarlo in un file (ad esempio csr.conf).
Si noti che il valore di MASTER_CLUSTER_IP è l'IP del cluster di servizio per il
Server API come descritto nella sottosezione precedente.
L'esempio sotto riportato assume anche che tu stia usando cluster.local come predefinito
Nome di dominio DNS
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = <country>
ST = <state>
L = <city>
O = <organization>
OU = <organization unit>
CN = <MASTER_IP>
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.default.svc.cluster.local
IP.1 = <MASTER_IP>
IP.2 = <MASTER_CLUSTER_IP>
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
Generate the certificate signing request based on the config file:
openssl req -new -key server.key -out server.csr -config csr.conf
Generare il certificato del server usando ca.key, ca.crt e server.csr:
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 10000 \
-extensions v3_ext -extfile csr.conf -sha256
Visualizza il certificato:
openssl x509 -noout -text -in ./server.crt
Infine, aggiungi gli stessi parametri nei parametri di avvio del server API.
** cfssl ** è un altro strumento per la generazione di certificati.
Scaricare, decomprimere e preparare gli strumenti da riga di comando come mostrato di seguito. Si noti che potrebbe essere necessario adattare i comandi di esempio in base all'hardware architettura e versione di cfssl che stai utilizzando.
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o cfssl
chmod +x cfssl
curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o cfssljson
chmod +x cfssljson
curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o cfssl-certinfo
chmod +x cfssl-certinfo
Create a directory to hold the artifacts and initialize cfssl:
mkdir cert
cd cert
../cfssl print-defaults config > config.json
../cfssl print-defaults csr > csr.json
Creare un file di configurazione JSON per generare il file CA, ad esempio, ca-config.json:
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
Creare un file di configurazione JSON per la richiesta di firma del certificato CA (CSR), ad esempio,
Ca-csr.json. Assicurarsi di sostituire i valori contrassegnati da parentesi angolari con
valori reali che si desidera utilizzare.
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names":[{
"C": "<country>",
"ST": "<state>",
"L": "<city>",
"O": "<organization>",
"OU": "<organization unit>"
}]
}
Generate CA key (ca-key.pem) and certificate (ca.pem):
../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
Creare un file di configurazione JSON per generare chiavi e certificati per l'API
server, ad esempio, server-csr.json. Assicurati di sostituire i valori tra parentesi angolari con
valori reali che si desidera utilizzare. MASTER_CLUSTER_IP è il cluster di servizio
IP per il server API come descritto nella sottosezione precedente.
L'esempio sotto riportato assume anche che tu stia usando cluster.local come predefinito
Nome di dominio DNS
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"<MASTER_IP>",
"<MASTER_CLUSTER_IP>",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "<country>",
"ST": "<state>",
"L": "<city>",
"O": "<organization>",
"OU": "<organization unit>"
}]
}
Generare la chiave e il certificato per il server API, che sono per impostazione predefinita
salvati nel file server-key.pem e server.pem rispettivamente:
../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
--config=ca-config.json -profile=kubernetes \
server-csr.json | ../cfssljson -bare server
Un nodo client può rifiutarsi di riconoscere un certificato CA autofirmato come valido. Per una distribuzione non di produzione o per una distribuzione che viene eseguita dietro una società firewall, è possibile distribuire un certificato CA autofirmato a tutti i client e aggiornare l'elenco locale per i certificati validi.
Su ciascun client, eseguire le seguenti operazioni:
$ sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....
done.
È possibile utilizzare l'API certificates.k8s.io per eseguire il provisioning
certificati x509 da utilizzare per l'autenticazione come documentato
here.
Questa pagina spiega come gestire Kubernetes in esecuzione su uno specifico fornitore di servizi cloud.
kubeadm è un'opzione popolare per la creazione di cluster di kuberneti. kubeadm ha opzioni di configurazione per specificare le informazioni di configurazione per i provider cloud. Ad esempio un tipico il provider cloud in-tree può essere configurato utilizzando kubeadm come mostrato di seguito:
apiVersion: kubeadm.k8s.io/v1beta1
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
---
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: v1.13.0
apiServer:
extraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
extraVolumes:
- name: cloud
hostPath: "/etc/kubernetes/cloud.conf"
mountPath: "/etc/kubernetes/cloud.conf"
controllerManager:
extraArgs:
cloud-provider: "openstack"
cloud-config: "/etc/kubernetes/cloud.conf"
extraVolumes:
- name: cloud
hostPath: "/etc/kubernetes/cloud.conf"
mountPath: "/etc/kubernetes/cloud.conf"
I provider cloud in-tree in genere richiedono sia --cloud-provider e --cloud-config specificati nelle righe di
comando per kube-apiserver, kube-controller-manager
e il Kubelet. Anche il contenuto del file specificato in --cloud-config per ciascun provider
è documentato di seguito.
Per tutti i fornitori di servizi cloud esterni, seguire le istruzioni sui singoli repository.
Questa sezione descrive tutte le possibili configurazioni che possono essere utilizzato durante l'esecuzione di Kubernetes su Amazon Web Services.
Il provider cloud AWS utilizza il nome DNS privato dell'istanza AWS come nome dell'oggetto Nodo Kubernetes.
È possibile impostare bilanciamento del carico esterno per utilizzare funzionalità specifiche in AWS configurando le annotazioni come mostrato di seguito.
apiVersion: v1
kind: Service
metadata:
name: example
namespace: kube-system
labels:
run: example
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:xx-xxxx-x:xxxxxxxxx:xxxxxxx/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxx #replace this value
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
spec:
type: LoadBalancer
ports:
- port: 443
targetPort: 5556
protocol: TCP
selector:
app: example
È possibile applicare impostazioni diverse a un servizio di bilanciamento del carico in AWS utilizzando annotations. Quanto segue descrive le annotazioni supportate su ELB AWS:
service.beta.kubernetes.io / aws-load-balancer-access-log-emit-interval: utilizzato per specificare l'intervallo di emissione del registro di accesso.service.beta.kubernetes.io / aws-load-balancer-access-log-enabled: utilizzato sul servizio per abilitare o disabilitare i log di accesso.service.beta.kubernetes.io / aws-load-balancer-access-log-s3-bucket-name: usato per specificare il nome del bucket di log degli accessi s3.service.beta.kubernetes.io / aws-load-balancer-access-log-s3-bucket-prefix: utilizzato per specificare il prefisso del bucket del registro di accesso s3.service.beta.kubernetes.io / aws-load-balancer-additional-resource-tags: utilizzato sul servizio per specificare un elenco separato da virgole di coppie chiave-valore che verranno registrate come tag aggiuntivi nel ELB. Ad esempio: "Key1 = Val1, Key2 = Val2, KeyNoVal1 =, KeyNoVal2".service.beta.kubernetes.io / aws-load-balancer-backend-protocol: utilizzato sul servizio per specificare il protocollo parlato dal backend (pod) dietro un listener. Se http (predefinito) o https, viene creato un listener HTTPS che termina la connessione e analizza le intestazioni. Se impostato su ssl o tcp, viene utilizzato un listener SSL "raw". Se impostato su http e aws-load-balancer-ssl-cert non viene utilizzato, viene utilizzato un listener HTTP.service.beta.kubernetes.io / aws-load-balancer-ssl-cert: utilizzato nel servizio per richiedere un listener sicuro. Il valore è un certificato ARN valido. Per ulteriori informazioni, vedere ELB Listener Config CertARN è un ARN certificato IAM o CM, ad es. ARN: AWS: ACM: US-est-1: 123456789012: certificato / 12345678-1234-1234-1234-123456789012.service.beta.kubernetes.io / aws-load-balancer-connection-draining-enabled: utilizzato sul servizio per abilitare o disabilitare il drenaggio della connessione.service.beta.kubernetes.io / aws-load-balancer-connection-draining-timeout: utilizzato sul servizio per specificare un timeout di drenaggio della connessione.service.beta.kubernetes.io / aws-load-balancer-connection-idle-timeout: utilizzato sul servizio per specificare il timeout della connessione inattiva.service.beta.kubernetes.io / aws-load-balancer-cross-zone-load-bilanciamento-abilitato: utilizzato sul servizio per abilitare o disabilitare il bilanciamento del carico tra zone.service.beta.kubernetes.io / aws-load-balancer-extra-security-groups: utilizzato sul servizio per specificare gruppi di sicurezza aggiuntivi da aggiungere a ELB creatoservice.beta.kubernetes.io / aws-load-balancer-internal: usato nel servizio per indicare che vogliamo un ELB interno.service.beta.kubernetes.io / aws-load-balancer-proxy-protocol: utilizzato sul servizio per abilitare il protocollo proxy su un ELB. Al momento accettiamo solo il valore * che significa abilitare il protocollo proxy su tutti i backend ELB. In futuro potremmo regolarlo per consentire l'impostazione del protocollo proxy solo su determinati backend.service.beta.kubernetes.io / aws-load-balancer-ssl-ports: utilizzato sul servizio per specificare un elenco di porte separate da virgole che utilizzeranno listener SSL / HTTPS. Il valore predefinito è * (tutto)Le informazioni per le annotazioni per AWS sono tratte dai commenti su aws.go
Il provider cloud di Azure utilizza il nome host del nodo (come determinato dal kubelet o sovrascritto
con --hostname-override) come nome dell'oggetto Nodo Kubernetes. Si noti che il nome del nodo Kubernetes deve
corrispondere al nome VM di Azure.
Il provider cloud CloudStack utilizza il nome host del nodo (come determinato dal kubelet o sovrascritto
con --hostname-override) come nome dell'oggetto Nodo Kubernetes. Si noti che il nome del nodo Kubernetes deve
corrispondere al nome VM di CloudStack.
Il provider cloud GCE utilizza il nome host del nodo (come determinato dal kubelet o sovrascritto
con --hostname-override) come nome dell'oggetto Nodo Kubernetes. Si noti che il primo segmento del nome del nodo
Kubernetes deve corrispondere al nome dell'istanza GCE (ad esempio, un nodo denominato kubernetes-node-2.c.my-proj.internal
deve corrispondere a un'istanza denominata kubernetes-node-2) .
Questa sezione descrive tutte le possibili configurazioni che possono essere utilizzato quando si utilizza OpenStack con Kubernetes.
Il provider cloud OpenStack utilizza il nome dell'istanza (come determinato dai metadati OpenStack) come nome dell'oggetto Nodo Kubernetes. Si noti che il nome dell'istanza deve essere un nome nodo Kubernetes valido affinché kubelet registri correttamente il suo oggetto Node.
Il provider cloud OpenStack implementazione per Kubernetes supporta l'uso di questi servizi OpenStack da la nuvola sottostante, ove disponibile:
| Servizio | Versioni API | Richiesto | | -------------------------- | ---------------- | ----- ----- | | Block Storage (Cinder) | V1 †, V2, V3 | No | | Calcola (Nova) | V2 | No | | Identity (Keystone) | V2 ‡, V3 | Sì | | Load Balancing (Neutron) | V1§, V2 | No | | Load Balancing (Octavia) | V2 | No |
† Il supporto dell'API di storage block V1 è obsoleto, il supporto dell'API di Storage Block V3 era aggiunto in Kubernetes 1.9.
‡ Il supporto dell'API di Identity V2 è obsoleto e verrà rimosso dal provider in una versione futura. A partire dalla versione "Queens", OpenStack non esporrà più il file Identity V2 API.
§ Il supporto per il bilanciamento del carico V1 API è stato rimosso in Kubernetes 1.9.
La scoperta del servizio si ottiene elencando il catalogo dei servizi gestito da
OpenStack Identity (Keystone) usando auth-url fornito nel provider
configurazione. Il fornitore si degraderà garbatamente in funzionalità quando
I servizi OpenStack diversi da Keystone non sono disponibili e semplicemente disconoscono
supporto per le caratteristiche interessate. Alcune funzionalità sono anche abilitate o disabilitate
in base all'elenco delle estensioni pubblicate da Neutron nel cloud sottostante.
Kubernetes sa come interagire con OpenStack tramite il file cloud.conf. È il file che fornirà a Kubernetes le credenziali e il percorso per l'endpoint auth di OpenStack. È possibile creare un file cloud.conf specificando i seguenti dettagli in esso
Questo è un esempio di una configurazione tipica che tocca i valori più spesso devono essere impostati. Punta il fornitore al Keystone del cloud di OpenStack endpoint, fornisce dettagli su come autenticarsi con esso e configura il bilanciamento del carico:
[Global]
username=user
password=pass
auth-url=https://<keystone_ip>/identity/v3
tenant-id=c869168a828847f39f7f06edd7305637
domain-id=2a73b8f597c04551a0fdc8e95544be8a
[LoadBalancer]
subnet-id=6937f8fa-858d-4bc9-a3a5-18d2c957166a
Queste opzioni di configurazione per il provider OpenStack riguardano la sua globalità
configurazione e dovrebbe apparire nella sezione [Globale] di cloud.conf
file:
auth-url (obbligatorio): l'URL dell'API keystone utilizzata per l'autenticazione. Sopra
Pannelli di controllo OpenStack, questo può essere trovato in Access and Security> API
Accesso> Credenziali.username (obbligatorio): si riferisce al nome utente di un set utente valido in keystone.password (obbligatorio): fa riferimento alla password di un set utente valido in keystone.tenant-id (obbligatorio): usato per specificare l'id del progetto dove si desidera
per creare le tue risorse.tenant-name (Opzionale): utilizzato per specificare il nome del progetto in cui si trova
vuoi creare le tue risorse.trust-id (Opzionale): utilizzato per specificare l'identificativo del trust da utilizzare
autorizzazione. Un trust rappresenta l'autorizzazione di un utente (il fidato) a
delegare i ruoli a un altro utente (il trustee) e facoltativamente consentire al trustee
per impersonare il fiduciario. I trust disponibili si trovano sotto
/v3/OS-TRUST/trust endpoint dell'API Keystone.domain-id (Opzionale): usato per specificare l'id del dominio a cui appartiene l'utente
a.domain-name (Opzionale): utilizzato per specificare il nome del dominio dell'utente
appartiene a.region (Opzionale): utilizzato per specificare l'identificatore della regione da utilizzare quando
in esecuzione su un cloud OpenStack multiregionale. Una regione è una divisione generale di
una distribuzione OpenStack. Anche se una regione non ha una geografia rigorosa
connotazione, una distribuzione può utilizzare un nome geografico per un identificatore di regione
come us-east. Le regioni disponibili si trovano sotto /v3/region
endpoint dell'API Keystone.ca-file (Opzionale): utilizzato per specificare il percorso del file CA personalizzato.Quando si usa Keystone V3 - che cambia il titolare del progetto - il valore tenant-id
viene automaticamente associato al costrutto del progetto nell'API.
Queste opzioni di configurazione per il provider OpenStack riguardano il carico
bilanciamento e dovrebbe apparire nella sezione [LoadBalancer] di cloud.conf
file:
lb-version (Opzionale): usato per sovrascrivere il rilevamento automatico della versione. Valido
i valori sono v1 o v2. Dove non viene fornito alcun valore, lo sarà il rilevamento automatico
seleziona la versione supportata più alta esposta dal sottostante OpenStack
nube.use-octavia (Opzionale): utilizzato per determinare se cercare e utilizzare un
Octavia LBaaS V2 endpoint del catalogo di servizi. I valori validi sono true o false.
Dove true è specificato e non è possibile trovare una voce V2 Octaiva LBaaS, il
il provider si ritirerà e tenterà di trovare un endpoint Neutron LBaaS V2
anziché. Il valore predefinito è false.subnet-id (Opzionale): usato per specificare l'id della sottorete che si desidera
crea il tuo loadbalancer su Può essere trovato su Rete> Reti. Clicca sul
rispettiva rete per ottenere le sue sottoreti.floating-network-id (Opzionale): se specificato, creerà un IP mobile per
il bilanciamento del carico.lb-method (Opzionale): utilizzato per specificare l'algoritmo in base al quale verrà caricato il carico
distribuito tra i membri del pool di bilanciamento del carico. Il valore può essere
ROUND_ROBIN, LEAST_CONNECTIONS o SOURCE_IP. Il comportamento predefinito se
nessuno è specificato è ROUND_ROBIN.lb-provider (Opzionale): utilizzato per specificare il provider del servizio di bilanciamento del carico.
Se non specificato, sarà il servizio provider predefinito configurato in neutron
Usato.create-monitor (Opzionale): indica se creare o meno una salute
monitorare il bilanciamento del carico Neutron. I valori validi sono true e false.
L'impostazione predefinita è false. Quando è specificato true quindi monitor-delay,
monitor-timeout, e monitor-max-retries deve essere impostato.monitor-delay (Opzionale): il tempo tra l'invio delle sonde a
membri del servizio di bilanciamento del carico. Assicurati di specificare un'unità di tempo valida. Le unità di tempo
valide sono "ns", "us" (o "μs"), "ms", "s", "m", "h"monitor-timeout (Opzionale): tempo massimo di attesa per un monitor
per una risposta ping prima che scada. Il valore deve essere inferiore al ritardo
valore. Assicurati di specificare un'unità di tempo valida. Le unità di tempo valide sono "ns", "us" (o "μs"), "ms", "s", "m", "h"monitor-max-retries (Opzionale): numero di errori ping consentiti prima
cambiare lo stato del membro del bilanciamento del carico in INATTIVO. Deve essere un numero
tra 1 e 10.manage-security-groups (Opzionale): Determina se il carico è o meno
il sistema di bilanciamento dovrebbe gestire automaticamente le regole del gruppo di sicurezza. Valori validi
sono true e false. L'impostazione predefinita è false. Quando è specificato true
node-security-group deve anche essere fornito.node-security-group (Opzionale): ID del gruppo di sicurezza da gestire.Queste opzioni di configurazione per il provider OpenStack riguardano lo storage a blocchi
e dovrebbe apparire nella sezione [BlockStorage] del file cloud.conf:
bs-version (Opzionale): usato per sovrascrivere il rilevamento automatico delle versioni. Valido
i valori sono v1, v2, v3 e auto. Quando auto è specificato automatico
il rilevamento selezionerà la versione supportata più alta esposta dal sottostante
Cloud OpenStack. Il valore predefinito se nessuno è fornito è auto.trust-device-path (Opzionale): Nella maggior parte degli scenari i nomi dei dispositivi a blocchi
fornito da Cinder (ad esempio /dev/vda) non può essere considerato attendibile. Questo commutatore booleano
questo comportamento Impostandolo su true risulta fidarsi dei nomi dei dispositivi a blocchi
fornito da Cinder. Il valore predefinito di false risulta nella scoperta di
il percorso del dispositivo in base al suo numero di serie e mappatura /dev/disk/by-id ed è
l'approccio raccomandatoignore-volume-az (Opzionale): usato per influenzare l'uso della zona di disponibilità quando
allegando i volumi di Cinder. Quando Nova e Cinder hanno una diversa disponibilità
zone, questo dovrebbe essere impostato su true. Questo è più comunemente il caso in cui
ci sono molte zone di disponibilità Nova ma solo una zona di disponibilità Cinder.
Il valore predefinito è false per preservare il comportamento utilizzato in precedenza
rilasci, ma potrebbero cambiare in futuro.Se si distribuiscono le versioni di Kubernetes <= 1.8 su una distribuzione OpenStack che utilizza
percorsi piuttosto che porte per distinguere tra endpoint potrebbe essere necessario
per impostare in modo esplicito il parametro bs-version. Un endpoint basato sul percorso è del
forma http://foo.bar/ volume mentre un endpoint basato sulla porta è del modulo
Http://foo.bar: xxx.
In ambienti che utilizzano endpoint basati sul percorso e Kubernetes utilizza il precedente logica di auto-rilevamento un errore dell'autodeterminazione della versione API BS non riuscito. Errore restituito al tentativo di distacco del volume. Per risolvere questo problema lo è possibile forzare l'uso dell'API di Cinder versione 2 aggiungendo questo al cloud configurazione del provider:
[BlockStorage]
bs-version=v2
Queste opzioni di configurazione per il provider OpenStack riguardano i metadati e
dovrebbe apparire nella sezione [Metadata] del file cloud.conf:
ricerca-ordine (facoltativo): questo tasto di configurazione influenza il modo in cui il
il provider recupera i metadati relativi alle istanze in cui viene eseguito. Il
il valore predefinito di configDrive, metadataService risulta nel provider
recuperare i metadati relativi all'istanza dall'unità di configurazione prima se
disponibile e quindi il servizio di metadati. I valori alternativi sono:
* configDrive - recupera solo i metadati dell'istanza dalla configurazione
guidare.
* metadataService: recupera solo i metadati dell'istanza dai metadati
servizio.
* metadataService, configDrive - Recupera i metadati dell'istanza dai metadati
prima assistenza se disponibile, quindi l'unità di configurazione.Influenzare questo comportamento può essere desiderabile come i metadati sul l'unità di configurazione può diventare obsoleta nel tempo, mentre il servizio di metadati fornisce sempre la vista più aggiornata. Non tutti i cloud di OpenStack forniscono sia l'unità di configurazione che il servizio di metadati e solo l'uno o l'altro potrebbe essere disponibile, motivo per cui l'impostazione predefinita è controllare entrambi.
Queste opzioni di configurazione per il provider OpenStack riguardano kubenet
Il plugin di rete di Kubernetes dovrebbe apparire nella sezione [Router] di
File cloud.conf:
router-id (opzionale): se supporta la distribuzione Neutron del cloud sottostante
l'estensione extraroutes quindi usa router-id per specificare un router da aggiungere
percorsi per. Il router scelto deve estendersi alle reti private che contengono il tuo
nodi del cluster (in genere esiste solo una rete di nodi e questo valore dovrebbe essere
il router predefinito per la rete di nodi). Questo valore è necessario per utilizzare kubenet
su OpenStack.Il provider di cloud OVirt utilizza il nome host del nodo (come determinato dal kubelet o sovrascritto
con --hostname-override) come nome dell'oggetto Nodo Kubernetes. Si noti che il nome del nodo Kubernetes deve
corrispondere al FQDN del VM (riportato da OVirt in <vm> <guest_info> <fqdn> ... </fqdn> </guest_info> </vm>)
Il provider cloud Photon utilizza il nome host del nodo (come determinato dal kubelet o sovrascritto
con --hostname-override) come nome dell'oggetto Nodo Kubernetes. Si noti che il nome del nodo Kubernetes deve
corrispondere al nome VM Photon (o se "overrideIP è impostato su true in --cloud-config`, il nome del nodo Kubernetes
deve corrispondere all'indirizzo IP della macchina virtuale Photon).
Il provider cloud VSphere utilizza il nome host rilevato del nodo (come determinato dal kubelet) come nome dell'oggetto Nodo Kubernetes.
Il parametro --hostname-override viene ignorato dal fornitore di cloud VSphere.
Utilizzando il provider di servizi IBM Cloud Kubernetes, è possibile creare cluster con una combinazione di nodi virtuali e fisici (bare metal) in una singola zona o su più zone in una regione. Per ulteriori informazioni, consultare Pianificazione dell'installazione di cluster e nodo di lavoro.
Il nome dell'oggetto Nodo Kubernetes è l'indirizzo IP privato dell'istanza del nodo di lavoro IBM Cloud Kubernetes Service.
Il fornitore di servizi IBM Cloud Kubernetes fornisce VLAN per le prestazioni di rete di qualità e l'isolamento della rete per i nodi. È possibile configurare firewall personalizzati e criteri di rete Calico per aggiungere un ulteriore livello di sicurezza per il cluster o per connettere il cluster al data center on-prem tramite VPN. Per ulteriori informazioni, vedere Pianificazione in-cluster e rete privata.
Per esporre le app al pubblico o all'interno del cluster, è possibile sfruttare i servizi NodePort, LoadBalancer o Ingress. È anche possibile personalizzare il bilanciamento del carico dell'applicazione Ingress con le annotazioni. Per ulteriori informazioni, vedere Pianificazione per esporre le app con reti esterne.
Il fornitore di servizi IBM Cloud Kubernetes sfrutta i volumi persistenti nativi di Kubernetes per consentire agli utenti di montare archiviazione di file, blocchi e oggetti cloud nelle loro app. È inoltre possibile utilizzare il componente aggiuntivo database-as-a-service e di terze parti per la memorizzazione permanente dei dati. Per ulteriori informazioni, vedere Pianificazione dell'archiviazione persistente altamente disponibile.
Il provider di cloud Baidu utilizza l'indirizzo IP privato del nodo (come determinato dal kubelet o sovrascritto
con --hostname-override) come nome dell'oggetto Nodo Kubernetes. Si noti che il nome del nodo Kubernetes deve
corrispondere all'IP privato VM di Baidu.
Hai distribuito la tua applicazione e l'hai esposta tramite un servizio. Ora cosa? Kubernetes fornisce una serie di strumenti per aiutarti a gestire la distribuzione delle applicazioni, compreso il ridimensionamento e l'aggiornamento. Tra le caratteristiche che discuteremo in modo più approfondito ci sono file di configurazione e labels.
Molte applicazioni richiedono la creazione di più risorse, ad esempio una distribuzione e un servizio. La gestione di più risorse può essere semplificata raggruppandole nello stesso file (separate da --- in YAML). Per esempio:
apiVersion: v1
kind: Service
metadata:
name: my-nginx-svc
labels:
app: nginx
spec:
type: LoadBalancer
ports:
- port: 80
selector:
app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Multiple resources can be created the same way as a single resource:
$ kubectl create -f https://k8s.io/examples/application/nginx-app.yaml
service/my-nginx-svc created
deployment.apps/my-nginx created
Le risorse verranno create nell'ordine in cui appaiono nel file. Pertanto, è meglio specificare prima il servizio, poiché ciò assicurerà che lo scheduler possa distribuire i pod associati al servizio man mano che vengono creati dal / i controller, ad esempio Deployment.
kubectl create accetta anche più argomenti -f:
$ kubectl create -f https://k8s.io/examples/application/nginx/nginx-svc.yaml -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
E una directory può essere specificata piuttosto che o in aggiunta ai singoli file:
$ kubectl create -f https://k8s.io/examples/application/nginx/
kubectl leggerà tutti i file con suffissi .yaml, .yml o .json.
Si consiglia di inserire nello stesso file risorse correlate allo stesso livello di microservice o di applicazione e di raggruppare tutti i file associati all'applicazione nella stessa directory. Se i livelli dell'applicazione si associano tra loro tramite DNS, è quindi possibile distribuire in massa tutti i componenti dello stack.
Un URL può anche essere specificato come origine di configurazione, utile per la distribuzione direttamente dai file di configurazione controllati in github:
$ kubectl create -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx created
La creazione di risorse non è l'unica operazione che kubectl può eseguire alla rinfusa. Può anche estrarre i nomi delle risorse dai file di configurazione per eseguire altre operazioni, in particolare per eliminare le stesse risorse che hai creato:
$ kubectl delete -f https://k8s.io/examples/application/nginx-app.yaml
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
Nel caso di due sole risorse, è anche facile specificare entrambi sulla riga di comando usando la sintassi risorsa / nome:
$ kubectl delete deployments/my-nginx services/my-nginx-svc
Per un numero maggiore di risorse, troverai più semplice specificare il selettore (query etichetta) specificato usando -l o --selector, per filtrare le risorse in base alle loro etichette:
$ kubectl delete deployment,services -l app=nginx
deployment.apps "my-nginx" deleted
service "my-nginx-svc" deleted
130/5000
Poiché kubectl restituisce i nomi delle risorse nella stessa sintassi che accetta, è facile concatenare le operazioni usando$ ()o xargs:
$ kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-nginx-svc LoadBalancer 10.0.0.208 <pending> 80/TCP 0s
Con i suddetti comandi, prima creiamo le risorse sotto examples/application/nginx/ e stampiamo le risorse create con il formato di output -o name
(stampa ogni risorsa come risorsa / nome). Quindi grep solo il" servizio ", e poi lo stampiamo con kubectl get.
Se si organizzano le risorse su più sottodirectory all'interno di una particolare directory, è possibile eseguire ricorsivamente anche le operazioni nelle sottodirectory, specificando --recursive o -R accanto al flag --filename, -f.
Ad esempio, supponiamo che ci sia una directory project/k8s/development che contiene tutti i manifesti necessari per l'ambiente di sviluppo, organizzati per tipo di risorsa:
project/k8s/development
├── configmap
│ └── my-configmap.yaml
├── deployment
│ └── my-deployment.yaml
└── pvc
└── my-pvc.yaml
Per impostazione predefinita, l'esecuzione di un'operazione bulk su project/k8s/development si interromperà al primo livello della directory, senza elaborare alcuna sottodirectory. Se avessimo provato a creare le risorse in questa directory usando il seguente comando, avremmo riscontrato un errore:
$ kubectl create -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)
Invece, specifica il flag --recursive o -R con il flag --filename, -f come tale:
$ kubectl create -f project/k8s/development --recursive
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
Il flag --recursive funziona con qualsiasi operazione che accetta il flag --filename, -f come: kubectl {crea, ottieni, cancella, descrivi, implementa} ecc .
Il flag --recursive funziona anche quando sono forniti più argomenti -f:
$ kubectl create -f project/k8s/namespaces -f project/k8s/development --recursive
namespace/development created
namespace/staging created
configmap/my-config created
deployment.apps/my-deployment created
persistentvolumeclaim/my-pvc created
Se sei interessato a saperne di più su kubectl, vai avanti e leggi Panoramica di kubectl.
Gli esempi che abbiamo utilizzato fino ad ora si applicano al massimo una singola etichetta a qualsiasi risorsa. Esistono molti scenari in cui è necessario utilizzare più etichette per distinguere i set l'uno dall'altro.
Ad esempio, diverse applicazioni utilizzerebbero valori diversi per l'etichetta app, ma un'applicazione multilivello, come l'esempio guestbook, avrebbe inoltre bisogno di distinguere ogni livello. Il frontend potrebbe contenere le seguenti etichette:
labels:
app: guestbook
tier: frontend
while the Redis master and slave would have different tier labels, and perhaps even an additional role label:
labels:
app: guestbook
tier: backend
role: master
and
labels:
app: guestbook
tier: backend
role: slave
Le etichette ci permettono di tagliare e tagliare le nostre risorse lungo qualsiasi dimensione specificata da un'etichetta:
$ kubectl create -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
$ kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-ght6d 1/1 Running 0 1m guestbook frontend <none>
guestbook-fe-jpy62 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-slave-2q2yf 1/1 Running 0 1m guestbook backend slave
guestbook-redis-slave-qgazl 1/1 Running 0 1m guestbook backend slave
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
my-nginx-o0ef1 1/1 Running 0 29m nginx <none> <none>
$ kubectl get pods -lapp=guestbook,role=slave
NAME READY STATUS RESTARTS AGE
guestbook-redis-slave-2q2yf 1/1 Running 0 3m
guestbook-redis-slave-qgazl 1/1 Running 0 3m
Un altro scenario in cui sono necessarie più etichette è quello di distinguere distribuzioni di diverse versioni o configurazioni dello stesso componente. È prassi comune distribuire un * canarino * di una nuova versione dell'applicazione (specificata tramite il tag immagine nel modello pod) parallelamente alla versione precedente in modo che la nuova versione possa ricevere il traffico di produzione in tempo reale prima di distribuirlo completamente.
Ad esempio, puoi usare un'etichetta track per differenziare le diverse versioni.
La versione stabile e primaria avrebbe un'etichetta track con valore come stable:
name: frontend
replicas: 3
...
labels:
app: guestbook
tier: frontend
track: stable
...
image: gb-frontend:v3
e quindi puoi creare una nuova versione del frontend del guestbook che porta l'etichetta track con un valore diverso
(ad esempio canary), in modo che due gruppi di pod non si sovrappongano:
name: frontend-canary
replicas: 1
...
labels:
app: guestbook
tier: frontend
track: canary
...
image: gb-frontend:v4
Il servizio di frontend coprirebbe entrambe le serie di repliche selezionando il sottoinsieme comune delle loro
etichette (ad esempio omettendo l'etichetta track), in modo che il traffico venga reindirizzato ad entrambe le
applicazioni:
selector:
app: guestbook
tier: frontend
452/5000 È possibile modificare il numero di repliche delle versioni stable e canary per determinare il rapporto tra ciascuna versione che riceverà il traffico di produzione live (in questo caso, 3: 1). Una volta che sei sicuro, puoi aggiornare la traccia stabile alla nuova versione dell'applicazione e rimuovere quella canarino.
Per un esempio più concreto, controlla il tutorial di distribuzione di Ghost.
A volte i pod esistenti e altre risorse devono essere rinominati prima di creare nuove risorse. Questo può essere fatto
con l'etichetta kubectl. Ad esempio, se desideri etichettare tutti i tuoi pod nginx come livello frontend, esegui
semplicemente:
$ kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
pod/my-nginx-2035384211-u3t6x labeled
Questo prima filtra tutti i pod con l'etichetta "app = nginx", quindi li etichetta con il "tier = fe". Per vedere i pod appena etichettati, esegui:
$ kubectl get pods -l app=nginx -L tier
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
my-nginx-2035384211-u3t6x 1/1 Running 0 23m fe
questo produce tutti i pod "app = nginx", con un'ulteriore colonna di etichette del livello dei pod (specificata
con -L o --label-columns).
Per ulteriori informazioni, consultare labels e kubectl label.
A volte vorresti allegare annotazioni alle risorse. Le annotazioni sono metadati arbitrari non identificativi per il
recupero da parte di client API come strumenti, librerie, ecc. Questo può essere fatto con kubectl annotate. Per
esempio:
$ kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
$ kubectl get pods my-nginx-v4-9gw19 -o yaml
apiversion: v1
kind: pod
metadata:
annotations:
description: my frontend running nginx
...
Per ulteriori informazioni, consultare il documento annotazioni e kubectl annotate.
Quando si carica o si riduce la richiesta, è facile ridimensionare con kubectl. Ad esempio, per ridurre il numero di
repliche nginx da 3 a 1, fare:
$ kubectl scale deployment/my-nginx --replicas=1
deployment.apps/my-nginx scaled
Ora hai solo un pod gestito dalla distribuzione
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
my-nginx-2035384211-j5fhi 1/1 Running 0 30m
Per fare in modo che il sistema scelga automaticamente il numero di repliche nginx secondo necessità, da 1 a 3, fare:
$ kubectl autoscale deployment/my-nginx --min=1 --max=3
horizontalpodautoscaler.autoscaling/my-nginx autoscaled
Ora le repliche di nginx verranno ridimensionate automaticamente in base alle esigenze.
Per maggiori informazioni, vedi scala kubectl, kubectl autoscale e documento orizzontale pod autoscaler.
A volte è necessario apportare aggiornamenti stretti e senza interruzioni alle risorse che hai creato.
Si consiglia di mantenere un set di file di configurazione nel controllo del codice sorgente (vedere
configurazione come codice), in modo che possano essere
mantenuti e versionati insieme al codice per le risorse che configurano. Quindi, puoi usare
kubectl apply per inviare le modifiche alla configurazione
nel cluster.
Questo comando confronterà la versione della configurazione che stai spingendo con la versione precedente e applicherà le modifiche che hai apportato, senza sovrascrivere le modifiche automatiche alle proprietà che non hai specificato.
$ kubectl apply -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml
deployment.apps/my-nginx configured
Si noti che kubectl apply allega un'annotazione alla risorsa per determinare le modifiche alla configurazione
dall'invocazione precedente. Quando viene invocato, kubectl apply fa una differenza a tre tra la configurazione
precedente, l'input fornito e la configurazione corrente della risorsa, al fine di determinare come modificare la
risorsa.
Attualmente, le risorse vengono create senza questa annotazione, quindi la prima chiamata di kubectl apply ricadrà su
una differenza a due vie tra l'input fornito e la configurazione corrente della risorsa. Durante questa prima chiamata,
non è in grado di rilevare l'eliminazione delle proprietà impostate al momento della creazione della risorsa. Per questo
motivo, non li rimuoverà.
Tutte le chiamate successive a kubectl apply, e altri comandi che modificano la configurazione, come kubectl replace
e kubectl edit, aggiorneranno l'annotazione, consentendo le successive chiamate a kubectl apply per rilevare ed
eseguire cancellazioni usando un tre via diff.
kubectl apply or kubectl create --save-config.In alternativa, puoi anche aggiornare le risorse con kubectl edit:
$ kubectl edit deployment/my-nginx
Questo equivale a prima get la risorsa, modificarla nell'editor di testo e quindi apply la risorsa con la
versione aggiornata:
$ kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
$ vi /tmp/nginx.yaml
# do some edit, and then save the file
$ kubectl apply -f /tmp/nginx.yaml
deployment.apps/my-nginx configured
$ rm /tmp/nginx.yaml
Questo ti permette di fare più cambiamenti significativi più facilmente. Nota che puoi specificare l'editor con le
variabili di ambiente EDITOR o KUBE_EDITOR.
Per ulteriori informazioni, consultare il documento kubectl edit.
You can use kubectl patch to update API objects in place. This command supports JSON patch,
JSON merge patch, and strategic merge patch. See
Update API Objects in Place Using kubectl patch
and
kubectl patch.
375/5000
In alcuni casi, potrebbe essere necessario aggiornare i campi di risorse che non possono essere aggiornati una volta
inizializzati, oppure si può semplicemente voler fare immediatamente una modifica ricorsiva, come per esempio correggere
i pod spezzati creati da una distribuzione. Per cambiare tali campi, usa replace --force, che elimina e ricrea la
risorsa. In questo caso, puoi semplicemente modificare il tuo file di configurazione originale:
$ kubectl replace -f https://k8s.io/examples/application/nginx/nginx-deployment.yaml --force
deployment.apps/my-nginx deleted
deployment.apps/my-nginx replaced
A un certo punto, alla fine sarà necessario aggiornare l'applicazione distribuita, in genere specificando una nuova
immagine o un tag immagine, come nello scenario di distribuzione canarino precedente. kubectl supporta diverse
operazioni di aggiornamento, ognuna delle quali è applicabile a diversi scenari.
Ti guideremo attraverso come creare e aggiornare le applicazioni con le distribuzioni. Se l'applicazione distribuita è
gestita dai controller di replica, dovresti leggere
come usare kubectl rolling-update.
Diciamo che stavi usando la versione 1.7.9 di nginx:
$ kubectl run my-nginx --image=nginx:1.7.9 --replicas=3
deployment.apps/my-nginx created
Per aggiornare alla versione 1.9.1, cambia semplicemente .spec.template.spec.containers [0] .image da nginx: 1.7.9
a nginx: 1.9.1, con i comandi kubectl che abbiamo imparato sopra.
$ kubectl edit deployment/my-nginx
Questo è tutto! La distribuzione aggiornerà in modo dichiarativo l'applicazione nginx distribuita progressivamente dietro la scena. Garantisce che solo un certo numero di vecchie repliche potrebbe essere inattivo mentre vengono aggiornate e solo un certo numero di nuove repliche può essere creato sopra il numero desiderato di pod. Per ulteriori informazioni su di esso, visitare Pagina di distribuzione.
kubectl per l'introspezione e il debug delle applicazioni.Il networking è una parte centrale di Kubernetes, ma può essere difficile capire esattamente come dovrebbe funzionare. Ci sono 4 reti distinte problemi da affrontare:
localhost.Kubernetes è tutto basato sulla condivisione di macchine tra le applicazioni. Tipicamente, la condivisione di macchine richiede che due applicazioni non provino a utilizzare il stesse porte. È molto difficile coordinare le porte tra più sviluppatori fare su larga scala ed esporre gli utenti a problemi a livello di cluster al di fuori del loro controllo.
L'allocazione dinamica delle porte apporta molte complicazioni al sistema: tutte l'applicazione deve prendere le porte come flag, i server API devono sapere come inserire numeri di porta dinamici in blocchi di configurazione, i servizi devono sapere come trovarsi, ecc. Piuttosto che occuparsene, Kubernetes prende un approccio diverso.
Ogni Pod ottiene il proprio indirizzo IP. Ciò significa che non è necessario esplicitamente
crea collegamenti tra Pod 'e non hai quasi mai bisogno di gestire la mappatura porte del contenitore per ospitare le porte. Questo crea un pulito, retrocompatibile modello in cui Pods` può essere trattato in modo molto simile a VM o host fisici da
prospettive di allocazione delle porte, denominazione, individuazione dei servizi, bilanciamento del carico,
configurazione dell'applicazione e migrazione.
Kubernetes impone i seguenti requisiti fondamentali su qualsiasi rete implementazione (salvo eventuali politiche di segmentazione di rete intenzionale):
* i pod su un nodo possono comunicare con tutti i pod su tutti i nodi senza NAT * agenti su un nodo (ad esempio i daemon di sistema, kubelet) possono comunicare con tutti pod su quel nodo
Nota: per quelle piattaforme che supportano Pods in esecuzione nella rete host (ad es.
Linux):
* i pod nella rete host di un nodo possono comunicare con tutti i pod su tutti nodi senza NAT
Questo modello non è solo complessivamente meno complesso, ma è principalmente compatibile con il desiderio di Kubernetes di abilitare il porting a bassa frizione di app da VM ai contenitori. Se il tuo lavoro è già stato eseguito in una macchina virtuale, la tua macchina virtuale ha avuto un indirizzo IP e potrebbe parla con altre macchine virtuali nel tuo progetto. Questo è lo stesso modello base.
Gli indirizzi IP di Kubernetes esistono nello scope Pod - contenitori all'interno di un 'Podcondividere i loro spazi dei nomi di rete, compreso il loro indirizzo IP. Ciò significa che i contenitori all'interno di unPodpossono raggiungere tutti gli altri porti sulocalhost. Questo significa anche che i contenitori all'interno di un 'Pod devono coordinare l'utilizzo della porta, ma questo
non è diverso dai processi in una VM. Questo è chiamato il modello "IP-per-pod".
Il modo in cui viene implementato è un dettaglio del particolare runtime del contenitore in uso.
È possibile richiedere le porte sul Node stesso che inoltrerà al tuo 'Pod(chiamate porte host), ma questa è un'operazione molto di nicchia. Come è quella spedizione implementato è anche un dettaglio del runtime del contenitore. IlPod` stesso è
cieco all'esistenza o alla non esistenza dei porti di accoglienza.
Ci sono diversi modi in cui questo modello di rete può essere implementato. Questo il documento non è uno studio esaustivo dei vari metodi, ma si spera che serva come introduzione a varie tecnologie e serve da punto di partenza.
Le seguenti opzioni di networking sono ordinate alfabeticamente - l'ordine no implica uno stato preferenziale.
Cisco Application Centric Infrastructure offers an integrated overlay and underlay SDN solution that supports containers, virtual machines, and bare metal servers. ACI provides container networking integration for ACI. An overview of the integration is provided here.
AOS è un sistema di rete basato sull'intento che crea e gestisce ambienti di data center complessi da una semplice piattaforma integrata. AOS sfrutta un design distribuito altamente scalabile per eliminare le interruzioni di rete riducendo al minimo i costi.
Il progetto di riferimento AOS attualmente supporta gli host connessi Layer-3 che eliminano i problemi di commutazione Layer-2 legacy. Questi host Layer-3 possono essere server Linux (Debian, Ubuntu, CentOS) che creano relazioni vicine BGP direttamente con gli switch top of rack (TOR). AOS automatizza le adiacenze di routing e quindi fornisce un controllo a grana fine sulle iniezioni di integrità del percorso (RHI) comuni in una distribuzione di Kubernetes.
AOS dispone di un ricco set di endpoint REST API che consentono a Kubernetes di modificare rapidamente i criteri di rete in base ai requisiti dell'applicazione. Ulteriori miglioramenti integreranno il modello AOS Graph utilizzato per la progettazione della rete con il provisioning del carico di lavoro, consentendo un sistema di gestione end-to-end per cloud privati e pubblici.
AOS supporta l'utilizzo di apparecchiature di produttori comuni di produttori quali Cisco, Arista, Dell, Mellanox, HPE e un gran numero di sistemi white-box e sistemi operativi di rete aperti come Microsoft SONiC, Dell OPX e Cumulus Linux.
I dettagli su come funziona il sistema AOS sono disponibili qui: http://www.apstra.com/products/how-it-works/
Big Cloud Fabric è un'architettura di rete nativa cloud, progettata per eseguire Kubernetes in ambienti cloud privati / on-premise. Utilizzando un SDN fisico e virtuale unificato, Big Cloud Fabric affronta problemi intrinseci di rete di container come bilanciamento del carico, visibilità, risoluzione dei problemi, politiche di sicurezza e monitoraggio del traffico container.
Con l'aiuto dell'architettura multi-tenant del pod virtuale di Big Cloud Fabric, i sistemi di orchestrazione di container come Kubernetes, RedHat OpenShift, Mesosphere DC / OS e Docker Swarm saranno integrati nativamente con i sistemi di orchestrazione VM come VMware, OpenStack e Nutanix. I clienti saranno in grado di interconnettere in modo sicuro qualsiasi numero di questi cluster e abilitare la comunicazione tra i titolari, se necessario.
BCF è stato riconosciuto da Gartner come un visionario nell'ultimo Magic Quadrant. Viene anche fatto riferimento a una delle distribuzioni on-premises BCF Kubernetes (che include Kubernetes, DC / OS e VMware in esecuzione su più DC in diverse regioni geografiche) [https://portworx.com/architects-corner-kubernetes-satya -komala-nio /).
Cilium è un software open source per fornire e proteggere in modo trasparente la connettività di rete tra le applicazioni contenitori. Cilium è consapevole di L7 / HTTP e può applicare i criteri di rete su L3-L7 utilizzando un modello di sicurezza basato sull'identità che è disaccoppiato dalla rete indirizzamento.
CNI-Genie è un plugin CNI che consente a Kubernetes di avere simultaneamente accesso a diverse implementazioni del modello di rete Kubernetes in runtime. Ciò include qualsiasi implementazione che funziona come un plugin CNI, come Flannel, Calico, Romana, Weave-net.
CNI-Genie supporta anche assegnando più indirizzi IP a un pod, ciascuno da un diverso plugin CNI.
cni-ipvlan-vpc-k8s contiene un set di plugin CNI e IPAM per fornire una semplice, host-local, bassa latenza, alta throughput e stack di rete conforme per Kubernetes in Amazon Virtual Ambienti Private Cloud (VPC) facendo uso di Amazon Elastic Network Interfacce (ENI) e associazione degli IP gestiti da AWS in pod usando il kernel di Linux Driver IPvlan in modalità L2.
I plugin sono progettati per essere semplici da configurare e distribuire all'interno di VPC. Kubelets si avvia e quindi autoconfigura e ridimensiona il loro utilizzo IP secondo necessità senza richiedere le complessità spesso raccomandate della gestione della sovrapposizione reti, BGP, disabilitazione dei controlli sorgente / destinazione o regolazione del percorso VPC tabelle per fornire sottoreti per istanza a ciascun host (che è limitato a 50-100 voci per VPC). In breve, cni-ipvlan-vpc-k8s riduce significativamente il complessità della rete richiesta per implementare Kubernetes su larga scala all'interno di AWS.
226/5000 Contiv fornisce un networking configurabile (nativo l3 usando BGP, overlay usando vxlan, classic l2 o Cisco-SDN / ACI) per vari casi d'uso. Contiv è tutto aperto.
Contrail, basato su Tungsten Fabric, è un virtualizzazione della rete e piattaforma di gestione delle policy realmente aperte e multi-cloud. Contrail e Tungsten Fabric sono integrati con vari sistemi di orchestrazione come Kubernetes, OpenShift, OpenStack e Mesos e forniscono diverse modalità di isolamento per macchine virtuali, contenitori / pod e carichi di lavoro bare metal.
DANM è una soluzione di rete per carichi di lavoro di telco in esecuzione in un cluster Kubernetes. È costituito dai seguenti componenti:
Con questo set di strumenti DANM è in grado di fornire più interfacce di rete separate, la possibilità di utilizzare diversi back-end di rete e funzionalità IPAM avanzate per i pod.
Flannel è un overlay molto semplice rete che soddisfa i requisiti di Kubernetes. Molti le persone hanno riportato il successo con Flannel e Kubernetes.
Per gli script di configurazione del cluster di Google Compute Engine,
avanzato routing è usato per assegna a ciascuna VM una sottorete
(l'impostazione predefinita è / 24 - 254 IP). Qualsiasi traffico vincolato per questo la sottorete verrà instradata
direttamente alla VM dal fabric di rete GCE. Questo è dentro aggiunta all'indirizzo IP "principale" assegnato alla VM,
a cui è stato assegnato NAT accesso a Internet in uscita. Un bridge linux (chiamato cbr0) è configurato per esistere
su quella sottorete, e viene passato al flag --bridge della finestra mobile.
Docker è avviato con:
DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false"
Questo bridge è creato da Kubelet (controllato da --network-plugin = kubenet flag) in base al Nodo .spec.podCIDR.
Docker ora assegna gli IP dal blocco cbr-cidr. I contenitori possono raggiungere l'un l'altro e Nodi sul
ponte cbr0. Questi IP sono tutti instradabili all'interno della rete del progetto GCE.
GCE non sa nulla di questi IP, quindi non lo farà loro per il traffico internet in uscita. Per ottenere ciò viene
utilizzata una regola iptables masquerade (aka SNAT - per far sembrare che i pacchetti provengano dal Node stesso)
traffico che è vincolato per IP al di fuori della rete del progetto GCE (10.0.0.0/8).
iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
Infine l'inoltro IP è abilitato nel kernel (quindi il kernel elaborerà pacchetti per contenitori a ponte):
sysctl net.ipv4.ip_forward=1
Il risultato di tutto questo è che tutti i Pods possono raggiungere l'altro e possono uscire
traffico verso internet.
Jaguar è una soluzione open source per la rete di Kubernetes basata su OpenDaylight. Jaguar fornisce una rete overlay utilizzando vxlan e Jaguar. CNIPlugin fornisce un indirizzo IP per pod.
363/5000 Knitter è una soluzione di rete che supporta più reti in Kubernetes. Fornisce la capacità di gestione dei titolari e gestione della rete. Knitter include una serie di soluzioni di rete container NFV end-to-end oltre a più piani di rete, come mantenere l'indirizzo IP per le applicazioni, la migrazione degli indirizzi IP, ecc.
430/5000 Kube-router è una soluzione di rete sviluppata appositamente per Kubernetes che mira a fornire alte prestazioni e semplicità operativa. Kube-router fornisce un proxy di servizio basato su Linux LVS / IPVS, una soluzione di rete pod-to-pod basata sul kernel di inoltro del kernel Linux senza sovrapposizioni, e il sistema di sicurezza della politica di rete basato su iptables / ipset.
Se hai una rete L2 "stupida", come un semplice switch in un "bare metal" ambiente, dovresti essere in grado di fare qualcosa di simile alla precedente configurazione GCE. Si noti che queste istruzioni sono state provate solo molto casualmente - a quanto pare lavoro, ma non è stato testato a fondo. Se usi questa tecnica e perfezionare il processo, fatecelo sapere.
Segui la sezione "Con dispositivi Linux Bridge" di questo molto bello tutorial da Lars Kellogg-Stedman.
Multus è un plugin Multi CNI per supportare la funzionalità Multi Networking in Kubernetes utilizzando oggetti di rete basati su CRD in Kubernetes.
Multus supporta tutti i plug-in di riferimento (ad esempio Flannel, DHCP, Macvlan) che implementano le specifiche CNI e i plugin di terze parti (ad esempio Calico, Weave ), Cilium, Contiv). Oltre a ciò, Multus supporta SRIOV, DPDK, OVS- DPDK e VPP carichi di lavoro in Kubernetes con applicazioni cloud native e basate su NFV in Kubernetes.
VMware NSX-T è una piattaforma di virtualizzazione e sicurezza della rete. NSX-T può fornire la virtualizzazione di rete per un ambiente multi-cloud e multi-hypervisor ed è focalizzato su architetture applicative emergenti e architetture con endpoint eterogenei e stack tecnologici. Oltre agli hypervisor vSphere, questi ambienti includono altri hypervisor come KVM, container e bare metal.
Plug-in contenitore NSX-T (NCP) fornisce integrazione tra NSX-T e orchestratori di contenitori come Kubernetes, così come l'integrazione tra NSX-T e piattaforme CaaS / PaaS basate su container come Pivotal Container Service (PKS) e OpenShift.
Nuage fornisce una piattaforma Software-Defined Networking (SDN) altamente scalabile basata su policy. Nuage utilizza open source Open vSwitch per il piano dati insieme a un controller SDN ricco di funzionalità basato su standard aperti.
La piattaforma Nuage utilizza gli overlay per fornire una rete basata su policy senza soluzione di continuità tra i Pod di Kubernetes e gli ambienti non Kubernetes (VM e server bare metal). Il modello di astrazione delle policy di Nuage è stato progettato pensando alle applicazioni e semplifica la dichiarazione di policy a grana fine per le applicazioni. Il motore di analisi in tempo reale della piattaforma consente la visibilità e il monitoraggio della sicurezza per le applicazioni Kubernetes.
OVN è una soluzione di virtualizzazione della rete opensource sviluppata da Apri la community di vSwitch. Permette di creare switch logici, router logici, ACL di stato, bilanciamento del carico ecc. per costruire reti virtuali diverse topologie. Il progetto ha un plugin e una documentazione specifici per Kubernetes a ovn-kubernetes.
Project Calico è un provider di rete contenitore open source e motore di criteri di rete.
Calico offre una soluzione di rete e di rete altamente scalabile per il collegamento di pod Kubernetes basati sugli stessi principi di rete IP di Internet, sia per Linux (open source) che per Windows (proprietario - disponibile da Tigera). Calico può essere distribuito senza incapsulamento o sovrapposizioni per fornire reti di data center ad alte prestazioni e su vasta scala. Calico fornisce inoltre una politica di sicurezza di rete basata su intere grane per i pod Kubernetes tramite il firewall distribuito.
Calico può anche essere eseguito in modalità di applicazione della policy insieme ad altre soluzioni di rete come Flannel, alias canal o native GCE, AWS o networking Azure.
Romana è una soluzione di automazione della sicurezza e della rete open source che consente di distribuire Kubernetes senza una rete di overlay. Romana supporta Kubernetes Politica di rete per fornire isolamento tra gli spazi dei nomi di rete.
Weave Net è un rete resiliente e semplice da usare per Kubernetes e le sue applicazioni in hosting. Weave Net funziona come un plug-in CNI o stand-alone. In entrambe le versioni, non richiede alcuna configurazione o codice aggiuntivo per eseguire, e in entrambi i casi, la rete fornisce un indirizzo IP per pod, come è standard per Kubernetes.
Il progetto iniziale del modello di rete e la sua logica, e un po 'di futuro i piani sono descritti in maggior dettaglio nella progettazione della rete documento.
I log di applicazioni e sistemi possono aiutarti a capire cosa sta accadendo all'interno del tuo cluster. I log sono particolarmente utili per il debug dei problemi e il monitoraggio delle attività del cluster. La maggior parte delle applicazioni moderne ha una sorta di meccanismo di registrazione; in quanto tale, la maggior parte dei motori di container sono progettati allo stesso modo per supportare alcuni tipi di registrazione. Il metodo di registrazione più semplice e più accettato per le applicazioni containerizzate è scrivere sull'output standard e sui flussi di errore standard.
Tuttavia, la funzionalità nativa fornita da un motore contenitore o dal runtime di solito non è sufficiente per una soluzione di registrazione completa. Ad esempio, se un container si arresta in modo anomalo, un pod viene rimosso, o un nodo muore, di solito vuoi comunque accedere ai log dell'applicazione. Pertanto, i registri devono avere una memoria e un ciclo di vita separati, indipendenti da nodi, pod o contenitori. Questo concetto è chiamato cluster-logging. La registrazione a livello di cluster richiede un back-end separato per archiviare, analizzare e interrogare i registri. Kubernetes non fornisce alcuna soluzione di archiviazione nativa per i dati di registro, ma è possibile integrare molte soluzioni di registrazione esistenti nel proprio cluster Kubernetes.
Le architetture di registrazione a livello di cluster sono descritte nel presupposto che un back-end per la registrazione è presente all'interno o all'esterno del cluster. Se tu sei non interessa avere la registrazione a livello di cluster, potresti ancora trovarlo la descrizione di come i registri sono memorizzati e gestiti sul nodo per essere utile.
In questa sezione, puoi vedere un esempio di registrazione di base in Kubernetes emette i dati sul flusso di output standard. Utilizza questa dimostrazione una specifica pod con un contenitore che scrive del testo sullo standard output una volta al secondo.
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
Per eseguire questo pod, utilizzare il seguente comando:
$ kubectl create -f https://k8s.io/examples/debug/counter-pod.yaml
pod/counter created
Per recuperare i registri, usa il comando kubectl logs, come segue:
$ kubectl logs counter
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
You can use kubectl logs to retrieve logsPuoi usare kubectl logs per recuperare i log da una precedente istanziazione di un contenitore con il flag --previous, nel caso in cui il contenitore si sia arrestato in modo anomalo. Se il pod ha più contenitori, è necessario specificare i registri del contenitore a cui si desidera accedere aggiungendo un nome contenitore al comando. Vedi la documentazione kubectl logs per maggiori dettagli. from a previous instantiation of a container with --previous flag, in case the container has crashed. If your pod has multiple containers, you should specify which container's logs you want to access by appending a container name to the command. See the kubectl logs documentation for more details.
Tutto ciò che una applicazione containerizzata scrive su stdout e stderr viene gestito e reindirizzato da qualche parte da un motore contenitore. Ad esempio, il motore del contenitore Docker reindirizza questi due flussi a un driver di registrazione, che è configurato in Kubernetes per scrivere su un file in formato json .
Di default, se un container si riavvia, kubelet mantiene un container terminato con i suoi log. Se un pod viene espulso dal nodo, tutti i contenitori corrispondenti vengono espulsi, insieme ai loro log.
Una considerazione importante nella registrazione a livello di nodo sta implementando la rotazione dei log,
in modo che i registri non consumino tutta la memoria disponibile sul nodo. kubernetes
al momento non è responsabile della rotazione dei registri, ma piuttosto di uno strumento di distribuzione
dovrebbe creare una soluzione per affrontarlo.
Ad esempio, nei cluster di Kubernetes, implementato dallo script kube-up.sh,
c'è un logrotate
strumento configurato per funzionare ogni ora. È anche possibile impostare un runtime del contenitore su
ruotare automaticamente i registri dell'applicazione, ad es. usando il log-opt di Docker.
Nello script kube-up.sh, quest'ultimo approccio viene utilizzato per l'immagine COS su GCP,
e il primo approccio è usato in qualsiasi altro ambiente. In entrambi i casi, da
la rotazione predefinita è configurata per essere eseguita quando il file di registro supera 10 MB.
Ad esempio, puoi trovare informazioni dettagliate su come kube-up.sh imposta
up logging per l'immagine COS su GCP nello [script] cosConfigureHelper corrispondente.
Quando esegui kubectl logs come in
l'esempio di registrazione di base, il kubelet sul nodo gestisce la richiesta e
legge direttamente dal file di log, restituendo il contenuto nella risposta.
log di kubectl. Per esempio. se c'è un file da 10 MB, esegue logrotate
la rotazione e ci sono due file, uno da 10 MB e uno vuoto,
kubectl logs restituirà una risposta vuota.Esistono due tipi di componenti di sistema: quelli che vengono eseguiti in un contenitore e quelli che non funziona in un contenitore. Per esempio:
Sulle macchine con systemd, il kubelet e il runtime del contenitore scrivono su journal. Se
systemd non è presente, scrive nei file .log nella directory/var/log.
I componenti di sistema all'interno dei contenitori scrivono sempre nella directory /var/log,
bypassando il meccanismo di registrazione predefinito. Usano il klog klog
biblioteca di registrazione. È possibile trovare le convenzioni per la gravità della registrazione per quelli
componenti nel documento di sviluppo sulla registrazione.
Analogamente ai log del contenitore, i log dei componenti di sistema sono in /var/log
la directory dovrebbe essere ruotata. Nei cluster di Kubernetes allevati da
lo script kube-up.sh, quei log sono configurati per essere ruotati da
lo strumento logrotate al giorno o una volta che la dimensione supera i 100 MB.
Sebbene Kubernetes non fornisca una soluzione nativa per la registrazione a livello di cluster, esistono diversi approcci comuni che è possibile prendere in considerazione. Ecco alcune opzioni:

È possibile implementare la registrazione a livello di cluster includendo un agente di registrazione a livello node su ciascun nodo. L'agente di registrazione è uno strumento dedicato che espone i registri o trasferisce i registri a un back-end. Comunemente, l'agente di registrazione è un contenitore che ha accesso a una directory con file di registro da tutti i contenitori delle applicazioni su quel nodo.
Poiché l'agente di registrazione deve essere eseguito su ogni nodo, è comune implementarlo come una replica DaemonSet, un pod manifest o un processo nativo dedicato sul nodo. Tuttavia, questi ultimi due approcci sono deprecati e altamente scoraggiati.
L'utilizzo di un agent di registrazione a livello di nodo è l'approccio più comune e consigliato per un cluster Kubernetes, poiché crea solo un agente per nodo e non richiede alcuna modifica alle applicazioni in esecuzione sul nodo. Tuttavia, la registrazione a livello di nodo funziona solo per l'output standard delle applicazioni e l'errore standard.
Kubernetes non specifica un agente di registrazione, ma due agenti di registrazione facoltativi sono impacchettati con la versione di Kubernetes: Stackdriver Logging da utilizzare con Google Cloud Platform e Elasticsearch. Puoi trovare ulteriori informazioni e istruzioni nei documenti dedicati. Entrambi usano fluentd con configurazione personalizzata come agente sul nodo.
Puoi utilizzare un contenitore sidecar in uno dei seguenti modi:
stdout.
Facendo scorrere i propri contenitori sidecar sul proprio stdout e stderr
flussi, è possibile sfruttare il kubelet e l'agente di registrazione che
già eseguito su ciascun nodo. I contenitori del sidecar leggono i log da un file, un socket,
o il diario. Ogni singolo contenitore sidecar stampa il log nel proprio stdout
o flusso stderr.
Questo approccio consente di separare diversi flussi di log da diversi
parti della tua applicazione, alcune delle quali possono mancare di supporto
per scrivere su stdout o stderr. La logica dietro il reindirizzamento dei registri
è minimo, quindi non è un sovraccarico significativo. Inoltre, perché
stdout e stderr sono gestiti da kubelet, puoi usare gli strumenti integrati
come log di kubectl.
Considera il seguente esempio. Un pod esegue un singolo contenitore e il contenitore scrive su due file di registro diversi, utilizzando due formati diversi. Ecco un file di configurazione per il pod:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
Sarebbe un disastro avere voci di registro di diversi formati nello stesso registro
stream, anche se si è riusciti a reindirizzare entrambi i componenti al flusso stdout di
Il container. Invece, potresti introdurre due container sidecar. Ogni sidecar
contenitore potrebbe accodare un particolare file di registro da un volume condiviso e quindi reindirizzare
i registri al proprio flusso stdout.
Ecco un file di configurazione per un pod con due contenitori sidecar:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox:1.28
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-1
image: busybox:1.28
args: [/bin/sh, -c, 'tail -n+1 -F /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-2
image: busybox:1.28
args: [/bin/sh, -c, 'tail -n+1 -F /var/log/2.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
Ora quando si esegue questo pod, è possibile accedere separatamente a ciascun flusso di log eseguendo i seguenti comandi:
$ kubectl logs counter count-log-1
0: Mon Jan 1 00:00:00 UTC 2001
1: Mon Jan 1 00:00:01 UTC 2001
2: Mon Jan 1 00:00:02 UTC 2001
...
$ kubectl logs counter count-log-2
Mon Jan 1 00:00:00 UTC 2001 INFO 0
Mon Jan 1 00:00:01 UTC 2001 INFO 1
Mon Jan 1 00:00:02 UTC 2001 INFO 2
...
L'agente a livello di nodo installato nel cluster preleva tali flussi di log automaticamente senza alcuna ulteriore configurazione. Se ti piace, puoi configurare l'agente per analizzare le righe di registro in base al contenitore di origine.
Si noti che, nonostante il basso utilizzo della CPU e della memoria (ordine di un paio di millesimi
per cpu e ordine di diversi megabyte per memoria), scrivere registri su un file e
quindi il loro streaming su stdout può raddoppiare l'utilizzo del disco. Se hai
un'applicazione che scrive in un singolo file, è generalmente meglio impostare
/dev/stdout come destinazione piuttosto che implementare il sidecar streaming
approccio contenitore.
I contenitori del sidecar possono anche essere usati per ruotare i file di log che non possono essere
ruotato dall'applicazione stessa. Un esempio
di questo approccio è un piccolo contenitore che esegue periodicamente logrotate.
Tuttavia, si raccomanda di usare stdout e stderr direttamente e lasciare la rotazione
e politiche di conservazione al kubelet.

Se l'agente di registrazione a livello di nodo non è abbastanza flessibile per la tua situazione, tu puoi creare un container sidecar con un logger separato che hai configurato specificamente per essere eseguito con la tua applicazione.
kubectl logs, perché non sono controllati
dal kubelet.Ad esempio, è possibile utilizzare Stackdriver, che utilizza fluentd come agente di registrazione. Qui ci sono due file di configurazione puoi usare per implementare questo approccio. Il primo file contiene a ConfigMap per configurare fluentd.
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
data:
fluentd.conf: |
<source>
type tail
format none
path /var/log/1.log
pos_file /var/log/1.log.pos
tag count.format1
</source>
<source>
type tail
format none
path /var/log/2.log
pos_file /var/log/2.log.pos
tag count.format2
</source>
<match **>
type google_cloud
</match>
Il secondo file descrive un pod con un contenitore sidecar in esecuzione fluentd. Il pod monta un volume dove fluentd può raccogliere i suoi dati di configurazione.
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-agent
image: registry.k8s.io/fluentd-gcp:1.30
env:
- name: FLUENTD_ARGS
value: -c /etc/fluentd-config/fluentd.conf
volumeMounts:
- name: varlog
mountPath: /var/log
- name: config-volume
mountPath: /etc/fluentd-config
volumes:
- name: varlog
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-config
Dopo un po 'di tempo è possibile trovare i messaggi di registro nell'interfaccia Stackdriver.
Ricorda che questo è solo un esempio e puoi effettivamente sostituire fluentd con qualsiasi agente di registrazione, leggendo da qualsiasi fonte all'interno di un'applicazione contenitore.

È possibile implementare la registrazione a livello di cluster esponendo o spingendo i registri direttamente da ogni applicazione; tuttavia, l'implementazione di un tale meccanismo di registrazione è al di fuori dello scopo di Kubernetes.
La garbage collection è una funzione utile di kubelet che pulisce le immagini inutilizzate e i contenitori inutilizzati. Kubelet eseguirà la raccolta dei rifiuti per i contenitori ogni minuto e la raccolta dei dati inutili per le immagini ogni cinque minuti.
Gli strumenti di garbage collection esterni non sono raccomandati in quanto questi strumenti possono potenzialmente interrompere il comportamento di kubelet rimuovendo i contenitori che si prevede esistano.
Kubernetes gestisce il ciclo di vita di tutte le immagini tramite imageManager, con la collaborazione di consulente.
La politica per la raccolta dei rifiuti delle immagini prende in considerazione due fattori:
HighThresholdPercent e LowThresholdPercent. Utilizzo del disco al di sopra della soglia alta
attiverà la garbage collection. La garbage collection cancellerà le immagini utilizzate meno di recente fino al minimo
soglia è stata soddisfatta.
La politica per la raccolta dei rifiuti delle immagini prende in considerazione due fattori:
HighThresholdPercent e LowThresholdPercent. Utilizzo del disco al di sopra della soglia alta
attiverà la garbage collection. La garbage collection cancellerà le immagini utilizzate meno di recente fino al minimo
soglia è stata soddisfatta.
La politica per i contenitori di garbage collection considera tre variabili definite dall'utente. MinAge è l'età minima
in cui un contenitore può essere raccolto dalla spazzatura. MaxPerPodContainer è il numero massimo di contenitori morti
ogni singolo la coppia pod (UID, nome contenitore) può avere. MaxContainers è il numero massimo di contenitori morti
totali. Queste variabili possono essere disabilitate individualmente impostando MinAge a zero e impostando MaxPerPodContainer
e MaxContainers rispettivamente a meno di zero.
Kubelet agirà su contenitori non identificati, cancellati o al di fuori dei limiti impostati dalle bandiere
precedentemente menzionate. I contenitori più vecchi saranno generalmente rimossi per primi. MaxPerPodContainer
e MaxContainer possono potenzialmente entrare in conflitto l'uno con l'altro in situazioni in cui il mantenimento del
numero massimo di contenitori per pod (MaxPerPodContainer) non rientra nell'intervallo consentito di contenitori morti
globali (MaxContainers). MaxPerPodContainer verrebbe regolato in questa situazione: uno scenario peggiore sarebbe
quello di eseguire il downgrade di MaxPerPodContainer su 1 e rimuovere i contenitori più vecchi. Inoltre, i
contenitori di proprietà dei pod che sono stati cancellati vengono rimossi una volta che sono più vecchi di "MinAge".
I contenitori che non sono gestiti da Kubelet non sono soggetti alla garbage collection del contenitore.
Gli utenti possono regolare le seguenti soglie per ottimizzare la garbage collection delle immagini con i seguenti flag kubelet:
image-gc-high-threshold, la percentuale di utilizzo del disco che attiva la garbage collection dell'immagine.
Il valore predefinito è 85%.image-gc-low-threshold, la percentuale di utilizzo del disco su cui tenta la garbage collection dell'immagine
liberare. Il valore predefinito è 80%.Permettiamo anche agli utenti di personalizzare la politica di raccolta dei rifiuti attraverso i seguenti flag kubelet:
minimum-container-ttl-duration, l'età minima per un container finito prima che sia
raccolta dei rifiuti L'impostazione predefinita è 0 minuti, il che significa che ogni contenitore finito verrà raccolto.maximum-dead-containers-per-container, numero massimo di vecchie istanze da conservare
per contenitore Il valore predefinito è 1.maximum-dead-containers, numero massimo di vecchie istanze di container da conservare globalmente.
Il valore predefinito è -1, il che significa che non esiste un limite globale.I contenitori possono potenzialmente essere raccolti prima che la loro utilità sia scaduta. Questi contenitori
può contenere log e altri dati che possono essere utili per la risoluzione dei problemi. Un valore sufficientemente grande per
maximum-dead-containers-per-container è altamente raccomandato per consentire almeno un contenitore morto
mantenuto per contenitore previsto. Un valore più grande per "massimo-dead-containers" è anche raccomandato per a
motivo simile. Vedi questo problema per maggiori dettagli.
Alcune funzionalità di raccolta dei rifiuti di Kubelet in questo documento verranno sostituite da sfratti di Kubelet in futuro.
Compreso:
| Bandiera esistente | Nuova bandiera | Motivazione |
|---|---|---|
--image-gc-high-threshold |
--eviction-hard o --eviction-soft |
i segnali di sfratto esistenti possono innescare la garbage collection delle immagini |
--image-gc-low-threshold |
--eviction-minimum-reclaim |
i reclami di sfratto ottengono lo stesso comportamento |
--maximum-dead-containers |
deprecato una volta che i vecchi log sono memorizzati al di fuori del contesto del contenitore | |
--maximum-dead-containers-per-container |
deprecato una volta che i vecchi log sono memorizzati al di fuori del contesto del contenitore | |
--minimum-container-ttl-duration |
deprecato una volta che i vecchi log sono memorizzati al di fuori del contesto del contenitore | |
--low-diskspace-threshold-mb |
--eviction-hard o eviction-soft |
lo sfratto generalizza le soglie del disco ad altre risorse |
--outofdisk-transition-frequency |
--eviction-pressure-transition-period |
lo sfratto generalizza la transizione della pressione del disco verso altre risorse |
Vedi Configurazione della gestione delle risorse esterne per maggiori dettagli.
Questa pagina spiega i proxy utilizzati con Kubernetes.
Esistono diversi proxy che puoi incontrare quando usi Kubernetes:
- viene eseguito sul computer di un utente o in un pod - collega un localhost address all'apiserver di Kubernetes - il client comunica con il proxy in HTTP - il proxy comunica con l'apiserver in HTTPS - individua l'apiserver - aggiunge gli header di autenticazione
- è un proxy presente nell'apiserver - collega un utente al di fuori del cluster agli IP del cluster che altrimenti potrebbero non essere raggiungibili - è uno dei processi dell'apiserver - il client comunica con il proxy in HTTPS (o HTTP se l'apiserver è configurato in tal modo) - il proxy comunica con il target via HTTP o HTTPS come scelto dal proxy utilizzando le informazioni disponibili - può essere utilizzato per raggiungere un nodo, un pod o un servizio - esegue il bilanciamento del carico quando viene utilizzato per raggiungere un servizio
- è eseguito su ciascun nodo - fa da proxy per comunicazioni UDP, TCP e SCTP - non gestisce il protocollo HTTP - esegue il bilanciamento del carico - è usato solo per raggiungere i servizi
- la sua esistenza e implementazione variano da cluster a cluster (ad esempio nginx) - si trova tra i client e uno o più apiserver - funge da bilanciatore di carico se ci sono più di un apiserver.
- sono forniti da alcuni fornitori di servizi cloud (ad es. AWS ELB, Google Cloud Load Balancer)
- vengono creati automaticamente quando il servizio Kubernetes ha tipo LoadBalancer
- solitamente supporta solo UDP / TCP
- il supporto SCTP dipende dall'implementazione del bilanciatore di carico del provider cloud
- l'implementazione varia a seconda del provider cloud.
Gli utenti di Kubernetes in genere non devono preoccuparsi alcun proxy, se non i primi due tipi. L'amministratore del cluster in genere assicurerà che gli altri tipi di proxy siano impostati correttamente.
I proxy hanno sostituito le funzioni di reindirizzamento. I reindirizzamenti sono stati deprecati.
Le metriche del controller controller forniscono informazioni importanti sulle prestazioni e la salute di il responsabile del controller.
Le metriche del controller forniscono informazioni importanti sulle prestazioni del controller. Queste metriche includono le comuni metriche di runtime del linguaggio Go, come il conteggio go_routine e le metriche specifiche del controller come latenze delle richieste etcd o latenze API Cloudprovider (AWS, GCE, OpenStack) che possono essere utilizzate per valutare la salute di un cluster.
A partire da Kubernetes 1.7, le metriche dettagliate di Cloudprovider sono disponibili per le operazioni di archiviazione per GCE, AWS, Vsphere e OpenStack. Queste metriche possono essere utilizzate per monitorare lo stato delle operazioni di volume persistenti.
Ad esempio, per GCE queste metriche sono chiamate:
cloudprovider_gce_api_request_duration_seconds { request = "instance_list"}
cloudprovider_gce_api_request_duration_seconds { request = "disk_insert"}
cloudprovider_gce_api_request_duration_seconds { request = "disk_delete"}
cloudprovider_gce_api_request_duration_seconds { request = "attach_disk"}
cloudprovider_gce_api_request_duration_seconds { request = "detach_disk"}
cloudprovider_gce_api_request_duration_seconds { request = "list_disk"}
In un cluster, le metriche di controller-manager sono disponibili da http://localhost:10252/metrics
dall'host su cui è in esecuzione il controller-manager.
Le metriche sono emesse in formato prometheus.
In un ambiente di produzione è possibile configurare prometheus o altri strumenti di misurazione delle metriche per raccogliere periodicamente queste metriche e renderle disponibili in una sorta di database di serie temporali.
I componenti aggiuntivi estendono la funzionalità di Kubernetes.
Questa pagina elenca alcuni componenti aggiuntivi disponibili e collegamenti alle rispettive istruzioni di installazione.
I componenti aggiuntivi in ogni sezione sono ordinati alfabeticamente - l'ordine non implica uno stato preferenziale.
Dashboard è un'interfaccia web dashboard per Kubernetes.
qui ci sono molti altri componenti aggiuntivi documentati nella directory deprecata cluster / addons.
Quelli ben mantenuti dovrebbero essere collegati qui.
Questa sezione della documentazione di Kubernetes contiene i tutorials. Un tutorial mostra come raggiungere un obiettivo più complesso di un singolo task. Solitamente un tutorial ha diverse sezioni, ognuna delle quali consiste in una sequenza di più task. Prima di procedere con vari tutorial, raccomandiamo di aggiungere il Glossario ai tuoi bookmark per riferimenti successivi.
Se sei interessato a scrivere un tutorial, vedi Utilizzare i Page Templates per informazioni su come creare una tutorial page e sul tutorial template.
Questo tutorial mostra come eseguire una semplice applicazione in Kubernetes utilizzando Minikube e Katacoda. Katacoda permette di operare su un'installazione di Kubernetes dal tuo browser.
Questo tutorial fornisce una container image che utilizza NGINX per risponde a tutte le richieste con un echo che visualizza i dati della richiesta stessa.
Click Launch Terminal
minikube start.Apri la console di Kubernetes nel browser:
minikube dashboard
Katacoda environment only: In alto alla finestra del terminale, fai click segno più, e a seguire click su Select port to view on Host 1.
Katacoda environment only: Inserisci 30000, a seguire click su Display Port.
Un Kubernetes Pod è un gruppo di uno o più Containers,
che sono uniti tra loro dal punto di vista amministrativo e che condividono lo stesso network.
Il Pod in questo tutorial ha un solo Container. Un Kubernetes
Deployment monitora lo stato del Pod ed
eventualmente provvedere a farlo ripartire nel caso questo termini. L'uso dei Deployments è la
modalità raccomandata per gestire la creazione e lo scaling dei Pods.
Usa il comando kubectl create per creare un Deployment che gestisce un singolo Pod. Il Pod
eseguirà un Container basato sulla Docker image specificata.
kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.53 -- /agnhost netexec --http-port=8080
Visualizza il Deployment:
kubectl get deployments
L'output del comando è simile a:
NAME READY UP-TO-DATE AVAILABLE AGE
hello-node 1/1 1 1 1m
Visualizza il Pod creato dal Deployment:
kubectl get pods
L'output del comando è simile a:
NAME READY STATUS RESTARTS AGE
hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m
Visualizza gli eventi del cluster Kubernetes:
kubectl get events
Visualizza la configurazione di kubectl:
kubectl config view
Con le impostazioni di default, un Pod è accessibile solamente dagli indirizzi IP interni
al Kubernetes cluster. Per far si che il Container hello-node sia accessibile dall'esterno
del Kubernetes virtual network, è necessario esporre il Pod utilizzando un
Kubernetes Service.
Esponi il Pod su internet untilizzando il comando kubectl expose:
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
Il flag --type=LoadBalancer indica la volontà di esporre il Service
all'esterno del Kubernetes cluster.
Visualizza il Servizio appena creato:
kubectl get services
L'output del comando è simile a:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
Nei cloud providers che supportano i servizi di tipo load balancers,
viene fornito un indirizzo IP pubblico per permettere l'acesso al Service. Su Minikube,
il service type LoadBalancer rende il Service accessibile attraverso il comando minikube service.
Esegui il comando:
minikube service hello-node
Katacoda environment only: Fai click segno più, e a seguire click su Select port to view on Host 1.
Katacoda environment only: Fai attenzione al numero di 5 cifre visualizzato a fianco di 8080 nell'output del comando. Questo port number è generato casualmente e può essere diverso nel tuo caso. Inserisci il tuo port number nella textbox, e a seguire fai click su Display Port. Nell'esempio precedente, avresti scritto 30369.
Questo apre un finestra nel browser dove l'applicazione visuallizza l'echo delle richieste ricevute.
Minikube include un set addons che possono essere attivati, disattivati o eseguti nel ambiente Kubernetes locale.
Elenca gli addons disponibili:
minikube addons list
L'output del comando è simile a:
addon-manager: enabled
dashboard: enabled
default-storageclass: enabled
efk: disabled
freshpod: disabled
gvisor: disabled
helm-tiller: disabled
ingress: disabled
ingress-dns: disabled
logviewer: disabled
metrics-server: disabled
nvidia-driver-installer: disabled
nvidia-gpu-device-plugin: disabled
registry: disabled
registry-creds: disabled
storage-provisioner: enabled
storage-provisioner-gluster: disabled
Attiva un addon, per esempio, metrics-server:
minikube addons enable metrics-server
L'output del comando è simile a:
metrics-server was successfully enabled
Visualizza i Pods ed i Service creati in precedenza:
kubectl get pod,svc -n kube-system
L'output del comando è simile a:
NAME READY STATUS RESTARTS AGE
pod/coredns-5644d7b6d9-mh9ll 1/1 Running 0 34m
pod/coredns-5644d7b6d9-pqd2t 1/1 Running 0 34m
pod/metrics-server-67fb648c5 1/1 Running 0 26s
pod/etcd-minikube 1/1 Running 0 34m
pod/influxdb-grafana-b29w8 2/2 Running 0 26s
pod/kube-addon-manager-minikube 1/1 Running 0 34m
pod/kube-apiserver-minikube 1/1 Running 0 34m
pod/kube-controller-manager-minikube 1/1 Running 0 34m
pod/kube-proxy-rnlps 1/1 Running 0 34m
pod/kube-scheduler-minikube 1/1 Running 0 34m
pod/storage-provisioner 1/1 Running 0 34m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/metrics-server ClusterIP 10.96.241.45 <none> 80/TCP 26s
service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 34m
service/monitoring-grafana NodePort 10.99.24.54 <none> 80:30002/TCP 26s
service/monitoring-influxdb ClusterIP 10.111.169.94 <none> 8083/TCP,8086/TCP 26s
Disabilita metrics-server:
minikube addons disable metrics-server
L'output del comando è simile a:
metrics-server was successfully disabled
Adesso puoi procedere a fare clean up delle risorse che hai creato nel tuo cluster:
kubectl delete service hello-node
kubectl delete deployment hello-node
Eventualmente, puoi stoppare la Minikube virtual machine (VM):
minikube stop
Eventualmente, puoi cancellare la Minikube VM:
minikube delete