Isolamento degli ambienti di sviluppo tramite container LXD

Parlerò dell'approccio all'organizzazione di ambienti di sviluppo locali isolati sulla mia workstation. Questo approccio è stato elaborato sotto l'influenza dei seguenti fattori:

  • sono necessari IDE e toolchain diversi per diversi linguaggi;
  • in diversi progetti possono essere utilizzate versioni diverse di toolchain e librerie.

L'approccio consiste nel condurre lo sviluppo all'interno di contenitori LXD eseguiti localmente su un laptop o su una workstation, con reindirizzamento dell'output grafico sull'host.

Configurazione con esempio Ubuntu 20.04.

Riflessioni sulle opzioni e le motivazioni sono riportate alla fine dell'articolo.

1. Installazione di LXD

In Ubuntu 20.04 LXD non è più disponibile per l'installazione come pacchetto deb, ma solo tramite snap:

$ snap install lxd

Dopo l'installazione, è necessario eseguire l'inizializzazione:

$ lxd init

L'unico parametro che cambio è storage backend — utilizzo dir come il più semplice. Poiché non utilizzo snapshot e copie, gli avvertimenti in documentazione non mi spaventano:

Allo stesso modo, il backend directory deve essere considerato come un'opzione di ultima istanza.
Supporta tutte le principali funzionalità di LXD, ma è terribilmente lento e inefficiente poiché non può eseguire
copie instantanee o snapshot, e quindi deve copiare l'intero spazio di archiviazione dell'istanza ogni volta.

2. Configurazione del profilo LXD

I profili in LXD sono insiemi di parametri applicati a più contenitori. Per le mie esigenze mi basta un solo profilo predefinito default con le seguenti modifiche:

  • $ lxc profile device add default X0 disk source=/tmp/.X11-unix/X0 path=/tmp/.X11-unix/X0 — in modo che le applicazioni nei contenitori possano interagire con il server X11 dell'host;
  • $ lxc profile set default environment.DISPLAY :0 — affinché la variabile d'ambiente DISPLAY nei contenitori sia impostata correttamente;
  • $ lxc profile set default raw.idmap "both 1000 1000" — per una corretta mappatura degli identificatori..

3. Creazione e configurazione del contenitore

Creazione di un contenitore basato sull'immagine images:ubuntu/20.04:

$ lxc launch images:ubuntu/20.04 dev1

Preferisco le immagini dal repository https://images.linuxcontainers.org, poiché contengono meno software preinstallato. Per questo motivo ho aggiunto un prefisso immagini: al nome dell'immagine. La creazione di un contenitore basato su un'immagine del repository Ubuntu può essere eseguita come segue: $ lxc launch ubuntu/20.04 dev1.

Accesso alla shell root del contenitore:

$ lxc exec dev1 -- bash

Installerò Firefox e VS Code (dal repository secondo le istruzioni):

$ apt update
$ apt install curl gpg firefox

$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > packages.microsoft.gpg
$ install -o root -g root -m 644 packages.microsoft.gpg /usr/share/keyrings/
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list

$ apt update
$ apt install code

Attiverò il contenitore per chiarezza

poweroff

Bonus! È abbastanza semplice passare la GPU a un contenitore in modo che le applicazioni eseguite al suo interno possano utilizzare la scheda grafica. Per fare ciò, è necessario:

  • aggiungere il dispositivo $ lxc config device add dev1 mygpu gpu;
  • installare i driver della scheda video nel contenitore, gli stessi già installati sull'host.

4. Uso del contenitore

Nel caso in cui il contenitore non sia già avviato, è necessario avviarlo:

lxc start dev1

Avvio di VS Code come utente non privilegiato ubuntu:

lxc exec dev1 -- sudo --login --user ubuntu code

Avvio di Firefox:

lxc exec dev1 -- sudo --login --user ubuntu firefox

Le finestre delle applicazioni verranno visualizzate sull'host, ma verranno eseguite all'interno del contenitore, simile al passaggio della grafica tramite ssh.

Non spengo manualmente i contenitori attivi, poiché non ne vedo un particolare senso; mi limito a chiudere le finestre delle applicazioni in esecuzione.

5. Conclusione

Preferisco non utilizzare il sistema operativo host per lo sviluppo, poiché richiederebbe l'installazione di strumenti di sviluppo, versioni di debugging delle librerie, configurazioni di sistema specifiche e altre manovre. Tutto ciò può portare a comportamenti inaspettati nel resto del software non legato allo sviluppo, o anche nel sistema operativo. Ad esempio, le modifiche nella configurazione di OpenSSL possono causare il malfunzionamento del sistema operativo.

Ho provato diversi strumenti per isolare gli ambienti di sviluppo:

  • macchine virtuali (KVM, VirtualBox ecc.) — l'opzione più ovvia, ma consuma significativamente più risorse, anche se per lo sviluppo su Windows (se l'host è Linux) non ci sono altre opzioni;
  • strumenti di sviluppo cloud eseguiti su macchina locale (Cloud9 in contenitore o macchina virtuale, Eclipse Che ecc.) — non sono progettati per questo tipo di utilizzo, richiedono configurazioni aggiuntive e manutenzione, è meglio utilizzarli per lo scopo previsto — nel cloud;
  • I contenitori Docker, a mio avviso, sono destinati a un altro scopo; non sono molto adatti per prototipare rapidamente utilizzando software che non è ancora impacchettato in contenitori separati.

L'approccio scelto mi piace per la sua semplicità e il basso livello di ingresso. Nei contenitori stessi, è possibile applicare approcci specifici per i progetti: installare e configurare tutto manualmente oppure utilizzare l'automazione (Puppet, Ansible, ecc.), persino distribuire l'infrastruttura basata su Docker.Utilizzo anche contenitori LXD per eseguire software specifico che richiede l'installazione di molte dipendenze, oppure una versione diversa del sistema operativo: in questo caso, è possibile creare un contenitore con la versione di sistema operativo necessaria, ad esempio $ lxc launch images:ubuntu/16.04 dev16.

È importante tenere a mente che, in termini di isolamento, la containerizzazione presenta una superficie di attacco più ampia rispetto alla virtualizzazione: l'host e il contenitore condividono lo stesso kernel, la cui vulnerabilità può permettere a software dannoso di scappare dal contenitore. Per esperimenti con software dubbio, è meglio utilizzare meccanismi di isolamento più appropriati.

Link utili

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster