Automatyzacja – Szkoła Dockera https://szkoladockera.pl Najlepsze miejsce dla entuzjastów konteneryzacji i Dockera Tue, 10 Nov 2020 11:59:25 +0000 pl-PL hourly 1 https://wordpress.org/?v=5.7.13 https://szkoladockera.pl/wp-content/uploads/2019/07/cropped-Shelftons-5-32x32.png Automatyzacja – Szkoła Dockera https://szkoladockera.pl 32 32 Wprowadzenie do Terraform – infrastruktura jako kod https://szkoladockera.pl/terraform-automatyzacja-wdrazania-infrastruktury-na-potrzeby-szkolen-z-dockera/ https://szkoladockera.pl/terraform-automatyzacja-wdrazania-infrastruktury-na-potrzeby-szkolen-z-dockera/#comments Tue, 03 Nov 2020 06:31:59 +0000 https://szkoladockera.pl/?p=2253 Wprowadzenie do Terraform – dlaczego na Szkoła Dockera? Wielu moich czytelników interesuje się automatyzacją i szeroko pojętą kulturą DevOps. Potwierdził to wynik ankiety na moim koncie na Instagramie. Łącznie ponad 20 osób zaznaczyło, że „chętnie obejrzą film pt. „Wprowadzenie do Terraform”. Czy to jest kolejny „Terraform tutorial” po polsku? Odpowiedź Więcej…

Artykuł Wprowadzenie do Terraform – infrastruktura jako kod pochodzi z serwisu Szkoła Dockera.

]]>
Wprowadzenie do Terraform – dlaczego na Szkoła Dockera?

Wielu moich czytelników interesuje się automatyzacją i szeroko pojętą kulturą DevOps. Potwierdził to wynik ankiety na moim koncie na Instagramie. Łącznie ponad 20 osób zaznaczyło, że „chętnie obejrzą film pt. „Wprowadzenie do Terraform”.


Czy to jest kolejny „Terraform tutorial” po polsku?

Odpowiedź brzmi: i tak i nie.

To nie jest typowy tutorial Terraforma. Bardziej jest to wprowadzenie na przykładzie moich doświadczeń.

W tym wideo chcę pokazać Ci, w jaki sposób można przechowywać infrastrukturę jako kod, a co najważniejsze w pełni zautomatyzować jej wdrażanie.

Jak mogłeś/-aś zauważyć – jestem zwolennikiem Dockera, konteneryzacji, ale również jestem zwolennikiem automatyzacji i podejścia „As a Code”.

Całość będzie dotyczyć narzędzia Terraform, który jest jednym z najpopularniejszych jeśli chodzi o podejście „Infra as a Code”.


Gdzie będzie tworzona infrastruktura?

Infrastrukturę tworzyć będziemy w chmurze publicznej Microsoft Azure. Stosuję takie rozwiązania podczas przygotowywania moich autorskich szkoleń z konteneryzacji i Dockera.

Jeśli jesteś zainteresowany szkoleniami z Dockera / kontenerów dla Twojej firmy – ZAJRZYJ TUTAJ.

Nie pozostaje mi nic innego, jak zaprosić Cię do oglądania! : )

Mam do Ciebie prośbę.

Podziel się proszę tym filmem, przynajmniej z jedną osobą, która interesuje się automatyzacją i kulturą DevOps

PS. NIE PLANUJĘ „SZKOŁY TERRAFORMA ” : )

Artykuł Wprowadzenie do Terraform – infrastruktura jako kod pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/terraform-automatyzacja-wdrazania-infrastruktury-na-potrzeby-szkolen-z-dockera/feed/ 2
Docker Socket – czyli /var/run/docker.sock https://szkoladockera.pl/docker-socket-czyli-var-run-docker-sock/ https://szkoladockera.pl/docker-socket-czyli-var-run-docker-sock/#respond Thu, 24 Sep 2020 05:36:18 +0000 https://szkoladockera.pl/?p=2115 Jeżeli kiedykolwiek korzystałeś z Dockera metodą Kopiego-Pasty, być może spotkałeś się już z następującym argumentem: -v /var/run/docker.sock:/var/run/docker.sock Co to jest i jaką pełni rolę? Dlaczego czasami jest wykorzystywany, a czasami nie – oraz w jakich przypadkach warto wiedzieć, o co w tym wszystkim chodzi? TLDR; Chcąc ująć to w jednym Więcej…

