ProHoster > Блог > адміністрування > Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines
Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines
Привіт усім у цьому блозі! З вами третій пост із серії, в якій ми показуємо, як розгортати сучасні веб-програми на Red Hat OpenShift.
У двох попередніх постах ми розповіли, як розгортати сучасні веб-застосунки всього за кілька кроків і як використовувати новий образ S2I разом з готовим чином HTTP-сервера, наприклад, NGINX за допомогою пов'язаних збірок chained builds для організації продакшн-розгортання.
Сьогодні ми покажемо, як запустити на платформі OpenShift сервер розробки для своєї програми та синхронізувати його з локальною файловою системою, а також поговоримо про те, що таке OpenShift Pipelines і як можна застосовувати як альтернативу пов'язаним збіркам.
OpenShift як середовище розробки
Робочий процес розробки (development workflow)
Як уже говорилося в першому пості, типовий процес розробки для сучасних веб-додатків – це просто «сервер розробки», який відстежує зміни в локальних файлах. Коли вони відбуваються, запускається складання програми, а потім вона оновлюється у браузер.
У більшості сучасних фреймворків такий «сервер розробки» вбудований у відповідні інструменти командного рядка.
Локальний приклад
Для початку подивимося, як це працює у разі локального запуску програм. Як приклад візьмемо додаток Реагувати з попередніх статей, хоча ті ж концепції робочого процесу застосовуються й у всіх інших сучасних фреймворках.
Отже, щоб запустити "сервер розробки" у нашому прикладі з React, введемо таку команду:
$ npm run start
Тоді у вікні терміналу ми побачимо приблизно таке:
А наша програма відкриється в браузері за замовчуванням:
Тепер, якщо ми внесемо зміни до файлу, програма повинна оновитися в браузері.
OK, з розробкою в локальному режимі все ясно, а як досягти такого ж на OpenShift?
Сервер розробки на OpenShift
Якщо пам'ятаєте, у попередньому пості, ми розбирали так званий етап запуску (run phase) образу S2I і побачили, що за умовчанням обслуговування нашого веб-додатку займається модуль serve.
Однак якщо уважніше поглянути запустити сценарій з того прикладу, то в ньому є змінна оточення $NPM_RUN, яка дозволяє виконати свою команду.
Наприклад, можна використовувати модуль nodeshift, щоб розгорнути нашу програму:
Примітка: приклад наведений у скороченому вигляді для того, щоб проілюструвати загальну ідею.
Тут ми додали в наше розгортання змінну оточення NPM_RUN, яка говорить етапу виконання, що він повинен запустити команду yarn start, яка стартує сервером розробки React всередині нашого pod-а OpenShift.
Якщо подивитися лог працюючого pod-а, то там буде приблизно таке:
Звичайно, це все буде ні про що доти, доки ми не зможемо синхронізувати локальний код з кодом, який також контролюється щодо змін, але живе на віддаленому сервері.
Синхронізація віддаленого та локального коду
На щастя, з синхронізацією легко допоможе nodeshift, а для відстеження змін можна скористатися командою watch.
Так що після того, як ми виконали команду для розгортання сервера розробки для нашої програми, ми можемо сміливо використовувати таку команду:
$ npx nodeshift watch
В результаті буде проведено підключення до запущеного pod'у, який ми створили раніше, активується синхронізація наших локальних файлів з віддаленим кластером, а файли на нашій локальній системі почнуть відстежуватися на предмет змін.
Тому, якщо тепер оновити файл src/App.js, система зреагує на ці зміни, скопіює їх на віддалений кластер і запустити сервер розробки, який потім оновить нашу програму в браузері.
Для повноти картини покажемо, як виглядають ці команди:
Команда watch - це абстракція поверх команди oc rsync, докладніше дізнатися про те, як це працює можна тут.
Це був приклад для React, але такий самий метод можна використовувати і з іншими фреймворками, просто пропишіть потрібним чином змінну оточення NPM_RUN.
Конвеєри Openshift Pipelines
Далі ми поговоримо про такий інструмент, як OpenShift Pipelines, і про те, як його можна використовувати як альтернативу пов'язаним збіркам chained build.
Що таке OpenShift Pipelines
OpenShift Pipelines – це хмарно-орієнтована CI/CD-система безперервної інтеграції та доставки, призначена для організації конвеєрів з використанням Tekton. Tekton – це гнучкий Kubernetes-нативний CI/CD-фреймворк з відкритим кодом, що дозволяє автоматизувати розгортання на різних платформах (Kubernetes, serverless, віртуальні машини тощо) за рахунок абстрагування від рівня, що нижча.
Для розуміння цієї статті потрібні певні знання з Pipelines, тому ми радимо спочатку ознайомитись з офіційним підручником.
Налаштування робочого середовища
Щоб погратися з прикладами цієї статті, спочатку треба підготувати робоче середовище:
Встановити та налаштувати кластер OpenShift 4. У наших прикладах для цього використовуються CodeReady Containers (CRD), інструкції щодо встановлення якого можна знайти тут.
Після того, як кластер буде готовий, треба встановити Pipeline Operator. Не бійтеся, це легко, інструкції з встановлення тут.
Запустити інструмент командного рядка create-react-app, щоб створити програму, яка потім розгортатиметься (це проста програма Реагувати).
(Опціонально) Клонувати репозиторій, щоб локально запускати приклад програми командою npm install, а потім npm start.
У репозиторії програми також буде папка k8s, де лежатимуть YAML'и Kubernetes/OpenShift, що використовуються для розгортання програми. Там будуть Tasks, ClusterTasks, Resources та Pipelines, які ми створимо в цьому репозиторії.
приступаємо
Насамперед для нашого прикладу треба створити новий проект у кластері OpenShift. Назвемо цей проект webapp-pipeline та створимо його наступною командою:
$ oc new-project webapp-pipeline
Далі це ім'я проекту буде фігурувати в коді, так що якщо вирішите назвати його якось інакше, не забувайте відповідним чином правити код з прикладів. Починаючи з цього місця, ми підемо не згори-вниз, а знизу-вгору: тобто спочатку створимо всі складові конвеєра, і лише потім його самого.
Отже, насамперед…
Завдання Tasks
Створимо пару завдань (tasks), які допоможуть розгортати додаток в рамках нашого конвеєра pipeline. Перше завдання – apply_manifests_task – відповідає за застосування YAML тих Kubernetes-ресурсів (service, deployment та route), які знаходяться в папці k8s нашої програми. Друге завдання – update_deployment_task – відповідає за оновлення вже розгорнутого образу на той, що створюється нашим конвеєром.
Не переживайте, якщо поки що не дуже зрозуміло. Насправді ці завдання – щось на кшталт утиліт, і ми докладніше розберемо їх трохи пізніше. А поки що просто створимо їх:
Потім за допомогою команди tkn CLI перевіримо, що завдання створилися:
$ tkn task ls
NAME AGE
apply-manifests 1 minute ago
update-deployment 1 minute ago
Примітка: це локальні завдання поточного проекту.
Кластерні завдання Cluster tasks
Кластерні завдання - це те ж саме, що і просто завдання. Тобто, це повторно використовувана колекція кроків, які комбінуються тим чи іншим чином при запуску конкретного завдання. Відмінність у цьому, що кластерна завдання доступна скрізь у межах кластера. Щоб побачити список кластерних завдань, які автоматично створюються при додаванні Pipeline Operator, знову скористаємося командою tkn CLI:
$ tkn clustertask ls
NAME AGE
buildah 1 day ago
buildah-v0-10-0 1 day ago
jib-maven 1 day ago
kn 1 day ago
maven 1 day ago
openshift-client 1 day ago
openshift-client-v0-10-0 1 day ago
s2i 1 day ago
s2i-go 1 day ago
s2i-go-v0-10-0 1 day ago
s2i-java-11 1 day ago
s2i-java-11-v0-10-0 1 day ago
s2i-java-8 1 day ago
s2i-java-8-v0-10-0 1 day ago
s2i-nodejs 1 day ago
s2i-nodejs-v0-10-0 1 day ago
s2i-perl 1 day ago
s2i-perl-v0-10-0 1 day ago
s2i-php 1 day ago
s2i-php-v0-10-0 1 day ago
s2i-python-3 1 day ago
s2i-python-3-v0-10-0 1 day ago
s2i-ruby 1 day ago
s2i-ruby-v0-10-0 1 day ago
s2i-v0-10-0 1 day ago
А тепер створимо два кластерні завдання. Перша генеруватиме образ S2I і відправлятиме його у внутрішній реєстр OpenShift; друга – виконувати збірку нашого образу на базі NGINX, використовуючи як вміст вже зібраний нами додаток.
Створюємо та відправляємо образ
При створенні першого завдання ми повторимо те, що робили в попередній статті про пов'язані збірки. Нагадаємо, що ми використовували образ S2I (ubi8-s2i-web-app), щоб зібрати наш додаток, і в результаті отримували образ, що зберігається у внутрішньому реєстрі OpenShift. Тепер ми будемо використовувати цей S2I-образ веб-програми, щоб створити DockerFile для нашої програми, а потім задіямо Buildah, щоб провести реальну збірку і відправити отриманий образ у внутрішній реєстр OpenShift, оскільки це саме те, що OpenShift робить, коли ви розгортаєте свої програми за допомогою NodeShift.
Ми не будемо докладно розбирати це, а лише зупинимося на параметрі OUTPUT_DIR:
params:
- name: OUTPUT_DIR
description: The location of the build output directory
default: build
За промовчанням цей параметр дорівнює build, саме туди React складає зібраний контент. В інших фреймворках використовуються інші шляхи, наприклад, Ember це dist. Висновок нашої першої кластерної задачі буде образ, що містить зібрані нами HTML, JavaScript і CSS.
Збираємо образ на базі NGINX
Що стосується нашої другої кластерної задачі, то вона повинна збирати нам образ на основі NGINX, використовуючи контент вже зібраного додатка. По суті, ця та частина попереднього розділу, де ми розглядали пов'язані збірки chained builds.
Для цього ми – так само, як трохи вище – створимо кластерне завдання webapp-build-runtime:
Якщо подивитися код цих кластерних завдань, то видно, що там не конкретизується репозиторій Git, з яким ми працюємо, або імена образів, які ми створюємо. Ми тільки задаємо, що саме ми передаємо в Git, або образ, куди треба вивести підсумковий образ. Саме тому ці кластерні завдання можна повторно використовувати і під час роботи з іншими додатками.
І тут ми витончено переходимо до наступного пункту…
ресурси
Отже, оскільки, як ми щойно сказали, кластерні завдання мають бути максимально узагальненими, нам треба створити ресурси, які будуть використовуватися на вході (репозиторій Git) та на виході (підсумкові образи). Перший ресурс, який нам потрібен - це Git, де знаходиться наша програма, щось на зразок такого:
# This resource is the location of the git repo with the web application source
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: web-application-repo
spec:
type: git
params:
- name: url
value: https://github.com/nodeshift-starters/react-pipeline-example
- name: revision
value: master
Тут PipelineResource має тип git. Ключ url у секції params вказує на конкретний репозиторій та задає гілку master (це опціонально, але пишемо її для повноти).
Тепер нам треба створити ресурс для образу, куди зберігатимуться результати виконання завдання s2i-web-app task, це робиться так:
# This resource is the result of running "npm run build", the resulting built files will be located in /opt/app-root/output
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: built-web-application-image
spec:
type: image
params:
- name: url
value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-application:latest
Тут PipelineResource має тип image, а значення параметра url вказує на внутрішній OpenShift Image Registry, саме на той, що знаходиться в просторі імен webapp-pipeline. Не забудьте змінити цей параметр, якщо ви використовуєте інший простір імен.
І, нарешті, останній ресурс, який нам знадобиться, теж матиме тип image і це буде підсумковий образ NGINX, який потім використовуватиметься при розгортанні:
# This resource is the image that will be just the static html, css, js files being run with nginx
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: runtime-web-application-image
spec:
type: image
params:
- name: url
value: image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtime-web-application:latest
Знову зверніть увагу, що цей ресурс зберігає образ у внутрішньому реєстрі OpenShift у просторі імен webapp-pipeline.
Щоб разом створити всі ці ресурси, скористаємося командою create:
Це завдання бере вхідні (gir-ресурс) та вихідні (ресурс built-web-application-image) параметри. Ми також передаємо їй спеціальний параметр, щоб вона не верифікувала TLS, оскільки ми використовуємо самопідписані сертифікати:
Як і з попереднім завданням, ми передаємо ресурс, але тепер це built-web-application-image (висновок нашого попереднього завдання). І як висновок ми знову задаємо образ. Оскільки ця задача повинна виконуватися після попередньої, то додаємо поле runAfter:
Наступні два завдання відповідають за застосування YAML-файлів сервісу, маршруту та деплойменту, які живуть у каталозі k8s нашого веб-додатку, а також за те, щоб оновлювати цей деплоймент при створенні нових образів. Ці дві кластерні завдання ми поставили ще на початку статті.
Запуск конвеєра
Отже, всі частини нашого конвеєра створені, і ми запустимо його наступною командою:
$ tkn pipeline start build-and-deploy-react
На цьому етапі командний рядок використовується в інтерактивному режимі і треба вибирати відповідні ресурси у відповідь на кожен його запит: для ресурсу git вибираємо web-application-repo, потім для ресурсу першого образу - built-web-application-image, і, нарешті, ресурсу другого образу – runtime-web-application-image:
? Choose the git resource to use for web-application-repo: web-application-repo (https://github.com/nodeshift-starters/react-pipeline-example)
? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/built-web-
application:latest)
? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000/webapp-pipeline/runtim
e-web-application:latest)
Pipelinerun started: build-and-deploy-react-run-4xwsr
Тепер перевіримо статус конвеєра за допомогою наступної команди:
$ tkn pipeline logs -f
Після того, як конвеєр запуститься і програма буде розгорнута, запросимо опублікований маршрут наступною командою:
$ oc get route react-pipeline-example --template='http://{{.spec.host}}'
Для більшої візуальності можна переглянути наш конвеєр у Developer-режимі веб-консолі у розділі Трубопроводи, Як показано на Мал. 1.
Рис.1. Огляд запущених конвеєрів.
Клацніть на запущеному конвеєрі відображає додаткові відомості, як показано на Рис.2.
Мал. 2. Додаткові відомості про конвеєр.
Після додаткових відомостей можна переглянути запущені програми у поданні Топологія, Як показано на Рис.3.
Рис 3. Запущений під.
Клацніть по кружечку в правому верхньому кутку значка відкриває нашу програму, як показано на Рис.4.
Мал. 4. Запущена програма React.
Висновок
Отже, ми показали, як запустити на OpenShift сервер розробки для своєї програми та синхронізувати його з локальною файловою системою. Також ми розглянули, як зімітувати chained-build template за допомогою OpenShift Pipelines. Усі коди прикладів з цієї статті можна знайти тут.