Lanserer Jupyter i LXD-bane

Har du noen gang måttet eksperimentere med kode eller systemverktøy i Linux for ikke å bekymre deg for basissystemet og ikke rive ned alt i tilfelle en feil i koden som skal kjøre med root-privilegier?

Men hva med det faktum at la oss si at du trenger å teste eller kjøre en hel klynge av forskjellige mikrotjenester på én maskin? Hundre eller til og med tusen?

Med virtuelle maskiner administrert av en hypervisor kan og vil slike problemer løses, men til hvilken pris? For eksempel bruker en beholder i LXD basert på Alpine Linux-distribusjonen kun 7.60MB RAM, og hvor rotpartisjonen opptar etter oppstart 9.5MB! Hvordan liker du det, Elon Musk? Jeg anbefaler å sjekke ut grunnleggende funksjoner i LXD - et containersystem i Linux

Etter at det generelt ble klart hva LXD-beholdere er, la oss gå videre og tenke, hva om det fantes en slik innhøstingsplattform der du trygt kunne kjøre kode for verten, generere grafer, dynamisk (interaktivt) koble UI-widgets med koden din, supplere koden med tekst med blackjack... formatering? En slags interaktiv blogg? Wow... jeg vil ha det! Ønsker! 🙂

Se under katten hvor vi skal lansere i en container jupyter lab - neste generasjon brukergrensesnitt i stedet for den utdaterte Jupyter Notebook, og vi vil også installere Python-moduler som f.eks. nusset, pandaer, Matplotlib, IPyWidgets som lar deg gjøre alt som er oppført ovenfor og lagre alt i en spesiell fil - en IPython bærbar PC.

Lanserer Jupyter i LXD-bane

Orbital take-off plan ^

Lanserer Jupyter i LXD-bane

La oss skissere en kort handlingsplan for å gjøre det lettere for oss å implementere ordningen ovenfor:

  • La oss installere og lansere en beholder basert på distribusjonssettet Alpine Linux. Vi vil bruke denne distribusjonen fordi den er rettet mot minimalisme og vil kun installere den mest nødvendige programvaren i den, ikke noe overflødig.
  • La oss legge til en ekstra virtuell disk i beholderen og gi den et navn - hostfs og monter den til rotfilsystemet. Denne disken vil gjøre det mulig å bruke filer på verten fra en gitt katalog inne i beholderen. Dermed vil våre data være uavhengige av containeren. Hvis beholderen slettes, forblir dataene på verten. Denne ordningen er også nyttig for å dele de samme dataene mellom mange containere uten å bruke standard nettverksmekanismer for containerdistribusjonen.
  • La oss installere Bash, sudo, de nødvendige bibliotekene, legge til og konfigurere en systembruker
  • La oss installere Python, moduler og kompilere binære avhengigheter for dem
  • La oss installere og starte jupyter lab, tilpass utseendet, installer utvidelser for det.

I denne artikkelen starter vi med å lansere beholderen, vi vil ikke vurdere å installere og konfigurere LXD, du kan finne alt dette i en annen artikkel - Grunnleggende funksjoner i LXD - Linux containersystemer.

Installasjon og konfigurering av basissystemet ^

Vi lager en beholder med kommandoen der vi spesifiserer bildet - alpine3, identifikator for beholderen - jupyterlab og, om nødvendig, konfigurasjonsprofiler:

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

Her bruker jeg en konfigurasjonsprofil hddroot som spesifiserer å lage en beholder med en rotpartisjon i Oppbevaringsbasseng plassert på en fysisk harddisk:

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

Dette gir meg muligheten til å eksperimentere med containere på HDD-disken, og sparer ressursene til SSD-disken, som også er tilgjengelig i systemet mitt 🙂 som jeg har laget en egen konfigurasjonsprofil for ssdroot.

Etter at beholderen er opprettet, er den i tilstanden STOPPED, så vi må starte den ved å kjøre init-systemet i den:

lxc start jupyterlab

