Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Esta publicación se escribió porque nuestro personal tuvo bastantes conversaciones con clientes sobre el desarrollo de aplicaciones en Kubernetes y los detalles de dicho desarrollo en OpenShift.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Generalmente comenzamos con la tesis de que Kubernetes es solo Kubernetes y OpenShift ya es una plataforma de Kubernetes, como Microsoft AKS o Amazon EKS. Cada una de estas plataformas tiene sus propias ventajas, enfocadas a un público objetivo particular. Y después de eso, la conversación ya desemboca en una comparación de las fortalezas y debilidades de plataformas específicas.

En general, pensamos en escribir esta publicación con un resultado como "Escuche, no importa dónde ejecute el código, en OpenShift o en AKS, en EKS, en algunos Kubernetes personalizados, sí en cualquier Kubernetes". (llamémoslo KUK para abreviar) "Es realmente simple, tanto allí como allí".

Luego planeamos tomar el "Hola mundo" más simple y usarlo para mostrar qué es común y cuáles son las diferencias entre CMC y Red Hat OpenShift Container Platform (en adelante, OCP o simplemente OpenShift).

Sin embargo, mientras escribíamos esta publicación, nos dimos cuenta de que nos hemos acostumbrado tanto a usar OpenShift que simplemente no nos damos cuenta de cómo ha crecido y se ha convertido en una plataforma increíble que se ha convertido en mucho más que una simple distribución de Kubernetes. Tendemos a dar por sentada la madurez y la simplicidad de OpenShift, mientras pasamos por alto su magnificencia.

En general, ha llegado el momento del arrepentimiento activo, y ahora compararemos paso a paso la puesta en marcha de nuestro "Hello World" en KUK y en OpenShift, y lo haremos de la forma más objetiva posible (bueno, excepto que a veces mostramos una actitud personal). actitud hacia el tema). Si está interesado en una opinión puramente subjetiva sobre este tema, puede leerla. aquí (ES). Y en esta publicación nos ceñiremos a los hechos y sólo a los hechos.

Clústeres

Entonces, nuestro "Hola mundo" necesita clústeres. Digamos simplemente "no" a las nubes públicas, para no pagar por servidores, registros, redes, transferencia de datos, etc. En consecuencia, elegimos un clúster simple de un nodo en Minikube (para KUK) y Contenedores listos para código (para un clúster OpenShift). Ambas opciones son realmente fáciles de instalar, pero requieren bastantes recursos en su computadora portátil.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Montaje en KUK-e

Así que, vamos.

Paso 1: crear nuestra imagen de contenedor

Comencemos implementando nuestro "Hola mundo" en minikube. Esto requerirá:

  1. 1. Docker instalado.
  2. 2. Git instalado.
  3. 3. Instalé Maven (en realidad, este proyecto usa el binario mvnw, por lo que puedes prescindir de él).
  4. 4. En realidad, la fuente misma, es decir. clon del repositorio github.com/gcolman/quarkus-hello-world.git

El primer paso es crear un proyecto Quarkus. No te asustes si nunca has usado Quarkus.io: es fácil. Simplemente seleccione los componentes que desea usar en el proyecto (RestEasy, Hibernate, Amazon SQS, Camel, etc.) y luego el propio Quarkus, sin su participación, configura el arquetipo maven y coloca todo en github. Es decir, literalmente, un clic del mouse y listo. Por eso amamos Quarkus.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

La forma más sencilla de crear nuestro "Hola mundo" en una imagen en contenedor es utilizar las extensiones quarkus-maven para Docker, que harán todo el trabajo necesario. Con la llegada de Quarkus, esto se ha vuelto realmente fácil y simple: agregue la extensión contenedor-image-docker y podrá crear imágenes con comandos de Maven.

./mvnw quarkus:add-extension -Dextensions=”container-image-docker”

Y finalmente, construimos nuestra imagen usando Maven. Como resultado, nuestro código fuente se convierte en una imagen de contenedor lista para usar, que ya se puede ejecutar en el tiempo de ejecución del contenedor.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

./mvnw -X clean package -Dquarkus.container-image.build=true

Eso, de hecho, es todo, ahora puede ejecutar el contenedor con el comando docker run, asignando nuestro servicio al puerto 8080 para que se pueda acceder a él.

