Lanserar Jupyter i LXD-bana

Har du någonsin behövt experimentera med kod eller systemverktyg i Linux för att inte oroa dig för bassystemet och inte riva ner allt i händelse av ett fel i koden som ska köras med root-privilegier?

Men hur är det med det faktum att låt oss säga att du behöver testa eller köra ett helt kluster av olika mikrotjänster på en maskin? Hundra eller till och med tusen?

Med virtuella maskiner som hanteras av en hypervisor kan och kommer sådana problem att lösas, men till vilken kostnad? Till exempel, en behållare i LXD baserad på Alpine Linux-distributionen förbrukar endast 7.60MB RAM, och var rotpartitionen upptar efter uppstart 9.5MB! Hur gillar du det, Elon Musk? Jag rekommenderar att checka ut grundläggande funktioner i LXD - ett containersystem i Linux

Efter att det blev klart i allmänhet vad LXD-containrar är, låt oss gå vidare och tänka, tänk om det fanns en sådan skördarplattform där du säkert kunde köra kod för värden, generera grafer, dynamiskt (interaktivt) länka UI-widgets med din kod, komplettera koden med text med blackjack... formatering? Någon form av interaktiv blogg? Wow... jag vill ha det! Vilja! 🙂

Titta under katten där vi ska sjösätta i en container jupyter lab - nästa generations användargränssnitt istället för den föråldrade Jupyter Notebook, och vi kommer även att installera Python-moduler som t.ex. numpy, pandas, matplotlib, IPyWidgets vilket gör att du kan göra allt som anges ovan och spara allt i en speciell fil - en IPython-laptop.

Lanserar Jupyter i LXD-bana

Orbital startplan ^

Lanserar Jupyter i LXD-bana

Låt oss skissera en kort handlingsplan för att göra det lättare för oss att implementera schemat ovan:

  • Låt oss installera och lansera en behållare baserad på distributionssatsen Alpine Linux. Vi kommer att använda den här distributionen eftersom den är inriktad på minimalism och kommer bara att installera den mest nödvändiga programvaran i den, inget överflödigt.
  • Låt oss lägga till ytterligare en virtuell disk i behållaren och ge den ett namn - hostfs och montera den till rotfilsystemet. Denna disk gör det möjligt att använda filer på värden från en given katalog inuti behållaren. Således kommer vår data att vara oberoende av behållaren. Om behållaren raderas kommer data att finnas kvar på värden. Detta schema är också användbart för att dela samma data mellan många behållare utan att använda standardnätverksmekanismerna för behållardistributionen.
  • Låt oss installera Bash, sudo, de nödvändiga biblioteken, lägga till och konfigurera en systemanvändare
  • Låt oss installera Python, moduler och kompilera binära beroenden för dem
  • Låt oss installera och starta jupyter lab, anpassa utseendet, installera tillägg för det.

I den här artikeln börjar vi med att lansera behållaren, vi kommer inte att överväga att installera och konfigurera LXD, du kan hitta allt detta i en annan artikel - Grundläggande funktioner i LXD - Linux containersystem.

Installation och konfiguration av grundsystemet ^

Vi skapar en behållare med kommandot där vi anger bilden - alpine3, identifierare för behållaren - jupyterlab och, om nödvändigt, konfigurationsprofiler:

lxc init alpine3 jupyterlab --profile=default --profile=hddroot

Här använder jag en konfigurationsprofil hddroot som anger att skapa en behållare med en rotpartition i Förvaringspool finns på en fysisk hårddisk:

lxc profile show hddroot

config: {}
description: ""
devices:
  root:
    path: /
    pool: hddpool
    type: disk
name: hddroot
used_by: []
lxc storage show hddpool

config:
  size: 10GB
  source: /dev/loop1
  volatile.initial_source: /dev/loop1
description: ""
name: hddpool
driver: btrfs
used_by:
- /1.0/images/ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
- /1.0/profiles/hddroot
status: Created
locations:
- none

Detta ger mig möjlighet att experimentera med behållare på hårddisken, spara resurserna på SSD-disken, som också finns tillgänglig i mitt system 🙂 för vilket jag har skapat en separat konfigurationsprofil ssdroot.

