This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Concetti

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.

Overview

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:

  • Il Kubernetes Master è una raccolta di tre processi che vengono eseguiti su un singolo nodo nel cluster, che è designato come nodo principale. Questi processi sono: kube-apiserver, kube-controller-manager e kube-scheduler.
  • Ogni singolo nodo non principale nel cluster esegue due processi:   * kubelet, che comunica con il master di Kubernetes.   * kube-proxy, un proxy di rete che riflette i servizi di rete di Kubernetes su ciascun nodo.

Kubernetes Objects

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:

Kubernetes Control Plane

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.

Kubernetes Master

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.

Kubernetes Nodes

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.

Object Metadata

Voci correlate

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.

1 - Overview

1.1 - Cos'è 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 .

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à.

Facciamo un piccolo salto indietro

Diamo un'occhiata alla ragione per cui Kubernetes è così utile facendo un piccolo salto indietro nel tempo.

Deployment evolution

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:

  • Creazione e distribuzione di applicazioni in modalità Agile: maggiore facilità ed efficienza nella creazione di immagini container rispetto all'uso di immagini VM.
  • Adozione di pratiche per lo sviluppo/test/rilascio continuativo: consente la frequente creazione e la distribuzione di container image affidabili, dando la possibilità di fare rollback rapidi e semplici (grazie all'immutabilità dell'immagine stessa).
  • Separazione delle fasi di Dev e Ops: le container image vengono prodotte al momento della compilazione dell'applicativo piuttosto che nel momento del rilascio, permettendo così di disaccoppiare le applicazioni dall'infrastruttura sottostante.
  • L'osservabilità non riguarda solo le informazioni e le metriche del sistema operativo, ma anche lo stato di salute e altri segnali dalle applicazioni.
  • Coerenza di ambiente tra sviluppo, test e produzione: i container funzionano allo stesso modo su un computer portatile come nel cloud.
  • Portabilità tra cloud e sistemi operativi differenti: lo stesso container funziona su Ubuntu, RHEL, CoreOS, on-premise, nei più grandi cloud pubblici e da qualsiasi altra parte.
  • Gestione incentrata sulle applicazioni: Aumenta il livello di astrazione dall'esecuzione di un sistema operativo su hardware virtualizzato all'esecuzione di un'applicazione su un sistema operativo utilizzando risorse logiche.
  • Microservizi liberamente combinabili, distribuiti, ad alta scalabilità: le applicazioni sono suddivise in pezzi più piccoli e indipendenti che possono essere distribuite e gestite dinamicamente - niente stack monolitici che girano su una singola grande macchina.
  • Isolamento delle risorse: le prestazioni delle applicazioni sono prevedibili.
  • Utilizzo delle risorse: alta efficienza e densità.

Perché necessito di Kubernetes e cosa posso farci

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:

  • Scoperta dei servizi e bilanciamento del carico Kubernetes può esporre un container usando un nome DNS o il suo indirizzo IP. Se il traffico verso un container è alto, Kubernetes è in grado di distribuire il traffico su più container in modo che il servizio rimanga stabile.
  • Orchestrazione dello storage Kubernetes ti permette di montare automaticamente un sistema di archiviazione di vostra scelta, come per esempio storage locale, dischi forniti da cloud pubblici, e altro ancora.
  • Rollout e rollback automatizzati Puoi utilizzare Kubernetes per descrivere lo stato desiderato per i propri container, e Kubernetes si occuperà di cambiare lo stato attuale per raggiungere quello desiderato ad una velocità controllata. Per esempio, puoi automatizzare Kubernetes per creare nuovi container per il tuo servizio, rimuovere i container esistenti e adattare le loro risorse a quelle richieste dal nuovo container.
  • Ottimizzazione dei carichi Fornisci a Kubernetes un cluster di nodi per eseguire i container. Puoi istruire Kubernetes su quanta CPU e memoria (RAM) ha bisogno ogni singolo container. Kubernetes allocherà i container sui nodi per massimizzare l'uso delle risorse a disposizione.
  • Self-healing Kubernetes riavvia i container che si bloccano, sostituisce container, termina i container che non rispondono agli health checks, e evita di far arrivare traffico ai container che non sono ancora pronti per rispondere correttamente.
  • Gestione di informazioni sensibili e della configurazione Kubernetes consente di memorizzare e gestire informazioni sensibili, come le password, i token OAuth e le chiavi SSH. Puoi distribuire e aggiornare le informazioni sensibili e la configurazione dell'applicazione senza dover ricostruire le immagini dei container e senza svelare le informazioni sensibili nella configurazione del tuo sistema.

Cosa non è Kubernetes

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:

  • Non limita i tipi di applicazioni supportate. Kubernetes mira a supportare una grande varietà di carichi di lavoro, compresi i carichi di lavoro stateless, stateful e elaborazione di dati. Se un'applicazione può essere eseguita in un container, dovrebbe funzionare alla grande anche su Kubernetes.
  • Non compila il codice sorgente e non crea i container. I flussi di Continuous Integration, Delivery, and Deployment (CI/CD) sono determinati dalla cultura e dalle preferenze dell'organizzazione e dai requisiti tecnici.
  • Non fornisce servizi a livello applicativo, come middleware (per esempio, bus di messaggi), framework di elaborazione dati (per esempio, Spark), database (per esempio, mysql), cache, né sistemi di storage distribuito (per esempio, Ceph) come servizi integrati. Tali componenti possono essere eseguiti su Kubernetes, e/o possono essere richiamati da applicazioni che girano su Kubernetes attraverso meccanismi come l'Open Service Broker.
  • Non impone soluzioni di logging, monitoraggio o di gestione degli alert. Fornisce alcune integrazioni come dimostrazione, e meccanismi per raccogliere ed esportare le metriche.
  • Non fornisce né rende obbligatorio un linguaggio/sistema di configurazione (per esempio, Jsonnet). Fornisce un'API dichiarativa che può essere richiamata da qualsiasi sistema.
  • Non fornisce né adotta alcun sistema di gestione completa della macchina, configurazione, manutenzione, gestione o sistemi di self healing.
  • Inoltre, Kubernetes non è un semplice sistema di orchestrazione. Infatti, questo sistema elimina la necessità di orchestrazione. La definizione tecnica di orchestrazione è l'esecuzione di un flusso di lavoro definito: prima si fa A, poi B, poi C. Al contrario, Kubernetes è composto da un insieme di processi di controllo indipendenti e componibili che guidano costantemente lo stato attuale verso lo stato desiderato. Non dovrebbe importare come si passa dalla A alla C. Anche il controllo centralizzato non è richiesto. Questo si traduce in un sistema più facile da usare, più potente, robusto, resiliente ed estensibile.

Voci correlate

1.2 - I componenti di Kubernetes

Un cluster di Kubernetes è costituito da un insieme di componenti che sono, come minimo, un Control Plane e uno o più sistemi di elaborazione, detti nodi.

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 di Kubernetes

Componenti della Control Plane

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.

kube-apiserver

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.

etcd

È 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.

kube-scheduler

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.

kube-controller-manager

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:

  • Node Controller: Responsabile del monitoraggio dei nodi del cluster, e.g. della gestione delle azioni da eseguire quando un nodo diventa non disponibile.
  • Replication Controller: Responsabile per il mantenimento del corretto numero di Pod per ogni ReplicaSet presente nel sistema
  • Endpoints Controller: Popola gli oggetti Endpoints (cioè, mette in relazioni i Pods con i Services).
  • Service Account & Token Controllers: Creano gli account di default e i token di accesso alle API per i nuovi namespaces.

cloud-controller-manager

Un componente della control plane di Kubernetes che aggiunge logiche di controllo specifiche per il cloud. Il cloud-controller-manager ti permette di collegare il tuo cluster con le API del cloud provider e separa le componenti che interagiscono con la piattaforma cloud dai componenti che interagiscono solamente col cluster.

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:

  • Node Controller: Per controllare se sul cloud provider i nodi che hanno smesso di rispondere sono stati cancellati
  • Route Controller: Per configurare le network route nella sottostante infrastruttura cloud
  • Service Controller: Per creare, aggiornare ed eliminare i load balancer del cloud provider

Componenti dei Nodi

I componenti del nodo vengono eseguiti su ogni nodo, mantenendo i pod in esecuzione e fornendo l'ambiente di runtime Kubernetes.