docker run -i — rm -p 8080:8080 gcolman/quarkus-hello-world

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Una vez iniciada la instancia del contenedor, solo queda comprobar con el comando curl que nuestro servicio se está ejecutando:

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Entonces, todo funciona y fue realmente fácil y sencillo.

Paso 2: envíe nuestro contenedor al repositorio de imágenes del contenedor

Por ahora, la imagen que creamos se almacena localmente en nuestro contenedor de almacenamiento local. Si queremos utilizar esta imagen en nuestro entorno KUK, debemos colocarla en algún otro repositorio. Kubernetes no tiene estas características, por lo que usaremos dockerhub. Porque, en primer lugar, es gratis y, en segundo lugar, (casi) todo el mundo lo hace.

Esto también es muy simple, aquí solo se necesita una cuenta de Dockerhub.

Entonces, instalamos Dockerhub y enviamos nuestra imagen allí.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Paso 3: iniciar Kubernetes

Hay muchas formas de armar una configuración de Kubernetes para ejecutar nuestro "Hola Mundo", pero usaremos la más simple de ellas, porque somos esas personas...

Primero, iniciamos el clúster minikube:

minikube start

Paso 4: Implementar nuestra imagen de contenedor

Ahora necesitamos convertir nuestro código y la imagen del contenedor a la configuración de Kubernetes. En otras palabras, necesitamos un pod y una definición de implementación que apunte a la imagen de nuestro contenedor en Dockerhub. Una de las formas más sencillas de hacer esto es ejecutar el comando de creación de implementación que apunte a nuestra imagen:

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

kubectl create deployment hello-quarkus — image =gcolman/quarkus-hello-world:1.0.0-SNAPSHOT

Con este comando, le dijimos a nuestro COCINERO que creara una configuración de implementación, que debería contener la especificación del pod para nuestra imagen de contenedor. Este comando también aplicará esta configuración a nuestro clúster de minikube y creará una implementación que descargará nuestra imagen de contenedor y ejecutará un pod en el clúster.

Paso 5: abra el acceso a nuestro servicio

Ahora que tenemos una imagen de contenedor implementada, es hora de pensar en cómo configurar el acceso externo a este servicio Restful, que, de hecho, está programado en nuestro código.

Hay muchas maneras aquí. Por ejemplo, puede utilizar el comando exponer para crear automáticamente componentes de Kubernetes adecuados, como servicios y puntos finales. En realidad, esto es lo que haremos ejecutando el comando de exposición para nuestro objeto de implementación:

kubectl expose deployment hello-quarkus — type=NodePort — port=8080

Detengámonos por un momento en la opción "-type" del comando de exposición.

Cuando exponemos y creamos los componentes necesarios para ejecutar nuestro servicio, necesitamos, entre otras cosas, poder conectarnos desde el exterior al servicio hello-quarkus que se encuentra dentro de nuestra red definida por software. y parámetro tipo nos permite crear y conectar cosas como balanceadores de carga para enrutar el tráfico a esa red.

Por ejemplo, escribir tipo=Equilibrador de carga, inicializamos automáticamente el equilibrador de carga de la nube pública para conectarnos a nuestro clúster de Kubernetes. Esto, por supuesto, es genial, pero debe comprender que dicha configuración estará estrechamente vinculada a una nube pública específica y será más difícil transferirla entre instancias de Kubernetes en diferentes entornos.

En nuestro ejemplo tipo=PuertoNodo, es decir, la llamada a nuestro servicio pasa por la dirección IP del nodo y el número de puerto. Esta opción le permite no utilizar ninguna nube pública, pero requiere una serie de pasos adicionales. Primero, necesita su propio balanceador de carga, por lo que implementaremos el balanceador de carga NGINX en nuestro clúster.

Paso 6: configurar un equilibrador de carga

minikube tiene una serie de características de plataforma que facilitan la creación de los componentes necesarios para el acceso externo, como los controladores de ingreso. Minikube viene incluido con el controlador de ingreso Nginx y todo lo que tenemos que hacer es habilitarlo y configurarlo.

minikube addons enable ingress

Ahora, con solo un comando, crearemos un controlador de ingreso Nginx que funcionará dentro de nuestro clúster minikube:

ingress-nginx-controller-69ccf5d9d8-j5gs9 1/1 Running 1 33m