Artykuł Docker Socket – czyli /var/run/docker.sock pochodzi z serwisu Szkoła Dockera.

]]>
Jeżeli kiedykolwiek korzystałeś z Dockera metodą Kopiego-Pasty, być może spotkałeś się już z następującym argumentem:
-v /var/run/docker.sock:/var/run/docker.sock

Co to jest i jaką pełni rolę? Dlaczego czasami jest wykorzystywany, a czasami nie – oraz w jakich przypadkach warto wiedzieć, o co w tym wszystkim chodzi?

TLDR;

Chcąc ująć to w jednym zdaniu: „Jest to Unix Socket, na którym domyślnie nasłuchuje Docker Daemon.”

Wystarczy zerknąć na powyższy diagram i w zasadzie wszystko powinno być już jasne ; -)

Dzięki podmontowaniu pliku /var/run/docker.sock (znajdującego się na hoście), kontener może komunikować się z Docker Deamonem – czyli jednym z komponentów wchodzących w skład architektury Dockera. Docker Daemon odpowiada za przyjmowanie „rozkazów” i przekazanie ich w dół, do warstwy OCI (container runtime).

Porównując to do architektury klient-serwer, kontener może stać się klientem, a Docker Deamon – serwerem.


Docker API

Jeżeli kiedykolwiek wpisałeś w terminalu docker container run (bądź też docker run) to na 99% „pod spodem” wykorzystałeś Docker Daemon Socket.

Jest to domyślny typ komunikacji pomiędzy Docker CLI a Docker Daemonem. Domyślny nie oznacza, że nie można go zmienić, ale tym za chwilę.

Gdy korzystamy z Docker CLI, np. docker image ls – automatycznie (w tle) dorzucany jest parametr -H unix:///var/run/docker.sock.

Parametr -H to informacja dla Docker CLI, z jakim Docker Daemonem ma się skomunikować. Inaczej mówiąc, gdzie polecenie ma zostać wykonane.


Warto podkreślić, że do parametru -H można przekazać również inną wartość. Na przykład adres hosta i port TCP lub inny unix socket.

WAŻNE: Jeżeli chcemy by Docker CLI komunikował się z Docker Daemonem po protokole TCP – zamiast Unix Sockets, należy pamiętać by najpierw „włączyć” ten typ komunikacji w ustawieniach Docker Daemon’a.

Jeżeli to, co do tej pory przeczytałeś odnośnie komunikacji na lini Docker CLI => Docker Daemon – nie jest dla Ciebie do końca zrozumiałe, to koniecznie zerknij TUTAJ, gdzie jakiś czasu temu opisywałem, w jaki sposób komunikować się ze zdalnym Docker Hostem z wykorzystaniem Docker Contexts.


Portainer – pierwszy przykład zastosowania

Wykorzystanie pliku /var/run/docker.sock możemy spotkać na przykład przy uruchamianiu Portainera – narzędzia do zarządzania Dockerem z poziomu przeglądarki.

$ docker container run -d \
  -p 9000:9000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  portainer/portainer

Portainer to aplikacja webowa, która umożliwia zarządzanie poszczególnymi obiektami w Dockerze (obrazy, kontenery, volumeny itd.)

Zamiast wpisywania docker container stop <moj_kontener> czy też innych poleceń – możesz to „wyklikać”. Ale nie o tym dzisiaj.

Dzięki podmontowaniu pliku /var/run/docker.sock – Portainer uruchomiony w kontenerze może komunikować się z Docker Daemonem. Inaczej mówiąc, kontener Portainera otrzymuje dostęp do głównego Dockera, na którym został uruchomiony.


Szukasz wiedzy z zakresu konteneryzacji?

Sprawdź koniecznie mój autorski program DOCKER MAESTRO

Najbardziej obszerny kurs online z Dockera po polsku

* minimum 13 godzin materiału (nowe materiału w produkcji)
dożywotni dostęp do materiałów & aktualizacji
certyfikat Docker Maestro
gwarancja satysfakcji 
(masz 14 dni na zwrot kasy, licząc od dnia zakupu, jeśli COKOLWIEK Ci się nie spodoba)


Portainer & Docker API – jak to działa?

Najczęściej stosowanym typem komunikacji po HTTP jest protokoł TCP.

W przypadku Portainera – żądania HTTP do Docker Daemona nie są jednak wysyłane po TCP, ale właśnie przez Unix Socket.

Jeżeli wyklikamy w Portainerze utworzenie kontenera na podstawie obrazu wordpress, to pod spodem zostanie wykonane zbliżone polecenie:

curl -XPOST --unix-socket /var/run/docker.sock -d '{"Image":"wordpress"}' \
-H 'Content-Type: application/json' http://localhost/containers/create

{"Id":"fcb65c6147efb862d5ea3a2ef20e793c52f0fafa3eb04e4292cb4784c5777d65","Warnings":null}

Istnieje możliwość skonfigurowania Docker Daemona tak, by oprócz Unix Socket, dodatkowo nasłuchiwał po protokole TCP.

Z perspektywy bezpieczeństwa jest to jednak niezalecane.

Trzeba wiedzieć co się robi, i jak to działa. W przeciwnym wypadku – może to zostać wykorzystane przeciwko nam (przez osoby trzecie). Przykład takiego „włamania” do Docker Daemona można znaleźć TUTAJ.


Narzędzia do CI/CD w kontenerze (Gitlab, Jenkins)

Od dłuższego czasu, narzędzia takie jak GitLab czy Jenkins możemy uruchomić z poziomu Dockera. Obydwa narzędzia mogą być z powodzeniem wykorzystane do skonfigurowania procesów automatycznego budowania i publikowania obrazów w Docker Registry.

Swego czasu w takich zastosowaniach modne było podejście Docker-in-Docker. To podejście miało jednak sporo wad i szybko zostały uznane jako „anti-pattern”.

Aby mieć możliwość dostępu do „głównego” Dockera, bądź też – aby móc budować obrazy w skonteneryzowanym Gitlabie czy Jenkinsie – wystarczy podmontować Docker Socket.


Przykład – Gitlab Runner

Jak wspominałem wcześniej, istnieje możliwość uruchomienia lokalnej instancji GitLaba z poziomu Dockera. Gdy już to zrobimy, chcemy mieć możliwość automatycznego budowania obrazów.

Aby zbudować docker image, kontener gitlab-runner potrzebuje działającej instancji Dockera. (pamiętajmy, że kontener Gitlab Runnera to tak naprawdę tylko linuxowy proces!)

version: '3.5'

services:

  gitlab:
    image: gitlab/gitlab-ce:latest
    container_name: gitlab
    restart: always
    ...
    ...
 
  gitlab-runner:
    image: gitlab/gitlab-runner:alpine
    container_name: gitlab-runner
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /srv/gitlab-runner/config:/etc/gitlab-runner
    depends_on:
      - gitlab

Obecnie rekomendowanym podejściem jest podmontowanie /var/run/docker.sock:/var/run/docker.sock – dzięki czemu budowanie obrazów odbywa się na „głównym” Dockerze (pomimo tego, że cały GitLab jest uruchomionyjako kontener).

Benefitem tego rozwiązania jest przede wszystkim pełne wykorzystanie cache podczas budowania obrazów — gdyż cały proces wykonywany jest ZAWSZE na tej samej (i jedynej) instancji Dockera.


Podsumowanie

Mam nadzieję, że ten post pozwolił Ci na zrozumienie, w jakim celu wykorzystywany jest Docker Socket.

Podmontowanie pliku /var/run/docker.sock może pozwalać na zarządzanie Dockerem z poziomu kontenera. Daje nam to ogrom możliwości i może mieć zastosowanie w narzędziach integrujących się z Dockerem, czy procesach CI/CD.

PS. Jeżeli ten wpis był dla Ciebie wartościowy – będę BARDZO wdzięczny jeśli udostępnisz go/podzielisz się nim ze znajomym.

Artykuł Docker Socket – czyli /var/run/docker.sock pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/docker-socket-czyli-var-run-docker-sock/feed/ 0
Inicjalizacja kontenera za pomocą drugiego kontenera na przykładzie HashiCorp Vault https://szkoladockera.pl/inicjalizacja-kontenera-za-pomoca-drugiego-kontenera-na-przykladzie-hashicorp-vault/ https://szkoladockera.pl/inicjalizacja-kontenera-za-pomoca-drugiego-kontenera-na-przykladzie-hashicorp-vault/#comments Thu, 30 Apr 2020 06:04:38 +0000 https://szkoladockera.pl/?p=1806 Inicjalizacja danych kontenera to zagwozdka, z którą spotyka się wiele osób. Przeglądając pytania na forach i grupach tematycznych, jak i otrzymując wiadomości na priv, zauważyłem, że jest to dość powszechny problem. Postanowiłem więc odpowiedzieć na to w formie blog posta, abyś i Ty mógł/mogła z tego skorzystać. Dzisiejszy wpis dotyczyć Więcej…

Artykuł Inicjalizacja kontenera za pomocą drugiego kontenera na przykładzie HashiCorp Vault pochodzi z serwisu Szkoła Dockera.

]]>
Inicjalizacja danych kontenera to zagwozdka, z którą spotyka się wiele osób. Przeglądając pytania na forach i grupach tematycznych, jak i otrzymując wiadomości na priv, zauważyłem, że jest to dość powszechny problem. Postanowiłem więc odpowiedzieć na to w formie blog posta, abyś i Ty mógł/mogła z tego skorzystać. Dzisiejszy wpis dotyczyć będzie inicjalizacji danych kontenera za pomocą innego kontenera. Całość zostanie omówiona na przykładzie popularnego obecnie narzędzia — jakim jest HashiCorp Vault.

Wprowadzenie

Skoro to czytasz, to doskonale wiesz jak, Docker może ułatwić życie. Szczególnie mowa tutaj o środowiskach developerskich — i na nich głównie się skupimy.

Docker świetnie radzi sobie z uruchamianiem różnego rodzaju usług na potrzeby developerskie (i nie tylko). Mam tutaj na myśli usługi takie jak bazy danych (MySQL), serwery WWW (Nginx), brokery wiadomości (RabbitMq) czy narzędzia do przechowywania sekretów (HashiCorp Vault).

Często na potrzeby developerskie istnieje potrzeba inicjalizacji tychże usług zaraz po starcie. Przykładowo może to być inicjalizacja poprzez wczytanie danych, czy inicjalizacja konfiguracji danej usługi.

W niektórych przypadkach problem ten można rozwiązać za pomocą volumenów, czyli podmontowania danych lub plików konfiguracyjnych z hosta do kontenera. Nie zawsze jest jednak taka możliwość. Czasami musimy zainicjalizować usługę działającą w kontenerze danymi, ale dopiero po jego starcie. Tym tematem dzisiaj się zajmiemy.

Opis problemu

W jednym z projektów, nad którym ostatnio pracowałem, do przechowywania sekretów wykorzystaliśmy narzędzie HashiCorp Vault. Architektura i specyfika projektu wymagała pobrania sekretów z Vaulta przez kilka mikroserwisów — podczas ich startupu. Może się to wydawać oczywiste, ale warto dodać, że wspomniane mikroserwisy również były uruchamiane z poziomu Dockera.

Inicjalizacja kontenera
Źródło https://unsplash.com

Aby ułatwić sobie proces developmentu i mieć możliwość uruchomienia całego ekosystemu, potrzebowaliśmy automatyczną inicjalizację Vaulta testowymi danymi. Nad projektem pracowało kilka osób i naszym celem było stworzenie przenośnego środowiska.

Idealnym rozwiązaniem było uruchomienie wszystkich komponentów za pomocą tylko jednego polecenia. Dzięki temu każda nowa osoba w zespole mogła uruchomić cały projekt — pobierając kod źródłowy z repozytorium i wpisując jedno polecenie. Jedyne wymaganie to zainstalowany wcześniej Docker. Tak też się stało.

HashiCorp Vault z poziomu Dockera

Moim celem było uruchomienie całego projektu za pomocą jednego polecenie. Pierwszym pomysłem, który przychodzi w takiej sytuacji do głowy, jest skorzystanie z docker-compose. Aby uruchomić Vaulta jednym poleceniem, przygotowany został następujący plik docker-compose.yml.

version: "3.6"

services:

 vault:
    image: vault:1.3.2
    container_name: vault
    ports:
      - "8200:8200"
    cap_add:
      - IPC_LOCK
    environment:
      - VAULT_ADDR=http://127.0.0.1:8200
      - VAULT_DEV_ROOT_TOKEN_ID=21ebe9d7-a536-4b32-ae16-99b56352122b
    networks:
      - network-dev
    volumes:
      - vaultdata:/vault
    restart: unless-stopped

networks:
  network-dev:

