Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Привіт усім у цьому блозі! З вами третій пост із серії, в якій ми показуємо, як розгортати сучасні веб-програми на Red Hat OpenShift.

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

У двох попередніх постах ми розповіли, як розгортати сучасні веб-застосунки всього за кілька кроків і як використовувати новий образ S2I разом з готовим чином HTTP-сервера, наприклад, NGINX за допомогою пов'язаних збірок chained builds для організації продакшн-розгортання.

Сьогодні ми покажемо, як запустити на платформі OpenShift сервер розробки для своєї програми та синхронізувати його з локальною файловою системою, а також поговоримо про те, що таке OpenShift Pipelines і як можна застосовувати як альтернативу пов'язаним збіркам.

OpenShift як середовище розробки

Робочий процес розробки (development workflow)

Як уже говорилося в першому пості, типовий процес розробки для сучасних веб-додатків – це просто «сервер розробки», який відстежує зміни в локальних файлах. Коли вони відбуваються, запускається складання програми, а потім вона оновлюється у браузер.

У більшості сучасних фреймворків такий «сервер розробки» вбудований у відповідні інструменти командного рядка.

Локальний приклад

Для початку подивимося, як це працює у разі локального запуску програм. Як приклад візьмемо додаток Реагувати з попередніх статей, хоча ті ж концепції робочого процесу застосовуються й у всіх інших сучасних фреймворках.
Отже, щоб запустити "сервер розробки" у нашому прикладі з React, введемо таку команду:

$ npm run start

Тоді у вікні терміналу ми побачимо приблизно таке:

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

А наша програма відкриється в браузері за замовчуванням:

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Тепер, якщо ми внесемо зміни до файлу, програма повинна оновитися в браузері.

OK, з розробкою в локальному режимі все ясно, а як досягти такого ж на OpenShift?

Сервер розробки на OpenShift

Якщо пам'ятаєте, у попередньому пості, ми розбирали так званий етап запуску (run phase) образу S2I і побачили, що за умовчанням обслуговування нашого веб-додатку займається модуль serve.

Однак якщо уважніше поглянути запустити сценарій з того прикладу, то в ньому є змінна оточення $NPM_RUN, яка дозволяє виконати свою команду.

Наприклад, можна використовувати модуль nodeshift, щоб розгорнути нашу програму:

$ npx nodeshift --deploy.env NPM_RUN="yarn start" --dockerImage=nodeshift/ubi8-s2i-web-app

Примітка: приклад наведений у скороченому вигляді для того, щоб проілюструвати загальну ідею.

Тут ми додали в наше розгортання змінну оточення NPM_RUN, яка говорить етапу виконання, що він повинен запустити команду yarn start, яка стартує сервером розробки React всередині нашого pod-а OpenShift.

Якщо подивитися лог працюючого pod-а, то там буде приблизно таке:

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Звичайно, це все буде ні про що доти, доки ми не зможемо синхронізувати локальний код з кодом, який також контролюється щодо змін, але живе на віддаленому сервері.

Синхронізація віддаленого та локального коду

На щастя, з синхронізацією легко допоможе nodeshift, а для відстеження змін можна скористатися командою watch.

Так що після того, як ми виконали команду для розгортання сервера розробки для нашої програми, ми можемо сміливо використовувати таку команду:

$ npx nodeshift watch

В результаті буде проведено підключення до запущеного pod'у, який ми створили раніше, активується синхронізація наших локальних файлів з віддаленим кластером, а файли на нашій локальній системі почнуть відстежуватися на предмет змін.

Тому, якщо тепер оновити файл src/App.js, система зреагує на ці зміни, скопіює їх на віддалений кластер і запустити сервер розробки, який потім оновить нашу програму в браузері.

Для повноти картини покажемо, як виглядають ці команди:

$ npx nodeshift --strictSSL=false --dockerImage=nodeshift/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN="yarn start" --deploy.port 3000

$ npx nodeshift watch --strictSSL=false

Команда watch - це абстракція поверх команди oc rsync, докладніше дізнатися про те, як це працює можна тут.

Це був приклад для React, але такий самий метод можна використовувати і з іншими фреймворками, просто пропишіть потрібним чином змінну оточення NPM_RUN.

Конвеєри Openshift Pipelines

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Далі ми поговоримо про такий інструмент, як OpenShift Pipelines, і про те, як його можна використовувати як альтернативу пов'язаним збіркам chained build.

Що таке OpenShift Pipelines

OpenShift Pipelines – це хмарно-орієнтована CI/CD-система безперервної інтеграції та доставки, призначена для організації конвеєрів з використанням Tekton. Tekton – це гнучкий Kubernetes-нативний CI/CD-фреймворк з відкритим кодом, що дозволяє автоматизувати розгортання на різних платформах (Kubernetes, serverless, віртуальні машини тощо) за рахунок абстрагування від рівня, що нижча.

Для розуміння цієї статті потрібні певні знання з Pipelines, тому ми радимо спочатку ознайомитись з офіційним підручником.

