Container sicuri e leggeri con RedHat

  • Di
  • 2023-06-22 - 5 minuti
banner

Perché

Il rilascio di applicazioni tramite container leggeri presenta dei vantaggi pratici, dal momento che le immagini contengono tutte le dipendenze necessarie per il corretto funzionamento dell’applicazione. Tuttavia, si possono perdere i vantaggi della containerizzazione se queste immagini sono troppo grandi e quindi richiedono diversi minuti per l’avvio dell’applicazione.

In questo post vediamo come utilizzare le Universal Base Images (aka UBI) di Red Hat come base per costruire delle immagini per i vostri container che siano leggere e sicure per le vostre applicazioni.

Creare applicazioni

Red Hat fornisce delle immagini di base per la creazione di applicazioni cloud-based e applicazioni web in container. Con queste immagini, l’affidabilità, la sicurezza, le prestazioni e le caratteristiche del ciclo di vita delle immagini sono caratteristiche già integrate e verificate dalle persone che lavorano in quest’azienda, per cui è possibile creare un’applicazione containerizzata tramite un’immagine UBI, pusharla sul proprio registry preferito, condividerla facilmente e distribuirla anche su piattaforme che non siano Red Hat.

Cosa sono

Ogni immagine UBI è basata su Red Hat Enterprise Linux (alias RHEL), la distribuzione Linux di livello enterprise più diffusa degli ultimi due decenni. Costruire l’immagine del container su una base di software RHEL garantisce che l’immagine sia affidabile, sicura e liberamente distribuibile. Non è necessario essere clienti Red Hat per utilizzare o ridistribuire le immagini UBI: basta usarle e lasciare che Red Hat gestisca le immagini di base per voi senza alcun costo.

Dove trovarle

Sono facilmente disponibili sia sul Red Hat Container Catalog che sul repository ufficiale di Red Hat di Docker Hub.

Se dovessimo scegliere tra le due opzioni, si dovrebbe preferire l’utilizzo della console del catalogo Red Hat, perché mostra diverse informazioni come la dimensione dell’immagine, la versione, i controlli sulla sicurezza, l’elenco dei pacchetti presenti, il Dockerfile e le diverse opzioni disponibili per il pull dell’immagine.

Quale immagine utilizzare

Le Universal Base Images di Red Hat sono offerte in diversi formati:

  • Micro: si tratta di un’immagine ridotta che utilizza il gestore di pacchetti dell’host sottostante per installare i pacchetti, tipicamente utilizzando Buildah o una build multi-stage con Podman.
  • Minimal: definisce un’immagine ridotta che utilizza microdnf come gestore di pacchetti.
  • Standard: immagine pensata e progettata per essere il livello di base per tutte le applicazioni, il middleware e le utility containerizzate.
  • Init: progettata per eseguire un sistema con ID processo pari a 1 (che corrisponde al processo di init di Linux) per l’esecuzione di più servizi all’interno di un container.

Esempio

Vediamo un piccolo use case per Python: utilizzeremo un’applicazione di esempio che andremo a impacchettare in un’immagine UBI.

Il codice delle applicazioni di esempio, compreso il Dockerfile, è disponibile su questo repository GitHub.

Di seguito il Dockerfile:

FROM registry.access.redhat.com/ubi8/ubi

RUN yum install -y python3.11-pip-wheel  python3.11-wheel python3.11-pip;

WORKDIR /app

COPY ./requirements.txt ./app ./

RUN mkdir -p /.local; \
    chown -R 1001:0 /.local; \
    chmod -R ug+rwX /.local; \
	pip3 install -r requirements.txt; 

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Per l’esempio di Python abbiamo come immagine di base utilizzata quella standard ufficiale di Red Hat UBI, nella versione 8.

Il comando yum installa l’eseguibile di Python, mentre il comando WORKDIR specifica la directory in cui si trova l’applicazione all’interno dell’immagine del container e il comando RUN esegue l’installazione delle dipendenze.

Il comando COPY copia il file dei requisiti di Python nell’immagine UBI, che sarà poi utilizzato dal comando RUN per installare le dipendenze.

Il comando EXPOSE specifica la porta su cui l’applicazione si metterà in ascolto, che solitamente è la 8000 per FastAPI.

Infine, il comando CMD specifica il comando che verrà eseguito quando il container verrà eseguito.

Di seguito, riportiamo i comandi per eseguire la build e il run dell’immagine:

docker build -t python-ubi8 .

docker images | grep -i python-ubi8

docker run -it -p 8000:8000 -d python-ubi8

Il comando cURL dovrebbe restituire la seguente risposta:

curl -vk http://localhost:8000
>>>
*   Trying ::1:8000...
* TCP_NODELAY set
* Connected to localhost (::1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
  < HTTP/1.1 200 OK
  < date: Mon, 19 Jun 2023 09:22:48 GMT
  < server: uvicorn
  < content-length: 18
  < content-type: application/json
  <
* Connection #0 to host localhost left intact
  {"Hello":"World!"}

La dimensione finale dell’immagine è di soli 320 MB:

$ docker images
>>>
REPOSITORY              TAG     IMAGE ID       CREATED          SIZE
python-ubi8             latest  50c12e1ca549   55 minutes ago   320MB

Chiaramente, queste dimensioni potrebbero essere ridotte ulteriormente, utilizzando un’immagine UBI in versione minimal, magari con Python pre-installato, come nell’esempio seguente:

FROM registry.access.redhat.com/ubi8/ubi-minimal

RUN microdnf install -y python3

WORKDIR /app

COPY ./requirements.txt ./app ./

RUN python3 -m pip install -r /app/requirements.txt

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

In questo caso, le dimensioni vengono dimezzate, dal momento che i pacchetti non necessari sono già stati rimossi:

$ docker images
>>>
REPOSITORY              TAG     IMAGE ID       CREATED          SIZE
python-ubi8             latest  c4f0d7e3049c   8 minutes ago   161MB

Conclusioni

L’utilizzo delle UBI offre maggiore affidabilità, sicurezza e tranquillità per le vostre applicazioni containerizzate.

Inoltre, è possibile distribuire liberamente le applicazioni containerizzate basate su UBI ai vostri amici (e nemici) sia su piattaforme Red Hat che non Red Hat, avvalendosi dei controlli di sicurezza che vengono effettuati periodicamente.

Nell’esempio visto in precedenza abbiamo usato una semplice UBI8, ma in realtà ne esistono di già pronte con Python e altri linguaggi già installati e configurati di default: perché non provare?

Risorse utili

Post correlati

Iscriviti al TheRedCode.it Corner

La tecnologia corre, e tu devi correre più veloce per rimanere sempre sul pezzo! 🚀

Riceverai una volta al mese (o anche meno) con codici sconto per partecipare agli eventi del settore, quiz per vincere dei gadget e i recap degli articoli più interessanti pubblicati sul blog

Ci sto!

Partners

Community, aziende e persone che supportano attivamente il blog

Logo di Codemotion
Logo di GrUSP
Logo di Python Milano
Logo di Schrodinger Hat
Logo di Python Biella Group
Logo di Fuzzy Brains
Logo di Django Girls
Logo di Improove
Logo del libro open source
Logo di NgRome

Vuoi diventare #tech content writer? 🖊️

Se vuoi raccontare la tua sul mondo #tech con dei post a tema o vuoi condividere la tua esperienza con la community, sei nel posto giusto! 😉

Manda una mail a collaborazioni[at]theredcode.it con la tua proposta e diventa la prossima penna del blog!

Ma sì, facciamolo!