Vypuštění Jupyteru na oběžnou dráhu LXD

Museli jste někdy experimentovat s kódem nebo systémovými utilitami v Linuxu, aniž byste se museli starat o základní systém a bourat vše v případě chyby v kódu, který by měl běžet s právy root?

Ale co skutečnost, že řekněme, že potřebujete otestovat nebo spustit celý cluster různých mikroslužeb na jednom počítači? Sto nebo dokonce tisíc?

S virtuálními stroji spravovanými hypervizorem se takové problémy dají a budou řešit, ale za jakou cenu? Například kontejner v LXD založený na distribuci Alpine Linux spotřebovává pouze 7.60MB RAM a kde se kořenový oddíl po spuštění zabírá 9.5MB! Jak se ti to líbí, Elone Musku? Doporučuji zkontrolovat základní možnosti LXD - kontejnerového systému v Linuxu

Poté, co bylo obecně jasné, co jsou LXD kontejnery, pojďme dále a zamysleme se nad tím, co kdyby existovala taková platforma harvesteru, kde byste mohli bezpečně spouštět kód pro hostitele, generovat grafy, dynamicky (interaktivně) propojovat UI-widgety s vaším kódem, doplnit kód textem o blackjack... formátování? Nějaký interaktivní blog? Páni... chci to! Chtějte! 🙂

Podívejte se pod kočku, kde spustíme v kontejneru jupyterová laboratoř - nová generace uživatelského rozhraní namísto zastaralého Jupyter Notebooku a nainstalujeme také moduly Pythonu jako např. nemotorný, Pandy, matplotlib, IPyWidgets což vám umožní udělat vše výše uvedené a uložit to vše do speciálního souboru - notebooku IPython.

Vypuštění Jupyteru na oběžnou dráhu LXD

Orbitální plán vzletu ^

Vypuštění Jupyteru na oběžnou dráhu LXD

Pojďme si nastínit stručný akční plán, který nám usnadní implementaci výše uvedeného schématu:

  • Pojďme nainstalovat a spustit kontejner založený na distribuční sadě Alpine Linux. Tuto distribuci využijeme, protože je zaměřena na minimalismus a nainstaluje do ní pouze nejnutnější software, nic nadbytečného.
  • Pojďme do kontejneru přidat další virtuální disk a pojmenovat jej - hostfs a připojte jej ke kořenovému systému souborů. Tento disk umožní používat soubory na hostiteli z daného adresáře uvnitř kontejneru. Naše data tedy budou nezávislá na kontejneru. Pokud je kontejner smazán, data zůstanou na hostiteli. Toto schéma je také užitečné pro sdílení stejných dat mezi mnoha kontejnery bez použití standardních síťových mechanismů distribuce kontejnerů.
  • Pojďme nainstalovat Bash, sudo, potřebné knihovny, přidat a nakonfigurovat uživatele systému
  • Pojďme si nainstalovat Python, moduly a zkompilovat pro ně binární závislosti
  • Pojďme nainstalovat a spustit jupyterová laboratoř, přizpůsobte vzhled, nainstalujte pro něj rozšíření.

V tomto článku začneme spuštěním kontejneru, nebudeme uvažovat o instalaci a konfiguraci LXD, to vše najdete v jiném článku - Základní vlastnosti kontejnerových systémů LXD - Linux.

Instalace a konfigurace základního systému ^

Kontejner vytvoříme příkazem, ve kterém určíme obrázek - alpine3, identifikátor pro kontejner - jupyterlab a v případě potřeby konfigurační profily:

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

Zde používám konfigurační profil hddroot což určuje vytvoření kontejneru s kořenovým oddílem Skladovací bazén umístěné na fyzickém HDD disku:

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

To mi dává možnost experimentovat s kontejnery na HDD disku a šetřit tak zdroje SSD disku, který je také dostupný v mém systému 🙂 pro který jsem vytvořil samostatný konfigurační profil ssdroot.

Po vytvoření je kontejner ve stavu STOPPED, takže jej musíme spustit spuštěním systému init v něm:

lxc start jupyterlab