När behållaren har skapats är den i tillståndet STOPPED, så vi måste starta det genom att köra init-systemet i det:

lxc start jupyterlab

Låt oss visa en lista över behållare i LXD med hjälp av tangenten -c som indikerar vilken csiffror visas:

lxc list -c ns4b
+------------+---------+-------------------+--------------+
|    NAME    |  STATE  |       IPV4        | STORAGE POOL |
+------------+---------+-------------------+--------------+
| jupyterlab | RUNNING | 10.0.5.198 (eth0) | hddpool      |
+------------+---------+-------------------+--------------+

När vi skapade behållaren valdes IP-adressen slumpmässigt, eftersom vi använde en konfigurationsprofil default som tidigare konfigurerats i artikeln Grundläggande funktioner i LXD - Linux containersystem.

Vi kommer att ändra denna IP-adress till en mer minnesvärd genom att skapa ett nätverksgränssnitt på containernivå, och inte på konfigurationsprofilnivån som den är nu i den aktuella konfigurationen. Du behöver inte göra det här, du kan hoppa över det.

Skapa ett nätverksgränssnitt eth0 som vi länkar till switchen (nätverksbryggan) lxdbr0 där vi aktiverade NAT enligt föregående artikel och behållaren kommer nu att ha tillgång till Internet, och vi tilldelar även en statisk IP-adress till gränssnittet - 10.0.5.5:

lxc config device add jupyterlab eth0 nic name=eth0 nictype=bridged parent=lxdbr0 ipv4.address=10.0.5.5

När du har lagt till en enhet måste behållaren startas om:

lxc restart jupyterlab

Kontrollera behållarens status:

lxc list -c ns4b
+------------+---------+------------------+--------------+
|    NAME    |  STATE  |       IPV4       | STORAGE POOL |
+------------+---------+------------------+--------------+
| jupyterlab | RUNNING | 10.0.5.5 (eth0)  | hddpool      |
+------------+---------+------------------+--------------+

Installera grundläggande programvara och konfigurera systemet ^

För att administrera vår container måste du installera följande programvara:

Paket
Beskrivning

bash
GNU Bourne Again-skalet

bash-avslutande
Programmerbar komplettering för bash-skalet

sudo
Ge vissa användare möjligheten att köra vissa kommandon som root

skugga
Lösenords- och kontohanteringsverktygssvit med stöd för skuggfiler och PAM

tzdata
Källor för data om tidszon och sommartid

nano
Pico editor klon med förbättringar

Dessutom kan du installera support i systemets man-sidor genom att installera följande paket − man man-pages mdocml-apropos less

lxc exec jupyterlab -- apk add bash bash-completion sudo shadow tzdata nano

Låt oss titta på de kommandon och nycklar vi använde:

  • lxc — Ring LXD-klienten
  • exec - LXD-klientmetod som kör ett kommando i behållaren
  • jupyterlab — Container-ID
  • -- - En speciell nyckel som specificerar att inte tolka ytterligare nycklar som nycklar för lxc och för resten av strängen som den är till behållaren
  • apk — Alpine Linux distributionspakethanterare
  • add — En pakethanterarmetod som installerar paket som anges efter kommandot

Därefter kommer vi att ställa in en tidszon i systemet Europe/Moscow:

lxc exec jupyterlab -- cp /usr/share/zoneinfo/Europe/Moscow /etc/localtime

Efter installation av tidszonen, paketet tzdata inte längre behövs i systemet, det kommer att ta upp utrymme, så låt oss ta bort det:

lxc exec jupyterlab -- apk del tzdata

Kontrollera tidszonen:

lxc exec jupyterlab -- date

Wed Apr 15 10:49:56 MSK 2020

För att inte spendera mycket tid på att ställa in Bash för nya användare i behållaren kommer vi i följande steg att kopiera färdiga skel-filer från värdsystemet till den. Detta gör att du kan försköna Bash i en behållare interaktivt. Mitt värdsystem är Manjaro Linux och filerna som kopieras /etc/skel/.bash_profile, /etc/skel/.bashrc, /etc/skel/.dir_colors i princip är de lämpliga för Alpine Linux och orsakar inte kritiska problem, men du kan ha en annan distribution och du måste självständigt ta reda på om det finns ett fel när du kör Bash i behållaren.

