- PVSM.RU - https://www.pvsm.ru -

Обзор Skaffold для разработки под Kubernetes

Обзор Skaffold для разработки под Kubernetes - 1

Полтора года назад, 5 марта 2018, компания Google выпустила первую альфа-версию своего Open Source-проекта для CI/CD под названием Skaffold [1], целью которого стало создание «простой и воспроизводимой разработки под Kubernetes», чтобы разработчики могли сфокусироваться именно на разработке, а не на администрировании. Чем может быть интересен Skaffold? Как оказалось, у него есть несколько козырей в рукаве, благодаря которым он может стать сильным инструментом для разработчика, а может — и инженера по эксплуатации. Познакомимся с проектом и его возможностями.

NB: Кстати, мы уже рассказывали вкратце про Skaffold в нашем общем обзоре инструментов для разработчиков [2], жизнь которых связана с Kubernetes.

Теория. Предназначение и возможности

Итак, если говорить в общем, то Skaffold решает задачу автоматизации цикла CI/CD (на стадиях build, push, deploy), предлагая разработчику оперативную обратную связь, т.е. возможность быстро получать результат очередных изменений кода — в виде обновлённого приложения, работающего в кластере Kubernetes. А работать оно может в разных контурах (dev, stage, production…), для чего Skaffold помогает описывать соответствующие пайплайны для выката.

Исходный код Skaffold написан на языке Go, распространяется [3] на условиях свободной лицензии Apache License 2.0 (GitHub).

Рассмотрим основные функции и особенности. К первым можно отнести следующие:

  • Skaffold предлагает инструментарий для создания CI/CD-пайплайнов.
  • Позволяет в фоновом режиме следить за изменениями в исходном коде и запускать автоматизированный процесс сборки кода в образы контейнеров, публикации этих образов в Docker Registry и их деплоя в кластер Kubernetes.
  • Синхронизирует файлы в репозитории с рабочим каталогом в контейнере.
  • Автоматически тестирует с помощью container-structure-test.
  • Пробрасывает порты.
  • Читает логи приложения, запущенного в контейнере.
  • Помогает в отладке приложений, написанных на Java, Node.js, Python, Go.

Теперь — об особенностях:

  • У самого Skaffold нет компонентов на стороне кластера. То есть дополнительно настраивать Kubernetes для использования этой утилиты не требуется.
  • Разные пайплайны для вашего приложения. Нужно выкатывать код в локальный Minikube, пока ведете разработку, а после — на stage или production? Для этого предусмотрены профили [4] и пользовательские конфигурации, переменные окружения и флаги, что позволяют описывать разные пайплайны для одного приложения.
  • CLI. Только консольная утилита и конфигурации в YAML. В сети можно найти упоминания попыток создания экспериментального GUI [5], однако на данный момент это скорее лишь означает, что он кому-то нужен, но не очень.
  • Модульность. Skaffold не является самостоятельным комбайном, а стремится использовать отдельные модули или уже существующие решения для конкретных задач.

Иллюстрация последнего:

  • На стадии сборки можно использовать:
    • docker build локально, в кластере с помощью kaniko или в Google Cloud Build;
    • Bazel локально;
    • Jib Maven и Jib Gradle локально или в Google Cloud Build;
    • кастомные build-скрипты, запускаемые локально. Если вам нужно запускать другое (более гибкое/привычное/…) решение для сборки, оно описывается в скрипте, чтобы Skaffold запускал именно его (пример из документации [6]). Это позволяет использовать вообще любой сборщик, который можно вызвать с помощью скрипта;
  • На стадии тестирования поддерживается уже упомянутый container-structure-test [7];
  • Для деплоя предусмотрены:
    • Kubectl;
    • Helm;
    • kustomize.

Благодаря этому Skaffold можно назвать своеобразным фреймворком для построения CI/CD. Вот пример рабочего процесса при его использовании (из документации проекта):

Обзор Skaffold для разработки под Kubernetes - 2

