Gestire Limiti e Quote in Kubernetes

Kubernetes è un orchestratore di container, grazie al quale è possibile gestire e scalare facilmente le applicazioni in modo affidabile ed efficiente. Uno dei problemi da gestire è quello dei consumi: come è possibile gestire e controllare le risorse computazionali all’ interno di un Cluster?

In questo articolo sono esposti i metodi basilari per impostare richieste e limiti per le risorse interne al Cluster.

Requests e Limits per Container

È possibile gestire i consumi di risorse computazionali per singolo container, indicando sia le risorse minime per il corretto funzionamento del container, che indicare limiti alle risorse per evitare eccessivi utilizzi di tali risorse sui nodi.

Le risorse minime vengono chiamate Resource Requests, solitamente indicano i minimi valori di CPU e memoria necessari al container.

Lo Scheduler usa le Resource Requests per decidere quale Nodo usare per il deploy del Pod, se un nodo non soddisferà la richiesta di risorse, non verrà usato; se nessun nodo nel Cluster risponde a questi requisiti, il Pod non verrà creato.

I limiti applicati ai container sono chiamati Resource Limits, se questo parametro non è specificato, i container non hanno limiti, e possono usare tutte le risorse disponibili sul nodo; quando invece questi limiti sono applicati, sarà il Kubelet ad assicurarsi che essi vengano rispettati.

Di fianco (o di seguito, in base al vostro dispositivo), il manifest di un Pod con un solo container, sul quale sono indicate sia le Resource Requests che i Resource Limits:

				
					apiVersion: v1
kind: Pod
metadata:
  name: Pod
spec:
  containers:
  - name: app
    image: desotech/whoami
    resources:
      limits:
        cpu: "1000m"
        memory: "512Mi"
      requests:
        cpu: "500m"
        memory: "256Mi"

				
			

Le Richieste ed i Limiti del container sono indicati nella sezione resources. I valori di CP possono essere indicati per core, o per millicpu, un millesimo di CPU core, quindi 1000m indica un intero core, mentre 500m indica 0.5 core.

I valori di memoria vengono misurati in byte, nel caso sopracitato il valore di memoria è espresso in mebibytes.

LimitRange per Namespace

Un altro modo per controllare le risorse computazionali in un Cluster è quello di imporre dei limiti per Namespace.

Il LimitRange è un oggetto interno al Cluster, che si occupa di controllare i consumi di tutti i pod all’ interno di un Namespace, e garantisce che ogni Pod non superi i limiti a lui imposti.

				
					apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange
spec:
  limits:
  - default:
      cpu: 1
      memory: 500Mi
    defaultRequest:
      cpu: 0.5
      memory: 100Mi
    type: Container

				
			

Un altro modo per controllare le risorse computazionali in un Cluster è quello di imporre dei limiti per Namespace.

Il namespace da limitare, viene specificato quando il manifest viene applicato:

				
					kubectl apply -f limitrange.yaml -n namespace-1
				
			

A tutti i pod creati in questo namespace, verranno applicati i limiti indicati nel LimitRange.

Cosa accade se un container ha una Resource Requests superiore al limite specificato nel LimitRange?

Il Pod non sarà Schedulato, l’output ottenuto dopo il tentativo fallito di creazione del Pod, sarà:

				
					Pod “pod-1” is invalid: spec.containers[0].resources.requests: Invalid value “800m”: must be less than or equal to cpu limit
				
			

Resource Quotas

Un altro modo per controllare i limiti all’ interno di un namespace è l’utilizzo delle Resource Quota, con esse è possibile controllare i limiti di risorse computazionali di un namespace, ma anche il numero di oggetti al suo interno.

				
					apiVersion: v1
kind: ResourceQuota
metadata:
  name: resource-quota
  namespace: namespace-1
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1024Mi
    limits.cpu: "0.5"
    limits.memory: 2048M
    pods: "10"
    services: "10"

				
			

Una volta applicato questo manifest, verranno si imposti i parametri specificati di CPU e memoria, ma verranno imposti anche limiti al numero di pod e servizi all’ interno del namespace.

Usando un describe, è possibile controllare lo stato dei parametri specificati nella ResourceQuota:

				
					kubectl describe quota -n namespace-1
				
			
				
					Name:            compute-quota
Namespace:       limited-cpu-memory
Resource         Used  Hard
--------         ----  ----
limits.cpu       0     5
limits.memory    0     2Gi
requests.cpu     0     1
requests.memory  0     1Gi
pods             0     5
services         0     2
				
			

Grazie a questo comando è possibile controllare in diretta lo stato dei consumi del namespace indicato.

Conclusione

Impostare richieste e limiti per Container, Pod o Namespace è una buona pratica che può aiutare a migliorare l’efficienza del Cluster, a prevenire il sovraccarico dei nodi e garantire che le applicazioni funzionino correttamente. Se vuoi addentrarti nel mondo di Kubernetes, sfoglia il nostro catalogo di corsi su Kubernetes o seleziona un bundle per le certificazioni CKA, CKAD e CKS