Docker & containers: uso ideale

Docker is a tool that can package an application and its dependencies in a virtual container that can run on any Linux server. This helps enable flexibility and portability on where the application can run, whether on premisespublic cloudprivate cloudbare metal, etc.

Da https://en.wikipedia.org/wiki/Docker_(software)

Docker e la "containerizzazione" sono l'evoluzione di due tecnologie molto "antiche":

  • La prima è cgroups, evoluzione del comando unix chroot che consente di segregare un processo in un ambinete isolato, su un file system isolato e senza possibilità di visione degli altri processi (meltdown a parte)
  • La seconda è OverlayFS, un file system basato su "delta" in grado di effettuare il mix tra diversi file system in sola lettura, segregando le modifiche su file separati:
    The main mechanics of OverlayFS relate to the merging of directory access when both filesystems present a directory for the same name. Otherwise, OverlayFS presents the object[...]
    (Da https://en.wikipedia.org/wiki/OverlayFS)

Docker inizialmente era un progetto interno di dotCloud, una platform-as-service (PaaS) che ebbi la fortuna di usare poco prima che i creatori la vendessero (nel 2014) perché...si resero conto che era docker "il" business su cui investire, e non dotCloud

Docker consente di lanciare servizi ad una velocità molto maggiore di quella con cui un cloud può lanciare macchine virtuali (qualche millisecondo contro qualche secondo).

Si rende quindi possibile scalare orizzontalmente con un minor dispendio di risorse hardware, laddove le tecnologie di virtualizzazione richiedono invece uno sforzo maggiore anche solo di set up.

Tra le limitazioni, c'è il fatto che tutti i processi condividono il medesimo kernel (e quindi potenzialmente le medesime  vulnerabilità di sicurezza).

Docker è l'applicazione ideale per far girare servizi stateless mentre è fortemente sconsigliato per la gestione di database:

Docker is meant to be stateless. Containers have no permanent disk storage, whatever happens is ephemeral and is gone when the container stops. Containers are not meant to store data. Actually, they are meant by design to NOT store data. Any attempt to go against this philosophy is bound to disaster.

Da https://thehftguy.com/2016/11/01/docker-in-production-an-history-of-failure/

Difatti nel caso il file system del container venga corrotto, è molto più difficile recuperare le informazioni.

Inoltre una architettura a microservizi con database completamente distributi richiede l'uso di design pattern complessi per federare le transazioni; tale approccio è generalmente sconsigliato perché aggiunge una complessità non banale per dei semplici accessi a database (!). Per cui tenete il vostro database Oracle/PostgreSQL/MySQL/SQLServer fuori dal container, ed avvaletevi delle sue capacità native di segregazione e isolamento profilato (schemi, utenze ecc).

A tal proposito vi ricordo che Oracle e dispone di un livello di controllo sulle abilitazioni molto granulare (nel 1977 Larry Elison lavorò anche per la CIA....un posto che di segreti se ne intende).

Versionare l'infrastruttura

L'ultimo aspetto importante è che tecnologie come docker consentono di creare file dichiarativi che descrivono l'infrastruttura: per es i file di tipo "docker-compose.yml". 

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: username/repo:tag
    deploy:
      replicas: 5
      restart_policy:
        condition: on-failure
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
    ports:
      - "80:80"
    networks:
      - webnet
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]
    networks:
      - webnet
networks:
  webnet:

(Vedi  l'introduzione a docker e la documentazione sul compose file).

Tali file possono poi essere versionati ed agganciati al proprio sistema di build per tracciare i microservizi e l'infrastruttura ad essi sottesa.

Anche i Dockerfile possono essere versionati, ma essi sono più di tipo "operativo" che dichiarativo.