Har du nogensinde eksperimenteret med kode eller systemværktøjer i Linux, så du ikke behøver at være bange for det grundlæggende system og risikere at slette det hele ved en fejl i koden, som skal køres med root-rettigheder?
Hvad med at teste eller køre et helt klynge af forskellige mikrotjenester på én maskine? Hundrede eller endda tusinde?
Med virtuelle maskiner, der styres af hypervisorer, kan sådanne opgaver måske løses, men til hvilken pris? For eksempel, en container i LXD baseret på Alpine Linux forbruger minimalt 7.60MB RAM, og hvor roddreven efter opstart kun optager 9.5MB! Hvad siger du til det, Elon Musk? Jeg anbefaler at kigge nærmere på de grundlæggende funktioner i LXD — containersystemet i Linux.
Efter at have fået en generel forståelse af, hvad LXD-containere er, lad os gå videre og overveje, hvad hvis der var en platform-kombineret, hvor man kunne køre kode sikkert for værten, generere grafer, dynamisk (interaktivt) forbinde UI-widgets med din kode, supplere koden med tekst med blackjack… formatering? Noget i stil med en interaktiv blog? Wow… Jeg vil have! Jeg vil have! 🙂
Tjek indlægget hvor vi kører i en container JupyterLab — den næste generation af brugergrænsefladen i stedet for den forældede Jupyter Notebook, og installere moduler som NumPy, Pandas, Matplotlib, IPyWidgets som vil tillade os at udføre alt det ovenstående og gemme det i en særlig fil — en IPython-notebook.

Navigation
- Plan for opsendelse i kredsløb
- Installation og konfiguration af det grundlæggende system
- Installation af grundlæggende software og systemkonfiguration
- Installation og konfiguration af JupyterLab
- Deling af data med værten
- Hej, verden!
- Udvidelse af Python-funktionalitet
- Test af moduler i JupyterLab
- Hvad mere?
Plan for opsendelse i kredsløb ^