Paso 7: configurar la entrada

Ahora necesitamos configurar el controlador de ingreso de Nginx para aceptar solicitudes de hello-quarkus.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Y finalmente, necesitamos aplicar esta configuración.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

kubectl apply -f ingress.yml

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Dado que estamos haciendo todo esto en nuestra propia máquina, simplemente agregamos la dirección IP de nuestro nodo al archivo /etc/hosts para dirigir las solicitudes http a nuestro minikube al balanceador de carga NGINX.

192.168.99.100 hello-quarkus.info

Eso es todo, ahora nuestro servicio minikube está disponible desde el exterior a través del controlador de ingreso Nginx.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Bueno, eso fue fácil, ¿verdad? ¿O no tanto?

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Ejecutar en OpenShift (contenedores listos para código)

Y ahora veamos cómo se hace todo en Red Hat OpenShift Container Platform (OCP).

Como en el caso de minikube, elegimos un esquema con un clúster OpenShift de un solo nodo en forma de Code Ready Containers (CRC). Solía ​​​​llamarse minishift y se basaba en el proyecto OpenShift Origin, pero ahora es CRC y se basa en OpenShift Container Platform de Red Hat.

Aquí, lo siento, no podemos evitar decir: "¡OpenShift es genial!"

Inicialmente, pensamos en escribir que el desarrollo en OpenShift no es diferente del desarrollo en Kubernetes. Y de hecho, así es. Pero mientras escribíamos esta publicación, recordamos cuántos movimientos innecesarios tienes que hacer cuando no tienes OpenShift y, por lo tanto, nuevamente, es hermoso. Nos encanta que las cosas sean fáciles, y lo fácil que es implementar y ejecutar nuestro ejemplo en OpenShift en comparación con minikube es lo que nos inspiró a escribir esta publicación.

Repasemos el proceso y veamos qué debemos hacer.

Entonces, en el ejemplo del minikube, comenzamos con Docker... Espera, ya no necesitamos que Docker esté instalado en la máquina.

Y no necesitamos un git local.
Y Maven no es necesario.
Y no es necesario crear una imagen de contenedor a mano.
Y no es necesario buscar ningún repositorio de imágenes de contenedores.
Y no es necesario instalar un controlador de ingreso.
Y tampoco es necesario configurar el ingreso.

¿Lo entiendes? Para implementar y ejecutar nuestra aplicación en OpenShift, no se necesita nada de lo anterior. Y el proceso en sí es el siguiente.

Paso 1: iniciar su clúster OpenShift

Usamos Code Ready Containers de Red Hat, que es esencialmente el mismo Minikube, pero solo con un clúster Openshift completo de un solo nodo.

crc start

Paso 2: crear e implementar la aplicación en el clúster de OpenShift

Es en este paso donde la simplicidad y conveniencia de OpenShift se manifiestan en todo su esplendor. Como ocurre con todas las distribuciones de Kubernetes, tenemos muchas formas de ejecutar una aplicación en un clúster. Y, como en el caso de KUK, elegimos específicamente el más sencillo.

OpenShift siempre se ha creado como una plataforma para crear y ejecutar aplicaciones en contenedores. La creación de contenedores siempre ha sido una parte integral de esta plataforma, por lo que hay muchos recursos adicionales de Kubernetes para las tareas correspondientes.

Usaremos el proceso Source 2 Image (S2I) de OpenShift, que tiene varias formas diferentes de tomar nuestro código fuente (código o binarios) y convertirlo en una imagen en contenedor que se ejecuta en un clúster de OpenShift.

Para ello necesitamos dos cosas:

  • Nuestro código fuente en el repositorio de git
  • Imagen del constructor, a partir de la cual se realizará el montaje.

Hay muchas imágenes de este tipo, mantenidas tanto por Red Hat como por la comunidad, y usaremos la imagen OpenJDK, bueno, ya que estoy creando una aplicación Java.

Puede ejecutar una compilación S2I tanto desde la consola gráfica de OpenShift Developer como desde la línea de comandos. Usaremos el comando new-app y le indicaremos dónde obtener la imagen del generador y nuestro código fuente.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

oc new-app registry.access.redhat.com/ubi8/openjdk-11:latest~https://github.com/gcolman/quarkus-hello-world.git