kubelet

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

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.

Container Runtime

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).

Addons

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.

DNS

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.

Interfaccia web (Dashboard)

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.

Monitoraggio dei Container

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.

Log a livello di Cluster

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.

Voci correlate

1.3 - Le API di Kubernetes

Le API di Kubernetes ti permettono di interrogare e manipolare lo stato degli oggetti in Kubernetes. Il cuore del Control Plane di Kubernetes è l'API server e le API HTTP che esso espone. Ogni entità o componente che si interfaccia con il cluster (gli utenti, le singole parti del tuo cluster, i componenti esterni), comunica attraverso l'API server.

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.

Evoluzione delle 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.

Definizioni OpenAPI e Swagger

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.

Versionamento delle API

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:

  • Livello alpha:
    • Il nome di versione contiene alpha (e.g. v1alpha1).
    • Potrebbe contenere dei bug. Abilitare questa funzionalità potrebbe esporre al rischio di bugs. Disabilitata di default.
    • Il supporto di questa funzionalità potrebbe essere rimosso in ogni momento senza previa notifica.
    • Questa API potrebbe cambiare in modo incompatibile in rilasci futuri del Software e senza previa notifica.
    • Se ne raccomandata l'utilizzo solo in clusters di test creati per un breve periodo di vita, a causa di potenziali bugs e delle mancanza di un supporto di lungo periodo.
  • Livello beta:
    • Il nome di versione contiene beta (e.g. v2beta3).
    • Il codice è propriamente testato. Abilitare la funzionalità è considerato sicuro. Abilitata di default.
    • Il supporto per la funzionalità nel suo complesso non sarà rimosso, tuttavia potrebbe subire delle modifiche.
    • Lo schema e/o la semantica delle risorse potrebbe cambiare in modo incompatibile in successivi rilasci beta o stabili. Nel caso questo dovesse verificarsi, verrano fornite istruzioni per la migrazione alla versione successiva. Questo potrebbe richiedere la cancellazione, modifica, e la ri-creazione degli oggetti supportati da questa API. Questo processo di modifica potrebbe richiedere delle valutazioni. La modifica potrebbe richiedere un periodo di non disponibilità dell'applicazione che utilizza questa funzionalità.
    • Raccomandata solo per applicazioni non critiche per la vostra impresa a causa dei potenziali cambiamenti incompatibili in rilasci successivi. Se avete più clusters che possono essere aggiornati separatamente, potreste essere in grado di gestire meglio questa limitazione.
    • Per favore utilizzate le nostre versioni beta e forniteci riscontri relativamente ad esse! Una volta promosse a stabili, potrebbe non essere semplice apportare cambiamenti successivi.
  • Livello stabile:
    • Il nome di versione è vX dove X è un intero.
    • Le funzionalità relative alle versioni stabili continueranno ad essere presenti per parecchie versioni successive.

API groups

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:

  1. Il gruppo core, spesso referenziato come il legacy group, è disponibile al percorso REST /api/v1 ed utilizza apiVersion: v1.

  2. 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:

  1. CustomResourceDefinition è pensato per utenti con esigenze CRUD basilari.
  2. Utenti che necessitano di un nuovo completo set di API che utilizzi appieno la semantica di Kubernetes possono implementare il loro apiserver ed utilizzare l'aggregator per fornire ai propri utilizzatori la stessa esperienza a cui sono abituati con le API incluse nativamente in Kubernetes.

Abilitare o disabilitare gli API groups

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.

Abilitare specifiche risorse nel gruppo extensions/v1beta1

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.

2 - Architettura di Kubernetes

2.1 - Nodi

Un nodo è una macchina worker in Kubernetes, precedentemente noto come minion. Un nodo può essere una VM o una macchina fisica, a seconda del cluster. Ogni nodo contiene i servizi necessari per eseguire pods ed è gestito dal master componenti. I servizi su un nodo includono il container runtime, kubelet e kube-proxy. Vedere The Kubernetes Node sezione in documento di progettazione dell'architettura per maggiori dettagli.

Node Status

Lo stato di un nodo contiene le seguenti informazioni:

Ogni sezione è descritta in dettaglio di seguito.

Addresses

L'utilizzo di questi campi varia a seconda del provider cloud o della configurazione bare metal.

  • HostName: il nome host riportato dal kernel del nodo. Può essere sovrascritto tramite il parametro kubelet --hostname-override.
  • ExternalIP: in genere l'indirizzo IP del nodo che è esternamente instradabile (disponibile dall'esterno del cluster).
  • InternalIP: in genere l'indirizzo IP del nodo che è instradabile solo all'interno del cluster.

Condition

l campo conditions descrive lo stato di tutti i nodi Running.

Condizione del nodo Descrizione
OutOfDisk True se lo spazio disponibile sul nodo non è sufficiente per aggiungere nuovi pod, altrimenti False
Pronto True se il nodo è integro e pronto ad accettare i pod, False se il nodo non è integro e non accetta i pod e Sconosciuto se il controller del nodo non è stato ascoltato dal nodo nell'ultimo nodo-monitor -grace-periodo (il valore predefinito è 40 secondi)
MemoryPressure Vero se la pressione esiste sulla memoria del nodo, ovvero se la memoria del nodo è bassa; altrimenti False
PIDPressure True se la pressione esiste sui processi, ovvero se ci sono troppi processi sul nodo; altrimenti False
DiskPressure True se esiste una pressione sulla dimensione del disco, ovvero se la capacità del disco è bassa; altrimenti False
NetworkUnavailable True se la rete per il nodo non è configurata correttamente, altrimenti False

La condizione del nodo è rappresentata come un oggetto JSON. Ad esempio, la seguente risposta descrive un nodo sano.

"conditions": [
  {
    "type": "Ready",
    "status": "True"
  }
]

Se lo stato della condizione Ready rimane Unknown o False per un tempo superiore a pod-eviction-timeout, viene passato un argomento al gestore-kube-controller e tutti i pod sul nodo sono programmati per la cancellazione dal controller del nodo. La durata predefinita del timeout di sfratto è di ** cinque minuti **. In alcuni casi, quando il nodo non è raggiungibile, l'apiserver non è in grado di comunicare con kubelet sul nodo. La decisione di eliminare i pod non può essere comunicata al kubelet fino a quando non viene ristabilita la comunicazione con l'apiserver. Nel frattempo, i pod che sono programmati per la cancellazione possono continuare a funzionare sul nodo partizionato.

Nelle versioni di Kubernetes precedenti alla 1.5, il controllore del nodo forzerebbe la cancellazione questi pod non raggiungibili dall'apiserver. Tuttavia, in 1.5 e versioni successive, il controller del nodo non impone l'eliminazione dei pod finché non lo è confermato che hanno smesso di funzionare nel cluster. Puoi vedere i pod che potrebbero essere in esecuzione su un nodo irraggiungibile lo stato Terminating o Unknown. Nei casi in cui Kubernetes non può dedurre dall'infrastruttura sottostante se ha un nodo lasciato permanentemente un cluster, potrebbe essere necessario che l'amministratore del cluster elimini manualmente l'oggetto nodo. Cancellare l'oggetto nodo da Kubernetes fa sì che tutti gli oggetti Pod in esecuzione sul nodo vengano eliminati dal server apis e libera i loro nomi.

Nella versione 1.12, la funzione TaintNodesByCondition è promossa in versione beta, quindi il controller del ciclo di vita del nodo crea automaticamente taints che rappresentano le condizioni. Allo stesso modo lo schedulatore ignora le condizioni quando si considera un nodo; anziché guarda le tinte del Nodo e le tolleranze di un Pod.

Ora gli utenti possono scegliere tra il vecchio modello di pianificazione e un nuovo modello di pianificazione più flessibile. Un pod che non ha tolleranze viene pianificato in base al vecchio modello. Ma un baccello quello tollera che i nodi di un nodo particolare possano essere programmati su quel nodo.

Capacity

Descrive le risorse disponibili sul nodo: CPU, memoria e il massimo numero di pod che possono essere programmati sul nodo.

Info

Informazioni generali sul nodo, come la versione del kernel, la versione di Kubernetes (versione kubelet e kube-proxy), versione Docker (se utilizzata), nome del sistema operativo. Le informazioni sono raccolte da Kubelet dal nodo.