Zobrazme seznam kontejnerů v LXD pomocí klávesy -c což naznačuje které czobrazení sloupců:

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

Při vytváření kontejneru byla IP adresa vybrána náhodně, protože jsme použili konfigurační profil default který byl dříve nakonfigurován v článku Základní vlastnosti kontejnerových systémů LXD - Linux.

Tuto IP adresu změníme na lépe zapamatovatelnou vytvořením síťového rozhraní na úrovni kontejneru, nikoli na úrovni konfiguračního profilu, jak je tomu nyní v aktuální konfiguraci. Nemusíte to dělat, můžete to přeskočit.

Vytvoření síťového rozhraní eth0 který propojíme s přepínačem (síťovým mostem) lxdbr0 ve kterém jsme povolili NAT podle předchozího článku a kontejner bude mít nyní přístup k internetu a rozhraní také přiřadíme statickou IP adresu - 10.0.5.5:

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

Po přidání zařízení je nutné kontejner restartovat:

lxc restart jupyterlab

Kontrola stavu kontejneru:

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

Instalace základního softwaru a nastavení systému ^

Chcete-li spravovat náš kontejner, musíte nainstalovat následující software:

Balíček
Popis

praštit
Shell GNU Bourne Again

bash-dokončení
Programovatelné dokončení pro bash shell

sudo
Dejte určitým uživatelům možnost spouštět některé příkazy jako root

stín
Sada nástrojů pro správu hesel a účtů s podporou stínových souborů a PAM

tzdata
Zdroje dat pro časové pásmo a letní čas

nano
Klon editoru Pico s vylepšeními

Kromě toho můžete nainstalovat podporu do systémových manuálových stránek instalací následujících balíčků − man man-pages mdocml-apropos less

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

Podívejme se na příkazy a klávesy, které jsme použili:

  • lxc — Zavolejte klienta LXD
  • exec - Metoda klienta LXD, která spouští příkaz v kontejneru
  • jupyterlab — ID kontejneru
  • -- - Speciální klíč, který určuje, že další klíče nebudou interpretovány jako klíče pro lxc a předejte zbytek provázku tak, jak je, do nádoby
  • apk — Správce distribučních balíčků Alpine Linux
  • add — Metoda správce balíčků, která instaluje balíčky zadané za příkazem

Dále v systému nastavíme časové pásmo Europe/Moscow:

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

Po instalaci časového pásma balíček tzdata již není v systému potřeba, bude zabírat místo, takže jej smažte:

lxc exec jupyterlab -- apk del tzdata

Kontrola časového pásma:

lxc exec jupyterlab -- date

Wed Apr 15 10:49:56 MSK 2020

Abychom nestrávili spoustu času nastavováním Bash pro nové uživatele v kontejneru, v následujících krocích do něj zkopírujeme hotové soubory skel z hostitelského systému. To vám umožní interaktivně upravit Bash v kontejneru. Můj hostitelský systém je Manjaro Linux a soubory, které se kopírují /etc/skel/.bash_profile, /etc/skel/.bashrc, /etc/skel/.dir_colors v zásadě jsou vhodné pro Alpine Linux a nezpůsobují kritické problémy, ale můžete mít jinou distribuci a musíte nezávisle zjistit, zda nedošlo k chybě při spuštění Bash v kontejneru.

Zkopírujte soubory Skel do kontejneru. Klíč --create-dirs vytvoří potřebné adresáře, pokud neexistují:

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

Pro stávajícího uživatele root zkopírujte soubory skel právě zkopírované do kontejneru do domovského adresáře:

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 nainstaluje uživatelům systémový shell /bin/sh, nahradíme jej root uživatel v Bash:

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

Že root uživatel nebyl bez hesla, potřebuje heslo nastavit. Následující příkaz mu vygeneruje a nastaví nové náhodné heslo, které po jeho provedení uvidíte na obrazovce konzole:

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

Vytvořme také nového uživatele systému - jupyter pro které budeme konfigurovat později jupyterová laboratoř:

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

Pojďme si pro něj vygenerovat a nastavit heslo:

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ále provedeme dva příkazy, první vytvoří systémovou skupinu sudoa druhý do něj přidá uživatele jupyter:

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

Podívejme se, do jakých skupin uživatel patří jupyter:

lxc exec jupyterlab -- id -Gn jupyter

jupyter sudo

Všechno je v pořádku, jedeme dál.

Povolit všechny uživatele, kteří jsou členy skupiny sudo použít příkaz sudo. Chcete-li to provést, spusťte následující skript, kde sed odkomentuje řádek parametrů v konfiguračním souboru /etc/sudoers:

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

Instalace a konfigurace JupyterLab ^

jupyterová laboratoř je aplikace Python, takže musíme nejprve nainstalovat tento interpret. Taky, jupyterová laboratoř nainstalujeme pomocí správce balíčků Pythonu pip, a ne ten systémový, protože může být v systémovém úložišti zastaralý, a proto pro něj musíme ručně vyřešit závislosti instalací následujících balíčků − python3 python3-dev gcc libc-dev zeromq-dev:

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

Pojďme aktualizovat moduly pythonu a správce balíčků pip na aktuální verzi:

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

Sada jupyterová laboratoř přes správce balíčků pip:

lxc exec jupyterlab -- python3 -m pip install jupyterlab

Od rozšíření v jupyterová laboratoř jsou experimentální a nejsou oficiálně dodávány s balíčkem jupyterlab, takže je musíme nainstalovat a nakonfigurovat ručně.

Nainstalujme NodeJS a pro něj správce balíčků - NPM, od jupyterová laboratoř používá je pro svá rozšíření:

lxc exec jupyterlab -- apk add nodejs npm

K rozšířením pro jupyterová laboratoř které nainstalujeme fungovaly, je potřeba je nainstalovat do uživatelského adresáře, protože se aplikace spouští od uživatele jupyter. Problém je v tom, že v příkazu launch není žádný parametr, který by bylo možné předat do adresáře, aplikace přijímá pouze proměnnou prostředí, a proto ji musíme definovat. K tomu napíšeme příkaz export proměnné JUPYTERLAB_DIR v uživatelském prostředí jupyter, do souboru .bashrckterý se provede pokaždé, když se uživatel přihlásí:

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

Další příkaz nainstaluje speciální rozšíření - správce rozšíření jupyterová laboratoř:

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

Nyní je vše připraveno k prvnímu spuštění jupyterová laboratoř, ale stále můžeme nainstalovat několik užitečných rozšíření:

  • toc — Obsah, generuje seznam nadpisů v článku/zápisníku
  • jupyterlab-horizon-theme — Téma uživatelského rozhraní
  • jupyterlab_neon_theme — Téma uživatelského rozhraní
  • jupyterlab-ubu-theme - Další téma od autora tento článek :) Ale v tomto případě se ukáže instalace z úložiště GitHub

Chcete-li nainstalovat tato rozšíření, spusťte postupně následující příkazy:

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"

Po instalaci rozšíření je musíme zkompilovat, protože dříve jsme při instalaci specifikovali klíč --no-build ušetřit čas. Nyní výrazně urychlíme tím, že je sestavíme najednou:

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

Nyní spusťte následující dva příkazy, abyste jej spustili poprvé jupyterová laboratoř. Bylo by možné jej spustit jedním příkazem, ale v tomto případě si příkaz ke spuštění, který si v duchu těžko pamatujete, zapamatuje bash v kontejneru a ne na hostiteli, kde je již příkazů dostatek zapsat je do historie :)

Přihlaste se do kontejneru jako uživatel jupyter:

lxc exec jupyterlab -- su -l jupyter

Dále běž jupyterová laboratoř s klíči a parametry, jak je uvedeno:

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

Přejděte na adresu ve webovém prohlížeči http://10.0.5.5:8888 a na stránce, která se otevře, zadejte známka přístup, který uvidíte v konzole. Zkopírujte a vložte jej na stránku a poté klikněte Přihlášení. Po přihlášení přejděte do nabídky rozšíření vlevo, jak je znázorněno na obrázku níže, kde budete při aktivaci správce rozšíření vyzváni k přijetí bezpečnostních rizik instalací rozšíření od třetích stran, pro které je příkaz Vývoj JupyterLab není odpovědný:

Vypuštění Jupyteru na oběžnou dráhu LXD

Celé to však izolujeme jupyterová laboratoř a umístěte jej do kontejneru, aby rozšíření třetích stran, která vyžadují a používají NodeJS, nemohla alespoň ukrást data na disku jiná než ta, která otevřeme uvnitř kontejneru. Získejte své soukromé dokumenty na hostiteli v /home procesy z kontejneru pravděpodobně neuspějí, a pokud ano, pak musíte mít oprávnění k souborům v hostitelském systému, protože kontejner spouštíme v neprivilegovaný režim. Na základě těchto informací můžete posoudit riziko zahrnutí rozšíření do jupyterová laboratoř.

Vytvořené notebooky IPython (stránky v jupyterová laboratoř) bude nyní vytvořen v domovském adresáři uživatele - /home/jupyter, ale naše plány jsou rozdělit data (sdílet) mezi hostitele a kontejner, takže se vraťte do konzole a zastavte jupyterová laboratoř spuštěním klávesové zkratky - CTRL+C a odpovídání y na požádání. Poté ukončete interaktivní relaci uživatele jupyter dokončení horké klávesy CTRL+D.

Sdílení dat s hostitelem ^

Chcete-li sdílet data s hostitelem, musíte v kontejneru vytvořit zařízení, které vám to umožní, a za tímto účelem spusťte následující příkaz, kde zadáme následující klíče:

  • lxc config device add — Příkaz přidá konfiguraci zařízení
  • jupyter — ID kontejneru, do kterého je konfigurace přidána
  • hostfs - ID zařízení. Můžete nastavit libovolný název.
  • disk — Je uveden typ zařízení
  • path — Určuje cestu v kontejneru, ke kterému LXD připojí toto zařízení
  • source — Zadejte zdroj, cestu k adresáři na hostiteli, který chcete sdílet s kontejnerem. Určete cestu podle svých preferencí
lxc config device add jupyterlab hostfs disk path=/mnt/hostfs source=/home/dv/projects/ipython-notebooks

Pro katalog /home/dv/projects/ipython-notebooks oprávnění musí být nastaveno na uživatele kontejneru, který má aktuálně UID rovné SubUID + UID, viz kapitola Bezpečnost. Kontejnerová privilegia v článku Základní vlastnosti kontejnerových systémů LXD - Linux.

Nastavte oprávnění na hostiteli, kde vlastníkem bude uživatel kontejneru jupytera proměnná $USER určí vašeho hostitele jako skupinu:

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

Ahoj světe! ^

Pokud máte stále otevřenou relaci konzoly v kontejneru s jupyterová laboratořa poté jej restartujte s novým klíčem --notebook-dir nastavením hodnoty /mnt/hostfs jako cesta ke kořenovému adresáři notebooků v kontejneru pro zařízení, které jsme vytvořili v předchozím kroku:

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

Poté přejděte na stránku http://10.0.5.5:8888 a vytvořte si svůj první notebook kliknutím na tlačítko na stránce, jak je znázorněno na obrázku níže:

Vypuštění Jupyteru na oběžnou dráhu LXD

Poté do pole na stránce zadejte kód Pythonu, který zobrazí klasiku Hello World!. Po dokončení zadávání stiskněte CTRL+ENTER nebo tlačítko „přehrát“ na panelu nástrojů v horní části, aby JupyterLab provedl toto:

Vypuštění Jupyteru na oběžnou dráhu LXD

V tuto chvíli je téměř vše připraveno k použití, ale nebude zajímavé, pokud nebudeme instalovat další moduly Pythonu (plnohodnotné aplikace), které mohou výrazně rozšířit standardní možnosti Pythonu v jupyterová laboratoř, takže jdeme dál :)

PS Zajímavé je, že stará implementace jupyter pod kódovým jménem Jupyter Notebook nezmizelo a existuje paralelně s jupyterová laboratoř. Chcete-li přejít na starou verzi, klikněte na odkaz přidáním přípony do adresy/tree, a přechod na novou verzi se provede s příponou /lab, ale nemusí být specifikováno:

Rozšíření možností Pythonu ^

V této sekci nainstalujeme tak výkonné moduly jazyka Python jako nemotorný, Pandy, matplotlib, IPyWidgets jehož výsledky jsou integrovány do notebooků jupyterová laboratoř.

Před instalací uvedených modulů Pythonu prostřednictvím správce balíčků pip nejprve musíme vyřešit systémové závislosti v Alpine Linux:

  • g++ — Potřebné pro kompilaci modulů, protože některé z nich jsou implementovány v jazyce C + + a připojit se k Pythonu za běhu jako binární moduly
  • freetype-dev - závislost na modulu Python matplotlib

Instalace závislostí:

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

Je tu jeden problém: v současném stavu distribuce Alpine Linux nebude možné zkompilovat novou verzi NumPy, objeví se chyba kompilace, kterou jsem nedokázal vyřešit:

CHYBA: Nelze vytvořit kola pro numpy, která používají PEP 517 a nelze je nainstalovat přímo

Proto nainstalujeme tento modul jako systémový balíček, který distribuuje již zkompilovanou verzi, ale o něco starší, než je aktuálně dostupná na webu:

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

Dále nainstalujte moduly Pythonu prostřednictvím správce balíčků pip. Buďte prosím trpěliví, protože některé moduly se zkompilují a může to trvat několik minut. Na mém počítači trvala kompilace ~15 minut:

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

Vymazání mezipaměti instalace:

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

Testování modulů v JupyterLab ^

Pokud běžíte jupyterová laboratoř, restartujte jej, aby se aktivovaly nově nainstalované moduly. Chcete-li to provést, v relaci konzoly klepněte na CTRL+C kde to máte spuštěné a vstupte y pro zastavení požadavku a následné spuštění znovu jupyterová laboratoř stisknutím šipky nahoru na klávesnici, aby se příkaz nezadával znovu a pak Enter pro spuštění:

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

Přejít na stránku http://10.0.5.5:8888/lab nebo obnovte stránku v prohlížeči a poté zadejte následující kód do nové buňky poznámkového bloku:

%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

Měli byste získat výsledek jako na obrázku níže, kde IPyWidgets vygeneruje prvek uživatelského rozhraní na stránce, který interaktivně interaguje se zdrojovým kódem, a také matplotlib zobrazí výsledek kódu ve formě obrázku jako funkčního grafu:

Vypuštění Jupyteru na oběžnou dráhu LXD

Mnoho příkladů IPyWidgets najdete to v tutoriálech zde

Co jiného? ^

Dobře, pokud jste zůstali a dostali se až na konec článku. Schválně jsem na konec článku nedal hotový skript, který by se nainstaloval jupyterová laboratoř jedním kliknutím povzbudíte pracovníky :) Ale můžete to udělat sami, protože už víte jak, po shromáždění příkazů do jediného Bash skriptu :)

Můžete také:

  • Nastavte síťový název kontejneru místo IP adresy tak, že jej jednoduše zapíšete /etc/hosts a zadejte adresu do prohlížeče http://jupyter.local:8888
  • Pohrajte si s limitem zdrojů pro kontejner, k tomu si přečtěte kapitolu základní schopnosti LXD nebo získat více informací na vývojářských stránkách LXD.
  • Změňte téma:

Vypuštění Jupyteru na oběžnou dráhu LXD

A mnohem víc můžete udělat! To je vše. Přeji ti úspěch!

AKTUALIZACE: 15.04.2020 18:30 - Opraveny chyby v kapitole „Ahoj, světe!“
AKTUALIZACE: 16.04.2020/10/00 XNUMX:XNUMX — Opraven a doplněn text v popisu aktivace správce rozšíření jupyterová laboratoř
AKTUALIZACE: 16.04.2020/10/40 XNUMX:XNUMX — Opraveny chyby nalezené v textu a mírně změněny k lepšímu v kapitole „Instalace základního softwaru a nastavení systému“

Zdroj: www.habr.com

Přidat komentář