Skapa en container – varken svårt eller magiskt

av | Jun 19, 2017

Lars Åslin är konsult på Purple Scout, i den här artikeln visar han hur du hyfsat enkelt kan komma igång med namespaces. För det är ju fiffigt att kunna installera program trots att du sitter och jobbar i en kooperativ miljö (där du egentligen inte kan installera program).

Bygg ditt eget containerformat

Olika containerlösningar som Docker, rkt eller lxc-containers har blivit ett allt vanligare inslag i paketeringen av mjukvarulösningar. Det har fört med sig mycket gott men också en utmaning i form av en ny teknisk domän som måste bemästras. För att få en inblick i hur en container fungerar ska vi därför i denna artikel ge oss på att bygga en från grunden.

Innan vi börjar behöver vi skaffa oss ett rotfilsystem med en Linux-distribution. Det kan vi göra med följande kommando:

 

Okej, så vad är en container? Det korta svaret är Namespaces. En container är i grunden inget annat än en process som med hjälp av Namespaces är försatt i en isolerad miljö. Namespaces är en funktion i Linux-kerneln och sedan kernel 4.10 finns det sju olika typer av namespaces (pid, user, mount, net, uts, ipc, cgroup). Till exempel kan vi starta en process i ett eget nätverks-namespace och på så sätt ge processen en egen nästverkstack, skild från värdsystemets. Processen kan då definiera sina egna nätverksinterface, ha en egen route-tabell etc.

 För att starta en bash-process i ett eget namespace kör vi följande kommando:

 Eller om vi är lata skriver vi:

Här skapar vi en ny bash-process med ett eget namespace för user, mount, uts, net, ipc, pid, cgroup. Utöver det säger vi att vi vill mappa vår nuvarande användare till det nya user-namespacets root-användare, samt att vi vill att vår process (bash) ska forkas till en ny process. Det innebär att vår process kommer bli den första processen i vårt nya pid-namespace.

Nu har vi en isolerad process men den har fortfarande samma filsystem som värden. Det här vill vi ändra på så att vi kan köra på ett filsystem med vårt eget val av linux-distribution. Detta kan vi enkelt åstadkomma i och med att vi nu befinner oss i ett eget mount-namespace. När ett nytt mount-namespace skapas så får vi en klon av värdens namespace, men alla ändringar vi gör kommer bara återspeglas i vårt namespace. Således kan vi montera ett nytt rotfilsystem för våran container utan att förstöra något på värden. Till detta ändamål använder vi pivot_root.

pivot_root är en funktion för att peka om rotfilsystemet för en anropade process. Dess typiska användning är under boot-processen av linux då initrd används som ett temporärt rotfilsystem tills drivrutinerna för hårddisken är på plats och det riktiga rotfilsystemet kan monteras. Vi kommer använda det på ett liknande sätt för att byta vårt nuvarande rotfilsystem mot alpine_rootfs som vi förberedde tidigare.

Men innan vi kan köra pivot_root behöver vi göra några ytterligare förberedelser:

Innan vi kör pivot_root så behöver vi se till att sökvägarna för alpine-binärerna finns bland våra miljövariabler:

 Då är vi redo att göra bytet:

Nu har vi en isolerad process som i mångt och mycket kan likställas med en container. Det här är givetvis bara ett skrap på ytan och det finns många fler problem att lösa innan du har en fullvärdig lösning. Men mer magiskt än så behöver det faktiskt inte vara. Härifrån skulle du tekniskt sett kunna bygga ditt eget container-format. Lycka till.

Pin It on Pinterest