Programma
Man mano che le applicazioni di machine learning diventano più complesse, portare i nostri modelli dall’ambiente di sviluppo alla produzione non significa solo scrivere buon codice. Si tratta di garantire che l’applicazione giri in modo coerente su ambienti diversi. Qui entra in gioco la containerizzazione. Ma che cos’è esattamente la containerizzazione e perché è un punto di svolta per i workflow di machine learning?
La containerizzazione è un modo leggero e portatile per impacchettare un’applicazione insieme a tutte le sue dipendenze, librerie e configurazioni in un’unica unità chiamata container. A differenza delle macchine virtuali (VM) tradizionali, i container condividono il sistema operativo dell’host, risultando più veloci, efficienti e facili da scalare.
Per data scientist e ML engineer, questo significa poter creare un modello sulla tua macchina locale e distribuirlo ovunque, che sia su una piattaforma cloud, un server o persino il laptop di un collega, senza preoccuparti di problemi di compatibilità.
In questo tutorial, vedremo come containerizzare un’applicazione di machine learning usando Docker e Kubernetes. Alla fine saprai come:
- Creare un container Docker per la tua applicazione ML.
- Distribuire e gestire la tua applicazione containerizzata con Kubernetes.
- Scalare e monitorare la tua applicazione ML in un ambiente di produzione.
Se sei alle prime armi con Docker, dai un’occhiata alla nostra guida Come imparare Docker da zero. Puoi anche seguire il nostro corso Containerization and Virtualization with Docker and Kubernetes.
Prerequisiti
Prima di iniziare, dovresti avere una conoscenza di base di Python, dei workflow di machine learning e della riga di comando. La familiarità con i concetti di Docker (ad es. immagini, container, comandi di base) è consigliata, e conoscenze di base di Kubernetes sono opzionali ma utili per il deploy e la scalabilità.
Cos’è un’applicazione containerizzata?
Un’applicazione containerizzata è un’applicazione software impacchettata con tutte le sue dipendenze, librerie e configurazioni in un’unica unità leggera chiamata container. Per le applicazioni di machine learning, significa impacchettare tutto, dal modello addestrato alle librerie Python da cui dipende, garantendo che l’applicazione giri allo stesso modo ovunque.

