LinuxKit, unikernel e dintorni

Alla DockerCon17 è stato rilasciato opensource LinuxKit, ulteriore Kit che si aggiunge ai vari InfraKit, DataKit e SwarmKit nell’ecosistema dei progetti Moby.

LinuxKit, a toolkit for building custom minimal, immutable Linux distributions.

Questo strumento, al momento in fase (molto) alpha, si rivolge ad utenti, hypervisor e pipeline di CI/CD che devono costruire in modo ripetibile, veloce e facile immagini Linux per container minime, immutabili e sicure da gestire poi con meccanismi IaC come Terraform o InfraKit.

Ripetibile, perché immagini uguali sono prodotte da configurazioni YAML uguali. Veloce, perché il build richiede pochi secondi. Facile, perché chiunque abbia provato a creare sistemi Linux (unikernel) minimali sa quanto può essere molesto e fuorviante il processo: la promessa di LinuKit è quella di rendere tutto fattibile con un comando.

Il risultato è un’immagine Linux (.img o .iso) pronta a girare su qemu, vmware, GCP o hyperkit (OS X) minima, perché si inizializza in pochi secondi e include solo lo stretto necessario in Containerd come configurato (binari, librerie), immutabile, perché fissa requisiti e versioni (soprattutto kernel), e sicura perché riduce al minimo la superficie di attacco.

Il progetto Moby

Contestualmente al lancio di LinuxKit, i prodotti di Docker (in Github) passano sotto il contenitore del progetto Moby. Come promesso non ci saranno cambiamenti di tool e nomi, ma la transizione è in corso. Un’altra volta ancora, innovazione a tutti i costi. Prima di tutti a morire, come al solito, la retrocompatibilità: alcuni repo façade sono in fase di completamento per non rompere i build Go…

I prodotti downstream dentro Moby sono stati separati in Community Edition (CE) e Enterprise Edition (CE).

Come modello community e enterprise, verrà seguito quello di Fedora e Red Hat.

LinuxKit

LinuxKit non è un CoreOS o una distribuzione specializzata per container, ma un toolkit per costruire immagini Linux (al volo, possibilmente) a partire da configurazioni YAML. LinuxKit al momento costruisce immagini partendo da Linux Alpine aggiungendo gli extra in Containerd (Docker stesso nella fattispecie), ma l’idea del progetto è di fare da incubatore a progetti unikernel e altri relativi alla sicurezza dei sistemi operativi.

Una configurazione YAML tipica fissa la versione del kernel e dell’equipaggiamento base (runc, containerd, certificati), e specifica i servizi da aggiungere.

Una build con sshd

Inutile dilungarsi in discussioni teoriche quando il tutto è più semplice da capire con un esempio. Si usa LinuxKit con i comandi moby e linuxkit, che vanno compilati. La toolchain Go viene containerizzata in Docker, quindi non serve installare il compilatore:

$ git clone github.com:linuxkit/linuxkit $GOPATH/src/github.com/linuxkit/linuxkit
$ cd $GOPATH/src/github.com/linuxkit/linuxkit
$ make

Verifichiamo:

➜ linuxkit git:(master) ./bin/moby version
moby version 0.0
commit: f2d6752751318477ec86e4677514d5a4890249c1

Versione 0.0, avevamo già detto che il progetto è nuovo?

Ora, dentro examples/ e projects/ ci sono alcuni YAML di riferimento per incominciare. Creiamo una Alpine a partire dall’esempio di sshd. Occorre aggiungere una chiave valida in sshd.yml prima. Poi:

➜ examples git:(master) ../bin/moby build sshd
Extract kernel image: linuxkit/kernel:4.9.x
Add init containers:
Process init image: linuxkit/init:63eed9ca7a09d2ce4c0c5e7238ac005fa44f564b
Process init image: linuxkit/runc:b0fb122e10dbb7e4e45115177a61a3f8d68c19a9
Process init image: linuxkit/containerd:18eaf72f3f4f9a9f29ca1951f66df701f873060b
Process init image: linuxkit/ca-certificates:e091a05fbf7c5e16f18b23602febd45dd690ba2f
Add onboot containers:
Create OCI config for linuxkit/sysctl:2cf2f9d5b4d314ba1bfc22b2fe931924af666d8c
Add service containers:
Create OCI config for linuxkit/rngd:c42fd499690b2cb6e4e6cb99e41dfafca1cf5b14
Create OCI config for linuxkit/dhcpcd:48e249ebef6a521eed886b3bce032db69fbb4afa
Create OCI config for linuxkit/sshd:e108d208adf692c8a0954f602743e0eec445364e
Add files:
root/.ssh/authorizedkeys
Create outputs:
sshd-bzImage sshd-initrd.img sshd-cmdline
sshd.iso
sshd-efi.iso

Ecco l’output:

