
Półtora roku temu, 5 marca 2018 roku, firma Google wydała pierwszą wersję alfa swojego projektu open source do CI/CD o nazwie , którego celem jest stworzenie "prostej i reprodukowalnej infrastruktury deweloperskiej dla Kubernetes", aby programiści mogli skupić się na rozwoju, a nie na administracji. Co może być interesujące w Skaffold? Okazało się, że ma kilka asów w rękawie, dzięki którym może stać się silnym narzędziem zarówno dla programisty, jak i inżyniera operacyjnego. Poznajmy projekt i jego możliwości.
NB: Przy okazji, krótko już wspomnieliśmy o Skaffold w naszym ogólnym , których życie związane jest z Kubernetes.
Teoria. Cel i możliwości
Tak więc, mówiąc ogólnie, Skaffold rozwiązuje problem automatyzacji cyklu CI/CD (na etapach build, push, deploy), oferując programiście natychmiastową informację zwrotną, tzn. możliwość szybkiego uzyskania wyników kolejnych zmian w kodzie — w postaci zaktualizowanej aplikacji działającej w klastrze Kubernetes. Może działać w różnych konturach (dev, stage, production…), do czego Skaffold pomaga opisać odpowiednie pipeline'y do wdrożenia.
Kod źródłowy Skaffold napisany jest w języku Go, na warunkach wolnej licencji Apache License 2.0 (GitHub).
Przyjrzyjmy się głównym funkcjom i cechom. Do pierwszych można zaliczyć:
- Skaffold oferuje narzędzia do tworzenia pipeline'ów CI/CD.
- Pozwala w tle monitorować zmiany w kodzie źródłowym oraz uruchamiać zautomatyzowany proces budowy kodu w obrazy kontenerów, publikacji tych obrazów w Docker Registry oraz ich wdrożenia w klastrze Kubernetes.
- Synchronizuje pliki w repozytorium z katalogiem roboczym w kontenerze.
- Automatycznie testuje za pomocą container-structure-test.
- Przekazuje porty.
- Odczytuje logi aplikacji uruchomionej w kontenerze.
- Pomaga w debugowaniu aplikacji napisanych w Java, Node.js, Pythonie, Go.
Teraz — o cechach:
- Sama Skaffold nie ma komponentów po stronie klastra. To znaczy, że dodatkowe skonfigurowanie Kubernetes do użycia tego narzędzia nie jest wymagane.
- Różne pipeline'y dla Twojej aplikacji. Musisz wdrożyć kod w lokalnym Minikube podczas rozwoju, a następnie — na stage lub produkcję? W tym celu przewidziano i konfiguracje użytkowników, zmienne środowiskowe oraz flagi, które umożliwiają opis różnych pipeline'ów dla jednej aplikacji.
- CLI. Tylko narzędzie konsolowe oraz konfiguracje w YAML. W sieci można znaleźć wzmianki o próbach stworzenia , jednak na ten moment oznacza to jedynie, że ktoś go potrzebuje, ale niezbyt.
- Modularność. Skaffold nie jest samodzielnym kombajnem, ale dąży do wykorzystania oddzielnych modułów lub już istniejących rozwiązań do konkretnych zadań.
Ilustracja ostatniego:
- Na etapie budowy można używać:
- docker build lokalnie, w klastrze z użyciem kaniko lub w Google Cloud Build;
- Bazel lokalnie;
- Jib Maven i Jib Gradle lokalnie lub w Google Cloud Build;
- niestandardowych skryptów build, uruchamianych lokalnie. Jeśli potrzebujesz uruchomić inne (bardziej elastyczne/znane…) rozwiązanie do budowy, jest ono opisane w skrypcie, aby Skaffold uruchomił właśnie je (). To pozwala na użycie w ogóle dowolnego narzędzia do budowy, które można wywołać za pomocą skryptu;
- Na etapie testowania wspierany jest już wspomniany ;
- Do wdrożenia przewidziano:
- Kubectl;
- Helm;
- kustomize.
Dzięki temu Skaffold można nazwać swoistym frameworkiem do budowy CI/CD. Oto przykład workflow przy jego użyciu (z dokumentacji projektu):

Jak w ogólnych zarysach wygląda praca Skaffold?
- Narządzie śledzi zmiany w katalogu z kodem źródłowym. Jeśli w plikach wprowadzane są modyfikacje, synchronizowane są z pod’em aplikacji w klastrze Kubernetes. Jeśli to możliwe — bez ponownej budowy obrazu. W przeciwnym razie — budowany jest nowy obraz.
- Zbudowany obraz jest sprawdzany za pomocą container-structure-test, tagowany i wysyłany do Docker Registry.
- Po tym obraz jest wdrażany — uruchamiany w klastrze Kubernetes.
- Jeśli uruchomienie zostało zainicjowane za pomocą polecenia
skaffold dev, zaczynamy otrzymywać logi z aplikacji, a Skaffold czeka na zmiany, by powtórzyć wszystkie działania.

Ilustracja głównych etapów pracy Skaffold
Praktyka. Próbujemy Skaffold
Aby pokazać użycie Skaffold, wezmę przykład z A tak przy okazji, można znaleźć również wiele innych przykładów, uwzględniających różne specyfiki. Wszystkie działania wykonam lokalnie w Minikube. Instalacja jest prosta i zajmie kilka minut, a do rozpoczęcia pracy potrzebujesz kubectl.
Zainstalujemy Skaffold:
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
chmod +x skaffold
sudo mv skaffold /usr/local/bin
skaffold version
v0.37.1Sklonujmy repozytorium Skaffold z odpowiednimi przykładami:
git clone https://github.com/GoogleContainerTools/skaffold
cd skaffold/examples/microservicesWybrałem przykład z dwoma podami, z których każdy zawiera jedną małą aplikację napisaną w Go. Jedna aplikacja to frontend (leeroy-web), który przekierowuje zapytania do drugiej aplikacji - backendu (leeroy-app). Spójrzmy, jak to wygląda:
~/skaffold/examples/microservices # tree
.
├── leeroy-app
│ ├── app.go
│ ├── Dockerfile
│ └── kubernetes
│ └── deployment.yaml
├── leeroy-web
│ ├── Dockerfile
│ ├── kubernetes
│ │ └── deployment.yaml
│ └── web.go
├── README.adoc
└── skaffold.yaml
4 katalogi, 8 plikówleeroy-app i leeroy-web zawierają kod w Go oraz proste pliki Dockerfile do lokalnej budowy tego kodu:
~/skaffold/examples/microservices # cat leeroy-app/Dockerfile
FROM golang:1.12.9-alpine3.10 as builder
COPY app.go .
RUN go build -o /app .
FROM alpine:3.10
CMD ["./app"]
COPY --from=builder /app . Nie będę podawał kodu aplikacji — wystarczy wiedzieć, że leeroy-web przyjmuje zapytania i przekazuje je do leeroy-app. Dlatego w plikach Deployment.yaml jest zdefiniowana usługa tylko dla app (do wewnętrznej routingu). Port podu web będziemy przekazywać lokalnie dla szybkiego dostępu do aplikacji.
Jak wygląda skaffold.yaml:
~/skaffold/examples/microservices # cat skaffold.yaml
apiVersion: skaffold/v1beta13
kind: Config
build:
artifacts:
- image: leeroy-web
context: ./leeroy-web/
- image: leeroy-app
context: ./leeroy-app/
deploy:
kubectl:
manifests:
- ./leeroy-web/kubernetes/*
- ./leeroy-app/kubernetes/*
portForward:
- resourceType: deployment
resourceName: leeroy-web
port: 8080
localPort: 9000 Tutaj opisano wszystkie wymienione wcześniej etapy. Oprócz tej konfiguracji istnieje również plik z globalnymi ustawieniami — ~/ .skaffold/config. Można go edytować ręcznie lub za pomocą CLI — na przykład w ten sposób:
skaffold config set --global local-cluster true To polecenie ustawi globalną zmienną local-cluster na wartość true, po czym Skaffold nie będzie próbował 'pushować' obrazów do zdalnego rejestru. Jeśli pracujesz lokalnie, możesz użyć tego polecenia, aby przechowywać obrazy lokalnie.
Wracając do skaffold.yaml:
- Na etapie
buildokreślamy, że obrazy należy zbudować i zapisać lokalnie. Po pierwszym uruchomieniu budowy zobaczymy następujące:// т.к. Minikube создает кластер в отдельной виртуальной машине, // придется проникнуть внутрь, чтобы найти образы # minikube ssh $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE leeroy-app 7d55a50803590b2ff62e47e6f240723451f3ef6f8c89aeb83b34e661aa287d2e 7d55a5080359 4 hours ago 13MB leeroy-app v0.37.1-171-g0270a0c-dirty 7d55a5080359 4 hours ago 13MB leeroy-web 5063bfb29d984db1ff70661f17d6efcc5537f2bbe6aa6907004ad1ab38879681 5063bfb29d98 5 hours ago 13.1MB leeroy-web v0.37.1-171-g0270a0c-dirty 5063bfb29d98 5 hours ago 13.1MBJak widać, Skaffold samodzielnie otagował obrazy. Zresztą wspierane są różne polityki tagowania.
- Dalej w konfiguracji wskazane jest
context: ./leeroy-app/, tzn. określono kontekst, w którym budowany jest obraz. - Na etapie wdrożenia ustalamy, że będziemy używać kubectl i maski dla potrzebnych manifestów.
-
PortForward: podobnie jak zwykle przekierowujemy porty za pomocąkubectl port-forward, dajemy instrukcje Skaffold, aby wywołać tę komendę. W tym przypadku lokalny port 9000 jest przekierowywany na 8080 w Deployment'cie o nazwieleeroy-web.
Czas uruchomić skaffold dev: komenda stworzy kontynuujący się „cykl zwrotnej informacji”, tj. nie tylko zbuduje wszystko i wdroży do klastra, ale także przekaże informacje o stanie podów w danym momencie, będzie śledzić zmiany i aktualizować stan podów.
Oto wynik uruchomienia skaffold dev --port-forward przy ponownym budowaniu:

Po pierwsze, widać, że używano cache. Następnie - aplikacja jest budowana, wdrażana, porty są przekierowywane. Ponieważ podano --port-forward, Skaffold przekierował port do web, jak go proszono, a ten app przekierował według własnego uznania (wybrał najbliższy wolny). Po tym otrzymujemy pierwsze logi z aplikacji.
Sprawdzimy, czy działa?
~\/skaffold\/examples\/microservices # kubectl get po
NAME READY STATUS RESTARTS AGE
leeroy-app-6998dfcc95-2nxvf 1\/1 Running 0 103s
leeroy-web-69f7d47c9d-5ff77 1\/1 Running 0 103s
~\/skaffold\/examples\/microservices # curl localhost:9000
leeroooooy app!!! Modyfikujemy plik leeroy-app\/app.go — mijają sekundy… i:
~\/skaffold\/examples\/microservices # kubectl get po
NAME READY STATUS RESTARTS AGE
leeroy-app-ffd79d986-l6nwp 1\/1 Running 0 11s
leeroy-web-69f7d47c9d-5ff77 1\/1 Running 0 4m59s
~\/skaffold\/examples\/microservices # curl localhost:9000
leeroooooy Habr!!! Przy tym sam Skaffold wyświetlił w konsoli to samo, co wcześniej, z wyjątkiem jednego momentu: wypuścił tylko leeroy-app, a nie wszystko naraz.
Więcej praktyki
Warto również wspomnieć, że przy tworzeniu nowego projektu konfiguracje dla Skaffold można 'bootstrap'ować za pomocą komendy init, co jest bardzo wygodne. Poza tym można napisać kilka konfiguracji: prowadzić rozwój na konfiguracji domyślnej, a potem wdrożyć na stage komendą run (ten sam proces, co i dev, tylko nie śledzi zmian), korzystając z innej konfiguracji.
Na katacoda jest z przykładem jeszcze prostszym. Tam oferowana jest już gotowa piaskownica z Kubernetes, aplikacją i Skaffold. Doskonała opcja, jeśli chcesz samodzielnie spróbować najważniejszych podstaw.
Jedną z możliwości użycia Skaffold jest prowadzenie prac rozwojowych w zdalnym klastrze. Nie wszystkim wygodnie jest uruchamiać Minikube na własnym sprzęcie, a następnie wdrażać aplikację i czekać na jej odpowiednie funkcjonowanie… W takim przypadku Skaffold doskonale rozwiązuje zadany problem, co mogą potwierdzić na przykład inżynierowie Reddit, o czym już wcześniej wspomnieliśmy. w naszym blogu.
A w z Weaveworks można znaleźć przykład tworzenia pipeline'u dla produkcji.
Podsumowanie
Skaffold to wygodne narzędzie do budowania pipeline'ów, które zakłada wdrażanie aplikacji w Kubernetes i jest przede wszystkim dostosowane do potrzeb rozwoju. Dość łatwo jest stworzyć „krótki” pipeline, uwzględniający podstawowe potrzeby dewelopera, ale w razie potrzeby można zorganizować także bardziej rozbudowane procesy. Jako jeden z wyraźnych przykładów zastosowania Skaffold w procesach CI/CD taki z 10 mikroserwisami, wykorzystującymi możliwości Kubernetes, gRPC, Istio i OpenCensus Tracing.
Skaffold zdobył już prawie 8000+ gwiazdek na GitHubie, jest rozwijany przez Google i wchodzi w skład — obecnie można zatem przypuszczać, że projekt będzie się rozwijał długo i szczęśliwie.
P.S.
Przeczytaj także na naszym blogu:
- «»;
- «»;
- «»;
- «».
Źródło: habr.com
