===== Docker - wprowadzenie ===== ==== Ważne informacje ==== **//Nie wolno restartować maszyn//**\\ \\ Tematy ćwiczeń napisane //KURSYWĄ// są zrealizowane i proszę ich nie realizować. ==== Terminologia ==== **Klient dockera** - polecenie docker używane do kontrolowania środowiska dockera oraz komunikacji ze zdalnymi serwerami dockera.\\ **Serwer dockera** - polecenie docker uruchomione w trybie daemona. Zamienia serwer linuksowy w serwer dokera na którym można uruchamiać, budować i wyłączać kontenery za pomocą zdalnego klienta.\\ **Obrazy dockera** - obrazy zawierające jedną lub więcej abstrakcyjnych warstw filesystemu oraz istotne metadane reprezentujące wszystkie pliki niezbędne do uruchomienia aplikacji w kontenerze. Pojedynczy obraz może być kopiowany na inne hosty. Obraz z reguły posiada nazwę i tag, tag jest używany głównie do identyfikacji wydania obrazu.\\ **Kontener dockera** - jest to linuksowy kontener zainicjowany z konkretnego obrazu. Konkretny kontener może istnieć tylko raz, jednak można łatwo stworzyć wiele kontenerów z tego samego obrazu. ==== Wymagania ==== * Linux kernel w wersji nowszej niż 3.8 * Aplikacja musi działąć a FOREGROUNDZIE, nie może być demonizowana (można uruchamiać aplikacje jako daemony za pomocą systemd, ale to nie jest przedmiotem laboratoriów) ==== Instalacja ==== Instalacja za pomocą mamangera pakietów: apt-get install apt-transport-https ca-certificates curl iptables następnie: curl -sSL https://get.docker.com/ | sh Włączanie usługi dockera wraz ze startem systemu: systemctl enable docker Aby nie musieć korzystać z **sudo** za każdym razem warto dodać się też do grupy **docker** ==== Dockerfile ==== Aby zbudować obraz niezbędny jest poprawny **Dockerfile**, który opisuje każdą z warstw abstrakcji oraz metadane, które znajdą się w wyjściowym obrazie.\\ Typowy **Dockerfile** dla aplikacji **nodejs** może wyglądać tak: FROM node:0.10 MAINTAINER Jan Kowalski LABEL "ocena"="5 gwiazdek" "klasa"="pierwsza" USER root ENV AP /data/app ENV SCPATH /etc/supervisor/conf.d RUN apt -y update RUN apt -y install supervisor RUN mkdir -p /var/log/supervisor ADD .supervisor/conf.d/* $SCPATH ADD *.js* $AP/ WORKDIR $AP RUN npm install CMD ["supervisord", "-n"] Każda z linii nakłada na obraz kolejną warstwę abstrakcji, dobrą praktyką jest zaczynać od najniższego poziomu jako od systemu, gdyż w przypadku zmian, np ścieżki w zmiennej AP, budowa nowego obrazu rozpocznie się od zmienionej linii, wszystkie wcześniejsze zostaną pominięte, co zaoszczędzi czasu przy budowaniu.\\ Poniżej wyjaśnię anatomię pliku **Dockerfile** na powyższym przykładzie.\\ * **FROM node:0.10** - oznacza, że nasz obraz będzie budowany na podstawie obrazu node w wersji 0.10.X, by zablokować do konkretnej wersji trzeba ją uściślić, np.: node:0.10.33. * **MAINTAINER Jan Kowalski ** - pozwala dodać kontakt do autora, propaguje autora również w metadanych wszystkich tworzonych obrazów. * **LABEL "ocena"="5 gwiazdek" "klasa"="pierwsza"** - ta funkcjonalność istnieje od dockera 1.6, pozwala dodawać metadane w formie klucz=wartość, można na ich podstawie potem wyszukiwać i identyfikować kontenery * **USER root** - domyślnie docker uruchamia wszystkie procesy w kontenerze jako root, za pomocą USER można to zmienić (ze względóœ bezpieczeństwa nie polecam produkcyjnie uruchamiać konteneróœ z procesami roota, przypominam, że pomimo izolacji, nadal korzystamy z jądra gospodarza) * **ENV AP /data/app** - zmienna, które mogą być użyte podczas budowy obrazu * **ENV SCPATH /etc/supervisor/conf.d** - zmienna, które mogą być użyte podczas budowy obrazu * **RUN apt -y update** - polecenie RUN uruchamia jakąś instrukcję podczas budowy obrazu, np żeby zainstalować określone oprogramowanie czy zapewnić zależności. * **RUN apt -y install supervisor** - polecenie RUN uruchamia jakąś instrukcję podczas budowy obrazu, np żeby zainstalować określone oprogramowanie czy zapewnić zależności. * **RUN mkdir -p /var/log/supervisor** - polecenie RUN uruchamia jakąś instrukcję podczas budowy obrazu, np żeby zainstalować określone oprogramowanie czy zapewnić zależności. * **ADD .supervisor/conf.d/* $SCPATH\\ ADD *.js* $AP/** - ADD kopiuje pliki z lokalnego systemu do obrazu * **WORKDIR $AP\\ RUN npm install** - WORKDIR zmienia aktualny katalog w jakim pracuje podczas budowania obrazu dla kolejnych instrukcji * **CMD ["supervisord", "-n"]** - CMD definiuje polecenie uruchamiane razem kontenerem (właściwą aplikację) Każda kolejna linia Dockerfile i każdy krok tworzy nową warstwę, która zależy od poprzedniej! ====Budowanie obrazu==== Obrazy dockera budujemy za pomocą polecenia uruchamianego w katalogu z **Dockerfile**: docker build -t example/docker-node-hello:latest . ====Przykład==== ==== Ćwiczenia do wykonania na localhost ==== * //Zrób update systemu// apt update && apt upgrade * //Zainstaluj docker-engine// Obecnie apt-get install apt-transport-https ca-certificates curl iptables następnie: curl -sSL https://get.docker.com/ | sh Dawniej apt install docker.io * //Ustaw MTU na wartość 1454, aby tego dokonać należy dodać// --mtu=1454 //do obecnych// OPTIONS //w pliku// /etc/default/docker * //Ustaw autostart usługi docker// systemctl enable docker * //Uruchom usługę docker// systemctl start docker * **Zweryfikuj instalację dockera przez uruchomienie kontenera hello-world** docker run hello_world * //Zrestartuj hosta gospodarza// * //Zweryfikuj status usługi docker przez uruchomienie kontenera hello-world jeszcze raz// * //Zweryfikuj wartość MTU na interfejsie **docker0**// ip address show dev docker0 \\ \\ **Proszę odinstalować dockera na końcu laboratoriów** ==== Treść laboratorium ==== \\ \\ **Dockerfile** proszę zakładać w katalogu domowym użytkownika **student** lub jego podkatalogach\\ \\ \\ **Ćwiczenia proszę wykonywać dalej na localhost**\\ \\ === Ćwiczenie 1 === * Przygotuj **Dockerfile**, który zainstaluje httpd na oficjalnym obrazie Centos 6 * Dodaj pole **maintainer** * Zbuduj obraz z o nazwie **laborki** * Uruchom kontener w trybie interaktywnym -ti * Uruchom konener w tle -d * Sprawdź czy kontener jest uruchomiony docker ps * Sprawdź czy w kontenerze **jest zainstalowany httpd** * Sprawdź czy obraz ma około **261MB** === Ćwiczenie 2 === * Zmodyfikuj wcześniejszy **Dockerfile** tak, aby startował **httpd** (httpd ma być uruchomiony w **FOREGROUNDZIE, nie jako daemon!**) * przebuduj obraz * sprawdź czy kontener działa * sprawdź czy httpd działa === Ćwiczenie 3 === * Przygotuj index.html z wiadomością powitalną * Zmodyfikuj poprzedniego **Dockerfile** i dodaj plik index.html do obrazu w ścieżce: /var/www/html/index.html * przebuduj obraz * uruchom kontener z upublicznionym portem 80 * odwiedź stronę powitalną === Ćwiczenie 4 === * załóż konto na **docker.io** * zaloguj się do docker.io docker login * wyeksportuj docker push obraz (musi nazywać się jak użytkownik, czyli jeśli konto to **jkowalski**, to obraz powinien nazywać się: **jkowalski/nazwa_obrazu:tag**) - jeśli trzeba, przebuduj obraz do poprawnej nazwy * Ściągnij obraz grupy po lewej docker run -d nazwa_uzytkownika/nazwa_obrazu * uruchom kontener z tego obrazu * odwiedź stronę powitalną === Ćwiczenie 5 === * Proszę stworzyć plik **dockerfile** opisujący maszynę partą o system Centos w wersji 7. System ten ma mieć dodanych 2 użytkowników systemowych **jan** oraz **kinga**, każdy z nich ma mieć ustawione hasło: **DockerLab** * Użytkownicy dodane przez Państwa mają należeć do grup **users** oraz **sudo**. * Proszę zainstalować sudo i zmodyfikować plik sudoers tak, aby sudo działało dla grupy sudo. * Proszę zbudować i uruchomić obraz, zweryfikuj, że wszystko działa poprawnie oraz członkostwo użytkowników. === Ćwiczenie 6 === * Proszę uruchomić kontener dockera zawierający **bazę MySQL** w wersji 5.7 z nazwą: **mysql-container**, zostanie ona wykorzystana w późniejszych zadaniach. === Ćwiczenie 7 === * Proszę stworzyć i uruchomić kontener w którym zainstalują i uruchomią Państwo forum oparte o skrypt **flarum** (http://flarum.org/ zainstalowany za pomocą **composera**), jako bazę proszę wykorzystać kontener **mysql-container**. System dowolny. * Proszę przekierować port 8080 na port 80 kontenera z flarum. === Ćwiczenie 8 === * Proszę uruchomić kontener z wordpressem (zmapować port 8081), jako bazę wykorzystać kontener **mysql-container**