Огляд Skaffold для розробки під Kubernetes

Огляд Skaffold для розробки під Kubernetes

Півтора роки тому, 5 березня 2018 року, компанія Google випустила першу альфа-версію свого Open Source-проекту для CI/CD під назвою лісок, Метою якого стало створення «простої та відтворюваної розробки під Kubernetes», щоб розробники могли сфокусуватися саме на розробці, а не на адмініструванні. Чим може бути цікавим Skaffold? Як виявилося, він має кілька козирів у рукаві, завдяки яким він може стати сильним інструментом для розробника, а може й інженера з експлуатації. Познайомимося з проектом та його можливостями.

NB: До речі, ми вже розповідали коротко про Skaffold у нашому спільному. огляд інструментів для розробників, життя яких пов'язане з Kubernetes.

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

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

Вихідний код Skaffold написаний мовою Go, поширюється за умов вільної ліцензії Apache License 2.0 (GitHub).

Розглянемо основні функції та особливості. До перших можна віднести такі:

  • 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 для розробки під Kubernetes

Як загалом виглядає робота Skaffold?

  1. Утиліта стежить за змінами директорії з вихідним кодом. Якщо файли вносяться модифікації, вони синхронізуються з pod'ом програми у кластері Kubernetes. Якщо це можливо, без повторного складання образу. В іншому випадку збирається новий образ.
  2. Зібраний образ перевіряється за допомогою container-structure-test, тегується та відправляється до Docker Registry.
  3. Після цього образ деплоїться – розгортається у кластері Kubernetes.
  4. Якщо запуск було ініціалізовано за допомогою команди skaffold dev, то ми починаємо отримувати логи від програми, а Skaffold очікує змін, щоб повторити всі дії наново.

Огляд Skaffold для розробки під Kubernetes
Ілюстрація основних етапів роботи 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 при повторному складанні:

Огляд Skaffold для розробки під Kubernetes

По-перше, видно, що використовується кеш. Далі - додаток збирається, деплоїться, прокидаються порти. Оскільки вказано --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 є керівництво із прикладом ще простіше. Натомість там пропонується вже готова пісочниця з Kubernetes, додатком та Skaffold. Відмінний варіант, якщо вам цікаво самостійно спробувати основи.

Один із можливих варіантів використання Skaffold – ведення розробки на віддаленому кластері. Не всім зручно запускати Minikube на власному залізі, після чого викочувати додаток і чекати на його адекватне функціонування… У такому випадку Skaffold відмінно вирішує поставлене завдання, що можуть підтвердити, наприклад, інженери Reddit, про що ми вже писали у нашому блозі.

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

Висновок

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

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

PS

Читайте також у нашому блозі:

Джерело: habr.com

Додати коментар або відгук