Management

Unlike pods and services, a node is not inherently created by Kubernetes: it is created externally by cloud providers like Google Compute Engine, or it exists in your pool of physical or virtual machines. So when Kubernetes creates a node, it creates an object that represents the node. After creation, Kubernetes checks whether the node is valid or not. For example, if you try to create a node from the following content:

{
  "kind": "Node",
  "apiVersion": "v1",
  "metadata": {
    "name": "10.240.79.157",
    "labels": {
      "name": "my-first-k8s-node"
    }
  }
}

Kubernetes crea un oggetto nodo internamente (la rappresentazione), e convalida il nodo tramite il controllo dello stato in base al campo metadata.name. Se il nodo è valido - cioè, se necessario i servizi sono in esecuzione, è idoneo per l'esecuzione di un pod. Altrimenti, lo è ignorato per qualsiasi attività del cluster finché non diventa valido.

Attualmente, ci sono tre componenti che interagiscono con il nodo di Kubernetes interfaccia: controller del nodo, kubelet e kubectl.

Node Controller

Il controller del nodo è un componente master di Kubernetes che gestisce vari aspetti dei nodi.

Il controller del nodo ha più ruoli nella vita di un nodo. Il primo sta assegnando a Blocco CIDR sul nodo quando è registrato (se l'assegnazione CIDR è attivata).

Il secondo è mantenere aggiornato l'elenco interno dei nodi del controller del nodo l'elenco delle macchine disponibili del provider cloud. Quando si corre in una nuvola ambiente, ogni volta che un nodo non è sano, il controller del nodo chiede al cloud fornitore se la VM per quel nodo è ancora disponibile. Altrimenti, il nodo controller cancella il nodo dalla sua lista di nodi.

Il terzo è il monitoraggio della salute dei nodi. Il controller del nodo è responsabile dell'aggiornamento della condizione NodeReady di NodeStatus a Condizione Notata quando un nodo diventa irraggiungibile (ad esempio, il controller del nodo si arresta ricevere heartbeat per qualche motivo, ad es. a causa del fatto che il nodo si trova in basso), e poi in seguito sfratto tutti i pod dal nodo (usando una terminazione elegante) se il nodo continua essere irraggiungibile. (I timeout predefiniti sono 40 secondi per iniziare la segnalazione ConditionUnknown e 5m dopo di ciò per iniziare a sfrattare i pod.)

Il controller del nodo controlla lo stato di ogni nodo ogni --node-monitor-period secondi.

Nelle versioni di Kubernetes precedenti alla 1.13, NodeStatus è l'heartbeat di nodo. A partire da Kubernetes 1.13, la funzionalità di lease del nodo viene introdotta come un funzione alfa (porta caratteristica NodeLease, KEP-0009). Quando la funzione di lease del nodo è abilitata, ogni nodo ha un oggetto Lease associato in spazio dei nomi kube-node-lease che viene rinnovato periodicamente dal nodo ed entrambi NodeStatus e lease del nodo vengono considerati heartbeat dal nodo. Locazioni di nodi si rinnovano frequentemente mentre NodeStatus viene segnalato solo dal nodo al master quando c'è qualche cambiamento o è passato abbastanza tempo (il default è 1 minuto, che è più lungo del timeout predefinito di 40 secondi per i nodi non raggiungibili). Da il lease del nodo è molto più leggero di NodeStatus, questa caratteristica rende nodo battito cardiaco significativamente più economico sia per la scalabilità che per le prestazioni prospettive.

In Kubernetes 1.4, abbiamo aggiornato la logica del controller del nodo per gestire meglio casi in cui un numero elevato di nodi ha problemi con il raggiungimento del master (ad esempio perché il master ha problemi di rete). A partire da 1.4, il nodo controller controlla lo stato di tutti i nodi nel cluster quando si effettua un decisione sullo sfratto del pod.

Nella maggior parte dei casi, il controller del nodo limita il tasso di sfratto a --node-eviction-rate (default 0.1) al secondo, il che significa che non eliminerà i pod da più di 1 nodo per 10 secondi.

Il comportamento di sfratto del nodo cambia quando un nodo in una determinata zona di disponibilità diventa malsano. Il controller del nodo controlla quale percentuale di nodi nella zona sono malsani (la condizione NodeReady è ConditionUnknown o ConditionFalse) a lo stesso tempo. Se la frazione di nodi malsani è almeno --unhealthy-zone-threshold (default 0.55) quindi il tasso di sfratto è ridotto: se il cluster è piccolo (cioè ha meno o uguale a --large-cluster-size-threshold nodes - default 50) quindi gli sfratti sono fermato, altrimenti il ​​tasso di sfratto è ridotto a --secondary-node-eviction-rate (default 0.01) al secondo.

La ragione per cui le politiche sono implementate per zona di disponibilità è perché una zona di disponibilità potrebbe divenire partizionato dal master mentre gli altri rimangono connessi. Se il tuo cluster non si estende su più zone di disponibilità del provider cloud, quindi c'è solo una zona di disponibilità (l'intero cluster).

Un motivo chiave per diffondere i nodi tra le zone di disponibilità è che il carico di lavoro può essere spostato in zone sane quando un'intera zona viene interrotta. Pertanto, se tutti i nodi in una zona non sono sani, il controller del nodo viene sottratto a la normale frequenza --node-eviction-rate. Il caso d'angolo è quando tutte le zone sono completamente malsano (cioè non ci sono nodi sani nel cluster). In tale caso, il controller del nodo presuppone che ci sia qualche problema con il master connettività e interrompe tutti gli sfratti fino a quando non viene ripristinata la connettività.

A partire da Kubernetes 1.6, il NodeController è anche responsabile della rimozione i pod che sono in esecuzione sui nodi con NoExecute, quando i pod non tollerano i taints. Inoltre, come caratteristica alfa che è disabilitata per impostazione predefinita, il NodeController è responsabile per l'aggiunta di taints corrispondenti ai problemi del nodo come nodo irraggiungibile o non pronto. Vedi questa documentazione per i dettagli su NoExecute taints e la funzione alpha.

partire dalla versione 1.8, il controller del nodo può essere reso responsabile della creazione di taints che rappresentano le condizioni del nodo. Questa è una caratteristica alfa della versione 1.8.

Self-Registration of Nodes

Quando il flag kubelet --register-node è vero (il default), il kubelet tenterà di farlo registrarsi con il server API. Questo è il modello preferito, utilizzato dalla maggior parte delle distro.

Per l'autoregistrazione, il kubelet viene avviato con le seguenti opzioni:

  • --kubeconfig - Percorso delle credenziali per autenticarsi sull'apiserver.
  • --cloud-provider - Come parlare con un provider cloud per leggere i metadati su se stesso.
  • --register-node - Si registra automaticamente con il server API.
  • --register-with-taints - Registra il nodo con la lista data di taints (separati da virgola <chiave> = <valore>: <effetto>). No-op 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 master

Quando Node authorization mode e NodeRestriction admission plugin sono abilitati, kubelets è autorizzato solo a creare / modificare la propria risorsa nodo.

Manual Node Administration

Un amministratore di cluster può creare e modificare oggetti nodo.

Se l'amministratore desidera creare manualmente oggetti nodo, imposta il flag kubelet --Register nodo = false.

L'amministratore può modificare le risorse del nodo (indipendentemente dall'impostazione di --register-node). Le modifiche includono l'impostazione di etichette sul nodo e la marcatura non programmabile.

Le etichette sui nodi possono essere utilizzate insieme ai selettori di nodo sui pod per controllare la pianificazione, per esempio. vincolare un pod per poter essere eseguito solo su un sottoinsieme di nodi.

Contrassegnare un nodo come unschedulable impedisce a nuovi pod di essere programmati per quello nodo, ma non ha alcun effetto sui pod esistenti sul nodo. Questo è utile come fase preparatoria prima del riavvio del nodo, ecc. Ad esempio, per contrassegnare un nodo unschedulable, esegui questo comando:

kubectl cordon $NODENAME

Node capacity

La capacità del nodo (numero di cpu e quantità di memoria) è parte dell'oggetto nodo. Normalmente, i nodi si registrano e segnalano la loro capacità durante la creazione dell'oggetto nodo. Se stai facendo amministrazione manuale del nodo, quindi devi impostare il nodo capacità quando si aggiunge un nodo.