volumes:
  vaultdata:

Dzięki temu, już na tym etapie możemy uruchomić Vaulta za pomocą jednego polecenia: docker-compose up -d.

Kontener pomocniczy

Vault posiada wbudowaną opcję zarządzania zdalnymi instancjami. Dzieje się to za pomocą Vault CLI, które może komunikować się z innymi instancjami poprzez HTTP API. Wystarczy adres URL zdalnej instancji Vaulta oraz token do autoryzacji.

W tym celu wystarczy użyć polecenia:

vault login -address="REMOTE_ADDRES" <ACCESS_TOKEN>

Oznacza to, że z poziomu CLI, możemy skomunikować się z inną instancją Vaulta, znając tylko jego adres i token. To otwiera możliwość na stworzenie pomocniczego kontenera, który posłuży do inicjalizacji głównej instancji.

W tym celu stworzony został plik o nazwie Dockerfile.vaultinit. Jego zawartość znajduje się poniżej:

FROM vault:1.3.2

COPY ./vault_init.sh /usr/local/bin/

RUN chmod +x /usr/local/bin/vault_init.sh \
    && ln -s /usr/local/bin/vault_init.sh /

ENTRYPOINT ["vault_init.sh"]

Wewnątrz powyższego Dockerfile dodawany jest plik vault_init.sh, który zawiera zbiór poleceń służących do inicjalizacji głównej instancji Vaulta. Stanie się on głównym procesem pomocniczego kontenera. Dzieje się tak z powodu wskazania go w instrukcji ENTRYPOINT.

Plik inicjalizacyjny to nic innego jak zbiór poleceń specyficznych dla Vault CLI. Przykładowa zawartość pliku vault_init.sh znajduje się poniżej.

#!/bin/sh

while ! nc -z vault 8200; do sleep 3; done

vault login 21ebe9d7-a536-4b32-ae16-99b56352122b

vault secrets enable -version=2 -path=MyEngine kv

vault kv put MyEngine/MyFirstSecret Url=http://test.com/
vault kv put MyEngine/MySecondSecret Url=http://test221.com/

exit 0

Co tutaj się dzieje?

Po pierwsze w pętli while sprawdzamy połączenie z głównym kontenerem. Wykorzystujemy do tego narzędzie nc, którego zadaniem jest upewnienie się, że usługa w głównym kontenerze może przyjąć połączenie. Następnie logujemy się do głównej instancji. Na pierwszy rzut oka we wszystkich poleceniach brakuje tutaj parametru: -address="REMOTE_ADDRES" Parametr ten będzie dodawany automatycznie „w tle” dzięki dodatkowej zmiennej środowiskowej VAULT_ADDR, którą przekażemy do kontenera.

Pozostałe polecenia służą do dodania nowego engine’a oraz przykładowych sekretów.

Inicjalizacja kontenera – rozwiązanie

Na ten moment w głównym katalogu projektu znajdują się trzy pliki. 

Docker

Ostatnim krokiem jest dodanie kontenera pomocniczego do pliku docker-compose.yml. Zauważ, że za pomocą składni build wskazujemy plik Dockerfile.vaultinit. Dzięki temu osoba uruchamiająca skrypty po raz pierwszy nadal będzie mogła użyć tylko jednego polecenia: docker-compose up.

vault-initializer:
    build:
      context: .
      dockerfile: Dockerfile.vaultinit
    container_name: vault-initializer
    cap_add:
      - IPC_LOCK
    environment:
      - VAULT_ADDR=http://vault:8200
    depends_on:
      - "vault"
    networks:
      - network-dev

Na działanie tego rozwiązania mają wpływ również dwa inne czynniki.

Po pierwsze, przekazanie zmiennej środowiskowej VAULT_ADDR=http://vault:8200 oraz instrukcja  depends_on: "vault".

Dzięki tym wpisom kontener pomocniczy otrzymuje adres głównej instancji Vaulta, który będzie domyślnym adresem podczas komunikacji za pomocą Vault CLI. Dodatkowo instrukcja depends_on sprawi, że kontener pomocniczy zostanie stworzony dopiero po stworzeniu głównego kontenera. 

Oznacza to, że wszystkie instrukcje znajdujące się w pliku vault_init.sh zostaną wykonane, tak jakby za każdym razem dodawana był parametr -address "http://vault:8200". Przykład poniżej.