Lad os skitsere en kort handlingsplan, så vi nemmere kan realisere ovenstående skema:
- Vi installerer og kører en container baseret på distributionen Alpine Linux. Vi vælger denne distribution, da den er fokuseret på minimalisme og kun installerer den mest nødvendige software, intet overflødigt.
- Vi tilføjer en ekstra virtuel disk i containeren, som vi navngiver —
hostfsog vi monterer det til det rodede filsystem. Denne disk giver mulighed for at bruge filer på værten fra den angivne mappe inde i containeren. Dermed vil dataene være uafhængige af containeren. Hvis containeren slettes, forbliver dataene på værten. Desuden er denne opsætning nyttig til at dele data mellem mange containere uden at bruge de standard netværksmekanismer fra container-distributionen. - Vi vil installere Bash, sudo, nødvendige biblioteker, tilføje og konfigurere en systembruger.
- Vi vil installere Python, moduler og kompilere binære afhængigheder for dem.
- Vi vil installere og starte JupyterLab, tilpasse udseendet, installere udvidelser til det.
I denne artikel vil vi begynde med at starte containeren, vi vil ikke dække installationen og konfigurationen af LXD, alt det kan du finde i en anden artikel — Grundlæggende funktioner i LXD - container systemet i Linux.
Installation og konfiguration af det grundlæggende system ^
Vi opretter en container med kommandoen, hvor vi angiver billedet — alpine3, identifikatoren for containeren — jupyterlab og om nødvendigt konfigurationsprofilerne:
lxc init alpine3 jupyterlab --profile=default --profile=hddrootHer bruger jeg konfigurationsprofilen hddroot som angiver, at der skal oprettes en container med root-partitionen i Storage Pool placeret på den fysiske HDD-disk:
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:
- noneDette giver mig mulighed for at eksperimentere med containere på HDD-disken og spare ressourcer fra SSD-disken, som også findes i mit system 🙂 for hvilken jeg har oprettet en særskilt konfigurationsprofil. ssdroot.
Efter oprettelsen af containeren befinder den sig i tilstanden STOPPED, så vi skal starte den ved at køre init-systemet i den:
lxc start jupyterlabLad os vise listen over containere i LXD ved hjælp af parameteren -c som angiver, hvilke ckolonner der skal vises på skærmen:
lxc list -c ns4b
+------------+---------+-------------------+--------------+
| NAME | STATE | IPV4 | STORAGE POOL |
+------------+---------+-------------------+--------------+
| jupyterlab | RUNNING | 10.0.5.198 (eth0) | hddpool |
+------------+---------+-------------------+--------------+Når containeren oprettes, vælges IP-adressen tilfældigt, da vi brugte konfigurationsprofilen default som tidligere var konfigureret i artiklen Grundlæggende funktioner i LXD - container systemet i Linux.
Vi vil ændre denne IP-adresse til en mere mindeværdig ved at oprette et netværksinterface på container-niveau i stedet for konfigurationsprofilniveauet som i den nuværende konfiguration. Dette er ikke obligatorisk, og du kan vælge at springe det over.
Opretter et netværksinterface eth0 som vi forbinder til switchen (netværksbroen) lxdbr0 hvor vi har aktiveret NAT som beskrevet i den tidligere artikel, så containeren nu har internetadgang, og desuden tildeler vi et statisk IP-adresse til interfacet — 10.0.5.5:
lxc config device add jupyterlab eth0 nic name=eth0 nictype=bridged parent=lxdbr0 ipv4.address=10.0.5.5Efter tilføjelsen af enheden skal containeren genstartes:
lxc restart jupyterlabTjekker containerens status:
lxc list -c ns4b
+------------+---------+------------------+--------------+
| NAME | STATE | IPV4 | STORAGE POOL |
+------------+---------+------------------+--------------+
| jupyterlab | RUNNING | 10.0.5.5 (eth0) | hddpool |
+------------+---------+------------------+--------------+Installation af grundlæggende software og systemkonfiguration ^
For at administrere vores container er vi nødt til at installere følgende software:
Package
Beskrivelse
bash
GNU Bourne Again shell
bash-completion
Programmable completion for the bash shell
sudo
Giv bestemte brugere mulighed for at køre nogle kommandoer som root
shadow
Værktøjssuite til adgangskode- og kontoadministration med support for skygge-filer og PAM
tzdata
Kilder til tidszone- og sommertiddata
Mange har ventet på dette, og mange har været imod det, men det er sket: den standard teksteditor på konsollen i Fedora Workstation bliver nano.
Pico editor klon med forbedringer
Derudover kan du installere support i systemet man-pages ved at installere følgende pakker — man man-pages mdocml-apropos less
lxc exec jupyterlab -- apk add bash bash-completion sudo shadow tzdata nanoLad os gennemgå de kommandoer og nøgler, som vi brugte:
lxc— Kalder LXD-klientenexec— Metode til LXD-klienten, der udfører kommandoen i containerenjupyterlab— Containerens id--— Speciel nøgle, der angiver at ikke fortolke efterfølgende nøgler som nøgler forlxcog videregive hele den resterende streng som den er til containerenapk— Pakkehåndtering af Alpine Linux-distributionenadd— Metoden til pakkehåndteringen, der installerer de angivne pakker efter kommandoen
Næste skridt er at sætte tidszonen i systemet Europe/Moscow:
lxc exec jupyterlab -- cp /usr/share/zoneinfo/Europe/Moscow /etc/localtimeEfter installationen af tidszonen er pakken tzdata ikke længere nødvendig i systemet, da den vil tage plads, så lad os fjerne den:
lxc exec jupyterlab -- apk del tzdataTjekker tidszonen:
lxc exec jupyterlab -- date
Wed Apr 15 10:49:56 MSK 2020For ikke at bruge unødig tid på at konfigurere Bash for nye brugere i containeren, vil vi i de følgende trin kopiere de færdige skel-filer fra værtsystemet. Dette vil gøre det muligt at forbedre Bash i containeren i interaktiv tilstand. Mit værtsystem er Manjaro Linux, og de kopierede filer /etc/skel/.bash_profile, /etc/skel/.bashrc, /etc/skel/.dir_colors De fungerer generelt godt med Alpine Linux og forårsager ikke kritiske problemer, men du kan have en anden distribution, og du skal selv finde ud af det i tilfælde af en fejl, når Bash køres i containeren.
Vi kopierer skel-filerne til containeren. Nøglen --create-dirs vil oprette de nødvendige kataloger, hvis de ikke allerede findes:
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_colorsFor en allerede eksisterende root-bruger kopierer vi lige netop de skel-filer, der er kopieret til containeren, ind i hjemmemappen:
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_colorsI Alpine Linux installeres systemskallen for brugere /bin/sh, vi vil ændre den til root Bash for brugeren:
lxc exec jupyterlab -- usermod --shell=/bin/bash rootFor at root brugeren har ikke været uden adgangskode, han skal oprette en adgangskode. Næste kommando genererer og sætter en ny tilfældig adgangskode, som du vil se på konsolskærmen efter udførelsen:
lxc exec jupyterlab -- /bin/bash -c "PASSWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 12); echo "root:$PASSWD" | chpasswd && echo "Ny adgangskode: $PASSWD""
Ny adgangskode: sFiXEvBswuWADerudover opretter vi en ny systembruger — jupyter til hvilken vi senere vil konfigurere JupyterLab:
lxc exec jupyterlab -- useradd --create-home --shell=/bin/bash jupyterVi genererer og sætter en adgangskode for ham:
lxc exec jupyterlab -- /bin/bash -c "PASSWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 12); echo "jupyter:$PASSWD" | chpasswd && echo "Ny adgangskode: $PASSWD""
Ny adgangskode: ZIcbzWrF8tkiDernæst udfører vi to kommandoer, den første opretter en systemgruppe sudo, og den anden tilføjer brugeren til den jupyter:
lxc exec jupyterlab -- groupadd --system sudo
lxc exec jupyterlab -- groupmems --group sudo --add jupyterLad os se, hvilke grupper brugeren tilhører jupyter:
lxc exec jupyterlab -- id -Gn jupyter
jupyter sudoAlt er i orden, lad os fortsætte.
Lad os give alle brugere, der er medlem af gruppen sudo muligheden for at bruge kommandoen sudo. For at gøre dette udfører du følgende script, som sed afkommenterer linjen i konfigurationsfilen /etc/sudoers:
lxc exec jupyterlab -- /bin/bash -c "sed --in-place -e '/^#[ t]*%sudo[ t]*ALL=(ALL)[ t]*ALL$/ s/^[# ]*//' /etc/sudoers"Installation og konfiguration af JupyterLab ^
JupyterLab — dette er et Python-program, så vi skal først installere denne fortolker. Desuden, JupyterLab vi vil installere ved hjælp af Python's pakke manager pip, og ikke den systemmæssige, fordi den systemmæssige pakke kan være forældet, og derfor, skal vi manuelt løse afhængighederne ved at installere følgende pakker — python3 python3-dev gcc libc-dev zeromq-dev:
lxc exec jupyterlab -- apk add python3 python3-dev gcc libc-dev zeromq-devVi opdaterer python-moduler og pakkestyreren pip til den nyeste version:
lxc exec jupyterlab -- python3 -m pip install --upgrade pip setuptools wheelInstallerer JupyterLab gennem pakkestyreren pip:
lxc exec jupyterlab -- python3 -m pip install jupyterlabDa udvidelserne i JupyterLab er eksperimentelle og ikke officielt leveres sammen med pakken jupyterlab, skal vi derfor installere og konfigurere dette manuelt.
Vi installerer NodeJS og pakkestyreren til det — NPM, da JupyterLab bruger dem til sine udvidelser:
lxc exec jupyterlab -- apk add nodejs npmFor at udvidelserne til JupyterLab som vi installerer skal fungere, skal de installeres i brugerens mappe, da applikationen vil blive kørt af brugeren jupyter. Problemet er, at der ikke er en parameter i startkommandoen, hvor vi kan angive kataloget; applikationen erkender kun miljøvariablen, og derfor skal vi definere den. Til dette vil vi skrive eksportkommandoen for variablen JUPYTERLAB_DIR i brugerens miljø jupyter, i filen .bashrc, som udføres hver gang brugeren logger ind på systemet:
lxc exec jupyterlab -- su -l jupyter -c "echo -e "nexport JUPYTERLAB_DIR=$HOME/.local/share/jupyter/lab" >> .bashrc"Med den næste kommando installerer vi en særlig udvidelse — udvidelsesadministratoren i JupyterLab:
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 er alt klar til første opstart JupyterLab, men vi kan også installere flere nyttige udvidelser:
toc— Indholdsfortegnelse, genererer en liste over overskrifter i artiklen/notebookenjupyterlab-horizon-theme— UI-temajupyterlab_neon_theme— UI-temajupyterlab-ubu-theme— Endnu et tema fra forfatteren af denne artikel 🙂 Men i dette tilfælde vil installationen blive vist fra GitHub-repositoriet.
Så udfør følgende kommandoer i rækkefølge for at installere disse udvidelser:
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 installationen af udvidelserne skal vi kompilere dem, da vi tidligere angav nøglen --no-build for at spare tid. Nu vil vi markant fremskynde processen ved at kompilere dem sammen på én gang:
lxc exec jupyterlab -- su -l jupyter -c "export JUPYTERLAB_DIR=$HOME/.local/share/jupyter/lab; jupyter lab build"Udfør nu de næste to kommandoer for den første opstart JupyterLab. Det ville være muligt at starte det med én kommando, men i dette tilfælde vil startkommandoen, som man skal holde i tankerne, blive gemt af bash i containeren og ikke på værten, hvor der allerede er nok kommandoer til at blive indtastet i historikken 🙂
Log ind i containeren som bruger jupyter:
lxc exec jupyterlab -- su -l jupyterDernæst skal du køre JupyterLab med de nøgler og parametre som angivet:
[jupyter@jupyterlab ~]$ jupyter lab --ip=0.0.0.0 --no-browserGå til webbrowseren og naviger til http://10.0.5.5:8888 og indtast access token, som du vil se i konsollen. Kopier det og indsæt det på siden, og tryk derefter . Efter login, gå til venstre i udvidelsesmenuen, som vist på billedet nedenfor, hvor du bliver bedt om at acceptere sikkerhedsrisikoen ved at aktivere udvidelsesmanageren og installere tredjepartsudvidelser, som teamet JupyterLab development Log indikke påtager sig ansvar for: Men vi isolerer netop dette fuldstændigt og placerer det i en container, så tredjepartsudvidelser, der kræver og bruger NodeJS, ikke kan stjæle data på disken, bortset fra dem, som vi åbner inde i containeren. At få adgang til dine private dokumenter på værten fra

processer i containeren vil næppe være muligt, og hvis det er, kræver det privilegier til filer i værtsystemet, da vi kører containeren i JupyterLab uhindret tilstand /home . Ud fra denne information kan du vurdere risikoen ved at aktivere udvidelser i Oprettede IPython-notesbøger (sider i) vil nu blive oprettet i brugerens hjemmemappe — JupyterLab.
, men vi planlægger at dele data (dele) mellem værten og containeren, så gå tilbage til konsollen og stop JupyterLabved at udføre hotkey — /home/jupyterog svare JupyterLab på opfordringen. Derefter skal du afslutte den interaktive bruger-session CTRL+C ved at udføre hotkey y CTRL+D jupyter For at dele data med værten skal du oprette et sådant device i containeren, som muliggør dette, og brug derfor følgende kommando, hvor vi angiver følgende nøgler: lxc config device add.
Deling af data med værten ^
— Kommandoen føjer en enheds-konfiguration til
lxc config device add— Kommandoen tilføjer enhedsconfigurationsjupyter— Container Identifikatoren, hvori konfigurationen tilføjeshostfs— Enhedsidentifikatoren. Du kan angive ethvert navn.disk— Angiver enhedstypenpath— Angiver stien i containeren, hvor LXD vil montere denne enhedsource— Angiver kilden, stien til mappen på værten, som du ønsker at dele med containeren. Angiv stien efter dine præferencer
lxc config device add jupyterlab hostfs disk path=/mnt/hostfs source=/home/dv/projects/ipython-notebooksFor mappen /home/dv/projects/ipython-notebooks skal tilladelsen være givet til containerbrugeren, som nu har UID lig med SubUID + UID, se kapitel Sikkerhed. Containerrettigheder i artiklen Grundlæggende funktioner i LXD - container systemet i Linux.
Sætter tilladelsen på værten, hvor containerbrugeren vil være ejer jupyter, og variablen $USER angiver din vært-bruger som gruppe:
sudo chown 1001000:$USER /home/dv/projects/ipython-notebooksHej, verden! ^
Hvis du stadig har en konsolsession åben i containeren med JupyterLab, så genstart den med den nye nøgle --notebook-dir angivende værdien /mnt/hostfs som stien til rodmappen for notebookene i containeren for den enhed, vi oprettede i det forrige trin:
jupyter lab --ip=0.0.0.0 --no-browser --notebook-dir=/mnt/hostfsDerefter skal du gå til siden http://10.0.5.5:8888 og oprette din første notebook ved at trykke på knappen på siden, som vist på billedet nedenfor:

Indtast derefter koden i feltet på siden, som vil generere det klassiske Hello World!. Når du er færdig med at indtaste, skal du trykke på CTRL+ENTER eller knappen ‘play’ på værktøjslinjen ovenfor for at lade JupyterLab udføre dette:

Nu er næsten alt klar til brug, men det bliver kedeligt, hvis vi ikke installerer ekstra Python-moduler (fuldt udbyggede applikationer), som væsentligt udvider standardfunktionerne i Python i JupyterLab, så lad os komme videre 🙂
P.S. Det er interessant, at den gamle implementering Jupyter under kodenavnet Jupyter Notebook ikke er forsvundet og eksisterer parallelt med JupyterLab. For at skifte til den gamle version skal du klikke på linket ved at tilføje suffikset/tree, og skift til den nye version med suffikset /lab, men det er ikke nødvendigt at angive:
- Jupyter Notebook — http://10.0.5.5:8888/tree
- Jupyter Lab — http://10.0.5.5:8888/lab
Udvidelse af Python-funktionalitet ^
I dette afsnit vil vi installere kraftfulde Python-moduler som NumPy, Pandas, Matplotlib, IPyWidgets resultaterne af, som integreres i notebookene JupyterLab.
Før vi installerer de nævnte Python-moduler via pakkehåndtereren pip skal vi først tillade systemafhængigheder i Alpine Linux:
g++— Nødvendig for at kompilere moduler, da nogle af dem er implementeret i sproget C++ og tilsluttes Python i runtime som binære modulerfreetype-dev— afhængighed for Python-modulet Matplotlib
Installer afhængigheder:
lxc exec jupyterlab -- apk add g++ freetype-devDer er et problem; i den nuværende version af Alpine Linux kan en ny version af NumPy ikke compiles, der opstår en kompilationsfejl, som jeg ikke kunne løse:
FEJL: Kunne ikke bygge hjul for numpy, som bruger PEP 517 og kan ikke installeres direkte
Derfor vil vi installere dette modul som et systempakke, der allerede distribuerer en kompilering, men som er lidt ældre end den, der er tilgængelig nu på hjemmesiden:
lxc exec jupyterlab -- apk add py3-numpy py3-numpy-devDernæst installerer vi Python-moduler via pakkehåndtereren pip. Vær tålmodig, da nogle moduler vil blive kompilere, og det vil tage nogle minutter. På min maskine tog kompileringen ca. 15 minutter:
lxc exec jupyterlab -- python3 -m pip install pandas ipywidgets matplotlibRydder installationscacher:
lxc exec jupyterlab -- rm -rf /home/*/.cache/pip/*
lxc exec jupyterlab -- rm -rf /root/.cache/pip/*Test af moduler i JupyterLab ^
Hvis du har JupyterLab, genstart det for at aktivere de nye installerede moduler. For at gøre dette skal du trykke på CTRL+C der hvor det kører, og indtaste y ved anmodning om stop, og derefter starte det igen JupyterLab ved at trykke på pilen opad på tastaturet for ikke at skulle indtaste kommandoen igen og derefter Enter for at starte:
jupyter lab --ip=0.0.0.0 --no-browser --notebook-dir=/mnt/hostfsGå til siden http://10.0.5.5:8888/lab eller opdater siden i browseren, og indtast derefter følgende kode i en ny celle i notebooken:
%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_plotDu skal få et resultat som på billedet nedenfor, hvor IPyWidgets genererer et UI-element på siden, som interaktivt interagerer med kildekoden, samt Matplotlib viser resultatet af koden som et billede som en funktionsgraf:

Mange eksempler IPyWidgets kan du finde i tutorials her
Hvad mere? ^
I er seje, hvis I er blevet og nået til slutningen af artiklen. Jeg valgte bevidst ikke at offentliggøre et klart script i slutningen af artiklen, som ville installere JupyterLab med "et klik", for at opmuntre de hårdtarbejdende 🙂 Men I kan gøre det selv, da I allerede ved hvordan, ved at samle kommandoerne i et enkelt Bash-script 🙂
Derudover kan I:
- Angiv et netværksnavn for containeren i stedet for IP-adressen ved at skrive det i enkel
/etc/hostsog indtaste adressen i browseren http://jupyter.local:8888 - Prøv med resursebegrænsninger for containeren; læs kapitlet i grundlæggende muligheder for LXD eller få flere oplysninger på LXD-udviklerens websted.
- Skift designtema:

Og meget mere kan du! Det var alt. Jeg ønsker dig held og lykke!
OPDATERING: 15.04.2020 18:30 – Rettede fejl i kapitlet "Hello, World!"
OPDATERING: 16.04.2020 10:00 – Justerede og tilføjede tekst i beskrivelsen af aktiveringen af udvidelseshåndtereren JupyterLab
OPDATERING: 16.04.2020 10:40 – Rettede fundne fejl i teksten og forbedrede kapitlet "Installation af grundlæggende software og systemopsætning"
Kilde: habr.com