Lo scheduler di Kubernetes garantisce che ci siano risorse sufficienti per tutti i pod su un nodo. esso controlla che la somma delle richieste di container sul nodo non sia maggiore della capacità del nodo. esso include tutti i contenitori avviati da kubelet, ma non i contenitori avviati direttamente dal contenitore runtime né qualsiasi processo eseguito all'esterno dei contenitori.

Se si desidera riservare esplicitamente risorse per processi non Pod, seguire questo tutorial su riserva risorse per i demoni di sistema.

API Object

Il nodo è una risorsa di livello superiore nell'API REST di Kubernetes. Maggiori dettagli su L'oggetto API può essere trovato a: Node API object.

2.2 - Comunicazione Control Plane - Nodo

Questo documento cataloga le connessioni tra il piano di controllo (control-plane), in realtà l'apiserver, e il cluster Kubernetes. L'intento è di consentire agli utenti di personalizzare la loro installazione per rafforzare la configurazione di rete affinché il cluster possa essere eseguito su una rete pubblica (o su IP completamente pubblici resi disponibili da un fornitore di servizi cloud).

Dal Nodo al control-plane

Kubernetes adotta un pattern per le API di tipo "hub-and-spoke". Tutte le chiamate delle API eseguite sui vari nodi sono effettuate verso l'apiserver (nessuno degli altri componenti principali è progettato per esporre servizi remoti). L'apiserver è configurato per l'ascolto di connessioni remote su una porta HTTPS protetta (443) con una o più forme di autenticazioni client abilitate. Si dovrebbero abilitare una o più forme di autorizzazioni, in particolare nel caso in cui siano ammesse richieste anonime o token legati ad un account di servizio (service account).

Il certificato pubblico (public root certificate) relativo al cluster corrente deve essere fornito ai vari nodi di modo che questi possano connettersi in modo sicuro all'apiserver insieme alle credenziali valide per uno specifico client. Ad esempio, nella configurazione predefinita di un cluster GKE, le credenziali del client fornite al kubelet hanno la forma di un certificato client. Si veda inizializzazione TLS del kubelet TLS per la fornitura automatica dei certificati client al kubelet.

I Pod che desiderano connettersi all'apiserver possono farlo in modo sicuro sfruttando un account di servizio in modo che Kubernetes inserisca automaticamente il certificato pubblico di radice e un token valido al portatore (bearer token) all'interno Pod quando questo viene istanziato. In tutti i namespace è configurato un Service con nome kubernetes con un indirizzo IP virtuale che viene reindirizzato (tramite kube-proxy) all'endpoint HTTPS dell'apiserver.

Anche i componenti del piano d controllo comunicano con l'apiserver del cluster su di una porta sicura esposta da quest'ultimo.

Di conseguenza, la modalità operativa predefinita per le connessioni dai nodi e dai Pod in esecuzione sui nodi verso il control-plane è protetta da un'impostazione predefinita e può essere eseguita su reti non sicure e/o pubbliche.

Dal control-plane al nodo

Esistono due percorsi di comunicazione principali dal control-plane (apiserver) verso i nodi. Il primo è dall'apiserver verso il processo kubelet in esecuzione su ogni nodo nel cluster. Il secondo è dall'apiserver a ciascun nodo, Pod, o servizio attraverso la funzionalità proxy dell'apiserver.

Dall'apiserver al kubelet

Le connessioni dall'apiserver al kubelet vengono utilizzate per:

  • Prendere i log relativi ai vari Pod.
  • Collegarsi (attraverso kubectl) ai Pod in esecuzione.
  • Fornire la funzionalità di port-forwarding per i kubelet.

Queste connessioni terminano all'endpoint HTTPS del kubelet. Di default, l'apiserver non verifica il certificato servito dal kubelet, il che rende la connessione soggetta ad attacchi man-in-the-middle, e tale da essere considerato non sicuro (unsafe) se eseguito su reti non protette e/o pubbliche.

Per verificare questa connessione, si utilizzi il parametro --kubelet-certificate-authority al fine di fornire all'apiserver un insieme di certificati radice da utilizzare per verificare il il certificato servito dal kubelet.

Se questo non è possibile, si usi un tunnel SSH tra l'apiserver e il kubelet, se richiesto, per evitare il collegamento su una rete non protetta o pubblica.

In fine, l'autenticazione e/o l'autorizzazione del kubelet dovrebbe essere abilitate per proteggere le API esposte dal kubelet.

Dall'apiserver ai nodi, Pod, e servizi

Le connessioni dall'apiserver verso un nodo, Pod o servizio avvengono in modalità predefinita su semplice connessione HTTP e quindi non sono né autenticate né criptata. Queste connessioni possono essere eseguite su una connessione HTTPS sicura mediante il prefisso https: al nodo, Pod o nome del servizio nell'URL dell'API, ma non valideranno il certificato fornito dall'endpoint HTTPS né forniranno le credenziali del client così anche se la connessione verrà criptata, non fornirà alcuna garanzia di integrità. Non è attualmente sicuro eseguire queste connessioni su reti non protette e/o pubbliche.

I tunnel SSH

Kubernetes supporta i tunnel SSH per proteggere la comunicazione tra il control-plane e i nodi. In questa configurazione, l'apiserver inizializza un tunnel SSH con ciascun nodo del cluster (collegandosi al server SSH in ascolto sulla porta 22) e fa passare tutto il traffico verso il kubelet, il nodo, il Pod, o il servizio attraverso questo tunnel. Questo tunnel assicura che il traffico non sia esposto al di fuori della rete su cui sono in esecuzioni i vari nodi.

I tunnel SSH sono al momento deprecati ovvero non dovrebbero essere utilizzati a meno che ci siano delle esigenze particolari. Il servizio Konnectivity è pensato per rimpiazzare questo canale di comunicazione.

Il servizio Konnectivity

FEATURE STATE: 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

2.3 - Concetti alla base del Cloud Controller Manager

Il concetto di CCM (cloud controller manager), da non confondere con il binario, è stato originariamente creato per consentire di sviluppare Kubernetes indipendentemente dall'implementazione dello specifico cloud provider. Il cloud controller manager viene eseguito insieme ad altri componenti principali come il Kubernetes controller manager, il server API e lo scheduler. Può anche essere avviato come addon di Kubernetes, nel qual caso viene eseguito su Kubernetes.

Il design del cloud controller manager è basato su un meccanismo di plug-in che consente ai nuovi provider cloud di integrarsi facilmente con Kubernetes creando un plug-in. Sono in atto programmi per l'aggiunta di nuovi provider di cloud su Kubernetes e per la migrazione dei provider che usano il vecchio metodo a questo nuovo metodo.

Questo documento discute i concetti alla base del cloud controller manager e fornisce dettagli sulle funzioni associate.

Ecco l'architettura di un cluster Kubernetes senza il gestore del controller cloud:

Pre CCM Kube Arch

Architettura

Nel diagramma precedente, Kubernetes e il provider cloud sono integrati attraverso diversi componenti:

  • Kubelet
  • Kubernetes controller manager
  • Kubernetes API server

Il CCM consolida tutta la logica dipendente dal cloud presente nei tre componenti precedenti, per creare un singolo punto di integrazione con il cloud. La nuova architettura con il CCM si presenta così:

CCM Kube Arch

Componenti del CCM

Il CCM divide alcune funzionalità del Kubernetes controller manager (KCM) e le esegue in un differente processo. In particolare, toglie dal KCM le integrazioni con il cloud specifico. Il KCM ha i seguenti controller che dipendono dal cloud specifico:

  • Node controller
  • Volume controller
  • Route controller
  • Service controller

Nella versione 1.9, il CCM esegue i seguenti controller dall'elenco precedente:

  • Node controller
  • Route controller
  • Service controller

Il piano originale per supportare i volumi utilizzando il CCM era di utilizzare Flex per supportare volumi collegabili. Tuttavia, una implementazione parallela, nota come CSI è stata designata per sostituire Flex.

Considerando queste evoluzioni, abbiamo deciso di adottare un approccio intermedio finché il CSI non è pronto.

Funzioni del CCM

Il CCM eredita le sue funzioni da componenti di Kubernetes che dipendono da uno specifico provider di cloud. Questa sezione è strutturata sulla base di tali componenti.

1. Kubernetes controller manager