La oss vise en liste over beholdere i LXD ved å bruke tasten -c som indikerer hvilken cvisning av olumner:

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

Ved opprettelse av containeren ble IP-adressen valgt tilfeldig, siden vi brukte en konfigurasjonsprofil default som tidligere ble konfigurert i artikkelen Grunnleggende funksjoner i LXD - Linux containersystemer.

Vi vil endre denne IP-adressen til en mer minneverdig ved å lage et nettverksgrensesnitt på containernivå, og ikke på konfigurasjonsprofilnivået slik det er nå i gjeldende konfigurasjon. Du trenger ikke å gjøre dette, du kan hoppe over det.

Opprette et nettverksgrensesnitt eth0 som vi kobler til svitsjen (nettverksbroen) lxdbr0 der vi aktiverte NAT i henhold til forrige artikkel, og beholderen vil nå ha tilgang til Internett, og vi tildeler også en statisk IP-adresse til grensesnittet - 10.0.5.5:

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

Etter å ha lagt til en enhet, må beholderen startes på nytt:

lxc restart jupyterlab

Sjekke statusen til beholderen:

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

Installere grunnleggende programvare og sette opp systemet ^

For å administrere beholderen vår må du installere følgende programvare:

Pakke
Beskrivelse

bash
GNU Bourne Again-skallet

bash-fullføring
Programmerbar komplettering for bash-skallet

sudo
Gi enkelte brukere muligheten til å kjøre noen kommandoer som root

skygge
Passord- og kontoadministrasjonsverktøypakke med støtte for skyggefiler og PAM

tzdata
Kilder for tidssone og sommertid

nano
Pico editor klon med forbedringer

I tillegg kan du installere støtte i systemman-sidene ved å installere følgende pakker - man man-pages mdocml-apropos less

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

La oss se på kommandoene og tastene vi brukte:

  • lxc — Ring LXD-klient
  • exec - LXD-klientmetode som kjører en kommando i beholderen
  • jupyterlab — Container-ID
  • -- - En spesiell nøkkel som spesifiserer å ikke tolke flere nøkler som nøkler for lxc og før resten av strengen som den er til beholderen
  • apk — Alpine Linux distribusjonspakkebehandler
  • add — En pakkebehandlingsmetode som installerer pakker spesifisert etter kommandoen

Deretter vil vi sette en tidssone i systemet Europe/Moscow:

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

Etter å ha installert tidssonen, pakken tzdata ikke lenger er nødvendig i systemet, vil det ta opp plass, så la oss slette det:

lxc exec jupyterlab -- apk del tzdata

Sjekke tidssonen:

lxc exec jupyterlab -- date

Wed Apr 15 10:49:56 MSK 2020

For ikke å bruke mye tid på å sette opp Bash for nye brukere i containeren, vil vi i de følgende trinnene kopiere ferdige skel-filer fra vertssystemet til den. Dette vil tillate deg å forskjønne Bash i en beholder interaktivt. Vertssystemet mitt er Manjaro Linux og filene som kopieres /etc/skel/.bash_profile, /etc/skel/.bashrc, /etc/skel/.dir_colors i prinsippet er de egnet for Alpine Linux og forårsaker ikke kritiske problemer, men du kan ha en annen distribusjon og du må uavhengig finne ut om det er en feil når du kjører Bash i containeren.

Kopier skel-filene til beholderen. Nøkkel --create-dirs vil opprette de nødvendige katalogene hvis de ikke eksisterer:

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

For en eksisterende rotbruker, kopier skel-filene som nettopp ble kopiert inn i beholderen til hjemmekatalogen:

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 installerer et system-skall for brukere /bin/sh, vil vi erstatte den med root bruker i Bash:

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

At root brukeren var ikke passordløs, han må angi et passord. Følgende kommando vil generere og sette et nytt tilfeldig passord for ham, som du vil se på konsollskjermen etter at det er utført:

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