Как в общих чертах выглядит работа Skaffold?

  1. Утилита следит за изменениями в директории с исходным кодом. Если в файлы вносятся модификации, они синхронизируются с pod’ом приложения в кластере Kubernetes. Если это возможно — без повторной сборки образа. В ином случае — собирается новый образ.
  2. Собранный образ проверяется с помощью container-structure-test, тегируется и отправляется в Docker Registry.
  3. После этого образ деплоится — разворачивается в кластере Kubernetes.
  4. Если запуск был инициализирован с помощью команды skaffold dev, то мы начинаем получать логи от приложения, а Skaffold ожидает изменений, чтобы повторить все действия заново.

Обзор Skaffold для разработки под Kubernetes - 3
Иллюстрация основных этапов работы Skaffold

Практика. Пробуем Skaffold

Для демонстрации использования Skaffold возьму пример из GitHub-репозитория проекта [3]. Кстати, там же [8] можно найти и множество других примеров, учитывающих различную специфику. Все действия буду выполнять локально в Minikube. Установка простая и займет несколько минут, а для начала работы понадобится kubectl.

Установим 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.1

Склонируем себе репозиторий Skaffold'a с нужными примерами:

git clone https://github.com/GoogleContainerTools/skaffold
cd skaffold/examples/microservices

Я выбрал пример с двумя pod’ами, каждый из которых содержит по одному маленькому приложению на Go. Одно приложение — фронтенд (leeroy-web), перенаправляющий запрос на второе приложение — бэкенд (leeroy-app). Посмотрим, как это выглядит:

~/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 directories, 8 files

leeroy-app и leeroy-web содержат код на Go и простые Dockerfiles для локальной сборки этого самого кода:

~/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 .

Код приложений приводить не буду — достаточно знать, что leeroy-web принимает запросы и проксирует их на leeroy-app. Поэтому в файлах Deployment.yaml существует Service только для app (для внутренней маршрутизации). Порт pod’а web мы будем прокидывать себе для быстрого доступа к приложению.

Как выглядит 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

Здесь описываются все стадии, упомянутые выше. Кроме этого конфига есть и файл с глобальными настройками — ~/.skaffold/config. Его можно редактировать вручную или же через CLI — например, так:

skaffold config set --global local-cluster true

Эта команда установит глобальную переменную local-cluster в значение true, после чего Skaffold не будет пытаться за’push’ить образы в удаленный реестр. Если вы ведете разработку локально, можно воспользоваться этой командой, чтобы складывать образы так же локально.

Вернемся к skaffold.yaml:

  • На стадии build мы указываем, что собрать и сохранить образ нужно локально. После того, как впервые запустится сборка, увидим следующее:
    // т.к. 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.1MB

    Как видно, Skaffold самостоятельно протегировал образы. Кстати, поддерживается несколько политик тегирования.

  • Далее в конфиге указано context: ./leeroy-app/, т.е. задан контекст, в котором собирается образ.
  • На стадии деплоя определяется, что использовать будем kubectl и маску для нужных манифестов.
  • PortForward: аналогично тому, как мы обычно прокидываем порты с помощью kubectl port-forward, даём инструкции Skaffold для вызова этой команды. В данном случае — локальный порт 9000 пробрасывается на 8080 в Deployment’е с именем leeroy-web.

Самое время запустить skaffold dev: команда создаст продолжающийся «цикл обратной связи», т.е. не только соберет все и задеплоит в кластер, но и расскажет о состоянии pod’ов в данный момент, будет следить за изменениями и обновлять состояние pod’ов.

Вот результат запуска skaffold dev --port-forward при повторной сборке:

Обзор Skaffold для разработки под Kubernetes - 4

Во-первых, видно, что используется кэш. Далее — приложение собирается, деплоится, пробрасываются порты. Поскольку указан --port-forward, Skaffold пробросил порт до web, как его просили, а вот app он пробросил по собственному усмотрению (выбрал ближайший свободный). После этого мы получаем первые логи от приложений.

Проверим работоспособность?

~/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!!!

Модифицируем файл leeroy-app/app.go — проходит несколько секунд… и:

~/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!!!

При этом сам Skaffold вывел в консоль то же самое, что и раньше, за исключением одного момента: он выкатил только leeroy-app, а не все сразу.

Больше практики

Стоит упомянуть и то, что при создании нового проекта конфиги для Skaffold можно за’bootstrap’ить с помощью команды init, что очень удобно. К тому же, можно написать несколько конфигов: вести разработку на конфиге по умолчанию, после чего выкатиться на stage командой run (тот же процесс, что и dev, только не следит за изменениями), воспользовавшись другим конфигом.

На katacoda есть руководство [9] с примером ещё проще. Зато там предлагается уже готовая песочница с Kubernetes, приложением и Skaffold. Отличный вариант, если вам интересно самостоятельно попробовать самые основы.

Один из возможных вариантов использования Skaffold — ведение разработки на удаленном кластере. Не всем удобно запускать Minikube на собственном железе, после чего выкатывать приложение и ожидать его адекватного функционирования… В таком случае Skaffold отлично решает поставленную задачу, что могут подтвердить, например, инженеры Reddit, о чем мы уже писали [10] в нашем блоге.

А в этой публикации [11] от Weaveworks можно найти пример создания пайплайна для production.

Заключение

Skaffold — удобный инструмент для построения пайплайнов, подразумевающих выкат приложений в Kubernetes и ориентированных в первую очередь на нужды разработки. С ним довольно просто создавать «короткий» пайплайн, учитывающий основные потребности разработчика, однако при желании можно организовывать и более масштабные процессы. В качестве одного из наглядных примеров применения Skaffold в CI/CD-процессах приводится [12] такой тестовой проект [13] из 10 микросервисов, использующих возможности Kubernetes, gRPC, Istio и OpenCensus Tracing.

Skaffold уже получил почти 8000+ звезд на GitHub, разрабатывается Google и входит в состав GoogleContainerTools [14] — в общем, на данный момент есть все основания полагать, что проект будет развиваться долго и счастливо.

P.S.

Читайте также в нашем блоге:

Автор: Егоров Андрей

Источник [18]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/devops/335749

Ссылки в тексте:

[1] Skaffold: https://skaffold.dev/

[2] обзоре инструментов для разработчиков: https://habr.com/ru/company/flant/blog/462707/

[3] распространяется: https://github.com/GoogleContainerTools/skaffold

[4] профили: https://skaffold.dev/docs/how-tos/profiles/

[5] экспериментального GUI: https://github.com/GoogleContainerTools/skaffold/issues/1658

[6] пример из документации: https://skaffold.dev/docs/how-tos/builders/#custom-build-script-run-locally

[7] container-structure-test: https://github.com/GoogleContainerTools/container-structure-test

[8] там же: https://github.com/GoogleContainerTools/skaffold/tree/master/examples

[9] руководство: https://www.katacoda.com/lizrice/courses/containers-and-go/skaffold

[10] писали: https://habr.com/ru/company/flant/blog/441754/

[11] этой публикации: https://www.weave.works/blog/weaveworks-gitops-developer-toolkit-part-one-skaffold

[12] приводится: https://github.com/GoogleContainerTools/skaffold/issues/346

[13] тестовой проект: https://github.com/GoogleCloudPlatform/microservices-demo/

[14] GoogleContainerTools: https://github.com/GoogleContainerTools

[15] werf — наш инструмент для CI/CD в Kubernetes (обзор и видео доклада): https://habr.com/ru/company/flant/blog/460351/

[16] Garden v0.10.0: Вашему ноутбуку не нужен Kubernetes: https://habr.com/ru/company/flant/blog/459586/

[17] Kubernetes tips & tricks: о локальной разработке и Telepresence: https://habr.com/ru/company/flant/blog/446788/

[18] Источник: https://habr.com/ru/post/474692/?utm_source=habrahabr&utm_medium=rss&utm_campaign=474692