Kopiera skel-filerna till behållaren. Nyckel --create-dirs kommer att skapa de nödvändiga katalogerna om de inte finns:

lxc file push /etc/skel/.bash_profile jupyterlab/etc/skel/.bash_profile --create-dirs
lxc file push /etc/skel/.bashrc jupyterlab/etc/skel/.bashrc
lxc file push /etc/skel/.dir_colors jupyterlab/etc/skel/.dir_colors

För en befintlig rotanvändare, kopiera skel-filerna som just kopierats till behållaren till hemkatalogen:

lxc exec jupyterlab -- cp /etc/skel/.bash_profile /root/.bash_profile
lxc exec jupyterlab -- cp /etc/skel/.bashrc /root/.bashrc
lxc exec jupyterlab -- cp /etc/skel/.dir_colors /root/.dir_colors

Alpine Linux installerar ett systemskal för användare /bin/sh, kommer vi att ersätta den med root användare i Bash:

lxc exec jupyterlab -- usermod --shell=/bin/bash root

Att root användaren var inte lösenordslös, han måste ställa in ett lösenord. Följande kommando kommer att generera och ställa in ett nytt slumpmässigt lösenord för honom, som du kommer att se på konsolskärmen efter att det har körts:

lxc exec jupyterlab -- /bin/bash -c "PASSWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 12); echo "root:$PASSWD" | chpasswd && echo "New Password: $PASSWD""

New Password: sFiXEvBswuWA

Låt oss också skapa en ny systemanvändare - jupyter som vi kommer att konfigurera senare jupyter lab:

lxc exec jupyterlab -- useradd --create-home --shell=/bin/bash jupyter

Låt oss skapa och ställa in ett lösenord för det:

lxc exec jupyterlab -- /bin/bash -c "PASSWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 12); echo "jupyter:$PASSWD" | chpasswd && echo "New Password: $PASSWD""

New Password: ZIcbzWrF8tki

Därefter kommer vi att köra två kommandon, det första kommer att skapa en systemgrupp sudo, och den andra lägger till en användare till den jupyter:

lxc exec jupyterlab -- groupadd --system sudo
lxc exec jupyterlab -- groupmems --group sudo --add jupyter

Låt oss se vilka grupper användaren tillhör jupyter:

lxc exec jupyterlab -- id -Gn jupyter

jupyter sudo

Allt är ok, låt oss gå vidare.

Tillåt alla användare som är medlemmar i gruppen sudo använd kommandot sudo. För att göra detta, kör följande skript, där sed avkommentarer parameterraden i konfigurationsfilen /etc/sudoers:

lxc exec jupyterlab -- /bin/bash -c "sed --in-place -e '/^#[ t]*%sudo[ t]*ALL=(ALL)[ t]*ALL$/ s/^[# ]*//' /etc/sudoers"

Installera och konfigurera JupyterLab ^

jupyter lab är en Python-applikation, så vi måste först installera denna tolk. Också, jupyter lab vi kommer att installera med Python-pakethanteraren pip, och inte systemet ett, eftersom det kan vara föråldrat i systemförvaret och därför måste vi manuellt lösa beroenden för det genom att installera följande paket − python3 python3-dev gcc libc-dev zeromq-dev:

lxc exec jupyterlab -- apk add python3 python3-dev gcc libc-dev zeromq-dev

Låt oss uppdatera python-moduler och pakethanterare pip till den aktuella versionen:

lxc exec jupyterlab -- python3 -m pip install --upgrade pip setuptools wheel

Ställ jupyter lab via pakethanteraren pip:

lxc exec jupyterlab -- python3 -m pip install jupyterlab

Sedan förlängningarna i jupyter lab är experimentella och levereras inte officiellt med jupyterlab-paketet, så vi måste installera och konfigurera det manuellt.

Låt oss installera NodeJS och pakethanteraren för det - NPM, sedan jupyter lab använder dem för sina tillägg:

