Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Ola a todos neste blog! Esta é a terceira publicación dunha serie na que mostramos como implementar aplicacións web modernas en Red Hat OpenShift.

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Nas dúas publicacións anteriores, amosamos como implementar aplicacións web modernas en só uns poucos pasos e como usar unha nova imaxe S2I xunto cunha imaxe de servidor HTTP estándar, como NGINX, usando compilacións encadeadas para organizar despregamentos de produción. .

Hoxe mostraremos como executar un servidor de desenvolvemento para a túa aplicación na plataforma OpenShift e sincronizalo co sistema de ficheiros local, e tamén falaremos sobre o que son OpenShift Pipelines e como se poden usar como alternativa aos conxuntos vinculados.

OpenShift como ambiente de desenvolvemento

Fluxo de traballo de desenvolvemento

Como xa se indicou en primeiro post, o proceso de desenvolvemento típico das aplicacións web modernas é simplemente algún tipo de "servidor de desenvolvemento" que rastrexa os cambios nos ficheiros locais. Cando se producen, desenvólvese a compilación da aplicación e, a continuación, actualízase ao navegador.

Na maioría dos marcos modernos, un "servidor de desenvolvemento" deste tipo está integrado nas ferramentas de liña de comandos correspondentes.

Exemplo local

En primeiro lugar, vexamos como funciona isto cando se executan aplicacións localmente. Poñamos a aplicación como exemplo Reaccionar dos artigos anteriores, aínda que case os mesmos conceptos de fluxo de traballo aplícanse a todos os demais marcos modernos.
Entón, para iniciar o "servidor de desenvolvemento" no noso exemplo de React, introduciremos o seguinte comando:

$ npm run start

A continuación, na xanela do terminal veremos algo así:

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

E a nosa aplicación abrirase no navegador predeterminado:

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Agora, se facemos cambios no ficheiro, a aplicación debería actualizarse no navegador.

Vale, todo está claro co desenvolvemento en modo local, pero como conseguir o mesmo en OpenShift?

Servidor de desenvolvemento en OpenShift

Se te lembras, en publicación anterior, observamos a chamada fase de execución da imaxe S2I e vimos que, por defecto, o módulo serve é o encargado de dar servizo á nosa aplicación web.

Non obstante, se miras máis de cerca executar script a partir dese exemplo, contén a variable de ambiente $NPM_RUN, que lle permite executar o seu comando.

Por exemplo, podemos usar o módulo nodeshift para implementar a nosa aplicación:

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

Nota: o exemplo anterior abreviase para ilustrar a idea xeral.

Aquí engadimos a variable de ambiente NPM_RUN ao noso despregamento, que indica ao tempo de execución que execute o comando yarn start, que inicia o servidor de desenvolvemento React dentro do noso pod OpenShift.

Se miras o rexistro dun pod en execución, terá un aspecto así:

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Por suposto, todo isto non será nada ata que poidamos sincronizar o código local co código, que tamén está supervisado por cambios, pero vive nun servidor remoto.

Sincronizando código local e remoto

Afortunadamente, nodeshift pode axudar facilmente coa sincronización e pode usar o comando watch para rastrexar os cambios.

Entón, despois de executar o comando para implementar o servidor de desenvolvemento para a nosa aplicación, podemos usar con seguridade o seguinte comando:

$ npx nodeshift watch

Como resultado, establecerase unha conexión co pod en execución que creamos un pouco antes, activarase a sincronización dos nosos ficheiros locais co clúster remoto e comezarán a supervisarse os ficheiros do noso sistema local para detectar cambios.

Polo tanto, se agora actualizamos o ficheiro src/App.js, o sistema reaccionará a estes cambios, copiaráos no clúster remoto e iniciará o servidor de desenvolvemento, que despois actualizará a nosa aplicación no navegador.

Para completar a imaxe, imos mostrar como son estes comandos completos:

$ 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

O comando watch é unha abstracción enriba do comando oc rsync, podes aprender máis sobre como funciona aquí.

Este foi un exemplo para React, pero pódese usar exactamente o mesmo método con outros frameworks, só tes que configurar a variable de ambiente NPM_RUN segundo sexa necesario.

Openshift Pipelines

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

A continuación falaremos dunha ferramenta como OpenShift Pipelines e de como se pode usar como alternativa ás compilacións encadeadas.

Que son OpenShift Pipelines

OpenShift Pipelines é un sistema de integración e entrega continua de CI/CD nativo na nube deseñado para organizar canalizacións mediante Tekton. Tekton é un marco CI/CD nativo de Kubernetes de código aberto flexible que che permite automatizar a implantación en varias plataformas (Kubernetes, sen servidor, máquinas virtuais, etc.) abstraíndose da capa subxacente.

Para comprender este artigo é necesario un coñecemento de Pipelines, polo que recomendámosche encarecidamente que leas primeiro libro de texto oficial.

Configurando o seu ambiente de traballo

