{"id":1357,"date":"2022-12-22T18:13:05","date_gmt":"2022-12-22T17:13:05","guid":{"rendered":"https:\/\/alessandromasciadri.com\/?p=1357"},"modified":"2022-12-22T18:14:38","modified_gmt":"2022-12-22T17:14:38","slug":"come-scrivere-un-healthcheck-per-un-docker-container","status":"publish","type":"post","link":"https:\/\/alessandromasciadri.com\/come-scrivere-un-healthcheck-per-un-docker-container\/","title":{"rendered":"Come scrivere un healthcheck per un docker container"},"content":{"rendered":"\t\t<div data-akihiro-type=\"ama-post\" data-akihiro-id=\"1357\" class=\"akihiro akihiro-1357\" data-akihiro-post-type=\"post\">\n\t\t\t\t<div class=\"akihiro-element akihiro-element-69f4da7 e-flex e-con-boxed e-con e-parent\" data-id=\"69f4da7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"akihiro-element akihiro-element-25ff131 akihiro-widget akihiro-widget-text-editor\" data-id=\"25ff131\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Il controllo di healthcheck sono una importante funzionalit\u00e0 in Docker. Questa permette di definire come testare che la propria applicazione containerizzata sia in salute.<\/p><p>Quando Docker avvia un container monitora semplicemente lo stato del processo che in esso c&#8217;\u00e8 in esecuzione. Quando il processo in esecuzione nel container termina, il container va in exit e si spegne. Questo controllo che docker esegue \u00e8 molto semplice e non si occupa di entrare nel merito di cosa l&#8217;applicazione stia facendo ne tantomeno se questa \u00e8 &#8220;viva&#8221;. 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).<\/p><p>Healthcheck \u00e8 lo strumento che serve quindi per istruire docker che la nostra applicazione, oltre ad essere &#8220;viva&#8221;, \u00e8 &#8220;in salute&#8221;. In questo modo Docker sar\u00e0 in grado di contrassegnare il nostro container healthy o unhealthy sulla base del suo reale stato di salute.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"akihiro-element akihiro-element-2fa3a3d akihiro-widget akihiro-widget-heading\" data-id=\"2fa3a3d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t<h3 class=\"akihiro-heading-title akihiro-size-default\">Healthcheck con curl e iwr<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"akihiro-element akihiro-element-4555800 akihiro-widget akihiro-widget-text-editor\" data-id=\"4555800\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Il controllo di healthcheck viene definito con l&#8217;istruzione healthcheck all&#8217;interno del Dockerfile. Alcuni fantastici <a href=\"https:\/\/blog.alexellis.io\/test-drive-healthcheck\/\">blog<\/a> <a href=\"https:\/\/www.couchbase.com\/blog\/docker-health-check-keeping-containers-healthy\/\">post<\/a> ci danno istruzioni su come definire un healthcheck e l&#8217;esempio tipico \u00e8:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"akihiro-element akihiro-element-b04c9b5 akihiro-widget akihiro-widget-code-highlight\" data-id=\"b04c9b5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-okaidia copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>HEALTHCHECK CMD curl --fail http:\/\/localhost || exit 1<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"akihiro-element akihiro-element-428a0f3 akihiro-widget akihiro-widget-text-editor\" data-id=\"428a0f3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Questo healthcheck utilizza curl per effettuare una chiamata HTTP all&#8217;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\u00e0 un exit status 0, al contrario restituir\u00e0 1 in caso di stato unhealthy.<\/p><p>Nel caso si utilizzi Windows, curl viene invocato mediante l&#8217;alias Invoke-WebRequest. Siccome PowerShell gestisce gli exit code in modo leggermente diverso, il controllo di healthcheck in un Windows Dockerfile sar\u00e0 il seguente:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"akihiro-element akihiro-element-c2acba9 akihiro-widget akihiro-widget-code-highlight\" data-id=\"c2acba9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t\t\t<div class=\"prismjs-okaidia copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-bash \">\n\t\t\t\t<code readonly=\"true\" class=\"language-bash\">\n\t\t\t\t\t<xmp>HEALTHCHECK CMD powershell -command `  \n    try { `\n     $response = iwr http:\/\/localhost; `\n     if ($response.StatusCode -eq 200) { return 0} `\n     else {return 1}; `\n    } catch { return 1 }<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"akihiro-element akihiro-element-cf037c6 akihiro-widget akihiro-widget-heading\" data-id=\"cf037c6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t<h3 class=\"akihiro-heading-title akihiro-size-default\">Il problema con curl e iwr<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"akihiro-element akihiro-element-9e9683a akihiro-widget akihiro-widget-text-editor\" data-id=\"9e9683a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"akihiro-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>L&#8217;utilizzo di curl o iwr per impostare un healthcheck del container \u00e8 una soluzione rapida e semplice, ma presenta alcuni svantaggi se si sta lavorando su una immagine Docker di produzione.<\/p><ol><li>Anzitutto curl deve essere a bordo dell&#8217;immagine Linux che si sta utilizzando. Si potrebbe partire da <a href=\"https:\/\/hub.docker.com\/_\/alpine\">Alpine<\/a> che \u00e8 un&#8217;immagine da 4MB, la quale non ha a bordo curl e l&#8217;installazione usando <code>apk --update --no-cache add curl<\/code> si aggiungerebbero 2.5MB all&#8217;immagine, nonch\u00e9 tutta la superficie di attacco che si trascina dietro curl.<\/li><li>Nel caso di uso di un immagine Windows \u00e8 necessario avere a bordo PowerShell. L&#8217;ultima immagine di <a href=\"https:\/\/hub.docker.com\/_\/microsoft-windows-nanoserver\">Nano Server<\/a>\u00a0in virt\u00f9 di una minor dimensione dell&#8217;immagine e riduzione della superficie di attacco \u00e8 sprovvista di PowerShell, il che vuol dire nessuna presenza di iwr.<\/li><li>Basarsi su un tool specifico riduce drasticamente la portabilit\u00e0 del proprio Dockerfile. Se si sta pensando di sviluppare una app cross-platform, l&#8217;utilizzo di un tool specifico per OS per realizzare un healthcheck, romperebbe la cross-platformness. Best case scenario: il build dell&#8217;immagine fallisce. Worst case scenario: il build dell&#8217;immagine avviene, ma presenter\u00e0 un healthcheck che sempre fallir\u00e0 su una specifica piattaforma (perch\u00e9 prova ad utilizzare curl su Windows o viceversa iwr su Linux).<\/li><li>Ci sono alcuni limiti su quello che si pu\u00f2 fare mediante un tool HTTP. Per essere sicuri che la propria app funzioni correttamente si finirebbe per scrivere un <code>\/diagnostics<\/code> 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.<\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Il controllo di healthcheck sono una importante funzionalit\u00e0 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&#8217;\u00e8 in esecuzione. Quando il processo in esecuzione nel container termina, il container va in exit e [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[27],"class_list":["post-1357","post","type-post","status-publish","format-standard","hentry","category-programmazione","tag-docker"],"_links":{"self":[{"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/posts\/1357","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/comments?post=1357"}],"version-history":[{"count":7,"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/posts\/1357\/revisions"}],"predecessor-version":[{"id":1364,"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/posts\/1357\/revisions\/1364"}],"wp:attachment":[{"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/media?parent=1357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/categories?post=1357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alessandromasciadri.com\/ama-json\/wp\/v2\/tags?post=1357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}