Налаштування робочого середовища

Щоб погратися з прикладами цієї статті, спочатку треба підготувати робоче середовище:

  1. Встановити та налаштувати кластер OpenShift 4. У наших прикладах для цього використовуються CodeReady Containers (CRD), інструкції щодо встановлення якого можна знайти тут.
  2. Після того, як кластер буде готовий, треба встановити Pipeline Operator. Не бійтеся, це легко, інструкції з встановлення тут.
  3. Завантажити Tekton CLI (tkn) тут.
  4. Запустити інструмент командного рядка create-react-app, щоб створити програму, яка потім розгортатиметься (це проста програма Реагувати).
  5. (Опціонально) Клонувати репозиторій, щоб локально запускати приклад програми командою 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 – відповідає за оновлення вже розгорнутого образу на той, що створюється нашим конвеєром.

Не переживайте, якщо поки що не дуже зрозуміло. Насправді ці завдання – щось на кшталт утиліт, і ми докладніше розберемо їх трохи пізніше. А поки що просто створимо їх:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/update_deployment_task.yaml
$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/tasks/apply_manifests_task.yaml

Потім за допомогою команди 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.

Запитуєте, звідки ми все це дізналися? З офіційної версії official Node.jsМи просто скопіювали її і допилили під себе.

Так, а тепер створюємо кластерне завдання s2i-web-app:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/s2i-web-app-task.yaml

Ми не будемо докладно розбирати це, а лише зупинимося на параметрі 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:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/clustertasks/webapp-build-runtime-task.yaml

Якщо подивитися код цих кластерних завдань, то видно, що там не конкретизується репозиторій 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:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/resources/resource.yaml

Переконатися, що ресурси створилися можна так:

$ tkn resource ls

Конвеєр pipeline

Тепер, коли ми маємо всі необхідні складові, зберемо з них конвеєр, створивши його наступною командою:

$ oc create -f https://raw.githubusercontent.com/nodeshift/webapp-pipeline-tutorial/master/pipelines/build-and-deploy-react.yaml

Але перш ніж запускати цю команду, давайте розберемо ці складові. Перший це ім'я:

apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: build-and-deploy-react

Потім у секції spec ми бачимо вказівку ресурсів, які ми створили раніше:

spec:
  resources:
    - name: web-application-repo
      type: git
    - name: built-web-application-image
      type: image
    - name: runtime-web-application-image
      type: image

Потім ми створюємо завдання, які має виконати наш конвеєр. Насамперед він повинен виконати вже створене нами завдання s2i-web-app:

tasks:
    - name: build-web-application
      taskRef:
        name: s2i-web-app
        kind: ClusterTask

Це завдання бере вхідні (gir-ресурс) та вихідні (ресурс built-web-application-image) параметри. Ми також передаємо їй спеціальний параметр, щоб вона не верифікувала TLS, оскільки ми використовуємо самопідписані сертифікати:

resources:
        inputs:
          - name: source
            resource: web-application-repo
        outputs:
          - name: image
            resource: built-web-application-image
      params:
        - name: TLSVERIFY
          value: "false"

Наступне завдання майже таке саме, тільки тут викликається вже створене нами кластерне завдання webapp-build-runtime:

name: build-runtime-image
    taskRef:
      name: webapp-build-runtime
      kind: ClusterTask

Як і з попереднім завданням, ми передаємо ресурс, але тепер це built-web-application-image (висновок нашого попереднього завдання). І як висновок ми знову задаємо образ. Оскільки ця задача повинна виконуватися після попередньої, то додаємо поле runAfter:

resources:
        inputs:
          - name: image
            resource: built-web-application-image
        outputs:
          - name: image
            resource: runtime-web-application-image
        params:
        - name: TLSVERIFY
          value: "false"
      runAfter:
        - build-web-application

Наступні два завдання відповідають за застосування 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.

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Рис.1. Огляд запущених конвеєрів.

Клацніть на запущеному конвеєрі відображає додаткові відомості, як показано на Рис.2.

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Мал. 2. Додаткові відомості про конвеєр.

Після додаткових відомостей можна переглянути запущені програми у поданні Топологія, Як показано на Рис.3.

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Рис 3. Запущений під.

Клацніть по кружечку в правому верхньому кутку значка відкриває нашу програму, як показано на Рис.4.

Сучасні програми на OpenShift, частина 3: OpenShift як середовище розробки та конвеєри OpenShift Pipelines

Мал. 4. Запущена програма React.

Висновок

Отже, ми показали, як запустити на OpenShift сервер розробки для своєї програми та синхронізувати його з локальною файловою системою. Також ми розглянули, як зімітувати chained-build template за допомогою OpenShift Pipelines. Усі коди прикладів з цієї статті можна знайти тут.

Додаткові ресурси (EN)

Анонси майбутніх вебінарів

Ми розпочинаємо серію п'ятничних вебінарів про нативний досвід використання Red Hat OpenShift Container Platform та Kubernetes:

Джерело: habr.com

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