La oss også opprette en ny systembruker - jupyter som vi vil konfigurere senere jupyter lab:

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

La oss generere og angi et passord for 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

Deretter vil vi utføre to kommandoer, den første vil opprette en systemgruppe sudo, og den andre vil legge til en bruker til den jupyter:

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

La oss se hvilke grupper brukeren tilhører jupyter:

lxc exec jupyterlab -- id -Gn jupyter

jupyter sudo

Alt er ok, la oss gå videre.

Tillat alle brukere som er medlemmer av gruppen sudo bruk kommando sudo. For å gjøre dette, kjør følgende skript, hvor sed fjerner kommentarer fra parameterlinjen i konfigurasjonsfilen /etc/sudoers:

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

Installere og konfigurere JupyterLab ^

jupyter lab er en Python-applikasjon, så vi må først installere denne tolken. Også, jupyter lab vi installerer ved å bruke Python-pakkebehandleren pip, og ikke systemet, fordi det kan være utdatert i systemlageret, og derfor må vi løse avhengighetene for det manuelt ved å installere følgende pakker − python3 python3-dev gcc libc-dev zeromq-dev:

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

La oss oppdatere python-moduler og pakkebehandling pip til gjeldende versjon:

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

Satt jupyter lab via pakkebehandler pip:

lxc exec jupyterlab -- python3 -m pip install jupyterlab

Siden utvidelsene i jupyter lab er eksperimentelle og leveres ikke offisielt med jupyterlab-pakken, så vi må installere og konfigurere den manuelt.

La oss installere NodeJS og pakkebehandleren for det - NPM, siden jupyter lab bruker dem for sine utvidelser:

lxc exec jupyterlab -- apk add nodejs npm

Til utvidelser for jupyter lab som vi vil installere fungerte, de må installeres i brukerkatalogen siden applikasjonen vil bli lansert fra brukeren jupyter. Problemet er at det ikke er noen parameter i startkommandoen som kan sendes til en katalog; applikasjonen aksepterer bare en miljøvariabel og derfor må vi definere den. For å gjøre dette, vil vi skrive kommandoen for variabel eksport JUPYTERLAB_DIR i brukerens miljø jupyter, å lagre .bashrcsom utføres hver gang brukeren logger på:

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

Den neste kommandoen vil installere en spesiell utvidelse - 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"

Nå er alt klart for første lansering jupyter lab, men vi kan fortsatt installere noen nyttige utvidelser:

  • toc — Innholdsfortegnelse, genererer en liste over overskrifter i en artikkel/notatbok
  • jupyterlab-horizon-theme – UI-tema
  • jupyterlab_neon_theme – UI-tema
  • jupyterlab-ubu-theme - En annen tema fra forfatteren denne artikkelen :) Men i dette tilfellet vil installasjonen fra GitHub-depotet vises

Så kjør følgende kommandoer sekvensielt for å installere disse utvidelsene:

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"

Etter å ha installert utvidelsene, må vi kompilere dem, siden vi tidligere, under installasjonen, spesifiserte nøkkelen --no-build for å spare tid. Nå vil vi øke hastigheten betraktelig ved å sette dem sammen på en gang:

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

Kjør nå følgende to kommandoer for å kjøre den for første gang jupyter lab. Det ville være mulig å starte den med én kommando, men i dette tilfellet vil startkommandoen, som er vanskelig å huske i tankene dine, bli husket av bash i beholderen, og ikke på verten, der det allerede er nok kommandoer å registrere dem i historien :)

Logg på containeren som bruker jupyter:

lxc exec jupyterlab -- su -l jupyter

Neste, løp jupyter lab med taster og parametere som angitt:

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

Gå til adressen i nettleseren din http://10.0.5.5:8888 og skriv inn på siden som åpnes token tilgang som du vil se i konsollen. Kopier og lim den inn på siden, og klikk deretter Logg inn. Etter å ha logget inn, gå til utvidelsesmenyen til venstre, som vist i figuren nedenfor, hvor du vil bli bedt om, når du aktiverer utvidelsesbehandleren, å ta sikkerhetsrisikoer ved å installere utvidelser fra tredjeparter som kommandoen for JupyterLab utvikling er ikke ansvarlig:

Lanserer Jupyter i LXD-bane

Vi isolerer imidlertid hele jupyter lab og plasser den i en container slik at tredjepartsutvidelser som krever og bruker NodeJS i det minste ikke kan stjele data på disken andre enn de vi åpner inne i containeren. Få til dine private dokumenter på verten i /home prosesser fra containeren er usannsynlig å lykkes, og hvis de gjør det, må du ha privilegier på filer på vertssystemet, siden vi kjører containeren i uprivilegert modus. Basert på denne informasjonen kan du vurdere risikoen for å inkludere utvidelser i jupyter lab.

Laget IPython-notatbøker (sider inn jupyter lab) vil nå bli opprettet i brukerens hjemmekatalog - /home/jupyter, men planene våre er å dele dataene (delingen) mellom verten og beholderen, så gå tilbake til konsollen og stopp jupyter lab ved å kjøre hurtigtast - CTRL+C og svarer y på forespørsel. Avslutt deretter brukerens interaktive økt jupyter fullføre en hurtigtast CTRL+D.

Dele data med verten ^

For å dele data med verten, må du opprette en enhet i beholderen som lar deg gjøre dette, og for å gjøre dette, kjør følgende kommando der vi spesifiserer følgende nøkler:

  • lxc config device add — Kommandoen legger til enhetskonfigurasjonen
  • jupyter — ID for beholderen som konfigurasjonen er lagt til
  • hostfs — Enhets-ID. Du kan angi hvilket som helst navn.
  • disk — Type enhet er angitt
  • path — Angir banen i beholderen som LXD skal montere denne enheten til
  • source — Spesifiser kilden, banen til katalogen på verten du vil dele med beholderen. Spesifiser banen i henhold til dine preferanser
lxc config device add jupyterlab hostfs disk path=/mnt/hostfs source=/home/dv/projects/ipython-notebooks

For katalogen /home/dv/projects/ipython-notebooks tillatelse må settes til containerbrukeren som for øyeblikket har en UID lik SubUID + UID, se kapittel Sikkerhet. Containerprivilegier i artikkelen Grunnleggende funksjoner i LXD - Linux containersystemer.

Angi tillatelsen på verten, der eieren vil være beholderbrukeren jupyter, og variabelen $USER vil spesifisere vertsbrukeren din som en gruppe:

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

Hei Verden! ^

Hvis du fortsatt har en konsolløkt åpen i beholderen med jupyter lab, og start den på nytt med en ny nøkkel --notebook-dir ved å angi verdien /mnt/hostfs som banen til roten til de bærbare datamaskinene i beholderen for enheten som vi opprettet i forrige trinn:

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

Gå deretter til siden http://10.0.5.5:8888 og lag din første bærbare datamaskin ved å klikke på knappen på siden som vist på bildet nedenfor:

Lanserer Jupyter i LXD-bane

Deretter, i feltet på siden, skriver du inn Python-koden som skal vise klassikeren Hello World!. Når du er ferdig med å legge inn, trykk CTRL+ENTER eller "spill"-knappen på verktøylinjen øverst for å få JupyterLab til å gjøre dette:

Lanserer Jupyter i LXD-bane

På dette tidspunktet er nesten alt klart til bruk, men det vil være uinteressant hvis vi ikke installerer ytterligere Python-moduler (fullverdige applikasjoner) som kan utvide standardfunksjonene til Python betydelig i jupyter labderfor, la oss gå videre :)

PS Det interessante er at den gamle implementeringen jupyter under kodenavn Jupyter Notebook har ikke gått bort og den eksisterer parallelt med jupyter lab. For å bytte til den gamle versjonen, følg lenken som legger til suffikset i adressen/tree, og overgangen til den nye versjonen utføres med suffikset /lab, men det trenger ikke spesifiseres:

Utvide egenskapene til Python ^

I denne delen vil vi installere så kraftige Python-språkmoduler som nusset, pandaer, Matplotlib, IPyWidgets resultatene er integrert i bærbare datamaskiner jupyter lab.

Før du installerer de oppførte Python-modulene gjennom pakkebehandlingen pip vi må først løse systemavhengigheter i Alpine Linux:

  • g++ — Nødvendig for å kompilere moduler, siden noen av dem er implementert på språket C + + og koble til Python under kjøretid som binære moduler
  • freetype-dev - avhengighet for Python-modulen Matplotlib

Installere avhengigheter:

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

Det er ett problem: i den nåværende tilstanden til Alpine Linux-distribusjonen vil det ikke være mulig å kompilere den nye versjonen av NumPy; en kompileringsfeil vil dukke opp som jeg ikke kunne løse:

FEIL: Kunne ikke bygge hjul for numpy som bruker PEP 517 og ikke kan installeres direkte

Derfor vil vi installere denne modulen som en systempakke som distribuerer en allerede kompilert versjon, men litt eldre enn det som for øyeblikket er tilgjengelig på siden:

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

Installer deretter Python-moduler gjennom pakkebehandlingen pip. Vær tålmodig siden noen moduler vil kompileres og kan ta noen minutter. På maskinen min tok kompileringen ~15 minutter:

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

Tømme installasjonsbuffer:

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

Testing av moduler i JupyterLab ^

Hvis du løper jupyter lab, start den på nytt slik at de nylig installerte modulene aktiveres. For å gjøre dette, klikk i en konsolløkt CTRL+C hvor du har den i gang og går inn y for å stoppe forespørselen og deretter starte på nytt jupyter lab ved å trykke på pil opp på tastaturet for ikke å skrive inn kommandoen igjen og deretter Enter for å starte det:

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

Gå til siden http://10.0.5.5:8888/lab eller oppdater siden i nettleseren din, og skriv deretter inn følgende kode i en ny notatbokcelle:

%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å et resultat som på bildet under, hvor IPyWidgets genererer et UI-element på siden som samhandler interaktivt med kildekoden, og også Matplotlib viser resultatet av koden i form av et bilde som en funksjonsgraf:

Lanserer Jupyter i LXD-bane

Mange eksempler IPyWidgets du finner det i opplæringsprogrammer her

Hva annet? ^

Godt gjort hvis du ble og nådde helt til slutten av artikkelen. Jeg la bevisst ikke ut et ferdig skript på slutten av artikkelen som ville installere jupyter lab med "ett klikk" for å oppmuntre arbeidere :) Men du kan gjøre det selv, siden du allerede vet hvordan, etter å ha samlet kommandoene i et enkelt Bash-skript :)

Du kan også:

  • Angi et nettverksnavn for beholderen i stedet for en IP-adresse ved å skrive det på en enkel måte /etc/hosts og skriv inn adressen i nettleseren http://jupyter.local:8888
  • Lek litt med ressursgrensen for beholderen, for dette kan du lese kapittelet i grunnleggende LXD-egenskaper eller få mer informasjon på LXD-utviklernettstedet.
  • Endre tema:

Lanserer Jupyter i LXD-bane

Og mye mer du kan gjøre! Det er alt. Jeg ønsker deg suksess!

OPPDATERING: 15.04.2020/18/30 XNUMX:XNUMX - Rettet feil i kapittelet "Hei, verden!"
OPPDATERING: 16.04.2020/10/00 XNUMX:XNUMX — Rettet og lagt til tekst i beskrivelsen av aktivering av utvidelsesadministrator jupyter lab
OPPDATERING: 16.04.2020/10/40 XNUMX:XNUMX — Rettet feil funnet i teksten og litt endret til det bedre kapittelet "Installere grunnleggende programvare og sette opp systemet"

Kilde: www.habr.com

Legg til en kommentar