Applicazione tradizionale vs applicazione containerizzata
Perché la containerizzazione è importante per le applicazioni di machine learning
Quando sviluppi applicazioni di machine learning, probabilmente ti sei imbattuto nel problema del “sul mio PC funziona”. Magari il tuo modello gira perfettamente sul tuo laptop ma fallisce quando lo distribuisci sul cloud, oppure un collega non riesce a riprodurre i tuoi risultati perché ha versioni diverse di scikit-learn o TensorFlow installate.
La containerizzazione risolve questi problemi creando un ambiente coerente e isolato per la tua applicazione. Ecco cosa rende migliori le applicazioni containerizzate per il machine learning:
- Coerenza: la tua applicazione si comporta allo stesso modo su ambienti diversi—dallo sviluppo al test fino alla produzione.
- Isolamento: ogni container gira nel proprio ambiente, evitando conflitti tra applicazioni o dipendenze differenti.
- Portabilità: i container possono girare su qualsiasi piattaforma che supporti la containerizzazione, che sia la tua macchina locale, un servizio cloud o un server on-premises.
- Scalabilità: devi gestire più richieste? I container rendono semplice scalare orizzontalmente l’applicazione eseguendo più istanze.
Container vs macchine virtuali
Sebbene container e macchine virtuali (VM) vengano entrambi usati per isolare le applicazioni, differiscono in modo significativo per funzionamento e casi d’uso. Ecco una panoramica delle differenze e dei vantaggi chiave:
|
Aspetto |
Container |
Macchine virtuali (VM) |
|
Architettura |
Condividono il kernel del sistema operativo host; leggeri e isolati. |
Includono un sistema operativo completo; girano su un hypervisor. |
|
Prestazioni |
Leggeri, avvio rapido e basso overhead di risorse. |
Più pesanti, avvio più lento e maggior uso di risorse a causa dell’overhead del sistema operativo completo. |
|
Portabilità |
Altamente portabili; girano in modo coerente tra ambienti. |
Meno portabili a causa delle dipendenze dal sistema operativo; possibili problemi di compatibilità. |
|
Scalabilità |
Facilmente scalabili usando strumenti di orchestrazione come Kubernetes. |
Scalabili ma richiedono più risorse e sforzo di gestione. |
|
Sicurezza |
Si basano sulla sicurezza del sistema operativo host; isolamento inferiore rispetto alle VM. |
Forte isolamento grazie a istanze OS separate; più sicure per app sensibili. |
Per le applicazioni di machine learning, queste differenze contano. Quando devi scalare il tuo modello per gestire più predizioni o vuoi distribuire più versioni per fare A/B test, i container offrono l’agilità e l’efficienza nell’uso delle risorse di cui hai bisogno.
Per saperne di più su containerizzazione e virtualizzazione, esplora questo percorso di apprendimento: Containerization and Virtualization with Docker and Kubernetes.
Come containerizzare un’applicazione di machine learning
Nelle sezioni seguenti, abbiamo delineato una guida passo passo su come containerizzare un’applicazione:
1. Configurare l’ambiente
Prima di iniziare a containerizzare la nostra applicazione di machine learning, dobbiamo installare gli strumenti necessari e preparare l’ambiente. Questa sezione ti guiderà nell’installazione di Docker e nella preparazione di una semplice applicazione di machine learning alla containerizzazione.
Strumenti necessari
Per containerizzare un’applicazione di machine learning, ti serviranno i seguenti strumenti:
- Docker: una piattaforma per creare, distribuire ed eseguire container.
- Kubernetes (opzionale): uno strumento di orchestrazione per gestire i container su larga scala. (Lo vedremo più avanti nel tutorial.)
Iniziamo installando Docker.
Passo 1: Installare Docker
Docker è disponibile per Windows, macOS e Linux. Di seguito i passaggi per installare Docker sul tuo sistema.
Per Windows/macOS:
- Vai al sito Docker.
- Scarica e installa Docker Desktop.
- Segui le istruzioni fornite dall’installer.
Per Linux (Ubuntu/Debian):
Apri il terminale ed esegui i seguenti comandi per installare Docker:
# Update your package list
sudo apt-get update
# Install required packages to allow apt to use a repository over HTTPS
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
# Add Docker’s official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add the Docker repository to your system
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update your package list again
sudo apt-get update
# Install Docker
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
# Verify Docker installation
sudo docker --version
Questo processo di installazione aggiunge il repository di Docker al tuo sistema, ne verifica l’autenticità con la chiave GPG e installa il motore Docker insieme ai suoi strumenti da riga di comando.
Passo 2: Verificare l’installazione di Docker
Una volta installato Docker, verifica che funzioni correttamente eseguendo il seguente comando nel prompt dei comandi:
# Check Docker version
docker --version
# Run hello-world container
docker run hello-world
Questo comando scarica un’immagine di test leggera e la esegue come container. Se va a buon fine, vedrai un messaggio di benvenuto che conferma che l’installazione funziona correttamente, come mostrato di seguito:
Hello from Docker!
2. Preparare la tua applicazione di machine learning
Ora che Docker è installato, prepariamo una semplice applicazione di machine learning per la containerizzazione. Per questo tutorial, useremo uno script Python di base che carica un modello pre-addestrato e fornisce predizioni tramite una API Flask.
Passo 1: Crea una semplice applicazione ML
Crea una nuova directory per il progetto e aggiungi i seguenti file:
- app.py: uno script Python per fornire predizioni tramite una API Flask.
- requirements.txt: un file che elenca le dipendenze Python.
Ecco il codice per app.py:
# Import required libraries
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from flask import Flask, request, jsonify
import numpy as np
# Initialize Flask app
app = Flask(__name__)
# Load and prepare the model
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = RandomForestClassifier(random_state=42)
model.fit(X_train, y_train)
@app.route('/predict', methods=['POST'])
def predict():
# Get features from request
features = request.json['features']
# Make prediction
prediction = model.predict([features])
return jsonify({'prediction': int(prediction[0]),
'class_name': iris.target_names[prediction[0]]})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Il codice carica il dataset Iris, addestra un classificatore Random Forest e configura un endpoint API Flask che accetta valori di feature e restituisce predizioni. Lo stiamo costruendo come un servizio web per renderlo adatto alla containerizzazione.
Passo 2: Crea requirements.txt
Il file requirements.txt elenca le librerie Python richieste per eseguire lo script. Crea questo file nella stessa directory di app.py:
# requirements.txt
scikit-learn==1.3.0
numpy==1.24.3
flask==2.0.1
Questo specifica le esatte versioni dei pacchetti Python necessarie alla nostra applicazione. Avere versioni fissate garantisce che l’applicazione containerizzata sia coerente e riproducibile.
Ora che l’ambiente è configurato e la nostra applicazione ML è pronta, possiamo passare a creare il nostro primo container Docker. Nella prossima sezione scriveremo un Dockerfile e costruiremo un’immagine Docker per la nostra applicazione ML basata su Flask.
3. Creare il tuo primo container Docker
Ora che la nostra applicazione di machine learning è pronta, il passo successivo è containerizzarla con Docker. Questo comporta la creazione di un Dockerfile, ovvero uno script che contiene le istruzioni per creare un’immagine Docker. Una volta creata l’immagine, possiamo eseguirla come container.
Esempio di Dockerfile: scrivere un Dockerfile
Un Dockerfile è un documento di testo che contiene tutti i comandi per assemblare un’immagine. Ecco come crearne uno per la nostra applicazione ML basata su Flask.
- Nella stessa directory di
app.pyerequirements.txt, crea un nuovo file chiamatoDockerfile(senza estensione). - Aggiungi il seguente contenuto al
Dockerfile:
# Use an official Python runtime as the base image
FROM python:3.9-slim
# Set the working directory in the container
WORKDIR /app
# Copy the requirements file into the container
COPY requirements.txt .
# Install the Python dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy the rest of the application code into the container
COPY . .
# Expose port 5000 for the Flask app
EXPOSE 5000
# Define the command to run the Flask app
CMD ["python", "app.py"]
Spiegazione:
FROM python:3.9-slim: usiamo l’immagine ufficiale Python 3.9 slim come base. La versione slim è leggera e ideale per applicazioni containerizzate.WORKDIR /app: imposta la directory di lavoro all’interno del container su /app. Tutti i comandi successivi verranno eseguiti da qui.COPY requirements.txt .: copia il file requirements.txt dalla tua macchina locale al container.RUN pip install --no-cache-dir -r requirements.txt: installa le dipendenze Python elencate in requirements.txt. Il flag --no-cache-dir riduce la dimensione dell’immagine evitando di memorizzare la cache.COPY . .: copia tutti i file dalla directory corrente della tua macchina locale nella directory /app del container.EXPOSE 5000: espone la porta 5000, su cui è in ascolto la nostra app Flask.CMD ["python", "app.py"]: definisce il comando per avviare l’app Flask quando parte il container.
Creare e testare l’immagine Docker
Con il Dockerfile pronto, possiamo ora costruire l’immagine Docker ed eseguirla come container.
Passo 1: Build dell’immagine Docker
Esegui il seguente comando nel terminale per creare l’immagine Docker:
docker build -t ml-flask-app .
Questo comando crea un’immagine Docker dal Dockerfile nella directory corrente. Il flag -t ml-flask-app assegna all’immagine il tag ml-flask-app, facilitandone il riferimento in seguito.
Passo 2: Eseguire il container Docker
Una volta creata l’immagine, eseguila come container con il seguente comando:
docker run -p 5000:5000 ml-flask-app
Questo comando avvia un container dall’immagine ml-flask-app. Il flag -p 5000:5000 mappa la porta 5000 della tua macchina locale alla porta 5000 del container, permettendoti di accedere all’app Flask dal browser o con uno strumento come curl.
Passo 3: Testare l’applicazione containerizzata
Apri una nuova finestra del terminale e invia una richiesta di test all’app Flask in esecuzione nel container:
curl -X POST -H "Content-Type: application/json" -d '{"input": [5.1, 3.5, 1.4, 0.2]}' http://localhost:5000/predict
Dovresti vedere una risposta simile a questa:
{
"prediction": 0
}
Questo significa che l’app Flask containerizzata è in esecuzione correttamente ed è pronta a servire predizioni.
Debug dei problemi comuni
Se riscontri problemi durante la creazione o l’esecuzione del container, ecco alcuni suggerimenti per la risoluzione:
Controlla i log di Docker: usa il seguente comando per visualizzare i log di un container in esecuzione:
docker logs <container_id>
Verifica la sintassi del Dockerfile: ricontrolla il Dockerfile per individuare refusi o errori di sintassi.
Controlla i conflitti di porta: assicurati che la porta 5000 non sia già in uso sulla tua macchina locale. In caso affermativo, puoi mappare il container su un’altra porta, ad esempio:
docker run -p 5001:5000 ml-flask-app
Ricostruisci l’immagine:
Se apporti modifiche al Dockerfile o al codice dell’applicazione, ricostruisci l’immagine usando:
docker build -t ml-flask-app .
Ora che abbiamo creato e testato con successo il nostro container Docker, il prossimo passo è imparare a gestire e scalare l’applicazione containerizzata. Nella sezione successiva, vedremo come usare Kubernetes per distribuire e scalare la nostra applicazione ML.
Scopri altri progetti Docker nella nostra guida 10 idee di progetti Docker: da principiante ad avanzato.
Eseguire la tua applicazione containerizzata
Ora che abbiamo creato il nostro container Docker, vediamo come gestirlo efficacemente. Questa sezione ti guiderà tra i comandi Docker essenziali per avviare, arrestare e ispezionare i container, oltre a lavorare con log e porte.
Usare Docker per gestire i container
Docker fornisce una serie di comandi potenti per gestire i container. Vediamo i più comuni.
Avviare un container
Per avviare un container da un’immagine, usa il comando docker run. Ad esempio:
docker run -p 5000:5000 ml-flask-app
Questo comando avvia un container dall’immagine ml-flask-app e mappa la porta 5000 della tua macchina locale alla porta 5000 del container.
Se vuoi eseguire il container in background (modalità detached), aggiungi il flag -d:
docker run -d -p 5000:5000 ml-flask-app
Questo permette al container di girare in background, liberando il tuo terminale.
Arrestare un container
Per arrestare un container in esecuzione, prima trova il suo ID con:
docker ps
Questo elenca tutti i container in esecuzione con i relativi ID, nomi e altri dettagli. Una volta ottenuto l’ID, arresta il container con:
docker stop <container_id>
Ad esempio:
docker stop a1b2c3d4e5f6
Ispezionare un container
Per visualizzare informazioni dettagliate su un container, usa il comando docker inspect:
docker inspect <container_id>
Questo fornisce un output JSON con dettagli come impostazioni di rete, volumi montati e variabili d’ambiente del container.
Elencare i container
Per vedere tutti i container (sia in esecuzione che arrestati), usa:
docker ps -a
È utile per controllare lo stato dei tuoi container e trovare gli ID.
Lavorare con log e porte
Log e porte sono fondamentali per il debug e l’accesso alla nostra applicazione containerizzata. Vediamo come usarli.
Visualizzare i log del container
Per visualizzare i log di un container in esecuzione, usa:
docker logs <container_id>
Ad esempio:
docker logs a1b2c3d4e5f6
Questo mostra l’output della tua applicazione, inclusi eventuali errori o messaggi stampati in console. Se vuoi seguire i log in tempo reale (come tail -f), aggiungi il flag -f:
docker logs -f <container_id>
Mappare le porte
Quando esegui un container, puoi mappare le porte del container sulla tua macchina locale usando il flag -p. Ad esempio:
docker run -p 5000:5000 ml-flask-app
Questo mappa la porta 5000 del container alla porta 5000 della tua macchina locale. Se la porta 5000 è già in uso, puoi mapparla su un’altra porta, così:
docker run -p 5001:5000 ml-flask-app
Ora la tua app Flask sarà accessibile su http://localhost:5001.
Verificare i binding delle porte
Per vedere quali porte sono mappate su un container in esecuzione, usa:
docker port <container_id>
Questo elenca le mappature di porta del container, utile per il debug di problemi di connettività. Nella prossima sezione vedremo come distribuire la nostra applicazione ML containerizzata su Kubernetes e gestirla su larga scala.
Scalare con Kubernetes
Una volta containerizzata l’applicazione, possiamo distribuirla usando Kubernetes. Kubernetes automatizza il deploy, la scalabilità e la gestione delle applicazioni containerizzate, semplificando la gestione di carichi su larga scala. In questa sezione vedremo come distribuire la nostra applicazione ML su un cluster Kubernetes.
Distribuire container su Kubernetes
Kubernetes utilizza file YAML per definire lo stato desiderato della tua applicazione. Questi file descrivono come i container devono essere distribuiti, scalati e gestiti. Iniziamo creando un deployment Kubernetes per la nostra applicazione ML basata su Flask.
Passo 1: Scrivere un file YAML di deployment per Kubernetes
Crea un file chiamato ml-flask-app-deployment.yaml con il seguente contenuto:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ml-flask-app
spec:
replicas: 3
selector:
matchLabels:
app: ml-flask-app
template:
metadata:
labels:
app: ml-flask-app
spec:
containers:
- name: ml-flask-app
image: ml-flask-app
ports:
- containerPort: 5000
Questo file YAML definisce:
- Un Deployment chiamato
ml-flask-app. - Tre repliche dell’applicazione, per garantire alta disponibilità.
- Un container che usa l’immagine
ml-flask-appcreata in precedenza. - Una containerPort a 5000, la porta su cui è in ascolto la nostra app Flask.
Passo 2: Distribuire l’applicazione
Per distribuire l’applicazione su Kubernetes, usa il comando kubectl apply:
kubectl apply -f ml-flask-app-deployment.yaml
Questo comando dice a Kubernetes di creare le risorse definite nel file YAML. Puoi verificare lo stato del deployment usando:
kubectl get deployments
Questo mostra lo stato del tuo deployment, incluso il numero di repliche in esecuzione.
Passo 3: Esporre l’applicazione
Per rendere l’applicazione accessibile all’esterno del cluster Kubernetes, crea un Service. Crea un file chiamato ml-flask-app-service.yaml con il seguente contenuto:
apiVersion: v1
kind: Service
metadata:
name: ml-flask-app-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 5000
selector:
app: ml-flask-app
Questo file YAML definisce:
- Un Service chiamato
ml-flask-app-service. - Un tipo LoadBalancer, che espone l’applicazione a internet.
- Un mapping dalla porta 80 (esterna) alla porta 5000 (interna).
Applica il Service con:
kubectl apply -f ml-flask-app-service.yaml
Puoi verificare lo stato del Service usando:
kubectl get services
Questo mostra l’indirizzo IP esterno da cui la tua applicazione è accessibile.
Scalabilità e monitoraggio
Kubernetes semplifica la scalabilità della tua applicazione e il monitoraggio delle prestazioni. Vediamo come farlo.
Scalare l’applicazione
Per scalare l’applicazione, aggiorna il numero di repliche nel deployment. Ad esempio, per scalare a 5 repliche, esegui:
kubectl scale deployment ml-flask-app --replicas=5
Puoi anche aggiornare il campo replicas nel file YAML e riapplicarlo:
spec:
replicas: 5
Poi esegui:
kubectl apply -f ml-flask-app-deployment.yaml
Monitorare l’applicazione
Kubernetes fornisce diversi strumenti per monitorare la nostra applicazione. Vediamo alcuni strumenti per il monitoraggio.
Usa kubectl logs per vedere i log di un pod specifico:
kubectl logs <pod_name>
Usa kubectl get pods per controllare lo stato dei pod:
kubectl get pods
Usa kubectl top per visualizzare l’uso di CPU e memoria:
kubectl top pods
Autoscaling
Kubernetes supporta anche l’Horizontal Pod Autoscaler (HPA), che scala automaticamente il numero di pod in base all’utilizzo di CPU o memoria. Per abilitare l’autoscaling, esegui:
kubectl autoscale deployment ml-flask-app --cpu-percent=50 --min=3 --max=10
Questo garantisce che il deployment scali tra 3 e 10 repliche in base all’utilizzo della CPU.
Best practice per i deployment su Kubernetes
Ecco alcune best practice da seguire quando distribuisci applicazioni su Kubernetes.
Usare i limiti di risorse
Definisci limiti di CPU e memoria per i tuoi container per prevenire l’esaurimento delle risorse:
resources:
limits:
cpu: "1"
memory: "512Mi"
Usare liveness e readiness probe
Aggiungi health check per assicurarti che la tua applicazione stia girando correttamente:
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 5000
initialDelaySeconds: 5
periodSeconds: 10
Usare i namespace
Organizza le tue risorse usando i namespace per evitare conflitti:
kubectl create namespace ml-app
kubectl apply -f ml-flask-app-deployment.yaml -n ml-app
Nella prossima sezione, vedremo consigli per ottimizzare i Dockerfile, gestire le dipendenze e garantire la sicurezza.
Best practice per containerizzare applicazioni ML
Containerizzare applicazioni di machine learning comporta alcune sfide, come gestire dipendenze pesanti, garantire la riproducibilità e mantenere la sicurezza. Ecco alcune best practice per aiutarti a superare queste sfide e costruire applicazioni ML containerizzate robuste.
Ottimizzare i Dockerfile
Un Dockerfile ben ottimizzato può ridurre significativamente i tempi di build e la dimensione delle immagini. Ecco alcuni suggerimenti per ottimizzare i tuoi Dockerfile:
Usare i multi-stage build
I multi-stage build permettono di usare più istruzioni FROM in un singolo Dockerfile. Questo aiuta a ridurre la dimensione finale dell’immagine scartando file e dipendenze non necessari dagli stadi intermedi. Ad esempio:
# Stage 1: Build the application
FROM python:3.9-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
COPY . .
# Stage 2: Create the final image
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app .
ENV PATH=/root/.local/bin:$PATH
EXPOSE 5000
CMD ["python", "app.py"]
Questo Dockerfile:
- Usa uno stage
builderper installare le dipendenze e costruire l’applicazione. - Copia solo i file necessari (ad es. dipendenze installate e codice dell’applicazione) nell’immagine finale, riducendone la dimensione.
Minimizzare i layer
Ogni istruzione in un Dockerfile crea un nuovo layer. Per minimizzare il numero di layer e ridurre la dimensione dell’immagine:
- Combina più comandi
RUNin un unico comando usando&&. - Usa
COPYinvece diADDa meno che tu non abbia bisogno delle funzionalità aggiuntive diADD.
Ad esempio:
RUN apt-get update && \
apt-get install -y --no-install-recommends build-essential && \
rm -rf /var/lib/apt/lists/*
Usare immagini base leggere
Scegli immagini base leggere come python:3.9-slim invece di immagini più grandi come python:3.9. Le immagini slim contengono solo i pacchetti essenziali, riducendo la dimensione complessiva.
Gestire dipendenze e riproducibilità
La riproducibilità è fondamentale nei workflow di machine learning. Ecco come gestire le dipendenze e garantire la riproducibilità nelle tue applicazioni containerizzate.
Usare requirements.txt o pipen
Elenca tutte le dipendenze Python in un file requirements.txt o usa pipenv per gestirle. Ad esempio:
# requirements.txt
scikit-learn==1.3.0
numpy==1.24.3
Flask==2.3.2
Installa le dipendenze nel tuo Dockerfile:
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
Fissare le versioni delle dipendenze
Fissa sempre le versioni delle dipendenze per evitare cambiamenti imprevisti. Ad esempio:
scikit-learn==1.3.0
numpy==1.24.3
Flask==2.3.2
Usare variabili d’ambiente per la configurazione
Usa variabili d’ambiente per configurare l’applicazione invece di codificare valori fissi. Questo rende il container più flessibile e facile da configurare in ambienti diversi. Ad esempio:
ENV MODEL_PATH=/app/models/model.pkl
Quindi accedi alla variabile d’ambiente nella tua applicazione:
import os
model_path = os.getenv('MODEL_PATH')
Considerazioni sulla sicurezza
La sicurezza è un aspetto critico delle applicazioni containerizzate. Ecco alcune best practice per mettere in sicurezza le tue applicazioni ML:
Evitare di eseguire come root
Eseguire i container come utente root può esporre il sistema a rischi di sicurezza. Invece, crea un utente non root ed esegui il container con quell’utente. Ad esempio:
# Create a non-root user
RUN useradd -m myuser
# Switch to the non-root user
USER myuser
# Set the working directory
WORKDIR /home/myuser/app
# Copy the application code
COPY --chown=myuser:myuser . .
# Run the application
CMD ["python", "app.py"]
Scansionare le immagini per vulnerabilità
Usa strumenti come Trivy o Clair per scansionare le immagini Docker alla ricerca di vulnerabilità. Ad esempio, per scansionare un’immagine con Trivy:
trivy image ml-flask-app
Gestire i secret in modo sicuro
Non inserire mai informazioni sensibili come API key o credenziali del database direttamente nel Dockerfile o nel codice dell’applicazione. Usa invece Kubernetes Secrets o Docker Secrets per gestire i dati sensibili. Ad esempio, in Kubernetes:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
api_key: <base64-encoded-api-key>
Quindi monta il secret come variabile d’ambiente nel tuo deployment:
env:
- name: API_KEY
valueFrom:
secretKeyRef:
name: my-secret
key: api_key
Testing e debug
Testing e debug sono essenziali per assicurarti che la tua applicazione containerizzata funzioni come previsto. Ecco alcuni suggerimenti:
Testare in locale
Prima di distribuire su Kubernetes, testa il tuo container in locale con Docker. Ad esempio:
docker run -p 5000:5000 ml-flask-app
Usare i log per il debug
Usa docker logs o kubectl logs per fare debug della tua applicazione containerizzata. Ad esempio:
docker logs <container_id>
kubectl logs <pod_name>
Automatizzare i test
Usa pipeline CI/CD per automatizzare il testing e il deploy delle tue applicazioni containerizzate. Strumenti come GitHub Actions, GitLab CI o Jenkins possono aiutarti a configurare workflow automatizzati.
Seguendo queste best practice, possiamo costruire applicazioni di machine learning containerizzate efficienti, riproducibili e sicure. Dall’ottimizzazione dei Dockerfile alla gestione delle dipendenze e alla sicurezza, queste strategie ci aiutano a semplificare i workflow ML e distribuire i modelli con sicurezza.
Conclusione
Containerizzare applicazioni di machine learning con Docker e Kubernetes semplifica il deploy, assicura la riproducibilità e migliora la scalabilità. Seguendo best practice come l’ottimizzazione dei Dockerfile, la gestione delle dipendenze e la priorità alla sicurezza, possiamo costruire workflow ML robusti, efficienti e sicuri.
Per continuare a imparare la containerizzazione e migliorare i tuoi workflow di machine learning, dai un’occhiata a questi corsi:
Containerizzare applicazioni ML: FAQ
La containerizzazione è obbligatoria per i modelli di machine learning?
No, ma rende il deploy, la scalabilità e il version control molto più semplici e affidabili.
Posso aggiornare il mio modello ML senza interrompere il container?
Sì, puoi eseguire rolling update per sostituire i container con nuove versioni del modello senza downtime.
Più modelli ML possono girare nello stesso container?
Sì, anche se è più corretto eseguire ogni modello in container separati per una migliore gestione delle risorse.
Qual è la differenza tra Docker e Container?
Docker è una piattaforma che crea e gestisce i container; un container è l’applicazione effettivamente impacchettata.
Ho bisogno di Kubernetes per eseguire applicazioni containerizzate?
No, Docker da solo è sufficiente per eseguire i container; Kubernetes serve solo per scalare più container.
Sono una content writer specializzata in data science. Amo creare contenuti su temi di IA/ML/DS. Esploro anche nuovi strumenti di IA e ne scrivo.

