Kubernetes Basics
Concetti di base di Kubernetes
L'autore originale di questa pagina è Jorge (leggi il suo post originale qui)
Architettura e Concetti di base
Cosa fa Kubernetes?
Consente di eseguire container in un motore di container.
Lo scheduling consente di eseguire i container in modo efficiente.
Mantiene i container attivi.
Consente le comunicazioni tra i container.
Consente tecniche di distribuzione.
Gestisce volumi di informazioni.
Architettura
Nodo: sistema operativo con pod o pod.
Pod: Wrapper attorno a un container o a più container. Un pod dovrebbe contenere solo un'applicazione (quindi di solito, un pod esegue solo 1 container). Il pod è il modo in cui Kubernetes astrae la tecnologia dei container in esecuzione.
Servizio: Ogni pod ha 1 indirizzo IP interno dall'intervallo interno del nodo. Tuttavia, può essere esposto anche tramite un servizio. Il servizio ha anche un indirizzo IP e il suo obiettivo è mantenere la comunicazione tra i pod in modo che se uno muore il nuovo sostituto (con un diverso IP interno) sarà accessibile esposto nello stesso IP del servizio. Può essere configurato come interno o esterno. Il servizio agisce anche come bilanciatore di carico quando 2 pod sono collegati allo stesso servizio. Quando viene creato un servizio è possibile trovare gli endpoint di ciascun servizio eseguendo
kubectl get endpoints
Kubelet: Agente principale del nodo. Il componente che stabilisce la comunicazione tra il nodo e kubectl e può eseguire solo pod (tramite il server API). Il kubelet non gestisce i container che non sono stati creati da Kubernetes.
Kube-proxy: è il servizio responsabile delle comunicazioni (servizi) tra l'apiserver e il nodo. La base è un IPtables per i nodi. Gli utenti più esperti potrebbero installare altri kube-proxy da altri fornitori.
Container sidecar: I container sidecar sono i container che dovrebbero essere eseguiti insieme al container principale nel pod. Questo modello sidecar estende e migliora la funzionalità dei container attuali senza modificarli. Oggi sappiamo che utilizziamo la tecnologia dei container per incapsulare tutte le dipendenze necessarie affinché l'applicazione possa essere eseguita ovunque. Un container fa una sola cosa e la fa molto bene.
Processo master:
Server API: È il modo in cui gli utenti e i pod comunicano con il processo master. Dovrebbero essere consentite solo richieste autenticate.
Scheduler: Lo scheduling si riferisce a garantire che i Pod siano abbinati ai Nodi in modo che Kubelet possa eseguirli. Ha l'intelligenza sufficiente per decidere quale nodo ha più risorse disponibili per assegnare il nuovo pod. Nota che lo scheduler non avvia nuovi pod, comunica solo con il processo Kubelet in esecuzione all'interno del nodo, che avvierà il nuovo pod.
Kube Controller Manager: Controlla le risorse come i set di repliche o i deployment per verificare se, ad esempio, il numero corretto di pod o nodi è in esecuzione. In caso di mancanza di un pod, comunicherà con lo scheduler per avviarne uno nuovo. Controlla la replica, i token e i servizi account per l'API.
etcd: Archiviazione dati, persistente, coerente e distribuita. È il database di Kubernetes e lo storage chiave-valore dove conserva lo stato completo dei cluster (ogni modifica viene registrata qui). Componenti come lo Scheduler o il Controller Manager dipendono da questi dati per sapere quali modifiche sono state apportate (risorse disponibili dei nodi, numero di pod in esecuzione...)
Cloud controller manager: È il controller specifico per il controllo dei flussi e delle applicazioni, ad esempio: se si hanno cluster in AWS o OpenStack.
Si noti che poiché potrebbero esserci diversi nodi (che eseguono diversi pod), potrebbero anche esserci diversi processi master con accesso all'Api server bilanciato e il loro etcd sincronizzato.
Volumi:
Quando un pod crea dati che non devono essere persi quando il pod scompare, dovrebbero essere archiviati in un volume fisico. Kubernetes consente di collegare un volume a un pod per persistere i dati. Il volume può trovarsi nella macchina locale o in un archivio remoto. Se si eseguono pod in nodi fisici diversi, è necessario utilizzare un archivio remoto in modo che tutti i pod possano accedervi.
Altre configurazioni:
ConfigMap: È possibile configurare URL per accedere ai servizi. Il pod otterrà i dati da qui per sapere come comunicare con il resto dei servizi (pod). Si noti che questo non è il posto consigliato per salvare le credenziali!
Secret: Questo è il luogo in cui memorizzare dati segreti come password, chiavi API... codificati in B64. Il pod potrà accedere a questi dati per utilizzare le credenziali richieste.
Deployments: Qui vengono indicati i componenti da eseguire da Kubernetes. Di solito un utente non lavorerà direttamente con i pod, i pod sono astratti in ReplicaSets (numero di pod replicati), che vengono eseguiti tramite i deployments. Si noti che i deployments sono per applicazioni senza stato. La configurazione minima per un deployment è il nome e l'immagine da eseguire.
StatefulSet: Questo componente è specificamente pensato per applicazioni come database che devono accedere allo stesso archivio.
Ingress: Questa è la configurazione che viene utilizzata per esporre l'applicazione pubblicamente con un URL. Si noti che questo può essere fatto anche utilizzando servizi esterni, ma questo è il modo corretto per esporre l'applicazione.
Se si implementa un Ingress sarà necessario creare Ingress Controllers. L'Ingress Controller è un pod che sarà il punto finale che riceverà le richieste e le controllerà e le bilancerà ai servizi. l'Ingress controller inoltrerà la richiesta in base alle regole di Ingress configurate. Si noti che le regole di Ingress possono puntare a percorsi diversi o addirittura a sottodomini a diversi servizi interni di Kubernetes.
Una pratica di sicurezza migliore sarebbe utilizzare un bilanciatore di carico cloud o un server proxy come punto di ingresso per non avere alcuna parte del cluster Kubernetes esposta.
Quando viene ricevuta una richiesta che non corrisponde a nessuna regola di Ingress, l'Ingress controller la indirizzerà al "Backend predefinito". È possibile
descrivere
l'Ingress controller per ottenere l'indirizzo di questo parametro.minikube addons enable ingress
Infrastruttura PKI - Autorità di Certificazione CA:
CA è la radice fidata per tutti i certificati all'interno del cluster.
Consente ai componenti di convalidarsi reciprocamente.
Tutti i certificati del cluster sono firmati dalla CA.
ETCd ha il suo certificato.
tipi:
certificato apiserver.
certificato kubelet.
certificato scheduler.
Azioni di Base
Minikube
Minikube può essere utilizzato per eseguire alcuni test rapidi su Kubernetes senza la necessità di distribuire un intero ambiente Kubernetes. Eseguirà i processi master e node in una sola macchina. Minikube utilizzerà virtualbox per eseguire il nodo. Vedi qui come installarlo.
Concetti di base di Kubectl
Kubectl
è lo strumento a riga di comando per i cluster Kubernetes. Comunica con il server Api del processo principale per eseguire azioni in Kubernetes o per richiedere dati.
Dashboard di Minikube
Il dashboard ti permette di vedere più facilmente cosa sta eseguendo minikube, puoi trovare l'URL per accedervi in:
Esempi di file di configurazione YAML
Ogni file di configurazione ha 3 parti: metadata, specification (cosa deve essere avviato), status (stato desiderato). All'interno della specifica del file di configurazione del deployment puoi trovare il modello definito con una nuova struttura di configurazione che definisce l'immagine da eseguire:
Esempio di Deployment + Service dichiarati nello stesso file di configurazione (da qui)
Poiché un servizio è di solito correlato a un deployment, è possibile dichiarare entrambi nello stesso file di configurazione (il servizio dichiarato in questa configurazione è accessibile solo internamente):
Esempio di configurazione del servizio esterno
Questo servizio sarà accessibile esternamente (controlla gli attributi nodePort
e type: LoadBalancer
):
Questo è utile per i test, ma per la produzione dovresti avere solo servizi interni e un Ingress per esporre l'applicazione.
Esempio di file di configurazione di Ingress
Questo esporrà l'applicazione su http://dashboard.com
.
Esempio di file di configurazione dei segreti
Nota come le password siano codificate in B64 (che non è sicuro!)
Esempio di ConfigMap
Un ConfigMap è la configurazione che viene fornita ai pod in modo che sappiano come individuare e accedere ad altri servizi. In questo caso, ogni pod saprà che il nome mongodb-service
è l'indirizzo di un pod con cui possono comunicare (questo pod eseguirà un mongodb):
Quindi, all'interno di una configurazione di distribuzione questo indirizzo può essere specificato nel seguente modo in modo che sia caricato all'interno dell'ambiente del pod:
Esempio di configurazione del volume
È possibile trovare diversi esempi di file yaml di configurazione dello storage in https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes. Nota che i volumi non sono all'interno dei namespace
Namespace
Kubernetes supporta cluster virtuali multipli supportati dallo stesso cluster fisico. Questi cluster virtuali sono chiamati namespace. Sono destinati all'uso in ambienti con molti utenti distribuiti su più team o progetti. Per cluster con pochi o decine di utenti, non dovresti avere bisogno di creare o pensare ai namespace affatto. Dovresti iniziare ad utilizzare i namespace solo per avere un migliore controllo e organizzazione di ogni parte dell'applicazione distribuita in Kubernetes.
I namespace forniscono uno scope per i nomi. I nomi delle risorse devono essere univoci all'interno di un namespace, ma non tra namespace. I namespace non possono essere nidificati l'uno dentro l'altro e ogni risorsa di Kubernetes può essere in un solo namespace.
Ci sono 4 namespace di default se stai utilizzando minikube:
kube-system: Non è destinato all'uso degli utenti e non dovresti toccarlo. È per i processi master e kubectl.
kube-public: Dati accessibili pubblicamente. Contiene un configmap che contiene informazioni sul cluster.
kube-node-lease: Determina la disponibilità di un nodo.
default: Lo spazio dei nomi che l'utente utilizzerà per creare risorse.
Si noti che la maggior parte delle risorse di Kubernetes (ad esempio pod, servizi, controller di replica e altri) si trovano in alcuni namespace. Tuttavia, altre risorse come le risorse di namespace e le risorse di basso livello, come i nodi e i volumi persistenti, non si trovano in un namespace. Per vedere quali risorse di Kubernetes sono e non sono in un namespace:
Puoi salvare lo spazio dei nomi per tutti i comandi kubectl successivi in quel contesto.
Helm
Helm è il gestore dei pacchetti per Kubernetes. Consente di impacchettare file YAML e distribuirli in repository pubblici e privati. Questi pacchetti sono chiamati Helm Charts.
Segreti di Kubernetes
Un Segreto è un oggetto che contiene dati sensibili come una password, un token o una chiave. Tali informazioni potrebbero altrimenti essere inserite in una specifica di Pod o in un'immagine. Gli utenti possono creare Segreti e il sistema crea anche Segreti. Il nome di un oggetto Segreto deve essere un nome di sottodominio DNS valido. Leggi qui la documentazione ufficiale.
I segreti potrebbero essere cose come:
API, chiavi SSH.
Token OAuth.
Credenziali, Password (testo normale o b64 + crittografia).
Informazioni o commenti.
Codice di connessione al database, stringhe... .
Ci sono diversi tipi di segreti in Kubernetes
Tipo Incorporato | Utilizzo |
---|---|
Opaco | dati definiti dall'utente arbitrari (Predefinito) |
kubernetes.io/service-account-token | token dell'account di servizio |
kubernetes.io/dockercfg | file ~/.dockercfg serializzato |
kubernetes.io/dockerconfigjson | file ~/.docker/config.json serializzato |
kubernetes.io/basic-auth | credenziali per l'autenticazione di base |
kubernetes.io/ssh-auth | credenziali per l'autenticazione SSH |
kubernetes.io/tls | dati per un client o server TLS |
bootstrap.kubernetes.io/token | dati del token di bootstrap |
Il tipo Opaque è quello predefinito, il tipico coppia chiave-valore definito dagli utenti.
Come funzionano i segreti:
Il seguente file di configurazione definisce un segreto chiamato mysecret
con 2 coppie chiave-valore username: YWRtaW4=
e password: MWYyZDFlMmU2N2Rm
. Definisce anche un pod chiamato secretpod
che avrà username
e password
definiti in mysecret
esposti nelle variabili d'ambiente SECRET_USERNAME
e SECRET_PASSWOR
. Monta anche il segreto username
all'interno di mysecret
nel percorso /etc/foo/my-group/my-username
con permessi 0640
.
Segreti in etcd
etcd è un archivio chiave-valore coerente e altamente disponibile utilizzato come archivio di supporto di Kubernetes per tutti i dati del cluster. Accediamo ai segreti memorizzati in etcd:
Vedrai che i certificati, le chiavi e gli URL sono situati nel FS. Una volta ottenuti, sarai in grado di connetterti a etcd.
Una volta che hai stabilito la comunicazione, sarai in grado di ottenere i segreti:
Aggiunta di crittografia all'ETCD
Di default tutti i segreti sono memorizzati in chiaro all'interno di etcd a meno che non si applichi uno strato di crittografia. L'esempio seguente si basa su https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
Dopo di che, è necessario impostare il flag --encryption-provider-config
sul kube-apiserver
per puntare alla posizione del file di configurazione creato. È possibile modificare /etc/kubernetes/manifest/kube-apiserver.yaml
e aggiungere le seguenti righe:
Scorri verso il basso in volumeMounts:
Scorri in basso nei volumeMounts fino a hostPath:
Verifica che i dati siano crittografati
I dati sono crittografati quando vengono scritti su etcd. Dopo aver riavviato il tuo kube-apiserver
, qualsiasi segreto appena creato o aggiornato dovrebbe essere crittografato quando memorizzato. Per verificare, puoi utilizzare il programma a riga di comando etcdctl
per recuperare il contenuto del tuo segreto.
Crea un nuovo segreto chiamato
secret1
nello spazio dei nomidefault
:
Utilizzando il comando etcdctl, leggi quel segreto da etcd:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
dove [...]
devono essere gli argomenti aggiuntivi per connettersi al server etcd. 3. Verifica che il segreto memorizzato sia preceduto da k8s:enc:aescbc:v1:
, il che indica che il provider aescbc
ha crittografato i dati risultanti. 4. Verifica che il segreto venga correttamente decrittografato quando recuperato tramite l'API:
dovrebbe corrispondere a mykey: bXlkYXRh
, mydata è codificato, controlla decodifica di un segreto per decodificare completamente il segreto.
Poiché i segreti sono crittografati in scrittura, eseguire un aggiornamento su un segreto crittograferà quel contenuto:
Suggerimenti finali:
Cerca di non conservare segreti nel file system, ottienili da altri luoghi.
Dai un'occhiata a https://www.vaultproject.io/ per aggiungere ulteriore protezione ai tuoi segreti.
Riferimenti
Last updated