La maggior parte delle funzioni del CCM deriva dal KCM. Come menzionato nella sezione precedente, CCM esegue i seguenti cicli di controllo:

  • Node controller
  • Route controller
  • Service controller

Node controller

Il Node controller è responsabile per l'inizializzazione di un nodo ottenendo informazioni sui nodi in esecuzione nel cluster dal provider cloud. Il controller del nodo esegue le seguenti funzioni:

  1. Inizializzare un nodo con le label zone/region specifiche per il cloud in uso.
  2. Inizializzare un nodo con le specifiche, ad esempio, tipo e dimensione specifiche del cloud in uso.
  3. Ottenere gli indirizzi di rete del nodo e l'hostname.
  4. Nel caso in cui un nodo non risponda, controlla il cloud per vedere se il nodo è stato cancellato dal cloud. Se il nodo è stato eliminato dal cloud, elimina l'oggetto Nodo di Kubernetes.

Route controller

Il Route controller è responsabile della configurazione delle route nel cloud in modo che i container su nodi differenti del cluster Kubernetes possano comunicare tra loro. Il Route controller è utilizzabile solo dai cluster su Google Compute Engine.

Service Controller

Il Service Controller rimane in ascolto per eventi di creazione, aggiornamento ed eliminazione di servizi. In base allo stato attuale dei servizi in Kubernetes, configura i bilanciatori di carico forniti dal cloud (come gli ELB, i Google LB, o gli Oracle Cloud Infrastructure LB) per riflettere lo stato dei servizi in Kubernetes. Inoltre, assicura che i back-end dei bilanciatori di carico forniti dal cloud siano aggiornati.

2. Kubelet

Il Node Controller contiene l'implementazione dipendente dal cloud della kubelet. Prima dell'introduzione del CCM, la kubelet era responsabile dell'inizializzazione di un nodo con dettagli dipendenti dallo specifico cloud come gli indirizzi IP, le label region/zone e le informazioni sul tipo di istanza. L'introduzione del CCM ha spostato questa operazione di inizializzazione dalla kubelet al CCM.

In questo nuovo modello, la kubelet inizializza un nodo senza informazioni specifiche del cloud. Tuttavia, aggiunge un blocco al nodo appena creato che rende il nodo non selezionabile per eseguire container finché il CCM non inizializza il nodo con le informazioni specifiche del cloud. Il CCM rimuove quindi questo blocco.

Sistema a plug-in

Il cloud controller manager utilizza le interfacce di Go per consentire l'implementazione di implementazioni di qualsiasi cloud. In particolare, utilizza l'interfaccia CloudProvider definita qui.

L'implementazione dei quattro controller generici evidenziati sopra, alcune strutture, l'interfaccia cloudprovider condivisa rimarranno nel core di Kubernetes. Le implementazioni specifiche per i vari cloud saranno costruite al di fuori del core e implementeranno le interfacce definite nel core.

Per ulteriori informazioni sullo sviluppo di plug-in, consultare Developing Cloud Controller Manager.

Autorizzazione

Questa sezione dettaglia l'accesso richiesto dal CCM sui vari API objects per eseguire le sue operazioni.

Node controller

Il Node controller funziona solo con oggetti di tipo Node. Richiede l'accesso completo per ottenere, elencare, creare, aggiornare, applicare patch, guardare ed eliminare oggetti di tipo Node.

v1/Node:

  • Get
  • List
  • Create
  • Update
  • Patch
  • Watch
  • Delete

Route controller

Il Route controller ascolta la creazione dell'oggetto Node e configura le rotte in modo appropriato. Richiede l'accesso in lettura agli oggetti di tipo Node.

v1/Node:

  • Get

Service controller

Il Service controller resta in ascolto per eventi di creazione, aggiornamento ed eliminazione di oggetti di tipo Servizi, e configura gli endpoint per tali Servizi in modo appropriato.

Per accedere ai Servizi, è necessario il permesso per list e watch. Per aggiornare i Servizi, sono necessari i permessi patch e update.

Per impostare gli endpoint per i Servizi, richiede i permessi create, list, get, watch, e update.

v1/Service:

  • List
  • Get
  • Watch
  • Patch
  • Update

Others

L'implementazione del core di CCM richiede l'accesso per creare eventi e, per garantire operazioni sicure, richiede l'accesso per creare ServiceAccounts.

v1/Event:

  • Create
  • Patch
  • Update

v1/ServiceAccount:

  • Create

L'RBAC ClusterRole per il CCM ha il seguente aspetto:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cloud-controller-manager
rules:
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - create
  - patch
  - update
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - '*'
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - list
  - patch
  - update
  - watch
- apiGroups:
  - ""
  resources:
  - serviceaccounts
  verbs:
  - create
- apiGroups:
  - ""
  resources:
  - persistentvolumes
  verbs:
  - get
  - list
  - update
  - watch
- apiGroups:
  - ""
  resources:
  - endpoints
  verbs:
  - create
  - get
  - list
  - watch
  - update

Vendor Implementations

I seguenti fornitori di cloud hanno una implementazione di CCM:

Cluster Administration

Le istruzioni complete per la configurazione e l'esecuzione del CCM sono fornite qui.

2.4 - Controller

Nella robotica e nell'automazione, un circuito di controllo (control loop) è un un'iterazione senza soluzione di continuità che regola lo stato di un sistema.

Ecco un esempio di un circuito di controllo: il termostato di una stanza.

Quando viene impostata la temperatura, si definisce attraverso il termostato lo stato desiderato. L'attuale temperatura nella stanza è invece lo stato corrente. Il termostato agisce per portare lo stato corrente il più vicino possibile allo stato desiderato accendendo e spegnendo le apparecchiature.

In Kubernetes, i controller sono circuiti di controllo che osservano lo stato del cluster, e apportano o richiedono modifiche quando necessario. Ogni controller prova a portare lo stato corrente del cluster verso lo stato desiderato.

Il modello del controller

Un controller monitora almeno una tipo di risorsa registrata in Kubernetes. Questi oggetti hanno una proprietà chiamata spec (specifica) che rappresenta lo stato desiderato. Il o i controller per quella risorsa sono responsabili di mantenere lo stato corrente il più simile possibile rispetto allo stato desiderato.

Il controller potrebbe eseguire l'azione relativa alla risorsa in questione da sé; più comunemente, in Kubernetes, un controller invia messaggi all'API server che a sua volta li rende disponibili ad altri componenti nel cluster. Di seguito troverete esempi per questo scenario.

Controllo attraverso l'API server

Il Job controller è un esempio di un controller nativo in Kubernetes. I controller nativi gestiscono lo stato interagendo con l'API server presente nel cluster.

Il Job è una risorsa di Kubernetes che lancia uno o più Pod per eseguire un lavoro (task) e poi fermarsi.

(Una volta che è stato schedulato, un oggetto Pod diventa parte dello stato desisderato di un dato kubelet).

Quando il Job controller vede un nuovo lavoro da svolgere si assicura che, da qualche parte nel cluster, i kubelet anche sparsi su più nodi eseguano il numero corretto di Pod necessari per eseguire il lavoro richiesto. Il Job controller non esegue direttamente alcun Pod o container bensì chiede all'API server di creare o rimuovere i Pod. Altri componenti appartenenti al control plane reagiscono in base alle nuove informazioni (ci sono nuovi Pod da creare e gestire) e cooperano al completamento del job.

Dopo che un nuovo Job è stato creato, lo stato desiderato per quel Job è il suo completamento. Il Job controller fa sì che lo stato corrente per quel Job sia il più vicino possibile allo stato desiderato: creare Pod che eseguano il lavoro che deve essere effettuato attraverso il Job, così che il Job sia prossimo al completamento.

I controller aggiornano anche gli oggetti che hanno configurato. Ad esempio: una volta che il lavoro relativo ad un dato Job è stato completato, il Job controller aggiorna l'oggetto Job segnandolo come Finished.

(Questo è simile allo scenario del termostato che spegne un certo led per indicare che ora la stanza ha raggiungo la temperatura impostata)

Controllo diretto

A differenza del Job, alcuni controller devono eseguire delle modifiche a parti esterne al cluster.

Per esempio, se viene usato un circuito di controllo per assicurare che ci sia un numero sufficiente di Nodi nel cluster, allora il controller ha bisogno che qualcosa al di fuori del cluster configuri i nuovi Nodi quando sarà necessario.

