Хабрахабр

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


Иллюстрация основных этапов работы Skaffold

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

Для демонстрации использования Skaffold возьму пример из GitHub-репозитория проекта. Кстати, там же можно найти и множество других примеров, учитывающих различную специфику. Все действия буду выполнять локально в 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 при повторной сборке:

Далее — приложение собирается, деплоится, пробрасываются порты. Во-первых, видно, что используется кэш. После этого мы получаем первые логи от приложений. Поскольку указан --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, только не следит за изменениями), воспользовавшись другим конфигом.

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

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

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

Заключение

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

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

P.S.

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть