===== 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**