ProHoster > Blog > administración > Aplicaciones modernas en OpenShift, parte 3: OpenShift como entorno de desarrollo y OpenShift Pipelines
Aplicaciones modernas en OpenShift, parte 3: OpenShift como entorno de desarrollo y OpenShift Pipelines
¡Hola a todos en este blog! Esta es la tercera publicación de una serie en la que mostramos cómo implementar aplicaciones web modernas en Red Hat OpenShift.
En las dos publicaciones anteriores, mostramos cómo implementar aplicaciones web modernas en solo unos pocos pasos y cómo usar una nueva imagen S2I junto con una imagen de servidor HTTP disponible en el mercado, como NGINX, usando compilaciones encadenadas para orquestar implementaciones de producción. .
Hoy mostraremos cómo ejecutar un servidor de desarrollo para su aplicación en la plataforma OpenShift y sincronizarlo con el sistema de archivos local, y también hablaremos sobre qué son OpenShift Pipelines y cómo se pueden usar como una alternativa a los ensamblajes vinculados.
OpenShift como entorno de desarrollo
Flujo de trabajo de desarrollo
Como se menciona en Primer comentario, el proceso de desarrollo típico de las aplicaciones web modernas es simplemente una especie de "servidor de desarrollo" que rastrea los cambios en los archivos locales. Cuando ocurren, se activa la compilación de la aplicación y luego se actualiza en el navegador.
En la mayoría de los marcos modernos, dicho "servidor de desarrollo" está integrado en las herramientas de línea de comandos correspondientes.
Ejemplo local
Primero, veamos cómo funciona esto cuando se ejecutan aplicaciones localmente. Tomemos la aplicación como ejemplo. Reaccionar de artículos anteriores, aunque casi los mismos conceptos de flujo de trabajo se aplican en todos los demás marcos modernos.
Entonces, para iniciar el "servidor de desarrollo" en nuestro ejemplo de React, ingresaremos el siguiente comando:
$ npm run start
Luego en la ventana de la terminal veremos algo como esto:
Y nuestra aplicación se abrirá en el navegador predeterminado:
Ahora, si realizamos cambios en el archivo, la aplicación debería actualizarse en el navegador.
Bien, todo está claro con el desarrollo en modo local, pero ¿cómo lograr lo mismo en OpenShift?
Servidor de desarrollo en OpenShift
Si recuerdas, en Publicación anterior, observamos la llamada fase de ejecución de la imagen S2I y vimos que, de forma predeterminada, el módulo de servicio es responsable de dar servicio a nuestra aplicación web.
Sin embargo, si miras más de cerca ejecutar guión de ese ejemplo, contiene la variable de entorno $NPM_RUN, que le permite ejecutar su comando.
Por ejemplo, podemos usar el módulo nodeshift para implementar nuestra aplicación:
Nota: El ejemplo anterior está abreviado para ilustrar la idea general.
Aquí agregamos la variable de entorno NPM_RUN a nuestra implementación, que le indica al tiempo de ejecución que ejecute el comando de inicio de hilo, que inicia el servidor de desarrollo React dentro de nuestro pod OpenShift.
Si observa el registro de un pod en ejecución, se verá así:
Por supuesto, todo esto no será nada hasta que podamos sincronizar el código local con el código, que también se monitorea para detectar cambios, pero que vive en un servidor remoto.
Sincronización de código remoto y local
Afortunadamente, nodeshift puede ayudar fácilmente con la sincronización y puede usar el comando de vigilancia para realizar un seguimiento de los cambios.
Entonces, después de haber ejecutado el comando para implementar el servidor de desarrollo para nuestra aplicación, podemos usar de forma segura el siguiente comando:
$ npx nodeshift watch
Como resultado, se establecerá una conexión con el pod en ejecución que creamos un poco antes, se activará la sincronización de nuestros archivos locales con el clúster remoto y los archivos en nuestro sistema local comenzarán a ser monitoreados para detectar cambios.
Por lo tanto, si ahora actualizamos el archivo src/App.js, el sistema reaccionará a estos cambios, los copiará al clúster remoto e iniciará el servidor de desarrollo, que luego actualizará nuestra aplicación en el navegador.
Para completar la imagen, mostremos cómo se ven estos comandos completos:
El comando watch es una abstracción además del comando oc rsync; puede obtener más información sobre cómo funciona aquí.
Este fue un ejemplo para React, pero se puede usar exactamente el mismo método con otros marcos, simplemente configure la variable de entorno NPM_RUN según sea necesario.
Tuberías de cambio abierto
A continuación hablaremos sobre una herramienta como OpenShift Pipelines y cómo se puede utilizar como alternativa a las compilaciones encadenadas.
¿Qué son las canalizaciones de OpenShift?
OpenShift Pipelines es un sistema de entrega e integración continua de CI/CD nativo de la nube diseñado para organizar tuberías utilizando Tekton. Tekton es un marco de CI/CD nativo de Kubernetes de código abierto flexible que le permite automatizar la implementación en varias plataformas (Kubernetes, sin servidor, máquinas virtuales, etc.) al abstraerse de la capa subyacente.
Comprender este artículo requiere algunos conocimientos de Pipelines, por lo que le recomendamos encarecidamente que primero lea libro de texto oficial.
Configurando tu ambiente de trabajo
Para jugar con los ejemplos de este artículo, primero debe preparar su entorno de trabajo:
Instale y configure un clúster OpenShift 4. Nuestros ejemplos utilizan CodeReady Containers (CRD) para esto, cuyas instrucciones de instalación se pueden encontrar aquí.
Una vez que el clúster esté listo, deberá instalar Pipeline Operador en él. No tengas miedo, es fácil, instrucciones de instalación. aquí.
Ejecute la herramienta de línea de comando create-react-app para crear una aplicación que luego implementará (esta es una aplicación simple Reaccionar).
(Opcional) Clone el repositorio para ejecutar la aplicación de ejemplo localmente con npm install y luego npm start.
El repositorio de aplicaciones también tendrá una carpeta k8s, que contendrá los YAML de Kubernetes/OpenShift utilizados para implementar la aplicación. Habrá tareas, tareas de clúster, recursos y canalizaciones que crearemos en este repositorios.
Bajando
El primer paso de nuestro ejemplo es crear un nuevo proyecto en el clúster de OpenShift. Llamemos a este proyecto webapp-pipeline y creémoslo con el siguiente comando:
$ oc new-project webapp-pipeline
El nombre de este proyecto aparecerá en el código más adelante, por lo que si decide ponerle otro nombre, no olvide editar el código de ejemplo en consecuencia. A partir de este punto, no iremos de arriba hacia abajo, sino de abajo hacia arriba: es decir, primero crearemos todos los componentes del transportador, y solo luego el transportador en sí.
Entonces, antes que nada...
Tareas
Creemos un par de tareas, que luego ayudarán a implementar la aplicación dentro de nuestra canalización. La primera tarea, apply_manifests_task, se encarga de aplicar el YAML de aquellos recursos de Kubernetes (servicio, implementación y ruta) que se encuentran en la carpeta k8s de nuestra aplicación. La segunda tarea, update_deployment_task, es responsable de actualizar una imagen ya implementada a la creada por nuestra canalización.
No te preocupes si aún no está muy claro. De hecho, estas tareas son algo así como utilidades y las veremos con más detalle un poco más adelante. Por ahora, simplemente creémoslos:
Luego, mediante el comando tkn CLI comprobaremos que se han creado las tareas:
$ tkn task ls
NAME AGE
apply-manifests 1 minute ago
update-deployment 1 minute ago
Nota: Estas son tareas locales para su proyecto actual.
Tareas de clúster
Las tareas de clúster son básicamente las mismas que las tareas simples. Es decir, es una colección reutilizable de pasos que se combinan de una forma u otra al ejecutar una tarea específica. La diferencia es que una tarea de clúster está disponible en todas partes dentro del clúster. Para ver la lista de tareas de clúster que se crean automáticamente al agregar el operador de canalización, usaremos nuevamente el comando CLI tkn:
$ 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
Ahora creemos dos tareas de clúster. El primero generará la imagen S2I y la enviará al registro interno de OpenShift; el segundo es construir nuestra imagen basada en NGINX, usando la aplicación que ya hemos creado como contenido.
Crear y enviar la imagen.
Al crear la primera tarea, repetiremos lo que ya hicimos en el artículo anterior sobre ensamblajes vinculados. Recuerde que usamos la imagen S2I (ubi8-s2i-web-app) para "construir" nuestra aplicación y terminamos con una imagen almacenada en el registro interno de OpenShift. Ahora usaremos esta imagen de la aplicación web S2I para crear un DockerFile para nuestra aplicación y luego usaremos Buildah para hacer la compilación real y enviar la imagen resultante al registro interno de OpenShift, ya que eso es exactamente lo que hace OpenShift cuando implementas tus aplicaciones usando NodeShift. .
No analizaremos esto en detalle, solo nos centraremos en el parámetro OUTPUT_DIR:
params:
- name: OUTPUT_DIR
description: The location of the build output directory
default: build
De forma predeterminada, este parámetro es igual a compilación, que es donde React coloca el contenido ensamblado. Otros frameworks usan diferentes caminos, por ejemplo, en Ember es dist. El resultado de nuestra primera tarea de clúster será una imagen que contendrá el HTML, JavaScript y CSS que recopilamos.
Construya una imagen basada en NGINX
En cuanto a nuestra segunda tarea de clúster, debería crearnos una imagen basada en NGINX, utilizando el contenido de la aplicación que ya hemos creado. Básicamente, esta es la parte de la sección anterior donde analizamos las compilaciones encadenadas.
Para hacer esto, exactamente igual que arriba, crearemos una tarea de clúster webapp-build-runtime:
Si observa el código de estas tareas del clúster, puede ver que no especifica el repositorio Git con el que estamos trabajando ni los nombres de las imágenes que estamos creando. Solo especificamos qué estamos transfiriendo exactamente a Git, o una imagen determinada donde se debe generar la imagen final. Es por eso que estas tareas del clúster se pueden reutilizar cuando se trabaja con otras aplicaciones.
Y aquí pasamos con gracia al siguiente punto...
Recursos
Entonces, dado que, como acabamos de decir, las tareas del clúster deben ser lo más generales posible, necesitamos crear recursos que se utilizarán como entrada (el repositorio Git) y como salida (las imágenes finales). El primer recurso que necesitamos es Git, donde reside nuestra aplicación, algo como esto:
# 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 es de tipo git. La clave de URL en la sección de parámetros apunta a un repositorio específico y especifica la rama maestra (esto es opcional, pero lo escribimos para que esté completo).
Ahora necesitamos crear un recurso para la imagen donde se guardarán los resultados de la tarea s2i-web-app, esto se hace 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í, PipelineResource es de tipo imagen y el valor del parámetro URL apunta al Registro de imágenes interno de OpenShift, específicamente al que se encuentra en el espacio de nombres webapp-pipeline. No olvide cambiar esta configuración si está utilizando un espacio de nombres diferente.
Y finalmente, el último recurso que necesitamos también será de tipo imagen y esta será la imagen NGINX final que luego se usará durante la implementació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
Nuevamente, tenga en cuenta que este recurso almacena la imagen en el registro interno de OpenShift en el espacio de nombres webapp-pipeline.
Para crear todos estos recursos a la vez, usamos el comando crear:
Esta tarea toma parámetros de entrada (recurso gir) y salida (recurso de imagen de aplicación web incorporada). También le pasamos un parámetro especial para que no verifique TLS ya que estamos usando certificados autofirmados:
Al igual que con la tarea anterior, pasamos un recurso, pero ahora es una imagen de aplicación web integrada (el resultado de nuestra tarea anterior). Y como salida volvemos a configurar la imagen. Dado que esta tarea debe ejecutarse después de la anterior, agregamos el campo runAfter:
Las siguientes dos tareas son responsables de utilizar los archivos YAML de servicio, ruta e implementación que se encuentran en el directorio k8s de nuestra aplicación web, y también de actualizar esta implementación al crear nuevas imágenes. Definimos estas dos tareas de clúster al principio del artículo.
Iniciando el transportador
Entonces, se crean todas las partes de nuestra canalización y la ejecutaremos con el siguiente comando:
$ tkn pipeline start build-and-deploy-react
En esta etapa, la línea de comando se usa de forma interactiva y debe seleccionar los recursos apropiados en respuesta a cada una de sus solicitudes: para el recurso git, seleccione web-application-repo, luego para el primer recurso de imagen, build-web-application -image, y finalmente, para el segundo recurso de imagen –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
Ahora verifiquemos el estado de la tubería usando el siguiente comando:
$ tkn pipeline logs -f
Una vez iniciado el pipeline y desplegada la aplicación, podemos solicitar la ruta publicada con el siguiente comando:
$ oc get route react-pipeline-example --template='http://{{.spec.host}}'
Para una mayor visualización, puede visualizar nuestro pipeline en el modo Desarrollador de la consola web en la sección Pipelines, como se muestra en la Fig. 1.
Figura 1. Revisión de ductos en funcionamiento.
Al hacer clic en una canalización en ejecución se muestran detalles adicionales, como se muestra en la Figura 2.
Arroz. 2. Información adicional sobre el oleoducto.
Después de obtener más información, puede ver las aplicaciones en ejecución en la vista. topología, como se muestra en la Fig.3.
Fig 3. Cápsula lanzada.
Al hacer clic en el círculo en la esquina superior derecha del icono se abre nuestra aplicación, como se muestra en la Fig. 4.
Arroz. 4. Ejecutando la aplicación React.
Conclusión
Entonces, mostramos cómo ejecutar un servidor de desarrollo para su aplicación en OpenShift y sincronizarlo con el sistema de archivos local. También vimos cómo simular una plantilla de compilación encadenada usando OpenShift Pipelines. Todos los códigos de ejemplo de este artículo se pueden encontrar aquí.