vault login -address="http://vault:8200" 21ebe9d7-a536-4b32-ae16-99b56352122b
vault secrets enable -address="http://vault:8200" -version=2 -path=MyEngine kv


Komunikacja między kontenerami

Komunikacja między kontenerem pomocniczym a kontenerem głównym jest możliwa, ponieważ oba kontenery po uruchomieniu zostaną podpięte do tej samej sieci —network-dev.

Sieć ta zdefiniowana jest w pliku docker-compose.yml i zostanie automatycznie utworzona. Komunikacja z kontenera pomocniczego do kontenera głównego odbywa się po nazwie usługi —vault.

Finalnie plik docker-compose.yml może wyglądać następująco:

version: "3.6"

services:

 vault:
    image: vault:1.3.2
    container_name: vault
    ports:
      - "8200:8200"
    cap_add:
      - IPC_LOCK
    environment:
      - VAULT_ADDR=http://127.0.0.1:8200
      - VAULT_DEV_ROOT_TOKEN_ID=21ebe9d7-a536-4b32-ae16-99b56352122b
    networks:
      - network-dev
    volumes:
      - vaultdata:/vault
    restart: unless-stopped

  vault-initializer:
    build:
      context: .
      dockerfile: Dockerfile.vaultinit
    container_name: vault-initializer
    cap_add:
      - IPC_LOCK
    environment:
      - VAULT_ADDR=http://vault:8200
    depends_on:
      - "vault"
    networks:
      - network-dev

networks:
  network-dev:

volumes:
  vaultdata:

Jedyne co pozostaje, to wpisanie polecenia docker-compose up, które spowoduje uruchomienie Vaulta, a następnie jego inicjalizację przez kontener pomocniczy. Warto jeszcze zaznaczyć, że po zakończeniu procesu inicjalizacji, kontener pomocniczy kończy swoje działanie. Odpowiedzialne za to jest znajdujące się w pliku vault_init.sh polecenie exit 0, które wysyła sygnał zatrzymania kontenera.

Podsumowanie

Omawiany przykład pokazuje tylko jeden ze sposobów na zainicjalizowanie kontenera (danych) z wykorzystaniem kontenera pomocniczego. Należy podkreślić, że rozwiązanie jest przeznaczone wyłącznie do zastosowań developerskich. Produkcyjna konfiguracja Vaulta znacznie się różni i należy mieć tego świadomość. 

W niektórych przypadkach twórcy obrazu przewidzieli możliwość inicjalizacji i jest na to gotowa metoda. Bardzo dobrym przykładem jest PostgreSQL, gdzie skrypty inicjalizujące wystarczy dodać do katalogu /docker-entrypoint-initdb.d/. Mogą to być zarówno skrypty .sql jak i .sh, które wykonają się bezpośrednio po starcie kontenera.



Artykuł Inicjalizacja kontenera za pomocą drugiego kontenera na przykładzie HashiCorp Vault pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/inicjalizacja-kontenera-za-pomoca-drugiego-kontenera-na-przykladzie-hashicorp-vault/feed/ 2
Jak skonfigurować Docker CI/CD w mniej niż 10 minut? https://szkoladockera.pl/jak-skonfigurowac-docker-ci-cd-w-mniej-niz-10-minut/ https://szkoladockera.pl/jak-skonfigurowac-docker-ci-cd-w-mniej-niz-10-minut/#comments Thu, 16 Apr 2020 05:40:19 +0000 https://szkoladockera.pl/?p=1711 Dzisiejszy wpis porusza kwestie automatyzacji, a dokładniej skonfigurowanie procesu budowania obrazów dockerowych (Docker CI/CD) przy wykorzystaniu nowo wprowadzonej funkcjonalności — Docker Github Action. Dodatkowo dowiesz się o planach rozwoju Dockera na rok 2020. Road Mapa Dockera na rok 2020 Jeśli zaglądasz regularnie na tego bloga (jeśli nie to czas to zmienić :P), to już pewnie wiesz, że kilka Więcej…

Artykuł Jak skonfigurować Docker CI/CD w mniej niż 10 minut? pochodzi z serwisu Szkoła Dockera.

]]>
Dzisiejszy wpis porusza kwestie automatyzacji, a dokładniej skonfigurowanie procesu budowania obrazów dockerowych (Docker CI/CD) przy wykorzystaniu nowo wprowadzonej funkcjonalności — Docker Github Action. Dodatkowo dowiesz się o planach rozwoju Dockera na rok 2020.