Para xogar cos exemplos deste artigo, primeiro debes preparar o teu ambiente de traballo:

  1. Instale e configure un clúster de OpenShift 4. Os nosos exemplos usan CodeReady Containers (CRD) para iso, as instrucións de instalación que se poden atopar aquí.
  2. Despois de que o clúster estea listo, cómpre instalar nel Pipeline Operator. Non teñas medo, é fácil, instrucións de instalación aquí.
  3. Descargar Tekton CLI (tkn) aquí.
  4. Execute a ferramenta de liña de comandos create-react-app para crear unha aplicación que despois implementará (esta é unha aplicación sinxela Reaccionar).
  5. (Opcional) Clone o repositorio para executar a aplicación de exemplo localmente con npm install e despois npm start.

O repositorio da aplicación tamén terá un cartafol k8s, que conterá os YAML de Kubernetes/OpenShift utilizados para implementar a aplicación. Haberá Tarefas, ClusterTasks, Recursos e Pipelines que crearemos neste repositorios.

Comezando

O primeiro paso para o noso exemplo é crear un novo proxecto no clúster OpenShift. Chamemos a este proxecto webapp-pipeline e creemos co seguinte comando:

$ oc new-project webapp-pipeline

Este nome do proxecto aparecerá no código máis adiante, polo que se decide poñerlle outro nome, non esqueza editar o código de exemplo en consecuencia. Partindo deste punto, non iremos de arriba abaixo, senón de abaixo cara arriba: é dicir, primeiro crearemos todos os compoñentes do transportador e só despois o propio transportador.

Entón, en primeiro lugar...

Tarefas

Imos crear un par de tarefas, que despois axudarán a implementar a aplicación dentro da nosa canalización. A primeira tarefa - apply_manifests_task - encárgase de aplicar o YAML daqueles recursos de Kubernetes (servizo, despregamento e ruta) que se atopan no cartafol k8s da nosa aplicación. A segunda tarefa - update_deployment_task - encárgase de actualizar unha imaxe xa despregada á creada pola nosa canalización.

Non te preocupes se aínda non está moi claro. De feito, estas tarefas son algo parecido ás utilidades, e verémolas con máis detalle un pouco máis tarde. Polo momento, imos crealos:

$ 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

Despois, usando o comando tkn CLI, comprobaremos que as tarefas foron creadas:

$ tkn task ls

NAME                AGE
apply-manifests     1 minute ago
update-deployment   1 minute ago

Nota: Estas son tarefas locais para o teu proxecto actual.

Tarefas de cluster

As tarefas do clúster son basicamente as mesmas que as tarefas simples. É dicir, é unha colección reutilizable de pasos que se combinan dun xeito ou doutro cando se executa unha tarefa específica. A diferenza é que unha tarefa do clúster está dispoñible en todas as partes do clúster. Para ver a lista de tarefas do clúster que se crean automaticamente ao engadir Pipeline Operator, usaremos de novo o comando 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

Agora imos crear dúas tarefas de cluster. O primeiro xerará a imaxe S2I e enviaraa ao rexistro interno de OpenShift; o segundo é construír a nosa imaxe baseada en NGINX, utilizando a aplicación que xa construímos como contido.

Crea e envía a imaxe

Ao crear a primeira tarefa, repetiremos o que xa fixemos no artigo anterior sobre as montaxes vinculadas. Lembre que usamos a imaxe S2I (ubi8-s2i-web-app) para "construír" a nosa aplicación, e acabamos cunha imaxe almacenada no rexistro interno de OpenShift. Agora usaremos esta imaxe da aplicación web S2I para crear un DockerFile para a nosa aplicación e despois usaremos Buildah para facer a compilación real e enviar a imaxe resultante ao rexistro interno de OpenShift, xa que iso é exactamente o que fai OpenShift cando implementas as túas aplicacións usando NodeShift. .

Como sabiamos todo isto, preguntades? Desde versión oficial de Node.js oficial, só o copiamos e modificámolo por nós mesmos.

Entón, agora imos crear a tarefa do clúster s2i-web-app:

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

Non o analizaremos en detalle, senón que só nos centraremos no parámetro OUTPUT_DIR:

params:
      - name: OUTPUT_DIR
        description: The location of the build output directory
        default: build

Por defecto, este parámetro é igual a compilar, que é onde React pon o contido ensamblado. Outros frameworks usan camiños diferentes, por exemplo, en Ember é dist. A saída da nosa primeira tarefa do clúster será unha imaxe que contén o HTML, JavaScript e CSS que recompilamos.

Crea unha imaxe baseada en NGINX

En canto á nosa segunda tarefa de clúster, debería construír unha imaxe baseada en NGINX para nós, utilizando o contido da aplicación que xa construímos. Esencialmente, esta é a parte da sección anterior onde analizamos as compilacións encadeadas.

Para iso, crearemos unha tarefa de clúster webapp-build-runtime: exactamente o mesmo que anteriormente:

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

Se observas o código destas tarefas do clúster, podes ver que non especifica o repositorio de Git co que estamos a traballar nin os nomes das imaxes que estamos a crear. Só especificamos o que exactamente estamos a transferir a Git, ou unha determinada imaxe onde debería saír a imaxe final. É por iso que estas tarefas do clúster pódense reutilizar cando se traballa con outras aplicacións.

