Сучасныя прыкладанні на 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.

Аднак калі больш уважліва зірнуць run script з таго прыкладу, то ў ім ёсць зменная асяроддзі $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. Запушчаны pod.

Пстрычка па кружочку ў правым верхнім куце значка адкрывае наша дадатак, як паказана на Мал.4.

Сучасныя прыкладанні на OpenShift, частка 3: OpenShift як асяроддзе распрацоўкі і канвееры OpenShift Pipelines

Мал. 4. Запушчанае прыкладанне React.

Заключэнне

Такім чынам, мы паказалі, як запусціць на OpenShift сервер распрацоўкі для свайго дадатку і сінхранізаваць яго з лакальнай файлавай сістэмай. Таксама мы разгледзелі, як зымітаваць chained-build template з дапамогай OpenShift Pipelines. Усе коды прыкладаў з гэтага артыкула можна знайсці тут.

Дадатковыя рэсурсы (EN)

Анонсы маючых адбыцца вебінараў

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

Крыніца: habr.com

Дадаць каментар