added docker.md
This commit is contained in:
parent
1412b70fc6
commit
a0884cc769
|
@ -0,0 +1,523 @@
|
|||
# Virtualizzazione
|
||||
|
||||
## Container
|
||||
|
||||
Il container come concetto è molto simile alla Virtual Machine.
|
||||
|
||||
Se la macchina virtuale tende ad emulare il comportamento di una macchina fisica 'reale', dall’hardware fino al software, il container condivide le risorse hardware in esecuzione con il sistema ospitante e anche parte del software (come il kernel).
|
||||
|
||||
Invece di virtualizzare l'intera macchina fisica, i container virtualizzano solo il sistema operativo host.
|
||||
|
||||
Il container è un pacchetto software 'autosufficienti' che contengono tutto il necessario per far partire un sistema con al suo interno un applicazione.
|
||||
|
||||
La containerizzazione implica l'incapsulamento o l'impacchettamento del codice di un software e di tutte le sue dipendenze, in modo che possa essere eseguito in modo uniforme e coerente su qualsiasi infrastruttura.
|
||||
|
||||
### Vantaggi container
|
||||
|
||||
I container hanno molti vantaggi:
|
||||
|
||||
- Leggerezza, condividono il kernel del sistema operativo;
|
||||
- Isolamento, infatti operano all’interno di uno spazio limitato del sistema operativo ospitante, e non hanno visibilità esterna;
|
||||
- Portabilità: questa tecnologia si presta ad essere facilmente trasportata da una macchina ad un altra, Spesso basta un file di testo o poco più. Possiamo avere diverse versioni della stessa applicazione sulla stessa macchina senza che vadano in conflitto tra loro.
|
||||
|
||||
### Container vs Docker
|
||||
|
||||
Se è vero che Docker crea container, non è altrettanto vero che i container sono Docker.
|
||||
|
||||
Docker non è l'unico strumento di containerizzazione sul mercato, è soltanto il più conosciuto. Un altro motore di containerizzazione che amo si chiama Podman, sviluppato da Red Hat
|
||||
|
||||
## Cos’è Docker
|
||||
|
||||
**Docker** è un software open source, multipiattaforma che permette di virtualizzare singole applicazioni in dei **container** che sono isolati dall'**host** (il sistema operativo per intenderci):
|
||||
|
||||
- Docker non virtualizza l’hardware ma lo condivide col sistema operativo;
|
||||
- su Docker non viene virtualizzato un intero sistema operativo, ma una specifica applicazione, contenuta in un immagine che contiene software, dipendenze e che generalmente possiamo trovare nei [repository ufficiali](https://hub.docker.com/).
|
||||
|
||||
## Installazione
|
||||
|
||||
### Debian
|
||||
|
||||
Direttamente dai repository ufficiali:
|
||||
|
||||
```
|
||||
sudo apt install docker.io docker-compose
|
||||
```
|
||||
|
||||
Altrimenti, bisogna seguire questa guida: [Install Docker on Debian 12](https://itsfoss.com/debian-install-docker/)
|
||||
|
||||
Dare i comandi `docker --version` e `docker-compose --version` per verificare che l'installazione sia avvenuta con successo.
|
||||
|
||||
## Attivazione
|
||||
|
||||
Una volta installato per attivare e abilitare il servizio:
|
||||
|
||||
```
|
||||
systemctl enable --now docker
|
||||
```
|
||||
|
||||
## Cos'è un'immagine Docker
|
||||
|
||||
Le immagini sono dei file autonomi a più livelli che agiscono come modello per la creazione di container. Sono come una copia congelata, di sola lettura di un container. Le immagini possono essere scambiate attraverso dei registri, come Docker Hub. I container sono semplicemente immagini in esecuzione.
|
||||
|
||||
> **NOTA** : Se volessimo utilizzare docker senza ogni volta richiamare il comando `sudo` possiamo aggiungere il nostro utente al gruppo docker con il comando `usermod -aG docker <nomeutente>`
|
||||
|
||||
### Persistenza
|
||||
|
||||
I container sono pensati per essere distrutti e ricreati più volte a partire dalla stessa immagine.
|
||||
Questo approccio fa parte del concetto di `infrastruttura immutabile` che garantisce lo stesso container ad ogni nuovo deploy.
|
||||
|
||||
Per gestire la persistenza dei dati, Docker fornisce due strade:
|
||||
|
||||
- Volumes
|
||||
- Bind Mounts
|
||||
|
||||
I volumi sono uno spazio creato al di fuori dello Union File System del container che può essere acceduto da più container e che viene persistito anche quando non è utilizzato da alcun container.
|
||||
|
||||
#### Bind Mounts
|
||||
|
||||
Alla stregua dei mount classici di linux, un bind mount è una condivisione di una cartella.
|
||||
Con questa tipologia di persistenza, andiamo a condividere una cartella dell’host con il container.
|
||||
|
||||
Un bind mount è una sorta di symlink, viene fatto un collegamento logico (mount) di un file o di una cartella dell’host in un file o una cartella del container.
|
||||
|
||||
## Dockerfile e Docker compose
|
||||
|
||||
Maggiori informazioni ai link sottostanti:
|
||||
|
||||
[Docker compose](https://linuxhub.it/articles/howto-creare-un-file-yaml-per-docker/)
|
||||
|
||||
Per dockerfile:
|
||||
|
||||
[https://dockertutorial.it/dockerfile-from-run-arg-e-cmd/](https://dockertutorial.it/dockerfile-from-run-arg-e-cmd/)
|
||||
|
||||
[https://dockertutorial.it/dockerfile-tutti-i-comandi/](https://dockertutorial.it/dockerfile-tutti-i-comandi/)
|
||||
|
||||
## Comandi principali
|
||||
|
||||
**Creare un container (senza avviarlo)**
|
||||
|
||||
```bash
|
||||
docker create <IMMAGINE>
|
||||
root@vbox:~# docker create hello-world
|
||||
```
|
||||
|
||||
**Rinominare un container esistente**
|
||||
|
||||
```bash
|
||||
docker rename <NOME CONTAINER> <NUOVO NOME>
|
||||
root@vbox:~# docker rename c1 c2
|
||||
```
|
||||
|
||||
**Eseguire un container**
|
||||
|
||||
```bash
|
||||
docker run <IMMAGINE> <COMANDO>
|
||||
root@vbox:~# docker run myapp
|
||||
|
||||
docker run --rm <IMMAGINE>
|
||||
root@vbox:~# docker run -rm myapp # rimuove il container quando questo termina l'esecuzione
|
||||
root@vbox:~# docker run -td myapp # avvia un container e lo mantiene in esecuzione.
|
||||
root@vbox:~# docker run -it myapp # avvia il container in maniera interattiva
|
||||
root@vbox:~# docker run -it -rm myapp
|
||||
```
|
||||
**Eliminare un container**
|
||||
|
||||
```bash
|
||||
docker rm <CONTAINER>
|
||||
root@vbox:~# docker rm c1
|
||||
## Questo comando può essere eseguito solo se il container non è in esecuzione, altrimenti verrà restituito un errore.
|
||||
```
|
||||
**Aggiornare la configurazione di uno o più container**
|
||||
|
||||
```bash
|
||||
docker update <CONTAINER>
|
||||
root@vbox:~# docker update c1
|
||||
```
|
||||
|
||||
**Avvio e arresto dei container**
|
||||
|
||||
```bash
|
||||
#Avviare un container
|
||||
docker start <CONTAINER>
|
||||
#Interrompere un container in esecuzione
|
||||
docker stop <CONTAINER>
|
||||
#Riavviare un container
|
||||
docker restart <CONTAINER>
|
||||
```
|
||||
|
||||
**Uccidere un container**
|
||||
|
||||
```bash
|
||||
docker kill <CONTAINER>
|
||||
root@vbox:~# docker kill c1
|
||||
```
|
||||
|
||||
### Ottenere informazioni
|
||||
|
||||
**Elencare i container in esecuzione**
|
||||
|
||||
```bash
|
||||
docker ps
|
||||
root@vbox:~# docker ps
|
||||
```
|
||||
>> NOTA: Con l’opzione -a viene prodotta una lista contenente sia i container in esecuzione sia quelli che sono arrestati.
|
||||
|
||||
|
||||
**Elencare i registri da un container in esecuzione**
|
||||
|
||||
```bash
|
||||
docker logs <CONTAINER>
|
||||
root@vbox:~# docker logs
|
||||
```
|
||||
|
||||
**Ispezionare**
|
||||
|
||||
```bash
|
||||
docker inspect <OBJECT_NAME/ID>
|
||||
root@vbox:~# docker inspect image1
|
||||
```
|
||||
|
||||
**Elencare gli eventi in tempo reale da un container**
|
||||
|
||||
```bash
|
||||
docker events <CONTAINER>
|
||||
root@vbox:~# docker events image1
|
||||
```
|
||||
|
||||
**Mostrare mappatura porta (o specifica) per un container**
|
||||
|
||||
```bash
|
||||
docker port <CONTAINER>
|
||||
root@vbox:~# docker port c1
|
||||
```
|
||||
|
||||
**Processi in esecuzione in un container**
|
||||
|
||||
```bash
|
||||
docker top <CONTAINER>
|
||||
root@vbox:~# docker top c1
|
||||
```
|
||||
|
||||
**Statistiche sull’utilizzo delle risorse in tempo reale dei container**
|
||||
|
||||
```bash
|
||||
docker stats <CONTAINER>
|
||||
root@vbox:~# docker stats c1
|
||||
```
|
||||
|
||||
**Mostrare le modifiche ai file (o directory) su un file system**
|
||||
|
||||
```bash
|
||||
docker diff <CONTAINER>
|
||||
root@vbox:~# docker diff c1
|
||||
```
|
||||
|
||||
**Elencare tutte le immagini archiviate localmente**
|
||||
|
||||
```bash
|
||||
docker image ls
|
||||
root@vbox:~# docker image ls
|
||||
```
|
||||
|
||||
**Mostrare la storia di un’immagine**
|
||||
|
||||
```bash
|
||||
docker history <IMMAGINE>
|
||||
root@vbox:~# docker history image1
|
||||
```
|
||||
|
||||
### Reti
|
||||
|
||||
**Elencare le reti presenti**
|
||||
|
||||
```bash
|
||||
docker network ls
|
||||
root@vbox:~# docker network ls
|
||||
```
|
||||
|
||||
**Rimuovere una o più reti**
|
||||
|
||||
```bash
|
||||
docker network rm [RETE]
|
||||
root@vbox:~# docker network rm custom-network
|
||||
```
|
||||
|
||||
**Mostrare informazioni su una o più reti**
|
||||
|
||||
```bash
|
||||
docker network inspect [RETE]
|
||||
root@vbox:~# docker network inspect custom-network
|
||||
```
|
||||
|
||||
**Connettere un container a una rete**
|
||||
|
||||
```bash
|
||||
docker network connect [RETE] <CONTAINER>
|
||||
root@vbox:~# docker network connect custom-network
|
||||
```
|
||||
|
||||
**Disconnettere un container da una rete**
|
||||
|
||||
```bash
|
||||
root@vbox:~# docker network disconnect [NETWORK] <CONTAINER>
|
||||
root@vbox:~# docker network disconnect custom-network
|
||||
```
|
||||
|
||||
### Dockerfile: istruzioni
|
||||
|
||||
Un Dockerfile è un file di testo contenente alcuni comandi comprensibili a Docker da cui è possibile, da un’immagine di partenza, creare una nostra immagine personalizzata. Per essere riconosciuto da Docker, il Docker file dovrà chiamarsi proprio Dockerfile senza estensioni e senza modificare maiuscole e minuscole.
|
||||
|
||||
FROM
|
||||
|
||||
Imposta l’immagine di base per il Dockerfile; le istruzioni successive si basano su questa immagine. L’immagine di base è specificata come <immagine>:<tag>. Se il tag viene omesso, si presume che sia il più recente, ma è vivamente consigliabile impostare sempre il tag su una versione specifica, per evitare sorprese. Deve essere la prima istruzione in un Dockerfile.
|
||||
|
||||
```bash
|
||||
FROM python:3 #l'immagine di base utilizzata sarà python nella versione 3
|
||||
FROM node #l'immagine di base sarà l'ultima versione disponibile sul registro
|
||||
```
|
||||
|
||||
WORKDIR
|
||||
|
||||
Imposta la directory di lavoro per le successive istruzioni RUN, CMD, ENTRYPOINT, ADD oppure COPY. Può essere usato più volte. Se la cartella specificata non esiste, verrà creata e verrà automaticamente cambiato il percorso di lavoro (questo comando può essere paragonato all’esecuzione del comando mkdir <cartella> && cd <cartella> di un sistema Unix-based).
|
||||
|
||||
```bash
|
||||
WORKDIR /c1 #la directory di lavoro ora è /c1
|
||||
WORKDIR c2 #la directory di lavoro ora è /c1/c2
|
||||
WORKDIR c3 #la directory di lavoro ora è /c1/c2/c3
|
||||
WORKDIR /app #la directory di lavoro ora è /app
|
||||
```
|
||||
|
||||
ADD
|
||||
|
||||
Copia i file dal percorso nel file system ospite o da un dato URL all’interno dell’immagine. Poiché la gamma di funzionalità coperta da ADD è piuttosto ampia, in genere è preferibile usare il comando COPY, di norma più semplice per copiare file e directory nel contesto di build
|
||||
|
||||
```bash
|
||||
ADD file.txt /home/ #copia file.txt nella cartella /home/ del container
|
||||
ADD file1 file2 /home/ #copia i file specificati nella cartella /home/
|
||||
```
|
||||
RUN
|
||||
|
||||
Esegue i comandi in un nuovo layer e crea una nuova immagine, spesso definita intermedia. Questo comando viene spesso utilizzato per l’installazione di pacchetti tramite i vari package manager.
|
||||
|
||||
```bash
|
||||
RUN apt update #ricerca degli aggiornamenti del sistema operativo
|
||||
RUN apt install -y nginx #installa il pacchetto nginx
|
||||
RUN [ "npm", "start" ] #esegue il comando "npm start"
|
||||
```
|
||||
|
||||
CMD
|
||||
|
||||
L’istruzione CMD consente di impostare un comando predefinito, che verrà eseguito solo quando si esegue il container senza specificare un comando. Se il container Docker viene eseguito con un comando, il comando predefinito verrà ignorato.
|
||||
|
||||
Se Dockerfile ha più di un’istruzione CMD, tutte le istruzioni CMD tranne l’ultima vengono ignorate.
|
||||
|
||||
```bash
|
||||
CMD echo "Hello world" #stampa "Hello World"
|
||||
CMD ["echo", "Hello world"] #stampa "Hello World"
|
||||
```
|
||||
|
||||
ENTRYPOINT
|
||||
|
||||
È simile all’istruzione CMD, perché consente anche di specificare un comando con dei parametri, ma a differenza è che i parametri non verranno ignorati quando il container Docker viene eseguito con i parametri passati tramite riga di comando.
|
||||
|
||||
```bash
|
||||
ENTRYPOINT ls #elenca file e directory presenti nella cartella di lavoro
|
||||
ENTRYPOINT ["/bin/echo", "Hello"] #stampa "Hello"
|
||||
ENTRYPOINT ["/bin/echo", "Hello"] #stampa "Hello world"
|
||||
CMD ["world"]
|
||||
|
||||
docker run -it <immagine> John #stampa "Hello John"
|
||||
```
|
||||
|
||||
Altre informazioni: [https://www.theredcode.it/docker/differenze-tra-run-cmd-e-entrypoint/](https://www.theredcode.it/docker/differenze-tra-run-cmd-e-entrypoint/)
|
||||
|
||||
COPY
|
||||
|
||||
Utilizzato per copiare file dal file system del sistema host nell’immagine. I caratteri jolly possono essere utilizzati e permettono di specificare più file o directory. Non è possibile specificare percorsi di origine al di fuori del contesto di compilazione.
|
||||
|
||||
```bash
|
||||
COPY file.txt /home/ #copia file.txt nella cartella /home del container
|
||||
COPY file1 file2 /home/ #copia i file specificati nella cartella /home
|
||||
COPY file1.py dest.py #copia il contenuto di file1.py nel file dest.py
|
||||
```
|
||||
|
||||
ENV
|
||||
Imposta le variabili d’ambiente all’interno dell’immagine; queste possono essere indicate in qualsiasi momento all’interno del Dockerfile, ovviamente prima dell’uso effettivo. Le variabili saranno disponibili anche all’interno dell’immagine.
|
||||
|
||||
```bash
|
||||
ENV VERSIONE 1.3
|
||||
RUN apt install -y pacchetto=$VERSIONE #installa il pacchetto nella versione 1.3
|
||||
```
|
||||
|
||||
EXPOSE
|
||||
Indica a Docker che il container avrà un processo in ascolto su una o più porte specificate. Queste informazioni vengono utilizzate da Docker durante il collegamento di container o la pubblicazione di porte.
|
||||
|
||||
```bash
|
||||
EXPOSE 8080 #il container sarà in ascolto sulla porta 8080
|
||||
```
|
||||
|
||||
LABEL
|
||||
|
||||
Aggiunge metadati a un’immagine; utilizza il formato coppia chiave-valore. Normalmente viene utilizzato per impostare il nome e i dettagli di contatto del manutentore dell’immagine.
|
||||
|
||||
```bash
|
||||
LABEL "nome"="pippo" #assegna alla chiave "nome" il valore "pippo"
|
||||
LABEL versione="1.0" #assegna alla chiave "versione" il valore "1.0"
|
||||
LABEL descrizione="Lorem ipsum \
|
||||
dolor sit amet, consectetur adipiscing elit." #label multiriga
|
||||
```
|
||||
|
||||
USER
|
||||
|
||||
Imposta l’utente (tramite nome o tramite UID) da utilizzare nelle successive istruzioni RUN, CMD o ENTRYPOINT. Nota che gli UID sono gli stessi tra l’host e il container, ma i nomi utente possono essere assegnati a UID diversi, il che può rendere le cose difficili quando si impostano le autorizzazioni.
|
||||
|
||||
```bash
|
||||
USER john #le istruzioni successive saranno eseguite con l'utenza john
|
||||
```
|
||||
|
||||
VOLUME
|
||||
|
||||
Dichiara il file o la directory specificati come volume.
|
||||
|
||||
```bash
|
||||
VOLUME /volume1 #crea un volume denominato volume1
|
||||
```
|
||||
|
||||
Esempio di Dockerfile:
|
||||
|
||||
```bash
|
||||
FROM node:lts-alpine
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
USER node
|
||||
|
||||
RUN mkdir -p /home/node/app
|
||||
|
||||
WORKDIR /home/node/app
|
||||
|
||||
COPY ./package.json .
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD [ "npm", "run", "dev" ]
|
||||
|
||||
# La seconda istruzione COPY copia il resto del contenuto della cartella corrente (.)
|
||||
# del file system host nella cartella di lavoro (.) all'interno dell'immagine.
|
||||
```
|
||||
|
||||
## Docker Compose: istruzioni
|
||||
|
||||
Docker permette di creare un ed eseguire applicazioni multicontainer attraverso un file YAML, un tipo di file human-readable utilizzato solitamente come file di configurazione. Per fare ciò dobbiamo creare un file denominato docker-compose.yml nel quale andremo ad inserire tutte le nostre configurazioni di ogni singolo servizio che andremo ad aggiungere all’interno del file. Una volta configurato il file, andrà “composto” attraverso un comando docker-compose up, e se tutto è andato per il verso giusto avremo funzionanti i container dei servizi che abbiamo inserito e configurato nel nostro file .yml.
|
||||
|
||||
Esempio di un file docker-compose.yml
|
||||
|
||||
```bash
|
||||
version: '2'
|
||||
services:
|
||||
# nome del servizio
|
||||
web:
|
||||
build: .
|
||||
# build a partire da un Dockerfile
|
||||
context: ./path/to/Dockerfile
|
||||
# nome del file
|
||||
dockerfile: Dockerfile
|
||||
# traffico instradato dalla porta 5000 del container sulla 5000 dell'host
|
||||
ports:
|
||||
- "5000:5000"
|
||||
volumes:
|
||||
- .:/mydata
|
||||
# nome del servizio
|
||||
redis:
|
||||
# immagine che viene scaricata dal registro ufficiale
|
||||
image: redis
|
||||
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:12
|
||||
container_name: notes-db-dev
|
||||
volumes:
|
||||
- notes-db-dev-data:/var/lib/postgresql/data
|
||||
environment:
|
||||
POSTGRES_DB: notesdb
|
||||
POSTGRES_PASSWORD: secret
|
||||
api:
|
||||
build:
|
||||
context: ./api
|
||||
dockerfile: Dockerfile.dev
|
||||
image: notes-api:dev
|
||||
container_name: notes-api-dev
|
||||
environment:
|
||||
DB_HOST: db ## same as the database service name
|
||||
DB_DATABASE: notesdb
|
||||
DB_PASSWORD: secret
|
||||
volumes:
|
||||
- /home/node/app/node_modules
|
||||
- ./api:/home/node/app
|
||||
ports:
|
||||
- 3000:3000
|
||||
|
||||
volumes:
|
||||
notes-db-dev-data:
|
||||
name: notes-db-dev-data
|
||||
```
|
||||
|
||||
**up**
|
||||
|
||||
Esegue la build del progetto e avvia i servizi specificati nel file docker-compose.yml.
|
||||
|
||||
```bash
|
||||
$ docker-compose up
|
||||
```
|
||||
|
||||
**down**
|
||||
|
||||
Arresta i servizi e rimuove i container, le reti, i volumi e le immagini create tramite comando docker-compose up. Per impostazione predefinita, vengono rimossi i soli container che sono stati creati tramite file docker-compose.yml.
|
||||
|
||||
```bash
|
||||
$ docker-compose down
|
||||
```
|
||||
|
||||
**stop**
|
||||
|
||||
Arresta i servizi.
|
||||
|
||||
```bash
|
||||
$ docker-compose stop
|
||||
```
|
||||
|
||||
**ps**
|
||||
|
||||
Elenca tutti i container e le relative informazioni rispetto ai servizi avviati tramite il file docker-compose.yml.
|
||||
|
||||
```bash
|
||||
$ docker-compose ps
|
||||
```
|
||||
|
||||
**scale**
|
||||
|
||||
Aggiunge o rimuove container per scalare orizzontalmente l’applicazione secondo la dimensione specificata.
|
||||
|
||||
```bash
|
||||
$ docker-compose scale test=6 #crea 6 repliche del container "test"
|
||||
```
|
||||
|
||||
**rm**
|
||||
|
||||
Arresta ed elimina i servizi.
|
||||
|
||||
```bash
|
||||
$ docker-compose rm
|
||||
```
|
||||
|
||||
## Collegamenti
|
||||
- [https://linuxhub.it/articles/howto-Installazione-ed-utilizzo-di-Docker-su-Linux/](https://linuxhub.it/articles/howto-Installazione-ed-utilizzo-di-Docker-su-Linux/)
|
||||
- [https://linuxhub.it/articles/pausadev-container-vm-wsl/](https://linuxhub.it/articles/pausadev-container-vm-wsl/)
|
||||
- [https://www.freecodecamp.org/italian/news/il-manuale-docker/#introduzione-alla-containerizzazione-e-a-docker](https://www.freecodecamp.org/italian/news/il-manuale-docker/#introduzione-alla-containerizzazione-e-a-docker)
|
||||
- [https://dockertutorial.it/](https://dockertutorial.it/)
|
||||
- [https://linuxhub.it/articles/howto-creare-un-file-yaml-per-docker/](https://linuxhub.it/articles/howto-creare-un-file-yaml-per-docker/)
|
||||
- [https://linuxhub.it/articles/howto-creare-un-Dockerfile/](https://linuxhub.it/articles/howto-creare-un-Dockerfile/)
|
Loading…
Reference in New Issue