E aquí con graza pasamos ao seguinte punto...

Recursos

Entón, dado que, como acabamos de dicir, as tarefas do clúster deben ser o máis xerais posible, necesitamos crear recursos que se empregarán como entrada (o repositorio de Git) e como saída (as imaxes finais). O primeiro recurso que necesitamos é Git, onde reside a nosa aplicación, algo así:

# 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

Aquí PipelineResource é de tipo git. A clave url na sección de parámetros apunta a un repositorio específico e especifica a rama mestra (isto é opcional, pero escribimos para completar).

Agora necesitamos crear un recurso para a imaxe onde se gardarán os resultados da tarefa s2i-web-app, isto faise así:

# 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

Aquí o PipelineResource é de tipo imaxe e o valor do parámetro url apunta ao Rexistro de imaxes OpenShift interno, concretamente ao que se atopa no espazo de nomes webapp-pipeline. Non esquezas cambiar esta configuración se estás a usar un espazo de nomes diferente.

E, finalmente, o último recurso que necesitamos tamén será de tipo imaxe e esta será a imaxe NGINX final que se utilizará despois durante a implantación:

# 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

De novo, teña en conta que este recurso almacena a imaxe no rexistro interno de OpenShift no espazo de nomes webapp-pipeline.

Para crear todos estes recursos á vez, usamos o comando create:

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

Podes asegurarte de que os recursos foron creados así:

$ tkn resource ls

Tubería transportadora

Agora que temos todos os compoñentes necesarios, imos montar unha canalización a partir deles creándoa co seguinte comando:

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

Pero antes de executar este comando, vexamos estes compoñentes. O primeiro é o nome:

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

A continuación, na sección de especificacións vemos unha indicación dos recursos que creamos anteriormente:

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

A continuación, creamos as tarefas que o noso pipeline necesita completar. En primeiro lugar, debe executar a tarefa s2i-web-app que xa creamos:

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

Esta tarefa leva parámetros de entrada (recurso gir) e de saída (recurso de imaxe da aplicación web construída). Tamén lle pasamos un parámetro especial para que non verifique TLS xa que estamos a usar certificados autofirmados:

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

A seguinte tarefa é case a mesma, só aquí chámase a tarefa do clúster webapp-build-runtime que xa creamos:

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

Como coa tarefa anterior, pasamos un recurso, pero agora é imaxe-aplicación-web integrada (a saída da nosa tarefa anterior). E como saída volvemos configurar a imaxe. Dado que esta tarefa debe executarse despois da anterior, engadimos o campo 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

As dúas seguintes tarefas encárganse de utilizar os ficheiros YAML de servizo, ruta e despregamento que residen no directorio k8s da nosa aplicación web, e tamén de actualizar este despregue ao crear novas imaxes. Definimos estas dúas tarefas de cluster ao comezo do artigo.

Arranque do transportador

Entón, todas as partes da nosa canalización están creadas e executarémola co seguinte comando:

$ tkn pipeline start build-and-deploy-react

Nesta fase, a liña de comandos úsase de forma interactiva e cómpre seleccionar os recursos axeitados en resposta a cada unha das súas solicitudes: para o recurso git, seleccione web-application-repo, despois para o primeiro recurso de imaxe, built-web-application -image e, finalmente, para o segundo recurso de imaxe –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

Agora imos comprobar o estado da canalización usando o seguinte comando:

$ tkn pipeline logs -f

Unha vez iniciada a canalización e implantada a aplicación, podemos solicitar a ruta publicada co seguinte comando:

$ oc get route react-pipeline-example --template='http://{{.spec.host}}'

Para unha maior visualización, podes ver o noso pipeline no modo Desenvolvedor da consola web na sección Liñas de tubería, como se mostra na Fig. 1.

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Fig.1. Revisión das conducións en funcionamento.

Ao facer clic nunha canalización en execución móstranse detalles adicionais, como se mostra na Figura 2.

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Arroz. 2. Información adicional sobre o gasoduto.

Despois de obter máis información, podes ver as aplicacións en execución na vista topoloxía, como se mostra na Fig.3.

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Fig 3. Vaina lanzada.

Facendo clic no círculo na esquina superior dereita da icona ábrese a nosa aplicación, como se mostra na figura 4.

Aplicacións modernas en OpenShift, parte 3: OpenShift como ambiente de desenvolvemento e OpenShift Pipelines

Arroz. 4. Execución da aplicación React.

Conclusión

Entón, mostramos como executar un servidor de desenvolvemento para a súa aplicación en OpenShift e sincronizalo co sistema de ficheiros local. Tamén analizamos como simular un modelo de construción encadeada usando OpenShift Pipelines. Pódense atopar todos os códigos de exemplo deste artigo aquí.

Recursos adicionais (EN)

Anuncios dos próximos seminarios web

Comezamos unha serie de seminarios web do venres sobre a experiencia nativa usando Red Hat OpenShift Container Platform e Kubernetes:

Fonte: www.habr.com

Engadir un comentario