lxc exec jupyterlab -- apk add nodejs npm

Till tillägg för jupyter lab som vi kommer att installera fungerade, de måste installeras i användarkatalogen eftersom applikationen kommer att startas från användaren jupyter. Problemet är att det inte finns någon parameter i startkommandot som kan skickas till en katalog, applikationen accepterar bara en miljövariabel och därför måste vi definiera den. För att göra detta kommer vi att skriva variabelexportkommandot JUPYTERLAB_DIR i användarens miljö jupyter, till fil .bashrcsom exekveras varje gång användaren loggar in:

lxc exec jupyterlab -- su -l jupyter -c "echo -e "nexport JUPYTERLAB_DIR=$HOME/.local/share/jupyter/lab" >> .bashrc"

Nästa kommando kommer att installera ett speciellt tillägg - extension manager in jupyter lab:

lxc exec jupyterlab -- su -l jupyter -c "export JUPYTERLAB_DIR=$HOME/.local/share/jupyter/lab; jupyter labextension install --no-build @jupyter-widgets/jupyterlab-manager"

Nu är allt klart för första lanseringen jupyter lab, men vi kan fortfarande installera några användbara tillägg:

  • toc — Innehållsförteckning, genererar en lista med rubriker i en artikel/anteckningsbok
  • jupyterlab-horizon-theme — UI-tema
  • jupyterlab_neon_theme — UI-tema
  • jupyterlab-ubu-theme - En till tema från författaren denna artikel :) Men i det här fallet kommer installationen från GitHub-förvaret att visas

Så kör följande kommandon sekventiellt för att installera dessa tillägg:

lxc exec jupyterlab -- su -l jupyter -c "export JUPYTERLAB_DIR=$HOME/.local/share/jupyter/lab; jupyter labextension install --no-build @jupyterlab/toc @mohirio/jupyterlab-horizon-theme @yeebc/jupyterlab_neon_theme"
lxc exec jupyterlab -- su -l jupyter -c "wget -c https://github.com/microcoder/jupyterlab-ubu-theme/archive/master.zip"
lxc exec jupyterlab -- su -l jupyter -c "unzip -q master.zip && rm master.zip"
lxc exec jupyterlab -- su -l jupyter -c "export JUPYTERLAB_DIR=$HOME/.local/share/jupyter/lab; jupyter labextension install --no-build jupyterlab-ubu-theme-master"
lxc exec jupyterlab -- su -l jupyter -c "rm -r jupyterlab-ubu-theme-master"

Efter installation av tilläggen måste vi kompilera dem, eftersom vi tidigare, under installationen, angav nyckeln --no-build för att spara tid. Nu kommer vi att snabba upp avsevärt genom att sammanställa dem på en gång:

lxc exec jupyterlab -- su -l jupyter -c "export JUPYTERLAB_DIR=$HOME/.local/share/jupyter/lab; jupyter lab build"

Kör nu följande två kommandon för att köra det för första gången jupyter lab. Det skulle vara möjligt att starta det med ett kommando, men i det här fallet kommer startkommandot, som är svårt att komma ihåg i ditt sinne, komma ihåg av bash i behållaren, och inte på värden, där det redan finns tillräckligt med kommandon att registrera dem i historien :)

Logga in på containern som användare jupyter:

lxc exec jupyterlab -- su -l jupyter

Nästa, spring jupyter lab med nycklar och parametrar som anges:

[jupyter@jupyterlab ~]$ jupyter lab --ip=0.0.0.0 --no-browser

Gå till adressen i din webbläsare http://10.0.5.5:8888 och skriv in på sidan som öppnas token åtkomst som du kommer att se i konsolen. Kopiera och klistra in det på sidan och klicka sedan Logga in. Efter att ha loggat in, gå till tilläggsmenyn till vänster, som visas i figuren nedan, där du, när du aktiverar tilläggshanteraren, uppmanas att ta säkerhetsrisker genom att installera tillägg från tredje part för vilka kommandot JupyterLab utveckling är inte ansvarig:

Lanserar Jupyter i LXD-bana