I controller che interagiscono con un sistema esterno trovano il loro stato desiderato attraverso l'API server, quindi comunicano direttamente con un sistema esterno per portare il loro stato corrente più in linea possibile con lo stato desiderato

(In realtà c'è un controller che scala orizzontalmente i nodi nel cluster. Vedi Cluster autoscaling).

Stato desiderato versus corrente

Kubernetes ha una visione cloud-native dei sistemi, ed è in grado di gestire continue modifiche.

Il cluster viene modificato continuamente durante la sua attività ed il circuito di controllo è in grado di risolvere automaticamente i possibili guasti.

Fino a che i controller del cluster sono in funzione ed in grado di apportare le dovute modifiche, non è rilevante che lo stato complessivo del cluster sia o meno stabile.

Progettazione

Come cardine della sua progettazione, Kubernetes usa vari controller ognuno dei quali è responsabile per un particolare aspetto dello stato del cluster. Più comunemente, un dato circuito di controllo (controller) usa un tipo di risorsa per il suo stato desiderato, ed utilizza anche risorse di altro tipo per raggiungere questo stato desiderato. Per esempio il Job controller tiene traccia degli oggetti di tipo Job (per scoprire nuove attività da eseguire) e degli oggetti di tipo Pod (questi ultimi usati per eseguire i Job, e quindi per controllare quando il loro lavoro è terminato). In questo caso, qualcos'altro crea i Job, mentre il Job controller crea i Pod.

È utile avere semplici controller piuttosto che un unico, monolitico, circuito di controllo. I controller possono guastarsi, quindi Kubernetes è stato disegnato per gestire questa eventualità.

I modi per eseguire i controller

Kubernetes annovera un insieme di controller nativi che sono in esecuzione all'interno del kube-controller-manager. Questi controller nativi forniscono importanti funzionalità di base.

Il Deployment controller ed il Job controller sono esempi di controller che vengono forniti direttamente da Kubernetes stesso (ovvero controller "nativi"). Kubernetes consente di eseguire un piano di controllo(control plane) resiliente, di modo che se un dei controller nativi dovesse fallire, un'altra parte del piano di controllo si occuperà di eseguire quel lavoro.

Al fine di estendere Kubernetes, si possono avere controller in esecuzione al di fuori del piano di controllo. Oppure, se si desidera, è possibile scriversi un nuovo controller. È possibile eseguire il proprio controller come una serie di Pod, oppure esternamente rispetto a Kubernetes. Quale sia la soluzione migliore, dipende dalla responsabilità di un dato controller.

Voci correlate

3 - Containers

La tecnologia per distribuire un'applicazione insieme con le dipendenze necessarie per la sua esecuzione.

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.

Immagine di container

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.

Container runtimes

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).

Voci correlate

3.1 - Immagini

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.

I nomi delle immagini

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.

Aggiornamento delle immagini

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:

  • impostando imagePullPolicy (specifica per il pull delle immagini) del container su Always (sempre).
  • omettendo imagePullPolicy ed usando il tag :latest (più recente) per l'immagine da utilizzare; Kubernetes imposterà la policy su Always (sempre).
  • omettendo imagePullPolicy ed il tag per l'immagine da utilizzare.
  • abilitando l'admission controller AlwaysPullImages.

Quando imagePullPolicy è definito senza un valore specifico, esso è impostato su Always.

Multi-architecture support nelle immagini

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.

Utilizzare un private registry

I private registry possono richiedere l'utilizzo di chiavi per accedere alle immagini in essi contenute.
Le credenziali possono essere fornite in molti modi:

  • configurando i nodi in modo tale da autenticarsi al private registry
    • tutti i pod possono acquisire informazioni da qualsiasi private registry configurato
    • è necessario che l'amministratore del cluster configuri i nodi in tal senso
  • tramite pre-pulled images (immagini pre-caricate sui nodi)
    • tutti i pod possono accedere alle immagini salvate sulla cache del nodo a cui si riferiscono
    • è necessario effettuare l'accesso come root di sistema su ogni nodo per inserire questa impostazione
  • specificando ImagePullSecrets su un determinato pod
    • solo i pod che forniscono le proprie chiavi hanno la possibilità di accedere al private registry
  • tramite estensioni locali o specifiche di un Vendor
    • se si sta utilizzando una configurazione personalizzata del nodo oppure se manualmente, o tramite il cloud provider, si implementa un meccanismo di autenticazione del nodo presso il container registry.

Di seguito la spiegazione dettagliata di queste opzioni.

Configurazione dei nodi per l'autenticazione ad un private registry

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.

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
  • /.dockercfg

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:

  1. Esegui docker login [server] per ogni set di credenziali che vuoi utilizzare. Questo comando aggiornerà $HOME/.docker/config.json sul tuo PC.
  2. Controlla il file $HOME/.docker/config.json in un editor di testo per assicurarti che contenga le credenziali che tu voglia utilizzare.
  3. Recupera la lista dei tuoi nodi; ad esempio:
    • se vuoi utilizzare i nomi: nodes=$( kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}' )
    • se vuoi recuperare gli indirizzi IP: nodes=$( kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}' )
  4. Copia il tuo file locale .docker/config.json in uno dei path sopra riportati nella lista di ricerca.
    • ad esempio, per testare il tutto: for n in $nodes; do scp ~/.docker/config.json root@"$n":/var/lib/kubelet/config.json; done

Puoi 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.

Immagini pre-pulled

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.

Specificare la proprietà imagePullSecrets su un Pod

Kubernetes da la possibilità di specificare le chiavi del container registry su un Pod.

Creare un Secret tramite Docker config

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.

Fare riferimento ad imagePullSecrets in un Pod

È 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.

Casi d'uso

Ci sono varie soluzioni per configurare i private registry. Di seguito, alcuni casi d'uso comuni e le soluzioni suggerite.

  1. Cluster in cui sono utilizzate soltanto immagini non proprietarie (ovvero open-source). In questo caso non sussiste il bisogno di nascondere le immagini.
    • Utilizza immagini pubbliche da Docker hub.
      • Nessuna configurazione richiesta.
      • Alcuni cloud provider mettono in cache o effettuano il mirror di immagini pubbliche, il che migliora la disponibilità delle immagini e ne riduce il tempo di pull.
  2. Cluster con container avviati a partire da immagini proprietarie che dovrebbero essere nascoste a chi è esterno all'organizzazione, ma visibili a tutti gli utenti abilitati nel cluster.
    • Utilizza un private Docker registry.
      • Esso può essere ospitato da Docker Hub, o da qualche altra piattaforma.
      • Configura manualmente il file .docker/config.json su ogni nodo come descritto sopra.
    • Oppure, avvia un private registry dietro il tuo firewall con accesso in lettura libero.
      • Non è necessaria alcuna configurazione di Kubernetes.
    • Utilizza un servizio di container registry che controlli l'accesso alle immagini
      • Esso funzionerà meglio con una configurazione del cluster basata su autoscaling che con una configurazione manuale del nodo.
    • Oppure, su un cluster dove la modifica delle configurazioni del nodo non è conveniente, utilizza imagePullSecrets.
  3. Cluster con immagini proprietarie, alcune delle quali richiedono un controllo sugli accessi.
    • Assicurati che l'admission controller AlwaysPullImages sia attivo. Altrimenti, tutti i Pod potenzialmente possono avere accesso a tutte le immagini.
    • Sposta i dati sensibili un un Secret, invece di inserirli in un'immagine.
  4. Un cluster multi-tenant dove ogni tenant necessiti di un private registry.
    • Assicurati che l'admission controller AlwaysPullImages sia attivo. Altrimenti, tutti i Pod di tutti i tenant potrebbero potenzialmente avere accesso a tutte le immagini.
    • Avvia un private registry che richieda un'autorizzazione all'accesso.
    • Genera delle credenziali di registry per ogni tenant, inseriscile in dei Secret, e popola i Secret per ogni namespace relativo ad ognuno dei tenant.
    • Il singolo tenant aggiunge così quel Secret all'impostazione imagePullSecrets di ogni namespace.

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.

Voci correlate

3.2 - Container Environment

Questa pagina descrive le risorse disponibili nei Container eseguiti in Kubernetes.

Container environment

Quando si esegue un Container in Kubernetes, le seguenti risorse sono rese disponibili:

  • Un filesystem, composto dal file system dell'image e da uno o più volumes.
  • Una serie di informazioni sul Container stesso.
  • Una serie di informazioni sugli oggetti nel cluster.

Informazioni sul Container

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.

Informazioni sul cluster

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.

Voci correlate

3.3 - Container Lifecycle Hooks

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.

Overview

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.

Container hooks

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.

Implementazione degli hook handler

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:

  • Exec - Esegue un comando specifico, tipo pre-stop.sh, all'interno dei cgroup e namespace del Container. Le risorse consumate dal comando vengono contate sul Container.
  • HTTP - Esegue una richiesta HTTP verso un endpoint specifico del Container.

Esecuzione dell'hook handler

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.

Garanzia della chiamata dell'hook

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.

Debugging Hook handlers

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

Voci correlate

4 - Configurazione

Risorse che fornisce Kubernetes per configurare i Pods.

4.1 - ConfigMaps

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.

Utilizzo

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.

Oggetto ConfigMap

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.

ConfigMaps e Pods

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:

  1. Argomento da riga di comando come entrypoint di un container
  2. Variabile d'ambiente di un container
  3. Aggiungere un file in un volume di sola lettura, per fare in modo che l'applicazione lo legga
  4. Scrivere il codice da eseguire all'interno del Pod che utilizza l'API di Kubernetes per leggere la ConfigMap

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.

Usare le ConfigMaps

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.

Usare le ConfigMaps come files in un Pod

Per utilizzare una ConfigMap in un volume all'interno di un Pod:

  1. Creare una ConfigMap o usarne una che già esiste. Più Pods possono utilizzare la stessa ConfigMap.
  2. Modificare la definizione del Pod per aggiungere un volume sotto .spec.volumes[]. Nominare il volume in qualsiasi modo, e avere un campo .spec.volumes[].configMap.name configurato per referenziare il tuo oggetto ConfigMap.
  3. Aggiungere un .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.
  4. Modificare l'immagine o il comando utilizzato così che il programma cerchi i files in quella cartella. Ogni chiave nella sezione 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.

Le ConfigMaps montate sono aggiornate automaticamente

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.

ConfigMaps Immutabili

FEATURE STATE: 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:

  • protezione da aggiornamenti accidentali (o non voluti) che potrebbero causare l'interruzione di applicazioni
  • miglioramento della performance del tuo cluster riducendo significativamente il carico sul kube-apiserver, chiudendo l'ascolto sulle ConfigMaps che sono segnate come immutabili.

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.

Voci correlate

5 - Amministrazione del Cluster

5.1 - Panoramica sull'amministrazione del cluster

La panoramica dell'amministrazione del cluster è per chiunque crei o gestisca un cluster Kubernetes. Presuppone una certa dimestichezza con i core Kubernetes concetti.

Progettare un cluster

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:

  • Vuoi provare Kubernetes sul tuo computer o vuoi creare un cluster multi-nodo ad alta disponibilità? Scegli la distro che più si adatti alle tue esigenze.
  • Se si sta progettando per l'alta disponibilità, impara a configurare cluster in più zone.
  • Utilizzerai un cluster di Kubernetes ospitato, come Motore di Google Kubernetes o che ospita il tuo cluster?
  • Il tuo cluster sarà on-premises o nel cloud (IaaS)? Kubernetes non supporta direttamente i cluster ibridi. Invece, puoi impostare più cluster.
  • Se stai configurando Kubernetes on-premises, considera quale modello di rete si adatti meglio.
  • Eseguirai Kubernetes su hardware "bare metal" o su macchine virtuali (VM)?
  • Vuoi solo eseguire un cluster, oppure ti aspetti di fare lo sviluppo attivo del codice del progetto di Kubernetes? In quest'ultimo caso, scegli una distribuzione sviluppata attivamente. Alcune distribuzioni utilizzano solo versioni binarie, ma offrono una maggiore varietà di scelte
  • Familiarizzare con i componenti necessari per eseguire un cluster.

Nota: non tutte le distro vengono mantenute attivamente. Scegli le distro che sono state testate con una versione recente di Kubernetes.

Managing a cluster

  • 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.

Proteggere un cluster

Securing the kubelet

Optional Cluster Services

5.2 - Certificati

Quando si utilizza l'autenticazione del certificato client, è possibile generare certificati manualmente tramite easyrsa, openssl o cfssl.

easyrsa

** easyrsa ** può generare manualmente certificati per il tuo cluster.

  1. Scaricare, decomprimere e inizializzare la versione patched di easyrsa3.

        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

  1. Generare una CA. (--batch imposta la modalità automatica. --req-cn default CN da usare.)

        ./easyrsa --batch "--req-cn = $ {MASTER_IP} @ date +% s "build-ca nopass

  1. Genera certificato e chiave del server.     L'argomento --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

  1. Copia pki / ca.crt, pki / issued / server.crt e pki / private / server.key nella tua directory.
  2. Compilare e aggiungere i seguenti parametri nei parametri di avvio del server API:

        --client-ca-file =/YourDirectory/ca.crt         --tls-cert-file =/YourDirectory/server.crt         --tls-chiave file privato=/YourDirectory/server.key

openssl

** openssl ** può generare manualmente certificati per il tuo cluster.

  1. Genera un tasto approssimativo con 2048 bit:

         openssl genrsa -out ca.key 2048

  1. In base al tasto approssimativo, generare ca.crt (utilizzare -giorni per impostare il tempo effettivo del certificato):

         openssl req -x509 -new -nodes -key ca.key -subj "/ CN = $ {MASTER_IP}" -days 10000 -out ca.crt

  1. Genera un server.key con 2048 bit:

         openssl genrsa -out server.key 2048

  1. 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
    
  2. Generate the certificate signing request based on the config file:

    openssl req -new -key server.key -out server.csr -config csr.conf
    
  3. 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
    
  4. Visualizza il certificato:

     openssl x509  -noout -text -in ./server.crt
    

Infine, aggiungi gli stessi parametri nei parametri di avvio del server API.

cfssl

** cfssl ** è un altro strumento per la generazione di certificati.

  1. 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
    
  2. 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
    
  3. 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"
           }
         }
       }
     }
    
  4. 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>"
       }]
     }
    
  5. Generate CA key (ca-key.pem) and certificate (ca.pem):

    ../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
    
  6. 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>"
       }]
     }
    
  7. 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
    

Distributing Self-Signed CA Certificate

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.

Certificates API

È possibile utilizzare l'API certificates.k8s.io per eseguire il provisioning certificati x509 da utilizzare per l'autenticazione come documentato here.

5.3 - Cloud Providers

Questa pagina spiega come gestire Kubernetes in esecuzione su uno specifico fornitore di servizi cloud.

kubeadm

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.

AWS

Questa sezione descrive tutte le possibili configurazioni che possono essere utilizzato durante l'esecuzione di Kubernetes su Amazon Web Services.

Node Name

Il provider cloud AWS utilizza il nome DNS privato dell'istanza AWS come nome dell'oggetto Nodo Kubernetes.

Load Balancers

È 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 creato
  • service.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

Azure

Node Name

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.

CloudStack

Node Name

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.

GCE

Node Name

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) .

OpenStack

Questa sezione descrive tutte le possibili configurazioni che possono essere utilizzato quando si utilizza OpenStack con Kubernetes.

Node Name

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.

Services

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.

cloud.conf

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

Typical configuration

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
Global

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.

Load Balancer

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.
Block Storage

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 raccomandato
  • ignore-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
Metadata

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.

Router

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.

OVirt

Node Name

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>)

Photon

Node Name

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).

VSphere

Node Name

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.

IBM Cloud Kubernetes Service

Compute nodes

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.

Networking

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.

Storage

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.

Baidu Cloud Container Engine

Node Name

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.

5.4 - Gestione delle risorse

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.

Organizzazione delle configurazioni delle risorse

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

Bulk operations in kubectl

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.

Usare le etichette in modo efficace

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

Distribuzioni canarie

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.

Updating labels

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.

Aggiornare annotazioni

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.

Ridimensionamento dell'applicazione

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.

Aggiornamenti sul posto delle risorse

A volte è necessario apportare aggiornamenti stretti e senza interruzioni alle risorse che hai creato.

kubectl apply

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 edit

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.

kubectl patch

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.

Disruptive updates

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

Aggiornamento dell'applicazione senza un'interruzione del servizio

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.

Voci correlate

5.5 - Cluster Networking

Il networking è una parte centrale di Kubernetes, ma può essere difficile capire esattamente come dovrebbe funzionare. Ci sono 4 reti distinte problemi da affrontare:

  1. Comunicazioni container-to-container altamente accoppiate: questo è risolto da     pod e comunicazioni localhost.
  2. Comunicazioni Pod-to-Pod: questo è l'obiettivo principale di questo documento.
  3. Comunicazioni Pod-to-Service: questo è coperto da servizi.
  4. Comunicazioni da esterno a servizio: questo è coperto da servizi.

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.

Il modello di rete di Kubernetes

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.

Come implementare il modello di rete di Kubernetes

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.

ACI

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 da Apstra

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 da Big Switch Networks

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

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 from Huawei

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

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.

Contiv

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 / Tungsten Fabric

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

DANM è una soluzione di rete per carichi di lavoro di telco in esecuzione in un cluster Kubernetes. È costituito dai seguenti componenti:

  • Un plugin CNI in grado di fornire interfacce IPVLAN con funzionalità avanzate     * Un modulo IPAM integrato con la capacità di gestire reti L3 multiple, a livello di cluster e discontinue e fornire uno schema di allocazione IP dinamico, statico o nullo su richiesta     * Metaplugin CNI in grado di collegare più interfacce di rete a un contenitore, tramite il proprio CNI o delegando il lavoro a qualsiasi soluzione CNI come SRI-OV o Flannel in parallelo     * Un controller Kubernetes in grado di gestire centralmente sia le interfacce VxLAN che VLAN di tutti gli host Kubernetes     * Un altro controller di Kubernetes che estende il concetto di rilevamento dei servizi basato sui servizi di Kubernetes per funzionare su tutte le interfacce di rete di un pod

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

Flannel è un overlay molto semplice rete che soddisfa i requisiti di Kubernetes. Molti le persone hanno riportato il successo con Flannel e Kubernetes.

Google Compute Engine (GCE)

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

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.

Knitter

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.

Kube-router

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.

L2 networks and linux bridging

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 (a Multi Network plugin)

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.

NSX-T

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 Networks VCS (Servizi cloud virtualizzati)

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 (Apri rete virtuale)

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.

Progetto Calico

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

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 di Weaveworks

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.

Voci correlate

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.

5.6 - Log di registrazione

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.

Basic logging in Kubernetes

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.

Logging at the node level

! Node level logging

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.

System component logs

Esistono due tipi di componenti di sistema: quelli che vengono eseguiti in un contenitore e quelli che non funziona in un contenitore. Per esempio:

  • Lo scheduler di Kubernetes e il proxy kube vengono eseguiti in un contenitore.
  • Il kubelet e il runtime del contenitore, ad esempio Docker, non vengono eseguiti nei contenitori.

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.

Cluster-level logging architectures

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:

  • Utilizzare un agente di registrazione a livello di nodo che viene eseguito su ogni nodo.
  • Includere un contenitore sidecar dedicato per l'accesso a un pod di applicazione.
  • Invia i registri direttamente a un back-end dall'interno di un'applicazione.

Using a node logging agent

Using a node level logging agent

È 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.

Using a sidecar container with the logging agent

Puoi utilizzare un contenitore sidecar in uno dei seguenti modi:

  • Il contenitore sidecar trasmette i log delle applicazioni al proprio stdout.
  • Il contenitore sidecar esegue un agente di registrazione, che è configurato per raccogliere i registri da un contenitore di applicazioni.

Streaming sidecar container

Sidecar container with a streaming container

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
    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
    args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  - name: count-log-2
    image: busybox
    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.

Sidecar container with a logging agent

Sidecar container with a logging agent

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.

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.

Exposing logs directly from the application

Exposing logs directly from the application

È 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.

5.7 - Configurazione della raccolta dati kubelet

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.

Image Collection

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.

Container Collection

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.

User Configuration

Gli utenti possono regolare le seguenti soglie per ottimizzare la garbage collection delle immagini con i seguenti flag kubelet:

  1. image-gc-high-threshold, la percentuale di utilizzo del disco che attiva la garbage collection dell'immagine. Il valore predefinito è 85%.
  2. 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:

  1. 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.
  2. maximum-dead-containers-per-container, numero massimo di vecchie istanze da conservare per contenitore Il valore predefinito è 1.
  3. 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.

Deprecation

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

Voci correlate

Vedi Configurazione della gestione delle risorse esterne per maggiori dettagli.

5.8 - Proxy in Kubernetes

Questa pagina spiega i proxy utilizzati con Kubernetes.

Proxy

Esistono diversi proxy che puoi incontrare quando usi Kubernetes:

  1. Il kubectl proxy:

    - 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

  1. L'apiserver proxy:

    - è 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

  1. Il kube proxy:

    - è 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

  1. Un proxy/bilanciatore di carico di fronte agli apiserver:

    - 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.

  1. Cloud Load Balancer su servizi esterni:

    - 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.

Richiedere reindirizzamenti

I proxy hanno sostituito le funzioni di reindirizzamento. I reindirizzamenti sono stati deprecati.

5.9 - Metriche del responsabile del controller

Le metriche del controller controller forniscono informazioni importanti sulle prestazioni e la salute di il responsabile del controller.

Cosa sono le metriche 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"}

Configurazione

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.

5.10 - Installazione dei componenti aggiuntivi

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.

Networking and Network Policy

  • ACI fornisce funzionalità integrate di networking e sicurezza di rete con Cisco ACI.
  • Calico è un provider di sicurezza e rete L3 sicuro.
  • Canal unisce Flannel e Calico, fornendo i criteri di rete e di rete.
  • Cilium è un plug-in di criteri di rete e di rete L3 in grado di applicare in modo trasparente le politiche HTTP / API / L7. Sono supportate entrambe le modalità di routing e overlay / incapsulamento.
  • CNI-Genie consente a Kubernetes di connettersi senza problemi a una scelta di plugin CNI, come Calico, Canal, Flannel, Romana o Weave.
  • Contiv offre networking configurabile (L3 nativo con BGP, overlay con vxlan, L2 classico e Cisco-SDN / ACI) per vari casi d'uso e un ricco framework di policy. Il progetto Contiv è completamente open source. Il programma di installazione fornisce sia opzioni di installazione basate su kubeadm che non su Kubeadm.
  • Flannel è un provider di reti sovrapposte che può essere utilizzato con Kubernetes.
  • Knitter è una soluzione di rete che supporta più reti in Kubernetes.
  • Multus è un multi-plugin per il supporto di più reti in Kubernetes per supportare tutti i plugin CNI (es. Calico, Cilium, Contiv, Flannel), oltre a SRIOV, DPDK, OVS-DPDK e carichi di lavoro basati su VPP in Kubernetes.
  • NSX-T Container Plug-in (NCP) fornisce l'integrazione tra VMware NSX-T e orchestratori di contenitori come Kubernetes, oltre all'integrazione tra NSX-T e piattaforme CaaS / PaaS basate su container come Pivotal Container Service (PKS) e OpenShift.
  • Nuage è una piattaforma SDN che fornisce una rete basata su policy tra i pod di Kubernetes e non Kubernetes con visibilità e monitoraggio della sicurezza.
  • Romana è una soluzione di rete Layer 3 per pod network che supporta anche API NetworkPolicy. Dettagli di installazione del componente aggiuntivo di Kubeadm disponibili qui.
  • Weave Net fornisce i criteri di rete e di rete, continuerà a funzionare su entrambi i lati di una partizione di rete e non richiede un database esterno.

Service Discovery

  • CoreDNS è un server DNS flessibile ed estensibile che può essere installato come in-cluster DNS per pod.

Visualization & Control

Dashboard è un'interfaccia web dashboard per Kubernetes.

Legacy Add-ons

qui ci sono molti altri componenti aggiuntivi documentati nella directory deprecata cluster / addons.

Quelli ben mantenuti dovrebbero essere collegati qui.

6 - Esempio di modello di concetto

Questa pagina spiega ...

Comprendendo ...

Kubernetes fornisce ...

Usando ...

Usare

Voci correlate

[Sezione opzionale]