Eso es todo, nuestra aplicación está creada. Al hacerlo, el proceso S2I hizo lo siguiente:

  • Creé un módulo de compilación de servicios para todo tipo de cosas relacionadas con la creación de la aplicación.
  • Creó una configuración de OpenShift Build.
  • Descargué la imagen del generador en el registro interno de la ventana acoplable OpenShift.
  • Cloné "Hello World" en el repositorio local.
  • Vi que había un maven pom allí y compilé la aplicación con maven.
  • Creó una nueva imagen de contenedor que contiene la aplicación Java compilada y colocó esta imagen en el registro de contenedor interno.
  • Creé una implementación de Kubernetes con especificaciones para un pod, servicio, etc.
  • Se lanzó la imagen del contenedor de implementación.
  • Se eliminó el módulo de compilación del servicio.

Hay mucho en esta lista, pero lo principal es que toda la compilación se lleva a cabo exclusivamente dentro de OpenShift, el registro interno de Docker está dentro de OpenShift y el proceso de compilación crea todos los componentes de Kubernetes y los ejecuta en el clúster.

Si monitorea visualmente el inicio de S2I en la consola, puede ver cómo se inicia el módulo de compilación durante la compilación.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Y ahora echemos un vistazo a los registros del módulo de creación: en primer lugar, allí puede ver cómo Maven hace su trabajo y descarga las dependencias para crear nuestra aplicación Java.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Una vez completada la compilación de Maven, se inicia la compilación de la imagen del contenedor y luego esta imagen compilada se envía al repositorio interno.

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Todo, el proceso de montaje está completo. Ahora asegurémonos de que los pods y servicios de nuestra aplicación se hayan iniciado en el clúster.

oc get service

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Eso es todo. Y sólo hay un equipo. Todo lo que tenemos que hacer es exponer este servicio para acceso externo.

Paso 3: exponer el servicio para acceder desde el exterior

Como en el caso de KUK, en la plataforma OpenShift, nuestro “Hello World” también necesita un enrutador para dirigir el tráfico externo a un servicio dentro del clúster. En OpenShift esto lo hace muy fácil. En primer lugar, el componente de enrutamiento HAProxy está instalado en el clúster de forma predeterminada (se puede cambiar al mismo NGINX). En segundo lugar, existen recursos especiales y altamente configurables llamados Rutas, que recuerdan a los objetos Ingress del viejo Kubernetes (de hecho, las Rutas de OpenShift influyeron mucho en el diseño de los objetos Ingress, que ahora se pueden usar en OpenShift), pero para nuestro "Hola Mundo", y en casi todos los demás casos, la Ruta estándar nos basta sin necesidad de configuración adicional.

Para crear un FQDN enrutable para "Hello World" (sí, OpenShiift tiene su propio DNS para enrutar por nombres de servicios), simplemente exponemos nuestro servicio:

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

oc expose service quarkus-hello-world

Si observa la ruta recién creada, podrá encontrar el FQDN y otra información de ruta allí:

oc get route

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

Y por último accedemos a nuestro servicio desde el navegador:

Lo siento, OpenShift, no te apreciamos lo suficiente y te dimos por sentado.

¡Pero ahora fue realmente fácil!

Nos encanta Kubernetes y todo lo que esta tecnología te permite hacer, y también nos encanta la sencillez y la ligereza. Kubernetes fue diseñado para hacer que los contenedores distribuidos y escalables sean increíblemente fáciles de operar, pero su simplicidad ya no es suficiente para llevar las aplicaciones a producción en la actualidad. Aquí es donde OpenShift entra en juego, manteniéndose al día y ofreciendo Kubernetes centrado en el desarrollador. Se ha invertido mucho esfuerzo para adaptar la plataforma OpenShift específicamente para el desarrollador, incluida la creación de herramientas como S2I, ODI, Portal de desarrollador, OpenShift Operador Framework, integración IDE, Catálogos de desarrollador, integración de Helm, monitoreo y muchos otros.

Esperamos que este artículo haya sido interesante y útil para usted. Y puede encontrar recursos adicionales, materiales y otras cosas útiles para desarrollar en la plataforma OpenShift en el portal. Desarrolladores de Red Hat.

Fuente: habr.com

Añadir un comentario