Men vi isolerar hela jupyter lab och placera den i en container så att tredjepartstillägg som kräver och använder NodeJS åtminstone inte kan stjäla andra data på disken än de som vi öppnar inuti containern. Gå till dina privata dokument på värden i /home processer från behållaren är osannolikt att lyckas, och om de gör det måste du ha privilegier på filer på värdsystemet, eftersom vi kör behållaren i oprivilegierat läge. Baserat på denna information kan du bedöma risken för att inkludera förlängningar i jupyter lab.

Skapade IPython-anteckningsböcker (sidor in jupyter lab) kommer nu att skapas i användarens hemkatalog - /home/jupyter, men våra planer är att dela upp data (delning) mellan värden och behållaren, så gå tillbaka till konsolen och sluta jupyter lab genom att köra snabbtangent - CTRL+C och svara y på förfrågan. Avsluta sedan användarens interaktiva session jupyter slutföra en snabbtangent CTRL+D.

Dela data med värden ^

För att dela data med värden måste du skapa en enhet i behållaren som låter dig göra detta och för att göra detta, kör följande kommando där vi anger följande nycklar:

  • lxc config device add — Kommandot lägger till enhetskonfigurationen
  • jupyter — ID för behållaren till vilken konfigurationen läggs till
  • hostfs - Enhets-ID. Du kan ställa in vilket namn som helst.
  • disk — Typ av anordning anges
  • path — Anger sökvägen i behållaren som LXD kommer att montera den här enheten på
  • source — Ange källan, sökvägen till katalogen på värden som du vill dela med behållaren. Ange sökvägen enligt dina preferenser
lxc config device add jupyterlab hostfs disk path=/mnt/hostfs source=/home/dv/projects/ipython-notebooks

För katalogen /home/dv/projects/ipython-notebooks behörighet måste ställas in för containeranvändaren som för närvarande har ett UID lika med SubUID + UID, se kapitel Säkerhet. Containerprivilegier i artikeln Grundläggande funktioner i LXD - Linux containersystem.

Ställ in behörigheten på värden, där ägaren kommer att vara containeranvändaren jupyter, och variabeln $USER kommer att ange din värdanvändare som en grupp:

sudo chown 1001000:$USER /home/dv/projects/ipython-notebooks

Hej världen! ^

Om du fortfarande har en konsolsession öppen i behållaren med jupyter lab, starta om den med en ny nyckel --notebook-dir genom att ställa in värdet /mnt/hostfs som sökvägen till roten av de bärbara datorerna i behållaren för enheten som vi skapade i föregående steg:

jupyter lab --ip=0.0.0.0 --no-browser --notebook-dir=/mnt/hostfs

Gå sedan till sidan http://10.0.5.5:8888 och skapa din första bärbara dator genom att klicka på knappen på sidan som visas på bilden nedan:

Lanserar Jupyter i LXD-bana

Ange sedan Python-koden som ska visa klassikern i fältet på sidan Hello World!. När du är klar trycker du på CTRL+ENTER eller "spela"-knappen i verktygsfältet högst upp för att få JupyterLab att göra detta:

Lanserar Jupyter i LXD-bana

Vid det här laget är nästan allt klart för användning, men det kommer att vara ointressant om vi inte installerar ytterligare Python-moduler (fullfjädrade applikationer) som avsevärt kan utöka standardkapaciteten för Python i jupyter labså låt oss gå vidare :)

PS Det intressanta är att den gamla implementeringen jupyter under kodnamn Jupyter Notebook har inte gått bort och den finns parallellt med jupyter lab. För att byta till den gamla versionen, följ länken och lägg till suffixet i adressen/tree, och övergången till den nya versionen utförs med suffixet /lab, men det behöver inte anges:

Utöka funktionerna i Python ^

I det här avsnittet kommer vi att installera så kraftfulla Python-språkmoduler som numpy, pandas, matplotlib, IPyWidgets vars resultat är integrerade i bärbara datorer jupyter lab.

Innan du installerar de listade Python-modulerna via pakethanteraren pip vi måste först lösa systemberoende i Alpine Linux:

  • g++ — Behövs för att kompilera moduler, eftersom vissa av dem är implementerade på språket C + + och anslut till Python vid körning som binära moduler
  • freetype-dev - beroende för Python-modulen matplotlib