Road Mapa Dockera na rok 2020

Jeśli zaglądasz regularnie na tego bloga (jeśli nie to czas to zmienić :P), to już pewnie wiesz, że kilka tygodni temu, Docker ogłosił roadmapę na rok 2020. Znajdziesz w niej całą masę usprawnień i feature’ów, które zostaną zaimplementowane w najbliższej przyszłości.

W 2019 roku Docker (jako firma) przeszedł dość sporą rewolucję. Kluczowym momentem była sprzedaż rozwiązania Docker Enterprise firmie Mirantis. Od tej pory Docker skupia się na rozwiązaniach dla developerów, co potwierdza wcześniej wymieniona roadmapa.

Jednym z nowych elementów było stworzenie Docker Github Action, która miała posłużyć do automatyzacji procesów CI/CD i finalnie przyjęła nazwę „build-push-action”.


Dlaczego CI/CD na Githubie?

Pojawia się pytanie. Dlaczego Github, a nie Gitlab, Bitbucket czy Jenkins?

Bez wątpienia Github jest najpopularniejszym miejscem w internecie dla projektów open source. Github posiada też opcję prywatnych repozytoriów, które przez dłuższy czas były dostępne tylko za odpowiednią opłatą.

Od niedawna ta opłata została zniesiona. Dzięki temu, jeżeli nie chcemy udostępniać kodu publicznie (przykładowo pracujemy nad swoim tajnym projektem / produktem) możemy skorzystać z GitHuba za darmo.

W dzisiejszych czasach stosowanie automatycznego budowania, czy automatycznego wdrażania aplikacji na różne środowiska jest standardem. Nawet dla własnych projektów, z czasem warto skonfigurować sobie taki proces.

Czas to najcenniejsze co mamy w życiu. Po co więc tracić go na rzeczy, które możemy zautomatyzować.


Jak działa Docker Github Action?

Do tej pory, chcąc skonfigurować automatycznie budowanie obrazu, taggowanie oraz wypchnięcie go do Docker Registry musieliśmy posługiwać się skryptami pomocniczymi, których na dodatek nie można było przetestować lokalnie. Problem ten został rozwiązany za pomocą przeznaczonej do tego akcji, którą możemy dodać jako krok w procesie ciągłej integracji (Docker CI/CD) bezpośrednio Github Marketplace.

Głównym założeniem tego rozwiązania jest po pierwsze zbudowanie obrazu, przypisanie mu odpowiedniego taga (np. nazwę branch’a czy też SHA danego commit’a), logowanie do prywatnego Docker Registry oraz wsparcie dla typowych poleceń Docker CLI takich jak określenie build context’u, czy nazwy Dockerfile’a.

Reasumując, nowo wprowadzoną akcja pozwala na:

  • Nadawanie obrazom tagów na podstawie referencji gitowych (pull requesty, branche, tagi)
  • Nadawanie obrazom tagów na podstawie commitów (SHA) mogących przydać się w bardziej złożonych procesach CI/CD.
  • Przekazywanie argumentów do Dockerfile (--build-arg)
  • Uwierzytelnianie do prywatnych Docker Registry
  • Warunkowe wypychanie obrazów do Docker Registry.
    Przykładowo, chcemy by obraz został wypchnięty do Docker Registry tylko po dodaniu nowego taga w repozytorium gita.


Docker CI/CD na Githubie – Przykład

Aby móc skorzystać z benefitów oferowanych przez tę akcję, potrzebujemy:

Po pierwsze: aplikacji dostępnej na Githubie, zawierającej w repozytorium plik Dockerfile.
Po drugie: Docker Registry, aby móc wypchnąć tam zbudowany obraz

Do skonfigurowania automatyzacji posłużę się jest prostym WebAPI, dostępnym na moim Githubie — oo TUTAJ.

Jako Docker Registry, skorzystam z rozwiązania oferowanego na platformie Microsoft Azure (Azure Container Registry). Utworzone Docker Registry dostępne jest pod adresem  dnaprawa.azurecr.io

Niestety nie jest to darmowe rozwiązanie i wymaga to posiadania subskrypcji.  Jeśli chodzi o darmowe Docker Registry, można skorzystać z TreeScale lub Canister. Ostatnio testowałem to ostanie (Canister) i póki co nie wykryłem żadnych problemów 😉