➜ examples git:(master) ls -lh sshd
-rw-r--r-- 1 fsoppelsa staff 6.7M Apr 28 11:52 sshd-bzImage
-rw-r--r-- 1 fsoppelsa staff 27B Apr 28 11:52 sshd-cmdline
-rw-r--r-- 1 fsoppelsa staff 40M Apr 28 11:52 sshd-efi.iso
-rw-r--r-- 1 fsoppelsa staff 32M Apr 28 11:52 sshd-initrd.img
-rw-r--r-- 1 fsoppelsa staff 40M Apr 28 11:52 sshd.iso
-rw-r--r-- 1 fsoppelsa staff 1.7K Apr 28 10:44 sshd.yml

Immagini pronte. Lanciamo la VM (nel mio caso su hyperkit):

➜ examples git:(master) ../bin/linuxkit run sshd
[ 1.674388] Freeing unused kernel memory: 1548K (ffff8e7ac987d000 - ffff8e7ac9a00000)
[ 1.679172] Freeing unused kernel memory: 1184K (ffff8e7ac9cd8000 - ffff8e7ac9e00000)

Starting containerd

Welcome to LinuxKit


                        ##         .
                  ## ## ##        ==
               ## ## ## ## ##    ===
           /"""""""""""""""""___/ ===
      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ /  ===- ~~~
           ______ o           __/
                          __/
              ___________/


/ # INFO[0000] starting containerd boot...

In circa 3 secondi parte. Ecco cosa fa girare:

/ # runc list
ID PID STATUS BUNDLE CREATED OWNER
dhcpcd 414 running /containers/services/dhcpcd 2017-04-28T16:56:06.1132568Z root
rngd 451 running /containers/services/rngd 2017-04-28T16:56:06.1299713Z root
sshd 458 running /containers/services/sshd 2017-04-28T16:56:06.1408088Z root

Via DHCPd sulla rete interna host, l’interfaccia eth0 prende un indirizzo:

/ # ip a s eth0
4: eth0: <BROADCAST,MULTICAST,UP,LOWERUP> mtu 1500 qdisc pfifofast state UP qlen 1000
  link/ether 02:50:00:00:00:07 brd ff:ff:ff:ff:ff:ff
  inet 192.168.65.8/24 brd 192.168.65.255 scope global eth0

Per fare ssh dentro questa VM di esempio su hyperkit, bisogna avere accesso alla rete interna host Docker, cosa fattibile tramite un container:

➜ examples git:(master) docker run -v ~/.ssh:/root/.ssh -ti jdeathe/centos-ssh ssh 192.168.65.8
The authenticity of host '192.168.65.8 (192.168.65.8)' can't be established.
ECDSA key fingerprint is 19:7b:25:df:47:a4:56:2c:e8:59:6b:f4:a4:01:47:83.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.65.8' (ECDSA) to the list of known hosts.
Welcome to LinuxKit
moby-025000000007:# hostname
moby-025000000007
moby-025000000007:# whoami
root
moby-025000000007:#

Scenari futuri

L’esempio di ssh è quello più banale. Sono già partiti progetti per iniziare a modellare servizi seri partendo da configurazioni LinuxKit (il mio preferito, in projects/kubernetes).

L’idea è quella di trainare tutto questo hype verso la direzione degli unikernel. I sistemi a unikernel non hanno un kernel vero e proprio, ma lo spazio di indirizzi tra kernel e userspace è fuso: le applicazioni compilano staticamente le parti di kernel e le syscall necessarie dentro il proprio binario. Se mi serve un oggetto unikernel per fare ping, non mi servono le syscall di accesso al filesystem o ai processi e la parte di crittografia del kernel. Così, l’oggetto ping unikernel compila se stesso, le raw socket e le primitive di networking e basta.

Qualcuno capace di accedere a un oggetto unikernel non ha modo di lanciare shell o usare script o librerie extra inutilizzate, perché semplicemente non ci sono. È abbastanza interessante? Per unikernel vedasi MirageOS. Però, momento, creare sistemi unikernel è un casino. Ed ecco che arriverà LinuxKit.

Certo, noi tutti amiamo i container (no?), ma unikernel è la prossima big thing.

Ti piacerebbe diventare anche tu uno di noi e pubblicare i tuoi articoli nel blog degli RHCE italiani?

Panoramica privacy
EXTRAORDY | Your Red Hat Trusted Mentor

Questo sito utilizza i cookie in modo da offrirti la migliore esperienza utente possibile. Le informazioni sui cookie sono memorizzate nel tuo browser e svolgono funzioni come riconoscerti quando ritorni sul nostro sito e aiutare il nostro team a capire quali sezioni del sito ritieni più interessanti e utili.

Pertanto per una completa fruizione del presente sito, si consiglia di configurare il browser in modo che accetti la ricezione dei cookie.

Cookie strettamente necessari

I cookie strettamente necessari dovrebbero essere abilitati in ogni momento in modo che possiamo salvare le tue preferenze per offrirti la miglior esperienza possibile sul nostro sito.

 

Se disabiliti questo cookie, non saremo in grado di salvare le tue preferenze. Ciò significa che ogni volta che visiti questo sito web dovrai abilitare o disabilitare nuovamente i cookie.

Cookie di terze parti

Questo sito utilizza Google Analytics per raccogliere informazioni anonime quali il numero di visitatori del sito e le pagine più popolari.

Mantenere abilitato questo cookie ci aiuta a migliorare il nostro sito.