Installera beroenden:

lxc exec jupyterlab -- apk add g++ freetype-dev

Det finns ett problem: i det nuvarande tillståndet för Alpine Linux-distributionen kommer det inte att vara möjligt att kompilera den nya versionen av NumPy; ett kompileringsfel kommer att visas som jag inte kunde lösa:

FEL: Kunde inte bygga hjul för numpy som använder PEP 517 och inte kan installeras direkt

Därför kommer vi att installera denna modul som ett systempaket som distribuerar en redan kompilerad version, men lite äldre än vad som för närvarande finns tillgängligt på sajten:

lxc exec jupyterlab -- apk add py3-numpy py3-numpy-dev

Installera sedan Python-moduler via pakethanteraren pip. Vänligen ha tålamod eftersom vissa moduler kommer att kompileras och kan ta några minuter. På min maskin tog kompileringen ~15 minuter:

lxc exec jupyterlab -- python3 -m pip install pandas ipywidgets matplotlib

Rensa installationscacher:

lxc exec jupyterlab -- rm -rf /home/*/.cache/pip/*
lxc exec jupyterlab -- rm -rf /root/.cache/pip/*

Testa moduler i JupyterLab ^

Om du springer jupyter lab, starta om den så att de nyinstallerade modulerna aktiveras. För att göra detta, klicka i en konsolsession CTRL+C där du har den igång och går in y för att stoppa begäran och sedan börja om jupyter lab genom att trycka på uppåtpilen på tangentbordet för att inte skriva in kommandot igen och sedan Enter för att starta det:

jupyter lab --ip=0.0.0.0 --no-browser --notebook-dir=/mnt/hostfs

Gå till sidan http://10.0.5.5:8888/lab eller uppdatera sidan i din webbläsare och ange sedan följande kod i en ny anteckningsbokcell:

%matplotlib inline

from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np

def f(m, b):
    plt.figure(2)
    x = np.linspace(-10, 10, num=1000)
    plt.plot(x, m * x + b)
    plt.ylim(-5, 5)
    plt.show()

interactive_plot = interactive(f, m=(-2.0, 2.0), b=(-3, 3, 0.5))
output = interactive_plot.children[-1]
output.layout.height = '350px'
interactive_plot

Du bör få ett resultat som på bilden nedan, där IPyWidgets genererar ett UI-element på sidan som interagerar interaktivt med källkoden, och även matplotlib visar resultatet av koden i form av en bild som en funktionsgraf:

Lanserar Jupyter i LXD-bana

Många exempel IPyWidgets du hittar det i tutorials här

Vad annars? ^

Bra gjort om du stannade och kom till slutet av artikeln. Jag lade medvetet inte upp ett färdigt skript i slutet av artikeln som skulle installera jupyter lab med "ett klick" för att uppmuntra arbetare :) Men du kan göra det själv, eftersom du redan vet hur, efter att ha samlat kommandona i ett enda Bash-skript :)

Du kan också:

  • Ställ in ett nätverksnamn för behållaren istället för en IP-adress genom att skriva det på ett enkelt sätt /etc/hosts och skriv adressen i webbläsaren http://jupyter.local:8888
  • Lek med resursgränsen för behållaren, för detta läs kapitlet i grundläggande LXD-funktioner eller få mer information på LXD-utvecklarwebbplatsen.
  • Ändra tema:

Lanserar Jupyter i LXD-bana

Och mycket mer du kan göra! Det är allt. Jag önskar er framgång!

UPPDATERING: 15.04.2020-18-30 XNUMX:XNUMX - Rättade fel i kapitlet "Hej världen!"
UPPDATERING: 16.04.2020/10/00 XNUMX:XNUMX — Korrigerad och tillagd text i beskrivningen av aktivering av tilläggshanteraren jupyter lab
UPPDATERING: 16.04.2020/10/40 XNUMX:XNUMX — Rättade fel hittade i texten och något ändrade till det bättre kapitlet "Installera grundläggande programvara och konfigurera systemet"

Källa: will.com

Lägg en kommentar