To tyle jeśli chodzi o wymagania wstępne. Zaczynamy ; )


1. Sekrety do prywatnego Docker Registry

Ideą prywatnych Docker Registry jest zabezpieczenie przed nieautoryzowanym dostępem do dodawania i pobierania obrazów.

Aby umożliwić komunikacje na lini Github-Registry, dodajemy sekrety DOCKER_USERNAME oraz DOCKER_PASSWORD zawierające dane do uwierzytelniania do Docker Registry.

Tworzenie sekretów dla Docker Regsitry na Githubie

Analogicznie dodajemy DOCKER_PASSWORD

Po dodaniu obu sekretów, powinniśmy otrzymać zbliżony efekt.

Tworzenie sekretów dla Docker Regsitry na Githubie

2. Dodanie akcji

Przechodzimy następnie do repozytorium do sekcji Actions.

Dodanie Docker Github Action

Następnie wybieram „Set up a workflow yourself”

Docker CI/CD

W tym miejscu dodaję akcję, jako osobny krok w definicji procesu. W moim przypadku wygląda to następująco:

    - name: Build and push Docker images
      uses: docker/[email protected]
      with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
          registry: dnaprawa.azurecr.io
          repository: currency-viewer
          tags: v1
          # Set build context as current (root) directory
          path: .

Krótko mówiąc, wystarczy wskazać dane do uwierzytelniania na podstawie sekretów zdefiniowanych w poprzednim kroku oraz dodać nazwę Docker Registry i repozytorium, do którego ma trafić zbudowany obraz. Oczywiście, potrzebujemy również tag, który u mnie testowo przybrał nazwę v1. Na koniec, określamy build context. Jako że plik Dockerfile znajduje się w głównym katalogu wewnątrz repozytorium gita, ustawiam build context na bieżący katalog za pomocą path: .


3. Zatwierdzenie zmian

Przed zatwierdzeniem zmian, całość wyglądała następująco:

Docker CI/CD - konfiguracja

Wystarczy teraz zatwierdzić zmiany (Start commit), co spowoduje utworzenie nowego pliku w katalogu ~/.github/workflows, a następnie uruchomi procesu budowania.

Docker CI/CD - konfiguracja

Proces budowania przeszedł poprawnie. Oznacza to, że obraz został zbudowany i wypchnięty do Docker Registry

Docker CI/CD - budowanie obrazów

Cała definicja, której użyłem wygląda następująco:

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v2

    - name: Build and push Docker images
      uses: docker/[email protected]
      with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
          registry: dnaprawa.azurecr.io
          repository: currency-viewer
          tags: v1
          # Set build context as current (root) directory
          path: .

4. Weryfikacja Docker Registry

Chcąc upewnić się, że obraz został przesłany do repozytorium, należy przejść do portalu Azure:

Widzimy, że zostało stworzone repozytorium o nazwie currency-viewer (tak jak podaliśmy w definicji) oraz został dodany obraz z tagiem v1

Na potrzeby testów, tag v1 został przypisany na stałe. Jak już wcześniej wspominałem, jako tag możemy użyć numeru commit’a czy też nazwę brancha, na podstawie którego budujemy obraz.


Podsumowanie

Jak widzimy, wystarczy tylko chwila czasu (i chęci), by zautomatyzować proces budowania obrazów dockerowych. Jeżeli pracujesz nad swoim projektem „po godzinach” to koniecznie rozważ skonfigurowanie takiego procesu. Wybranie któregoś z darmowych Docker Registry sprawi, że nie będzie to Cię nic kosztować. Mając zbudowany obraz aplikacji, możesz łatwo go udostępnić — komukolwiek zechcesz. Wystarczy, by ta osoba miała zainstalowanego Dockera.

Często firmy w swoich zadaniach rekrutacyjnych proszą, aby udostępnić kod na GitHubie. Zaskocz ich pozytywnie i powiedz, że oprócz zadania, dodałeś integrację z Dockerem i skonfigurowałeś automatyczne budowania obrazów.


Artykuł Jak skonfigurować Docker CI/CD w mniej niż 10 minut? pochodzi z serwisu Szkoła Dockera.

]]>
https://szkoladockera.pl/jak-skonfigurowac-docker-ci-cd-w-mniej-niz-10-minut/feed/ 2