diff --git a/README.md b/README.md index 922c8c6..ae7cff4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# presentazione docker for dummies +# presentazione ansible for dummies ## hugo dockerizzato diff --git a/config.toml b/config.toml index 8652d1c..42e5f48 100644 --- a/config.toml +++ b/config.toml @@ -1,4 +1,4 @@ -title = "Docker for dummies" +title = "Ansible for dummies" baseurl = "http://localhost:1313/" languageCode = "en-us" theme = "reveal-hugo" @@ -9,8 +9,9 @@ mediaType = "text/html" isHTML = true [params.reveal_hugo] -custom_theme = "reveal-hugo/themes/robot-lung.css" -#custom_theme = "reveal-hugo/themes/sunblind.css" +# custom_theme = "reveal-hugo/themes/robot-lung.css" +# custom_theme = "reveal-hugo/themes/sunblind.css" +theme = "sky" history = true slide_number = true transition = 'convex' diff --git a/content/_index.md b/content/_index.md index fab3f72..872789a 100644 --- a/content/_index.md +++ b/content/_index.md @@ -1,35 +1,33 @@ +++ -title = "Docker per principianti" +title = "Ansible per principianti" outputs = ["Reveal"] +++ -# Docker +# Ansible +### for dummies +#### (???) -## Cos'e': +--- -{{% fragment %}} * una piattaforma aperta per costruire, distribuire ed eseguire applicazioni all'interno di container {{% /fragment %}} +## Cos'è: -{{% fragment %}} * i container non sono macchine virtuali, ad es. condividono la RAM e il kernel col sistema che li ospita {{% /fragment %}} +{{% fragment %}} * E' un software per automatizzare la configurazione (_provisioning_) di un computer {{% /fragment %}} -{{% fragment %}} * sono pero' "isolati" dal sistema sottostante grazie a due funzioni del kernel: Control Groups (Cgroups) e Namespaces {{% /fragment %}} +{{% fragment %}} * E' una serie di programmi CLI (`ansible`, `ansible-playbook`, `ansible-galaxy`, `ansible-vault`, ...) {{% /fragment %}} -{{% fragment %}} * esiste per linux/mac/windows/cloud
https://docs.docker.com/engine/install/ {{% /fragment %}} +{{% fragment %}} * E' scritto in python {{% /fragment %}} -{{% fragment %}} * c'e' una versione gratuita (CE) e una a pagamento (EE) {{% /fragment %}} +{{% fragment %}} * Si configura in `yaml` (o `ini`, ma preferiamo `yaml`) {{% /fragment %}} --- ## A cosa serve: -* a provare un software senza "sporcare" il sistema e senza preoccuparsi dell'installazione +* A configurare _automaticamente_ una o più macchine -* a far girare un'applicazione in un ambiente piu' "protetto" (ma occhio alla sicurezza) - -* a offrire portabilita' delle applicazioni (es. da sviluppo a produzione) - -* a fare un sacco di cose in modo piu' veloce, piu' smart, piu' capitalismo insomma. +* A tenere traccia facilmente di tutti i passi necessari a configurare una macchina (_infrastructure-as-code_) --- @@ -37,341 +35,190 @@ outputs = ["Reveal"] # Concetti base -## Immagini +--- -* Un'immagine docker e' un template in sola lettura +## Playbook -* Esiste un Docker Hub, un repository di immagini gia' pronte (anche "ufficiali") +* Un _playbook_ è un documento strutturato (`yaml` o `ini`) che istruisce ansible su cosa fare. -* Si possono costruire immagini basandosi su immagini pre-esistenti (es. debian-mini o alpine) a cui posso aggiungere un singolo pacchetto - -* le immagini hanno delle tag associate, per cui possono esistere diverse "versioni" di una certa immagine, ad es. php:5 e php:7 - o anche debian:stretch e debian:buster +* Può contenere tutto il _codice_ che ci serve, ma in generale si usa insieme agli _inventory_ e ai _role_ ed è più che altro un entrypoint. --- -## Immagini +## Connettore -* Un’immagine e' fatta di layer immutabili +* Ansible interagisce con le macchine da configurare attraverso un connettore. -* Sul disco sono salvati i singoli layer, quindi un layer in comune tra piu' immagini e' presente una volta sola +* Lo standard *de facto* è `ssh` (quindi è essenziale avere un minimo di dimestichezza con la sintassi di ssh) -* Ogni volta che aggiungo qualcosa a un'immagine si crea un nuovo layer aggiuntivo (e quindi una nuova immagine) +--- -* L'immagine base: scratch https://hub.docker.com/_/scratch/ +## Inventory + +* L'_inventory_ è un registro di informazioni + +* Di default ansible legge l'inventory a `/etc/ansible/hosts`. Si può specificare l'inventory con l'opzione `-i `. + +--- + +## Inventory + +```yaml +--- +all: + hosts: + central.machine.org: + children: + nice: + hosts: + nancy.machine.org: + manny.machine.org: + naughty: + hosts: + john.machine.org: + bob.machine.org: + red: + hosts: + charon.machine.org: + godot.machine.org: + bob.machine.org: + blue: + hosts: + nancy.machine.org: +``` + +--- + +## Role + +* Un _role_ è una funzione autocontenuta + +* E' una ricetta da applicare ad una macchina ottenere una funzionalità su quella macchina + + +--- + +## Facts + +* I _facts_ sono le verità che riguardano una macchina su cui ansible agisce + +* Sono raccolti ad inizio esecuzione su ogni macchina + +* Sono locali alla macchina + +* Possono essere impostati direttamente da un playbook, se ne abbiamo bisogno + +--- + +## Module + +* Un _module_ è una libreria che ansible usa per eseguire codice + +* Rende (più) facile eseguire azioni complesse su una macchina remota + +* ```sh + $ ansible-doc -l|wc -l + 3387 + $ ansible-doc -l|grep -E "^apt" + apt Manages apt-packages + apt_key Add or remove an apt key + apt_repo Manage APT repositories via apt-repo + apt_repository Add and remove APT repositories + apt_rpm apt_rpm package manager + ``` {{% /section %}} - --- {{% section %}} - -# Concetti base - -## Container - -* Un container e' una "istanza" di un'immagine - -* Da un'immagine posso far partire piu' container indipendenti +# Roles --- -## Container +## Role -* Un container in genere esegue un solo processo +`ansible-galaxy role init gitea` -* Quindi ad esempio se si vuole un CMS servono almeno 2 container: uno per il webserver e uno per il database +```yaml +. +├── defaults +│   └── main.yml +├── files +├── handlers +│   └── main.yml +├── meta +│   └── main.yml +├── README.md +├── tasks +│   └── main.yml +├── templates +├── tests +│   ├── inventory +│   └── test.yml +└── vars + └── main.yml +``` -* I container possono comunicare tra di loro tramite un'interfaccia di rete dedicata +--- -* I container possono comunicare allo stesso modo anche con l'host, per cui ad esempio potrei avere il webserver - in un container e il database sull'host +## Task + +`tasks/main.yml` + +```yaml +--- +- name: Install prerequisites + apt: + name: postgres + state: present +``` + +--- + +## Task + +```yaml +- name: Configure database + template: + src: templates/pg_hba.conf.j2 + dest: /var/lib/postgres/pg_hba.conf + owner: postgres + group: postgres + mode: 0600 + notify: restart postgres +``` + +--- + +## Handler + +`handlers/main.yml` + +```yaml +--- +- name: restart postgres + systemd: + name: postgres.service + state: restarted +``` + +--- + +## Template + +`templates/pg_hba.conf.j2` +``` +{% for client in postgresql_hba_entries %} +{{ client.type }} {{ client.database }} {{ client.user }} {{ client.address|default('') }} {{ client.ip_address|default('') }} {{ client.ip_mask|default('') }} {{ client.auth_method }} {{ client.auth_options|default("") }} +{% endfor %} +``` + +[Jinja syntax](https://jinja.palletsprojects.com/) {{% /section %}} --- -# Componenti base - -## Docker Engine - -* Docker e' un'applicazione client/server - -* il Docker Engine e' il demone che controlla l'esecuzione dei containers, e gira coi permessi di root. - -* esiste un file di configurazione in /etc/docker/daemon.json - ---- - -{{% section %}} - -# Docker client - -* il client e' l'interfaccia (testuale) per fare tutto, dalla costruzione delle immagini all'esecuzione dei containers. - -* esistono interfacce grafiche, per tutti i gusti, mediamente inutili per un uso "casalingo". - -* esistono anche dei frontend da console, ad es. dry (http://moncho.github.io/dry/) - ---- - -## comandi per le immagini - -* docker search - cerca una immagine nel docker hub - -* docker pull - scarica un'immagine es. docker pull hello-world - -* docker images - lista le immagini presenti nel nostro sistema - -* docker rmi nomeimmagine - elimina una immagine dal disco - ---- - -``` -(~)# docker search nextcloud -NAME DESCRIPTION STARS OFFICIAL AUTOMATED -nextcloud A safe home for all your data 1492 [OK] -linuxserver/nextcloud A Nextcloud container, brought to you by Lin… 239 -wonderfall/nextcloud All-in-one alpine-based Nextcloud image. 82 [OK] -greyltc/nextcloud Nextcloud: a safe home for all your data. De… 39 [OK] -ownyourbits/nextcloudpi-armhf NextCloudPi ARM docker container 28 -ownyourbits/nextcloudpi NextCloudPi Docker container (all architectu… 12 -ownyourbits/nextcloudpi-x86 NextCloudPi x86 docker container 12 -``` - ---- - -``` -(~)$ docker images -REPOSITORY TAG IMAGE ID CREATED SIZE -nextcloud 18 30510f8fb18b 24 hours ago 726MB -nextcloud 17 b158dd64c9a3 2 months ago 724MB -wallabag/wallabag latest 89208e55d00c 5 months ago 482MB -putro/web2py latest 65ec2a7db4f2 7 months ago 607MB -putro/apache-php latest 958bf6f8388e 8 months ago 273MB -bitnami/minideb buster 0e45c7c725a0 8 months ago 67.5MB -bitnami/minideb stretch 04c0a4570b8c 13 months ago 53.7MB -postgres latest 79db2bf18b4a 10 months ago 312MB -x86dev/docker-ttrss latest dab1dd3dcc68 11 months ago 94.1MB -putro/taskd 0.1 a7aec0dc9429 13 months ago 78.4MB -``` - ---- - -## comandi per i container - -* docker ps - mostra i container in esecuzione - -* docker ps -a - mostra i container in esecuzione e quelli fermi - -* docker rm ID - elimina il container ID (funziona solo per quelli fermi) - -* docker start/stop ID avvia un container fermo o ne ferma uno in esecuzione - -* docker logs (-f) ID - mostra i log di un container - ---- - -``` -(~)$ docker ps -a -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -4d6cce1d9768 b158dd64c9a3 "/entrypoint.sh apac…" 2 months ago Up 2 months 80/tcp nextcloud -1bcc9ddd624b wallabag/wallabag:latest "/entrypoint.sh wall…" 5 months ago Up 5 months 80/tcp wallabag -a2627194dc0a a7aec0dc9429 "/run.sh" 7 months ago Up 5 months 0.0.0.0:53589->53589/tcp taskd -632a922e55f9 putro/apache-php "/usr/bin/apache2-fo…" 8 months ago Up 7 months 80/tcp, 443/tcp, 8080/tcp apache -cfa463df8e9d x86dev/docker-ttrss "/init" 11 months ago Up 7 months 4443/tcp, 8080/tcp ttrss -06d25d8acea4 postgres:latest "docker-entrypoint.s…" 13 months ago Up 7 months 5432/tcp postgres -5ca30876c4b2 jojomi/hugo:latest "/run.sh" 52 minutes ago Exited (137) 39 minutes ago hugo -``` ---- - -## docker run - -* fa partire un processo dentro un nuovo container partendo dall'immagine specificata, es. docker run hello-world - -* se non si specifica un nome il container avra' un nome casuale, altrimenti usare --name nomescelto - -* ci sono un sacco di opzioni, vedi man docker-run, perche' questo e' il comando con cui si fa partire un container e si specificano tutti i "parametri" - ---- - -## hello-world - -questa e' un'immagine minimale, contiene solo un eseguibile che viene lanciato all'avvio, che stampa un testo e poi esce - -quando il processo lanciato all'avvio del container esce, il container si spegne perche' non c'e' piu' nulla in esecuzione. - -**Un container esegue un solo processo** - -**un'immagine docker e' "programmata" per eseguire un solo comando quando avvia un container** - -Se e' necessario eseguire piu' processi dentro un container bisogna usare qualcosa tipo supervisord, cioe' un programma che una volta lanciato puo' fare cose e resta in esecuzione. - ---- - -## docker exec - -* esegue un comando dentro un container, es. docker exec -it /bin/sh mysql - -* in questo modo ci si ritrova in una shell sh **dentro** il container mysql in esecuzione. - -{{% /section %}} - ---- - -## La persistenza dei dati - -i container non devono **MAI** contenere dati volatili perche' i dati non sopravvivono alla distruzione o riavvio di un container - -#### come gestire i dati dentro i container: - -* bind-mount di una cartella sull'host dentro il container - -* docker volumes (stanno in /var/lib/docker/volumes) - ---- - -## docker network - -i container possono sempre comunicare tra di loro tramite un'interfaccia bridged docker0 (su linux) -mentre di default non sono raggiungibili dall'esterno. - -per rendere un container visibile pubblicamente si puo': - -* mettergli un reverse-proxy davanti (es. nginx, anche dockerizzato a sua volta) - -* mappare una porta dell'host su una porta del container (attenzione che bypassa le regole di UFW) - -e' comunque possibile creare reti e assegnare indirizzi IP ai container - ---- - -{{% section %}} - - -## Dockerfile - -* e' un file "ricetta" per creare una nuova immagine (con docker build) - -* definisce come creare l'immagine (da dove partire e cosa aggiungere (files e pacchetti)) - -* definisce alcune configurazioni dell'immagine (es. che porta di rete aprire all'esterno) - -* definisce cosa eseguire all'avvio - -* in genere su hub.docker.com sono disponibili i Dockerfile con cui si sono create le immagini - ---- - -##### esempio di Dockerfile per costruire un'immagine nginx - - -``` - -FROM bitnami/minideb:buster -MAINTAINER Mario Rossi (mario.rossi@diocovid.xxx) -RUN apt-get update -RUN apt-get install -y nginx -COPY index.html /var/www/html/ -ENTRYPOINT [“/usr/sbin/nginx”,”-g”,”daemon off;”] -EXPOSE 80 - -``` - - -docker run -d -p 80:80 --name webserver myimage - -{{% /section %}} - - ---- - -{{% section %}} - - -## docker-compose - -* e' un software che permette di leggere un file di configurazione per avviare containers - -* non fa parte di docker, va scaricato a parte - -* la sua sintassi e' variata nel tempo, infatti il docker-compose.yml riporta sempre la versione - -* permette di definire variabili, porte, volumi, reti per avviare containers. - -* semplifica l'uso di "docker run" - ---- - -https://hub.docker.com/_/nextcloud/ - -``` -version: '2' - -volumes: - nextcloud: - db: - -services: - db: - container_name: database - image: mariadb - restart: always - volumes: - - db:/var/lib/mysql - environment: - - MYSQL_ROOT_PASSWORD=rootpwd - - MYSQL_PASSWORD=nextcloudpwd - - MYSQL_DATABASE=nextcloud - - MYSQL_USER=nextcloud - - app: - image: nextcloud:18 - container_name: nextcloud - ports: - - 8080:80 - links: - - db - volumes: - - nextcloud:/var/www/html - restart: always -``` - -docker-compose up -d - -{{% /section %}} - - ---- - -## La pulizia - -* ogni tanto eliminare i container fermi e le immagini inutilizzate puo' aiutare a liberare parecchio spazio - -* ogni volta che si "aggiorna" un'immagine o se ne crea una nuova versione, la precedente resta sul disco - -* ogni volta che il processo eseguito nel container termina il suo compito, il container viene stoppato, e resta li in questo stato. - -* tutti i files stanno in /var/lib/docker (per linux), ma non toccate quella cartella se non sapete cosa state facendo. - -* "docker system df" per vedere lo spazio usato e quanto se ne puo' recuperare con un docker system prune - ---- - -## Sicurezza - -* ovviamente le immagini del docker hub sono "precompilate", meglio sarebbe ricostruirsele - -* evitare di usare immagini con troppa roba dentro, ed. es. ubuntu, preferire cose minimali come ad es. alpine - -* fare in modo che le applicazioni dentro i container girino con i permessi strettamente necessari - -* fare network segmentation - -* implementare un sistema di auditing per sapere chi fa cosa dentro i container - ---- - # FINE