Po co to?Nr 1 W grudniu 2020 roku zrobiłem webinar na temat Kubernetes i Dockera. Postanowiłem zrobić podobny poradnik dla początkującego tylko w formie tekstowej. Poza tym bądźmy szczerzy kopiowanie komend z filmu nie jest ciekawym doświadczeniem.
Technika idzie bardzo szybko. Już w Visual Studio 2019 mając zainstalowany .NET 5 możesz jawnie tworzyć projekty ASP.NET CORE, które domyślnie łączą się z Dockerem i debugować przy jego użyciu aplikację.
Wszystko fajnie pięknie tylko : Co to jest Docker i Co jest Kubernetes ? Do czego to służy ?
W praktyce jako programista któregoś dnia przychodzi do Ciebie admin i mówi, że od tej pory robimy aplikacje w Kubernetes i każe Ci zrobić konfigurację w taki sposób, aby Kubernetes to widział.
A powiesz mi jak?
No cóż, bądźmy szczery firma oczekuje od Ciebie, że ty to już wszystko wiesz i nie ma czasu na szkolenia i kursy dla Ciebie.
Potem oglądasz jakiś tutorial na YouTube i myślisz sobie, że jeśli jeszcze raz będziesz musiał słuchać coś na temat historii Kubernetes, k8s i dlaczego coś tam o Borgach i kotwicach to Ciebie krew zaleje.
Jak więc nauczyć się jak najszybciej podstaw, tak abyś mógł z dumą powiedzieć, że rozumiesz Kubernetes i Dockera na tyle aby się tym chwalić albo wpisać to w CV
Idealny programista w końcu musisz rozumieć proces wdrażania aplikacji.
Wielki skrót
Na początku masz swoją aplikację. Może ona być napisana w C#, Javie, Go, w Pythonie. Nie ma to znaczenia.
Jak wiesz każda technologia, język programowania wymaga swojego środowiska uruchomieniowego. Dla C# jest to .NET. Dla Javy jest to JDK.
Warto także pamiętać, że aplikacja potrzebuje też kontekstu, w jakim systemie operacyjnym się uruchamia. Może to być Linux, dlaczego nie.
Ostatecznie te wszystkie informacje, które są potrzebne do uruchomienia twojego kodu są pakowane do obrazu. Docker takie obrazy potrafi tworzyć, chociaż warto zaznaczyć, że istnieje wiele innych programów, które potrafią także tworzyć obrazy.
Mając obraz swojej aplikacji możesz go później go uruchamiać na każdym komputerze, nawet jeśli system operacyjny jest inny i nawet gdy nie ma na nim odpowiedniego środowiska uruchomieniowego.
Jak sobie uświadamiasz jest to spełnienie marzeń dla administratorów, którzy muszą konfigurować każde środowiska na komputerach.
A gdzie w tym wszystkim jest Kubernetes? Masz więc obrazy swoich aplikacji. Przydałby Ci się jakiś bardzo zaawansowany orkiestrator, który by tymi obrazami wszystkim sterował.
Co potrafi na przykład Kubernetes? Może tworzyć repliki twoich aplikacji. Może zarządzać połączeniami sieciowymi do twoich aplikacji. Gdy jakaś aplikacja będzie chora to ją uśmierci i stworzy automatycznie nową instancję twojej aplikacji.
Dodatkowo Kubernetes ma gotowy system sekretów i obsługi plików konfiguracyjnych.
W przyszłości Kubernetes nie będzie korzystał już Dockera. Na szczęście filozofia się nie zmienia więc Kubernetes będzie zarządzał każdym obrazem niezależnie jak on został utworzony.
Jak więc praca wygląda, jeśli mówimy tylko o Docker ?
- Docker utworzy obraz twojej aplikacji na podstawie pliku "dockerfile"
- Docker potem uruchamia obraz i teraz "to" nazywamy kontenerem
Jak więc praca wygląda, jeśli mówimy Kubernetes ?
- Korzystasz z Dockera lub czegoś innego, aby utworzyć obraz
- Ten obraz potem jest umieszczony w abstrakcyjnych jednostkach jak :
- Pod który może zawierać 1 lub więcej obrazów / kontenerów
- Deployment, który może zawierać repliki Pod-ów
- Serwisy, który komunikują się z wybranymi Deploymentami
- To przykładowy schemat tego, co może zawierać się w czym. Ty możesz zrobić to innaczej
- Sterujesz tym obrazem/kontenerem. O czym napiszę później
Podsumowując. Docker tworzy obraz. A uruchomionym obraz nazywamy kontenerem.
Chociaż czytając wiele tutorial więc, że obie definicję są używane zamienię.
Warto też zaznaczyć, że Kubernetes potrafi także uruchamiać wirtualne maszyny. Nie wszystko musi być kontenerem.
Po co to ?
Jeśli chodzi o Kubernetes to jego zalety najbardziej widać w chmurze. Możesz w końcu zainstalować w chmurze system operacyjny jak Windows czy Linus i na tym systemie operacyjnym wyodrębniać procesy i zasoby.
Możesz też w chmurze Amazon, Azure, Google zainstalować Kubernetes i w taki sposób wyodrębniać zasoby do mikroserwisów i natywnych aplikacji chmurowych.
Zmienia to także podejście do tworzenia infrastruktury. Infrastruktura zawsze była problemem programisty, ale wcześniej mogłeś to zwalić na adminów i architektów.
O samej infrastrukturze można zrobić oddzielny wpis. O czym teraz warto pamiętać. O tym, że jedna aplikacja powinna robić jedną rzecz. Stworzyć tak aplikację, aby można było ją skalować horyzontalnie w zależności od odpowiedzialności.
A jakie mamy zalety kontenerów / obrazów, bo już trochę poruszyłem tą kwestie.
Skoro obrazy twojej aplikacji można przenosić do każdego komputera bez problemu to zalety pojawia się same.
Przyspiesza to pracę między zespołami. Eliminuje to konflikty na środowiskach. Wszystkie środowiska dla danej aplikacji są spójne skoro są zawarte one w obrazie. Czyli już nikt Ci nie powie, że działa coś tylko na jego maszynie.
Dzięki temu szybciej dostarczysz aplikację i zrobisz wdrożenie.
Inne zalety kontenerów są następujące :
- Przenośność
- Łatwo jest przekazać obraz dalej
- Wyizolowany
- Inne aplikacje nie mają wpływu na twoją
- Stały
- Raz utworzony obraz magicznie się nie zmieni
- Lekki
- Kontener waży mniej niż maszyna wirtualna
Podsumowując to wszystko w dwóch zdaniach :
"Zbuduj raz. Zrób deploy wszędzie"
Kontener kontra maszyna wirtualna
Maszyny wirtualne szybko nie zniknął. Maszyna wirtualna automatycznie nie jest gorsza też od kontenera. Jak to mówią to zależy.
Jeśli masz aplikację legacy to prawdopobnie najlepiej jest ją umieścić w maszynie wirtualnej. Jeśli twoja aplikacja ma skomplikowaną konfigurację lub musi być bardzo dobrze zabezpieczona to lepiej jest ją umieścić w maszynie wirtualnej.
Pamiętaj do maszyny wirtualnej możesz się zalogować jak do normalnego systemu operacyjnego.
Jak to jednak możliwe, że kontener zajmuje mniej miejsca.
https://blog.netapp.com/blogs/containers-vs-vms
W kontenerze informację o systemie operacyjnym, jak i o środowisku uruchomieniowym są pobierane z jedno źródła.
Maszyna wirtualna może mieć wiele systemów operacyjnych i środowisk w sobie.
Najlepiej użyć takiej metafory aby to wyjaśnić.
Maszyna wirtualna jest jak dom gdzie prąd, woda, ogrzewanie dochodzi z jednego źródła. Każdy dom ma swoje 1 źródło tych zasobów.
Kontener jest jak mieszkanie w bloku gdzie prąd,woda, ogrzewanie jest współdzielone pomiędzy innymi mieszkaniami w bloku.
Esencji to sprawia, że kontener waży mniej niż maszyna wirtualna.
Przypadki użycia
Wróćmy do kwesti po co to wszystko raz jeszcze. Jakie przypadki użycia będzie mógł zrobić korzystając z Dockera i Kubernetesa :
- Emulowanie produkcji
- Stworzenie środowiska na Testy end-to-end
- Sekrety/Konfiguracje gotowe mechanizmy
- Pewność, że aplikacja skaluje się poprawnie
- Tworzenie testów wydajnościowych
- Pomoc dla adminów, aby programiści stali się DEV-OPS
- Ciekawe strategie wdrażania aplikacji
- Migracja do chmury
- Scenariusze CI/CD
Docker i Kubernetes, czyli polityka
Obie firmy się nie lubią. Była bitwa pomiędzy Docker Swarm, a Kubernetes w 2016-2017 roku.
Bitwę o orkiestrator obrazów wygrał Kubernetes.
Kubernetes w grudniu 2020 roku stwierdził, że chce się pozbyć Dockershizm.
Powodem tego jest nie tylko fakt, że obie firmy się nie lubią, ale także fakt, że Kubernetes słusznie stwierdził, że Docker jest za ciężki, aby był on częścią Kubernetes.
W czerwonym kwadracie widzisz funkcje, z który korzysta Kubernetes w Docker.
Docker też nie został stworzony z myślą, aby działał wewnątrz Kubernetes. Po prostu obie popularne technologie przypadkiem zostały łączone ze sobą.
Dobra wiadomość jest taka, że obrazy utworzone w Docker nadal będą działać w Kubernetes.
Jednakże warto poszukać czegoś co jest kompatybilne z Container Runtime Interface. Zwłaszcza jeśli mówimy o środowiskach produkcyjnych, a nie o aplikacjach "hello world" do nauki Dockera i Kubernetes.
Jakie mamy alternatywy do Dockera, jeśli chodzi o obsługę obrazów:
- ContainerD
- Cri-o
- crun
Jakie mamy alternatywy do Dockera, jeśli chodzi o budowanie obrazów:
- Buildah
Jako początkujący nie musisz się tym przejmować. Filozofia tworzenia obrazów i uruchamiania się nie zmieni. Ta wiedza nigdy nie będzie utracona.
W chwili pisania tego wpisu nie jestem w stanie przewidzieć jaka technologia zastąpi Dockera. Docker był przez lata kojarzony z kontenerami więc jego dominacja nie zniknie z dnia na dzień.
Co trzeba mieć, aby zainstalować Dockera z Kubernetes na swojej maszynie
W przypadku Windows musiałem rozszerzyć swoją wersję Windows z Home do Professional. Zakupiłem klucz z Allegro, żeby nie wydać za dużo pieniędzy na ten awans.
Mając Windows Professional mogłem zainstalować Hyper-V. Możesz grzebać w Aplikację i funkcje -> Pogramy i Funkcje -> Włącz lub wyłącz funkcje systemu Windows -> Hyper-V.
Możesz też wpisać komendę w PowerShell
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
Mając Hyper-V w końcu możesz zainstalować Dockera.
W samym Docker w ustawieniach zaznacz opcję : Enable Kubernetes i tak możesz zacząć swoją przygodę z tymi technologiami.
Na koniec w wierszu poleceń wpisz :
kubectl version
Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.0",
GitCommit:"af46c47ce925f4c4ad5cc8d1fca46c7b77d13b38", GitTreeState:"clean",
BuildDate:"2020-12-08T17:59:43Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"windows/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.3",
GitCommit:"1e11e4a2108024935ecfcb2912226cedeafd99df", GitTreeState:"clean",
BuildDate:"2020-10-14T12:41:49Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
Aby sprawdzić czy wszystko zainstalowało się poprawnie.
Co warto zainstalować do Visual Studio Code?
Dodatek : Kubernetes, który daje podpowiedzi przy tworzeniu plików YAML
Dodatek : YAML, który doda obsługę tych plików
Na koniec tego wpisu stworzymy statyczną stronę na serwerze APACHE
Chce stworzyć obraz / kontener z moją statyczną stroną internetową :
Mój genialny projekt składa się z 3 plików.
Aby utworzyć obraz Docker będę potrzebował pliku dockerfile tutaj
Jak Visual Studio rozpoznaje ten plik i dodał do niego ikonkę wieloryba. Do pliku dockerfile dodałem następujący kod.
FROM httpd:2.4
COPY ./index.html /usr/local/apache2/htdocs/index.html
COPY ./bakcground.jpg /usr/local/apache2/htdocs/bakcground.jpg
COPY ./wordart.png /usr/local/apache2/htdocs/wordart.png
Pierwsze wyrażenie FROM odnosi do bazowego obrazu z repozytorium Dockera. Ten obraz bazowy zawiera w sobie środowisko serwera HTTP Apache.
Jak się domyślasz mógłbym na nim uruchomić stronę napisaną w PHP lub w Javie. Ja tutaj robię prosty projekt ze statycznymi plikami.
Wyrażenia COPY kopiują pliki z jednego miejsca na drugie.
Warto zaznaczyć, że każde polecenie w Docker dzieli potem budowanie obrazu na poszczególne fazy, które są potem zapamiętywane, aby następne budowanie obrazu było szybsze.
Nie ma sensu kopiować każdy plik oddzielnie. Dlatego ten kod dockerfile można poprawić tak :
FROM httpd:2.4
COPY ./* /usr/local/apache2/htdocs/
Pozostało nam skorzystać z wiersza poleceń i utworzyć ten obraz. Wpisując "docker" do wiersza poleceń możesz zobaczyć ile poleceń ono ma :
PanNiebieski@CEZMSI [10:47]
docker
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default
"C:\\Users\\PanNiebieski\\.docker")
-c, --context string Name of the context to use to connect to the
daemon (overrides DOCKER_HOST env var and
default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level
("debug"|"info"|"warn"|"error"|"fatal")
(default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default
"C:\\Users\\PanNiebieski\\.docker\\ca.pem")
--tlscert string Path to TLS certificate file (default
"C:\\Users\\PanNiebieski\\.docker\\cert.pem")
--tlskey string Path to TLS key file (default
"C:\\Users\\PanNiebieski\\.docker\\key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
app* Docker App (Docker Inc., v0.9.1-beta3)
builder Manage builds
buildx* Build with BuildKit (Docker Inc., v0.4.2-docker)
config Manage Docker configs
container Manage containers
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
scan* Docker Scan (Docker Inc., v0.5.0)
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Run 'docker COMMAND --help' for more information on a command.
To get more help with docker, check out guides at https://docs.docker.com/go/guides/
Wpisując "docker images" możesz zobaczyć ile obrazów obecnie masz w swoim dockerze.
Powinieneś zobaczyć wszystkie obrazy pomocnicze, które zostały utworzone przez Dockera albo Kubernetes.
Jak więc zbudować obraz. W wierszu poleceń wchodzisz na ścieżkę swojego projektu i wpisujesz :
docker build -t mojblog:mojtag .
W taki sposób właśnie utworzyłeś swój pierwszy obraz Docker. Parametrem -t określiłeś nazwę swojego obrazu oraz jego tag. Kropka na końcu polecenia określa ścieżkę, w której dockerfile się znajduje. Jeśli docker file jest w tym samym katalogu to wpisujesz kropkę.
Teraz jak ten obraz uruchomić
docker run --name my-running-app -p 8080:80 mojblog:mojtag
--name określa nazwę naszego kontenera , w którym będzie działa nasza aplikacja. Nazwa nie jest wymagana Docker może dodać swoją losową nazwę.
-p : określa przejście portów. Domyślnie aplikacja serwera APACHE uruchomi się na porcie 80 więc robię przekierowanie na port 8080.
Na koniec polecenia muszę określić jaki obraz chce uruchomić.
W UI Dockera możesz zobaczyć, że faktycznie taki kontener. Samą stronę możesz uruchomić pod adresem localhost:8080
Jak zatrzymać tą aplikację?
docker container kill my-running-app
Kontener można uruchomić, ale my tego nie zrobimy.
Jak usunąć kontener?
docker container rm my-running-app
rm : jest trochę nie intuicyjnie i nie powiem wołałbym polecenie "delete"
Podsumowanie
Swoją drogą używanie Dockera/Kubernetes do plików statycznych to idiotyzm.
Co warto konteryzować?
- Pliki ".exe" do zadań
- API
- Aplikacje Webowe
Co nie konteryzować?
- Mobilne aplikacje
- Aplikacje desktopowe (na razie)
- Małe projekty
Czy miałem problem z budowanie obrazu w Dockerze, gdy szykowałem webinar i ten wpis?
Tak, w trakcie robienia właśnie tego przykładu dostawałem następujący błąd.
docker: Error response from daemon : driver failed programming external connectivity on endpoint xenodochail-snyder
Znalazłem w internecie, że podobno w Docker istnieje taki BUG przez wiele lat i nikt z nim nic nie zrobił. Zastosowałem zalecenia z wątku o tym błędzie i zrestartowałem po prostu Dockera.
To było tyle, jeżeli chodzi o ten wpis.
Przykład pierwszy jest pobrania z GitHub-a : https://github.com/PanNiebieski/DemoExamples-For-KubernetesDockerWebinar
Jeśli zainteresowała Cię tematyk do polecam swój webinar na temat Kubernetes i Dockera.
Możesz go obejrzeć go tutaj : https://www.youtube.com/watch?v=7g00wOg9Jto
;