Come scrivere un healthcheck per un docker container

Il controllo di healthcheck sono una importante funzionalità in Docker. Questa permette di definire come testare che la propria applicazione containerizzata sia in salute.

Quando Docker avvia un container monitora semplicemente lo stato del processo che in esso c’è in esecuzione. Quando il processo in esecuzione nel container termina, il container va in exit e si spegne. Questo controllo che docker esegue è molto semplice e non si occupa di entrare nel merito di cosa l’applicazione stia facendo ne tantomeno se questa è “viva”. A tutti gli effetti, il processo in esecuzione nel container potrebbe essere attivo, ma al tempo stesso essere in sovraccarico e restituire ad ogni nuova richiesta un errore 503 (il container in questo caso sarebbe ancora in esecuzione).

Healthcheck è lo strumento che serve quindi per istruire docker che la nostra applicazione, oltre ad essere “viva”, è “in salute”. In questo modo Docker sarà in grado di contrassegnare il nostro container healthy o unhealthy sulla base del suo reale stato di salute.

Healthcheck con curl e iwr

Il controllo di healthcheck viene definito con l’istruzione healthcheck all’interno del Dockerfile. Alcuni fantastici blog post ci danno istruzioni su come definire un healthcheck e l’esempio tipico è:

				
					HEALTHCHECK CMD curl --fail http://localhost || exit 1
				
			

Questo healthcheck utilizza curl per effettuare una chiamata HTTP all’interno del container con la quale verifica che la web app contenuta nel container risponda. In caso di web app in salute, il controllo restituirà un exit status 0, al contrario restituirà 1 in caso di stato unhealthy.

Nel caso si utilizzi Windows, curl viene invocato mediante l’alias Invoke-WebRequest. Siccome PowerShell gestisce gli exit code in modo leggermente diverso, il controllo di healthcheck in un Windows Dockerfile sarà il seguente:

				
					HEALTHCHECK CMD powershell -command `  
    try { `
     $response = iwr http://localhost; `
     if ($response.StatusCode -eq 200) { return 0} `
     else {return 1}; `
    } catch { return 1 }
				
			

Il problema con curl e iwr

L’utilizzo di curl o iwr per impostare un healthcheck del container è una soluzione rapida e semplice, ma presenta alcuni svantaggi se si sta lavorando su una immagine Docker di produzione.

  1. Anzitutto curl deve essere a bordo dell’immagine Linux che si sta utilizzando. Si potrebbe partire da Alpine che è un’immagine da 4MB, la quale non ha a bordo curl e l’installazione usando apk --update --no-cache add curl si aggiungerebbero 2.5MB all’immagine, nonché tutta la superficie di attacco che si trascina dietro curl.
  2. Nel caso di uso di un immagine Windows è necessario avere a bordo PowerShell. L’ultima immagine di Nano Server in virtù di una minor dimensione dell’immagine e riduzione della superficie di attacco è sprovvista di PowerShell, il che vuol dire nessuna presenza di iwr.
  3. Basarsi su un tool specifico riduce drasticamente la portabilità del proprio Dockerfile. Se si sta pensando di sviluppare una app cross-platform, l’utilizzo di un tool specifico per OS per realizzare un healthcheck, romperebbe la cross-platformness. Best case scenario: il build dell’immagine fallisce. Worst case scenario: il build dell’immagine avviene, ma presenterà un healthcheck che sempre fallirà su una specifica piattaforma (perché prova ad utilizzare curl su Windows o viceversa iwr su Linux).
  4. Ci sono alcuni limiti su quello che si può fare mediante un tool HTTP. Per essere sicuri che la propria app funzioni correttamente si finirebbe per scrivere un /diagnostics endpoint su cui eseguire una chiamata curl. Diagnostics endpoints sono un ottima cosa da avere, ma bisogno anche essere sicuri che gli endpoint restino privati.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.

Most Recent

Come modificare l’autore di commit precedenti

Anzitutto apriamo questo articolo precisando che modificare i commit passati è un’operazione sulla commit history di un repository e tale operazione può essere rischiosa. Questa

Come eliminare un Git remote branch

Mentre in questo articolo abbiamo trattato come eliminare un Git local branch, qui di seguito trattiamo come eliminare un Git remote branch. Anche in questo caso,

Partners