Please enable JavaScript.
Coggle requires JavaScript to display documents.
K8s for Developers - Coggle Diagram
K8s for Developers
Kubernetes
Services
Reverse proxy verso un gruppo di pod. Usa iptables come implementazione di default. I pod vengono selezionati tramite un selettore sulle label
-
-
Sono di tre tipi:
- ClusterIP: espone un ip valido all'interno del cluster. NON espone all'esterno del cluster.
- NodePort: espone all'esterno del cluster usando NAT su porte. Si definisce range di porte da 32K in su.Prende una porta dei nodi libera e assegno al service. Non è detto che il service sia su un nodo dove siano presenti pod gestiti.
- LoadBalancer: espone all'esterno del cluster un servizio che permetterà di chiamare nodi all'interno del cluster. Sotto usa i NodePort. Posso riutilizzare porte già usate nei nodi perché tanto crea un IP nuovo. Nelle installazioni locali (ad esempio minikube) può non essere disponibile.
Tutti e tre le modalità hanno stesso scopo, esporre i pod che gestiscono. Ogni modalità include quello sotto, LoadBalancer aggiunge funzionalità a NodePort che a sua volta aggiunge funzionalità a ClusterIP.
Come esterno si intende la rete fuori dal cluster, non è detto che sia collegata ad internet ad esempio.
Ingress
Load balancer di tipo applicativo (HTTP) che usa altri service. In base a delle regole può direzionare il traffico verso altri services, ad esempio via path, header, ecc..
-
-
Glossario
-
namespace [ns]
Gestione della visibilità per gli oggetti. Permette di separare gli oggetti per isolarli e permettere di eseguire sullo stesso cluster più applicazioni. Hanno nome univoco a livello di cluster
-
ReplicaSet [rs]
Controller che permette di replicare dei pod. Di tipo namespaced. Caratteristiche: selettore, numero di repliche, template.
-
service [svc]
Rende stabile volatilità dei pod. Permette scalabilità orizzontale dei pod agendo da reverse proxy. E' di tipo TCP/IP (livello 4 ISO/OSI)
StatefulSet [sfs]
Simile al ReplicaSet ma mantenuto lo stato: persistenza, ip, nome. La memoria viene persa.
Ingress [ing]
Load balancer di livello applicativo (livello 7 ISO/OSI). Permette di definire regole di routing in base a path, cookies, session affinity.
Non è nel subset base di k8s ma esterno. Internamente Ingress punta ad un service interno al cluster e non direttamente ai nodi.
kubectl
-
le risorse possono essere gestite tramite comandi o tramite descrittori, file di testo in formato YAML o JSON
YAML formato da:
- apiVersion: API da chiamare. Formato da apiGroup/versione. Se apiGroup non è specificato è usato core. Obbligatorio.
- kind: tipo di risorsa. Obbligatorio.
- metadata: contiene dati per legare informazioni all'oggetto. Ad esempio name. name obbligatorio. Se voglio aggiungere una risorsa ad un namespace va specificato nei metadata.
- spec: parte dinamica che dipende dal tipo di risorsa. Opzionale (ad esempio nei namespace non esiste)
-
comandi:
- create: permette di creare un oggetto. Se esiste da errore.
- apply: permette di applicare una modifica ad un oggetto. Se non esiste lo crea quindi attenzione, se esiste sovrascrive e rispetto alla create non da errore quindi attenzione.
- delete: cancella un oggetto. Attenzione se cancello un namespace cancello tutti gli oggetti contenuti.
Pod
Container probes
Hanno tutti un default timeout se non impostato. Se non soddisfatti viene distrutto pod e ricreato
-
-
-
Container hooks
PostStart
Hook che viene eseguito quando il container è creato. Non è garantito che il container sia pronto a ricevere le risposte.
-
init Containers
Servono per specificare una lista di container da lanciare (nell'ordine indicato). Una volta che tutti hanno eseguito con successo possono partire il container del pod. Ad esempio posso creare un container che aspetta l'avvio del database, una volta terminato fa exit con valore 0 e parte pod.
priority e preemption
Strategie per informare lo scheduler dell'importanza di alcuni Pod rispetto ad altre così da permettergli di fare le scelte su quali pod tagliare oppure no quando ci sono problemi di risorse.
LimitRange e ResourceQuota
Strumenti che permettono di limitare le risorse di un namespace. Ad esempio posso specifica massima RAM, CPU. Oppure posso definire una forbice min/max di RAM e CPU per container.
QoS
Ogni container può definire le risorse richieste e limit (RAM e CPU). Non è detto che si arrivi limit. I container possono essere classificati in:
- Guaranteed: sono definiti limit e request per ogni risorsa;
- Burstable: almeno un container ha definito risorse limit o request
- BestEffort: i container all'interno di un Pod non definiscono risorse richieste
I Pod con container guaranteed hanno priorità su altri. Se devo liberare risorse parto dai BestEffort perché non so di quante risorse possono avere bisogno per funzionare bene
ProrityClass
Ad ogni Pod è possibile attribuire un valore numerico intero (32 bit). Chi ha valore più alto ha priorità maggiore. I Pod di sistema hanno la priorità massima.
PreemptionPolicy può essere never o PreemptLowerPriority. Permette di avere sempre in esecuzione Pod con priorità più alta. Ad esempio se si sta schedulando un Pod con priorità altissima è possibile in assenza di risorse che venga distrutto un Pod con priorità più bassa.
-
Troubleshooting
cluster
- verificare che i nodi stiano eseguendo e registrati (kubectl get nodes). Ad esempio ready e della versione che mi aspetto;
- lettura log, sulle macchine sono localizzati sul path /var/log. Se usiamo GKE sono in StackDriver;
- verifica configurazione del cluster
application
- verifica stato dei pod (kubectl get pods). Sul singolo pod è possibile usare opzione -o yaml per vedere output dettagliato in yaml;
- debugging pod tramite verifica dei log (kubectl log ${POD_NAME}. Se su un pod ci sono più container nel comando è necessario specificare il container;
- debugging sui replica set (kubectl describe rs ${CONTROLLER_NAME});
- debugging dei services (kubectl get endpoints ${SERVICE_NAME}). Si possono usare che strumenti come kubectl port-forward
-
Service Discovery
-
Interna via DNS. Esiste kube-dns che permette di tradurre il nome mnemonico in ip; la tabella è aggiornata dopo ogni cambiamento di configurazione (c'è un controller in ascolto);
Variabili d'ambiente. K8s imposta su ogni container durante la creazione delle variabili d'ambiente che indica indirizzo e porta del service. Attenzione ad ordine di creazione, se creo prima pod (deployment) e poi service i pod non avranno le variabili d'ambiente.
Container
Container image
Immagine immutabile, punto di partenza
è rappresentata da:
- id univoco
- nome mnemonico composto da <host>/<registry name>/<image short name>[:tag].
Ad esempio docker.io/library/golang
Opzionalmente si può aggiungere il tag in coda. Se non specificato viene scaricata la "latest". La latest è considerata l'ultima stabile, notare che può non essere ultima.
Se richiedo la 1.13 scarico sempre l'ultima patch della 1.13.x. Stessa cosa se richiesto la 1, scarico sempre l'ultima minor 1.x.y
Container
istanza di un'immagine, esecuzione
Container Engine
Basato su:
Principali:
- Docker
- Rkt (alternativa che punta alla sicurezza)
Entrypoint
processo principale del container, finché vive il container vive. Il ciclo di vita del container dipende da quel processo. Possono essere lanciati altri processi ma dipendono dal processo principale, se muore si interrompe tutto
-
-
-
Service Mesh
Lavorando a livello di network permette funzionalità aggiuntive installando e configurando un proxy sidecar all'interno di ogni pod. Il proxy sidecar è in collegamento con il service mesh control plane.
Ogni pod quando deve comunicare passa sempre dal proxy sidecar sia ingresso che uscita.
Permette service discovery (anche extra cluster), tracing, monitoring, encryption, load balancing, authorization
-
Istio
Mixer
Permette di monitorare il traffico dei proxy del service mesh per aggiungere diverse feature. Logging, quote, caching
TLS mutual communication
Istio ha un suo CA che genera, gestisce, rinnova i certificati per i proxy. La comunicazione tra due proxy è sicura tramite TLS.
Decoupling Traffic
Istio permette di attuare politiche di smistamento del traffico.
Ad esempio:
Canary release: solo una percentuale di traffico su un certo servizio (che ha magari nuova versione dell'app);
Dynamic request routing for A/B testing
Gradual rollout
-
Docker
DockerFile
Crea l'immagine con il comando docker build
Build esegue il container per creare i layer, se c'è del codice malevolo viene eseguito già in build.
Best practices
creare meno layer possibile concentrando le RUN tramite operatore && tra un comando e l'altro. Se eseguo ad esempio apt-get prima scarico dipendenze, installo e poi pulisco cache (sempre nello stesso RUN).
differenza tra ADD e COPY è che la ADD se parto da uno zip espande il contenuto nella copia. Con il comando COPY avrei dovuto usare due comandi: COPY per copiare lo zip, RUN per fare unzip.
USER permette di specificare l'utente usato da quel layer in poi. Non deve essere root, perché se è eseguito un attacco il codice malevolo può fare tutto. Se serve usare root usiamo USER root e poi quando finito impostiamo un altro utente.
CMD e ENTRYPOINT indicano il comando da lanciare che diventerà il processo principale. ENTRYPOINT è pensato per lanciare comando, CMD pensato per gli argomenti. Ci pensa lui a concatenare. E' diviso in due per poter lasciare stesso ENTRYPOINT e sovrascrivere parametri con CMD. Viene preso sempre l'ultimo ENTRYPOINT e CMD. CMD può essere sovrascritto anche durante il comando docker run. Kubernetes cambia i nomi: ENTRYPOINT diventa CMD e CMD ARG
VOLUME permette di fare la mount di un esterno al container. I LINK sono dei volumi condivisi su può container e permettono la comuncazione.
Documento testuale che indica come è formata un'immagine. Ogni riga del DockerFile è un layer. L'ultima riga sancisce il contenuto finale dell'immagine se non ci sono stati errori.
Networking
- bridge: ogni container ha il suo IP. Ad esempio tutti possono esporre sulla stessa porta;
- host: usano rete dell'host, no overlapping porte;
- overlay: dedicato a orchestratori;
- maclan: comuncazione attraverso indirizzo fisico mac (seppur virtuale);
- none: disabilitata;
Best Practices
- ridurre numero layer;
- anticipare layer che cambiano raramente;
- rimuovere da ogni layer ciò che non serve;
- non usare root;
- usare Alpine Linux il più possibile;
- scrivere un buon entrypoint (eventualmente con precondizioni);
- gestire Linux signals (SIGTERM, SIGKILL);