Phase Plans (5 files): - 04-RESEARCH.md: Domain research on Docker limits, healthchecks, EC2 parallels - 04-VALIDATION.md: Success criteria and validation strategy - 04-01-PLAN.md: Test infrastructure (RED phase) - 04-02-PLAN.md: Diátxis documentation - 04-03-PLAN.md: Infrastructure implementation (GREEN phase) Test Scripts (6 files, 1300+ lines): - 01-resource-limits-test.sh: Validate INF-03 compliance - 02-healthcheck-test.sh: Validate healthcheck configuration - 03-enforcement-test.sh: Verify resource limits with docker stats - 04-verify-infrastructure.sh: Infrastructure verification - 99-final-verification.sh: End-to-end student verification - run-all-tests.sh: Test orchestration with fail-fast - quick-test.sh: Fast validation (<30s) Documentation (11 files, 2500+ lines): Tutorials (3): - 01-set-resource-limits.md: EC2 instance types, Docker limits syntax - 02-implement-healthchecks.md: ELB health check parallels - 03-dependencies-with-health.md: depends_on with service_healthy How-to Guides (4): - check-resource-usage.md: docker stats monitoring - test-limits-enforcement.md: Stress testing CPU/memory - custom-healthcheck.md: HTTP, TCP, database healthchecks - instance-type-mapping.md: Docker limits → EC2 mapping Reference (3): - compose-resources-syntax.md: Complete deploy.resources reference - healthcheck-syntax.md: All healthcheck parameters - ec2-instance-mapping.md: Instance type mapping table Explanation (1): - compute-ec2-parallels.md: Container=EC2, Limits=Instance Type, Healthcheck=ELB Infrastructure: - docker-compose.yml: 5 services (web, app, worker, db, stress-test) All services: INF-03 compliant (cpus + memory limits) All services: healthcheck configured EC2 parallels: t2.nano, t2.micro, t2.small, t2.medium, m5.large - Dockerfile: Alpine 3.19 + stress tools + non-root user Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
336 lines
7.6 KiB
Markdown
336 lines
7.6 KiB
Markdown
# Tutorial 1: Configurare i Limiti delle Risorse
|
|
|
|
In questo tutorial imparerai a configurare i limiti delle risorse CPU e memoria per i container Docker, simulando i diversi **EC2 Instance Types** di AWS.
|
|
|
|
## Obiettivi di Apprendimento
|
|
|
|
Al termine di questo tutorial sarai in grado di:
|
|
- Comprendere cosa sono gli **EC2 Instance Types** e come si applicano a Docker
|
|
- Configurare i limiti **CPU** e **memoria** in Docker Compose
|
|
- Mappare le configurazioni Docker alle istanze EC2
|
|
- Verificare i limiti delle risorse con `docker stats`
|
|
|
|
---
|
|
|
|
## Prerequisiti
|
|
|
|
- Docker Engine >= 24.0 installato e funzionante
|
|
- Docker Compose V2 (`docker compose` comando disponibile)
|
|
- Conoscenza base di Docker e docker-compose.yml
|
|
|
|
---
|
|
|
|
## Parte 1: EC2 Instance Types - Concetti Fondamentali
|
|
|
|
### Cos'è un EC2 Instance Type?
|
|
|
|
In AWS, un **Instance Type** definisce:
|
|
- **vCPUs**: Numero di CPU virtuali
|
|
- **Memory**: Quantità di RAM
|
|
- **Use case**: Tipo di carico di lavoro ottimale
|
|
|
|
### Famiglie di Instance Types Principali
|
|
|
|
| Famiglia | Prefix | Use Case | Esempio |
|
|
|----------|--------|----------|---------|
|
|
| **Burstable** | t2, t3 | Dev/test, basso costo | t2.micro |
|
|
| **General Purpose** | m5, m6 | Equilibrato CPU/memoria | m5.large |
|
|
| **Compute Optimized** | c5, c6 | Alta CPU | c5.xlarge |
|
|
| **Memory Optimized** | r5, r6 | Alta memoria | r5.large |
|
|
|
|
### Instance Types Comuni
|
|
|
|
| Instance Type | vCPUs | Memory | Use Case |
|
|
|---------------|-------|--------|----------|
|
|
| t2.nano | 0.5 | 512 MB | Microservizi |
|
|
| t2.micro | 1 | 1 GB | Dev/Test |
|
|
| t2.small | 1 | 2 GB | Web server |
|
|
| t2.medium | 2 | 4 GB | Application server |
|
|
| m5.large | 2 | 8 GB | Production app |
|
|
| m5.xlarge | 4 | 16 GB | High traffic |
|
|
|
|
---
|
|
|
|
## Parte 2: Limiti delle Risorse in Docker Compose
|
|
|
|
### Sintassi di Base
|
|
|
|
In Docker Compose, i limiti delle risorse si configurano con la sezione `deploy.resources.limits`:
|
|
|
|
```yaml
|
|
version: "3.8"
|
|
|
|
services:
|
|
app:
|
|
image: nginx:alpine
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '1' # Numero di CPU
|
|
memory: 1G # Memoria (M, G)
|
|
```
|
|
|
|
### Formati della Memoria
|
|
|
|
```yaml
|
|
memory: 512M # 512 Megabyte
|
|
memory: 1G # 1 Gigabyte
|
|
memory: 1024M # 1024 Megabyte (equivale a 1G)
|
|
```
|
|
|
|
### Format delle CPU
|
|
|
|
```yaml
|
|
cpus: '0.5' # Mezza CPU
|
|
cpus: '1' # 1 CPU completa
|
|
cpus: '2' # 2 CPU complete
|
|
cpus: '1.5' # 1.5 CPU (1 completa + 50% di un'altra)
|
|
```
|
|
|
|
---
|
|
|
|
## Parte 3: Pratica - Configurare un Container t2.micro
|
|
|
|
Creiamo un container simile a un'istanza **t2.micro** (1 vCPU, 1 GB RAM).
|
|
|
|
### Step 1: Creare il file docker-compose.yml
|
|
|
|
Crea il file `labs/lab-03-compute/docker-compose.yml`:
|
|
|
|
```yaml
|
|
version: "3.8"
|
|
|
|
services:
|
|
# Web server - simula t2.micro
|
|
web:
|
|
image: nginx:alpine
|
|
container_name: lab03-web
|
|
hostname: web
|
|
|
|
# Resource limits - t2.micro parallel
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '1'
|
|
memory: 1G
|
|
|
|
ports:
|
|
- "127.0.0.1:8080:80"
|
|
|
|
restart: unless-stopped
|
|
```
|
|
|
|
### Step 2: Verificare la sintassi
|
|
|
|
```bash
|
|
cd labs/lab-03-compute
|
|
docker compose config
|
|
```
|
|
|
|
Se non ci sono errori, vedrai la configurazione completa.
|
|
|
|
### Step 3: Avviare il container
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
### Step 4: Verificare i limiti applicati
|
|
|
|
```bash
|
|
# Ispeziona il container per vedere i limiti
|
|
docker inspect lab03-web --format '{{.HostConfig.NanoCpus}}'
|
|
# Output: 1000000000 (1e9 = 1 CPU)
|
|
|
|
docker inspect lab03-web --format '{{.HostConfig.Memory}}'
|
|
# Output: 1073741824 (1 GB in byte)
|
|
```
|
|
|
|
### Step 5: Monitorare l'utilizzo delle risorse
|
|
|
|
```bash
|
|
# Mostra l'utilizzo in tempo reale
|
|
docker stats lab03-web
|
|
```
|
|
|
|
Premi `Ctrl+C` per uscire.
|
|
|
|
```bash
|
|
# Snapshot singolo
|
|
docker stats --no-stream
|
|
```
|
|
|
|
**Output previsto:**
|
|
```
|
|
CONTAINER NAME CPU % MEM USAGE / LIMIT MEM %
|
|
12345 lab03-web 0.01% 2.5MiB / 1GiB 0.24%
|
|
```
|
|
|
|
Nota che il **LIMIT** è 1GiB, configurato correttamente.
|
|
|
|
---
|
|
|
|
## Parte 4: Pratica - Configurare un Container t2.small
|
|
|
|
Ora configuriamo un container simile a **t2.small** (1 vCPU, 2 GB RAM).
|
|
|
|
### Aggiungi il servizio app al docker-compose.yml:
|
|
|
|
```yaml
|
|
# Application server - simula t2.small
|
|
app:
|
|
image: nginx:alpine
|
|
container_name: lab03-app
|
|
hostname: app
|
|
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '1'
|
|
memory: 2G
|
|
|
|
ports:
|
|
- "127.0.0.1:8081:80"
|
|
|
|
restart: unless-stopped
|
|
```
|
|
|
|
### Avviare e verificare
|
|
|
|
```bash
|
|
docker compose up -d
|
|
docker compose ps
|
|
```
|
|
|
|
```bash
|
|
# Verifica i limiti
|
|
docker inspect lab03-app --format 'CPU: {{.HostConfig.NanoCpus}} CPUs, Memory: {{.HostConfig.Memory}} bytes'
|
|
```
|
|
|
|
---
|
|
|
|
## Parte 5: Pratica - Configurare un Container t2.medium
|
|
|
|
Configuriamo un container **t2.medium** (2 vCPU, 4 GB RAM).
|
|
|
|
### Aggiungi il servizio worker:
|
|
|
|
```yaml
|
|
# Worker - simula t2.medium
|
|
worker:
|
|
image: alpine:3.19
|
|
container_name: lab03-worker
|
|
hostname: worker
|
|
|
|
command: ["sh", "-c", "sleep 3600"]
|
|
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '2'
|
|
memory: 4G
|
|
|
|
restart: unless-stopped
|
|
```
|
|
|
|
### Avviare e verificare
|
|
|
|
```bash
|
|
docker compose up -d
|
|
docker stats --no-stream lab03-worker
|
|
```
|
|
|
|
---
|
|
|
|
## Parte 6: Tabella di Mapping Completa
|
|
|
|
Ecco la tabella completa di mapping tra Docker e EC2:
|
|
|
|
| Docker Limits | EC2 Instance | vCPUs | Memory | Use Case |
|
|
|---------------|--------------|-------|--------|----------|
|
|
| `cpus: '0.5'`<br>`memory: 512M` | t2.nano | 0.5 | 512 MB | Microservizi minimi |
|
|
| `cpus: '1'`<br>`memory: 1G` | t2.micro | 1 | 1 GB | Dev/Test |
|
|
| `cpus: '1'`<br>`memory: 2G` | t2.small | 1 | 2 GB | Web servers |
|
|
| `cpus: '2'`<br>`memory: 4G` | t2.medium | 2 | 4 GB | Application |
|
|
| `cpus: '2'`<br>`memory: 8G` | m5.large | 2 | 8 GB | Production |
|
|
| `cpus: '4'`<br>`memory: 16G` | m5.xlarge | 4 | 16 GB | High traffic |
|
|
|
|
---
|
|
|
|
## Parte 7: Verifica Finale
|
|
|
|
### Script di Verifica
|
|
|
|
Esegui questo comando per verificare tutti i limiti:
|
|
|
|
```bash
|
|
# Per ogni servizio, mostra i limiti
|
|
for service in web app worker; do
|
|
echo "Service: $service"
|
|
docker inspect "lab03-$service" --format ' CPUs: {{.HostConfig.NanoCpus}}'
|
|
docker inspect "lab03-$service" --format ' Memory: {{.HostConfig.Memory}}'
|
|
done
|
|
```
|
|
|
|
### Controllo INF-03
|
|
|
|
Lo script di verifica del lab controllerà automaticamente che tutti i servizi abbiano i limiti configurati (requisito **INF-03**).
|
|
|
|
```bash
|
|
bash tests/01-resource-limits-test.sh
|
|
```
|
|
|
|
---
|
|
|
|
## Risoluzione Problemi
|
|
|
|
### Errore: "no matching resources"
|
|
|
|
**Causa:** I limiti specificati superano le risorse disponibili sull'host.
|
|
|
|
**Soluzione:**
|
|
- Riduci i limiti CPU/memoria
|
|
- Libera risorse sull'host
|
|
- Usa un'istanza tipo più piccola
|
|
|
|
### Errore: "invalid memory format"
|
|
|
|
**Causa:** Formato della memoria non valido.
|
|
|
|
**Soluzione:**
|
|
- Usa `M` per Megabyte (es. `512M`)
|
|
- Usa `G` per Gigabyte (es. `1G`)
|
|
- Non usare spazi o formati misti
|
|
|
|
### Container OOM Killed
|
|
|
|
**Causa:** Il container sta tentando di usare più memoria del limite.
|
|
|
|
**Soluzione:**
|
|
- Aumenta il limite `memory`
|
|
- Indaga il consumo di memoria dell'applicazione
|
|
- Verifica memory leak
|
|
|
|
---
|
|
|
|
## Riepilogo
|
|
|
|
In questo tutorial hai imparato:
|
|
|
|
✓ **Concetto:** EC2 Instance Types definiscono CPU e memoria
|
|
✓ **Sintassi:** `deploy.resources.limits` in Docker Compose
|
|
✓ **Mapping:** Docker limits → EC2 instances
|
|
✓ **Verifica:** `docker stats` per monitorare l'utilizzo
|
|
✓ **Compliance:** INF-03 richiede limiti per tutti i container
|
|
|
|
---
|
|
|
|
## Prossimi Passi
|
|
|
|
Nel prossimo tutorial imparerai a:
|
|
- Implementare **healthchecks** per monitorare lo stato dei servizi
|
|
- Configurare dipendenze tra servizi con `depends_on`
|
|
- Mappare healthchecks Docker agli **ELB Health Checks** di AWS
|
|
|
|
Continua con **Tutorial 2: Implementare Healthchecks** →
|