Guía de Kubernetes, Parte 2: Crear y trabajar con un clúster

La última vez, examinamos dos enfoques para trabajar con microservicios. En particular, uno de ellos implica el uso de contenedores Docker, en los que puede ejecutar el código de microservicios y programas auxiliares. Hoy, utilizando nuestras imágenes de contenedor existentes, trabajaremos con Kubernetes.



Introduciendo Kubernetes


Lo prometo, y no exagero en absoluto cuando lees este artículo, pregúntate: "¿Por qué Kubernetes no se llama Supernetes?"


Supernetes

Si leyó la parte anterior de este material, sabrá que allí analizamos muchas cosas relacionadas con la preparación de aplicaciones para la contenedorización y el trabajo con contenedores Docker. Puede parecerle que lo más difícil le espera ahora, pero, de hecho, de lo que vamos a hablar aquí es mucho más simple de lo que ya hemos descubierto. La única razón por la que aprender Kubernetes puede parecer una tarea desalentadora para alguien es la cantidad de información adicional que necesita para comprender a Kubernetes y usarlo de manera efectiva. Ya hemos discutido toda la "información adicional" necesaria para el desarrollo exitoso de Kubernetes.

▍¿Qué es Kubernetes?


En la primera parte de este artículo, después de lanzar microservicios en contenedores, se le pidió que pensara sobre el tema de escalar aplicaciones en contenedores.
Sugiero reflexionar sobre esto juntos, en el formato de preguntas y respuestas:

Pregunta: ¿Cómo se escalan las aplicaciones en contenedores?
Respuesta: Inicie contenedores adicionales.

Pregunta: ¿Y cómo se distribuye la carga entre ellos? ¿Qué sucede si un determinado servidor ya se utiliza al máximo y el contenedor debe implementarse en otro servidor? ¿Cómo encontrar la forma más eficiente de usar hardware?
Respuesta: Entonces ... buscaré en Internet ...

Pregunta: ¿Cómo actualizar programas sin interrumpir el sistema? Y, si la actualización contiene un error, ¿cómo volver a la versión de trabajo de la aplicación?

De hecho, es la tecnología de Kubernetes la que da respuestas dignas a estas y muchas otras preguntas. Trataré de reducir la definición de Kubernetes a una oración: "Kubernetes es un sistema de gestión de contenedores que abstrae la infraestructura subyacente (el entorno en el que se ejecutan los contenedores)".

Creo que ahora no tiene muy claro el concepto de "gestión de contenedores", aunque ya lo hemos mencionado. A continuación consideraremos esta tecnología en la práctica. Sin embargo, el concepto de "abstraer la infraestructura básica" se encuentra por primera vez. Por lo tanto, ahora lo consideraremos.

▍Abstracción de infraestructura básica


Kubernetes permite que las aplicaciones se alejen de la infraestructura, brindándonos una API simple a la que puede enviar solicitudes. Kubernetes intenta cumplir con estas solicitudes utilizando todas sus capacidades. Por ejemplo, en un lenguaje normal, una solicitud similar se puede describir de la siguiente manera: "Kubernetes, expanda 4 contenedores de imágenes X". Después de recibir el comando, Kubernetes encontrará nodos que no estén demasiado ocupados (también se denominan "nodos", del "nodo" en inglés), en los que puede implementar nuevos contenedores.


Solicitud del servidor API

¿Qué significa esto para el desarrollador? Esto significa que no necesita preocuparse por la cantidad de nodos, por dónde exactamente se lanzan los contenedores o cómo interactúan. No tiene que lidiar con la optimización del hardware o preocuparse por los nodos que podrían estar funcionando mal (y algo similar, de acuerdo con la ley de Murphy, ciertamente sucederá), ya que, si es necesario, se pueden agregar nuevos nodos al clúster de Kubernetes. Si algo está mal con algunos nodos existentes, Kubernetes desplegará contenedores en aquellos nodos que todavía están en buen estado.

Gran parte de lo que se muestra en la figura anterior ya le es familiar. Pero también hay algo nuevo:

  • Servidor API Hacer llamadas a este servidor es la única forma de interactuar con el clúster que tenemos, ya sea que estemos hablando de iniciar o detener contenedores, verificar el estado del sistema, trabajar con registros o realizar otras acciones.
  • Kubelet Este es un agente que monitorea los contenedores dentro del nodo e interactúa con el nodo principal.

Tenga en cuenta que en un par de oraciones anteriores usamos el término "contenedor", pero aquí sería más correcto usar el término "pod". Estas entidades a menudo se llaman "pods" en las publicaciones en idioma ruso, y algunas veces "pods", en la documentación , aclarando el concepto de "pod", hablan de una "bandada de ballenas" (pod of whales) o "pea pod" pero nadie los llama "bandadas" o "vainas". Hablando de ellos, usaremos la palabra "debajo". Ahora puede considerarlos contenedores, hablaremos más sobre las vainas a continuación.

Nos detendremos en esto por ahora, ya que podemos hablar de todo esto más adelante, y, además, hay muchos buenos materiales sobre la teoría de Kubernetes. Por ejemplo, esta es documentación oficial, aunque no es fácil de leer, o libros como este .

▍ Estandarización del trabajo con proveedores de servicios en la nube


Otra fortaleza de Kubernetes radica en el hecho de que esta tecnología contribuye a la estandarización del trabajo con proveedores de servicios en la nube (Cloud Service Provider, CSP). Esta es una declaración audaz. Considere el siguiente ejemplo. Un especialista que conoce bien Azure o Google Cloud Platform tiene que trabajar en un proyecto diseñado para un entorno en la nube completamente nuevo para él, con el que no está familiarizado. En esta situación, muchas cosas pueden salir mal. Por ejemplo, los plazos para la entrega del proyecto pueden retrasarse, la empresa cliente del proyecto puede necesitar alquilar más recursos en la nube de lo planeado, y así sucesivamente.

Al usar Kubernetes, tal problema simplemente no puede surgir, ya que, independientemente del proveedor de servicios en la nube en particular del que estamos hablando, trabajar con Kubernetes siempre se ve igual. El desarrollador, en un estilo declarativo, le dice al servidor API lo que necesita, y Kubernetes trabaja con los recursos del sistema, lo que le permite ignorar los detalles de la implementación de este sistema.

Deténgase un poco en esta idea, ya que esta es una oportunidad muy poderosa de Kubernetes. Para las empresas, esto significa que sus decisiones no están vinculadas a un CSP específico. Si una empresa encuentra una mejor oferta en el mercado de servicios en la nube, puede aprovechar esta oferta libremente al cambiar a un nuevo proveedor. Además, la experiencia adquirida por los especialistas de la compañía no se pierde en ningún lado.

Ahora hablemos sobre el uso práctico de Kubernetes

Práctica de Kubernetes: vainas


Configuramos el lanzamiento de microservicios en contenedores, el proceso de configuración fue bastante tedioso, pero logramos llegar a un sistema que funcionara. Además, como ya se mencionó, nuestra solución no escala bien y no es resistente a fallas. Resolveremos estos problemas con Kubernetes. A continuación, llevaremos nuestro sistema a un formulario correspondiente al siguiente esquema. A saber, los contenedores serán gestionados por Kubernetes.


Los microservicios funcionan en un clúster gestionado por Kubernetes

Aquí, utilizaremos Minikube para la implementación local del clúster y para probar las capacidades de Kubernetes, aunque todo lo que haremos aquí se puede hacer utilizando plataformas en la nube como Azure o Google Cloud Platform.

▍Instalación e inicio de Minikube


Para instalar Minikube, siga las instrucciones que se encuentran en la documentación . Durante la instalación de Minikube, también instalará Kubectl. Este es un cliente que permite realizar solicitudes al servidor API de Kubernetes.

Para iniciar Minikube, ejecute el minikube start y, una vez que se complete, ejecute el kubectl get nodes . Como resultado, debería ver algo como lo siguiente:

 kubectl get nodes NAME       STATUS ROLES     AGE VERSION minikube   Ready <none>    11m v1.9.0 

Minikube pone a nuestra disposición un clúster que consta de un solo nodo. Es cierto, esto nos queda bastante bien. Aquellos que trabajan con Kubernetes no necesitan preocuparse exactamente por cuántos nodos hay en el clúster, ya que Kubernetes le permite abstraerse de dichos detalles.

Ahora hablemos de las vainas.

▍Pods


Realmente me gustan los contenedores, y probablemente también te gusten ahora. ¿Por qué Kubernetes nos ofrece utilizar pods, entidades que son las unidades informáticas mínimas desplegables en este sistema? ¿Bajo qué funciones realiza? El hecho es que el hogar puede incluir uno o más contenedores que comparten el mismo tiempo de ejecución.

Pero, ¿es necesario llevar a cabo, por ejemplo, dos contenedores en un hogar? Cómo decirlo ... Por lo general, solo hay un contenedor por contenedor, y eso es lo que vamos a hacer. Pero para aquellos casos en los que, por ejemplo, dos contenedores necesitan acceso compartido al mismo almacén de datos, o si están conectados mediante la técnica de comunicación entre procesos, o si están estrechamente conectados por alguna otra razón, todo esto puede realizarse ejecutándolos en un hogar. Otra posibilidad en la que las cápsulas difieren es que no tienen que usar contenedores Docker. Si es necesario, aquí puede aplicar otras tecnologías para la contenedorización de aplicaciones, por ejemplo, Rkt .

El siguiente diagrama muestra las propiedades de hogar numeradas.


Propiedades del hogar

Considere estas propiedades.

  1. Cada pod en un clúster de Kubernetes tiene una dirección IP única.
  2. Un hogar puede contener muchos recipientes. Comparten los números de puerto disponibles, es decir, pueden intercambiar información entre ellos a través de localhost (naturalmente, no pueden usar los mismos puertos). La interacción con los contenedores ubicados en otros pods se organiza utilizando las direcciones IP de estos pods.
  3. Los contenedores en pods comparten volúmenes de almacenamiento de datos, dirección IP, números de puerto, espacio de nombres IPC.

Cabe señalar que los contenedores tienen sus propios sistemas de archivos aislados, pero pueden compartir datos utilizando el recurso de Kubernetes llamado Volumen .

Para nosotros, lo que ya se ha dicho sobre los hogares es suficiente para seguir dominando los Kubernetes. Lea más sobre ellos aquí .

▍ Descripción del hogar


El siguiente es un archivo de manifiesto para la aplicación sa-frontend .

 apiVersion: v1 kind: Pod                                            # 1 metadata: name: sa-frontend                                  # 2 spec:                                                # 3 containers:   - image: rinormaloku/sentiment-analysis-frontend # 4     name: sa-frontend                              # 5     ports:       - containerPort: 80 

Vamos a explicar algunos de los parámetros especificados en él.

  1. Kind : especifica el tipo de recurso de Kubernetes que queremos crear. En nuestro caso, este es Pod .
  2. Name : nombre del recurso. Lo llamamos sa-frontend .
  3. Spec : un objeto que describe el estado deseado del recurso. La propiedad más importante aquí es la variedad de contenedores.
  4. Image : la imagen del contenedor que queremos ejecutar en este pod.
  5. Name : un nombre único para el contenedor debajo.
  6. ContainerPort : el puerto en el que el contenedor está escuchando. Este parámetro puede considerarse una indicación para quién lee este archivo (si omite este parámetro, esto no limitará el acceso al puerto).

▍Creando un hogar SA-Frontend


El archivo de descripción del pod del que hablamos se puede encontrar en resource-manifests/sa-frontend-pod.yaml . Debe ir a esta carpeta utilizando las herramientas del terminal o, cuando llame al comando apropiado, especifique la ruta completa al archivo. Aquí está este comando y un ejemplo de una reacción del sistema:

 kubectl create -f sa-frontend-pod.yaml pod "sa-frontend" created 

Para saber si funciona bajo, ejecute el siguiente comando:

 kubectl get pods NAME                          READY STATUS RESTARTS AGE sa-frontend                   1/1 Running 0 7s 

Si el estado del hogar durante la ejecución de este comando es ContainerCreating , puede ejecutar el mismo comando con el --watch . Debido a esto, cuando el hogar está en el estado En Running , la información sobre esto se mostrará automáticamente.

▍Acceso a la aplicación desde el exterior


Para organizar el acceso a la aplicación desde el exterior, será correcto crear un recurso Kubernetes del tipo de Servicio, del que hablaremos a continuación, pero aquí, por brevedad, utilizaremos un reenvío de puertos simple:

 kubectl port-forward sa-frontend 88:80 Forwarding from 127.0.0.1:88 -> 80 

Si ahora utiliza un navegador en 127.0.0.1:88 , puede ver la página de la aplicación React.

Approach Enfoque de escala incorrecto


Ya hemos dicho que una de las capacidades de Kubernetes es el escalado de aplicaciones. Para experimentar esta oportunidad, ejecutaremos otra debajo. Cree una descripción de otro recurso Pod colocando el siguiente código en el archivo sa-frontend-pod2.yaml :

 apiVersion: v1 kind: Pod                                           metadata: name: sa-frontend2      #   spec:                                                containers:   - image: rinormaloku/sentiment-analysis-frontend     name: sa-frontend                                  ports:       - containerPort: 80 

Como puede ver, si compara esta descripción con lo que examinamos anteriormente, el único cambio es el valor de la propiedad Name .

Cree uno nuevo en:

 kubectl create -f sa-frontend-pod2.yaml pod "sa-frontend2" created 

Asegúrese de que se esté ejecutando:

 kubectl get pods NAME                          READY STATUS RESTARTS AGE sa-frontend                   1/1 Running 0 7s sa-frontend2                  1/1 Running 0 7s 

¡Ahora tenemos dos hogares! Es cierto, no hay nada especial para disfrutar aquí. Tenga en cuenta que la solución al problema de escalado de la aplicación que se muestra aquí tiene muchos inconvenientes. Hablaremos sobre cómo hacerlo correctamente en la sección sobre otro recurso de Kubernetes llamado Implementación.

Ahora considere lo que obtuvimos después de lanzar dos hogares idénticos. A saber, el servidor web Nginx ahora se ejecuta en dos pods diferentes. En este sentido, podemos hacer dos preguntas:

  1. ¿Cómo dar acceso a estos servidores desde el exterior, por URL?
  2. ¿Cómo organizar el equilibrio de carga entre ellos?


Enfoque de escala incorrecto

Entre las herramientas de Kubernetes hay recursos del formulario Servicio. Hablemos de ellos.

Práctica Kubernetes: Servicios


Los servicios de Kubernetes actúan como puntos de acceso a conjuntos de hogares que proporcionan la misma funcionalidad que estos hogares. Los servicios realizan la solución de tareas difíciles de trabajar con hogares y equilibrar la carga entre ellos.


El servicio Kubernetes sirve direcciones IP

En nuestro clúster de Kubernetes habrá pods que implementarán diferentes funciones. Esta es una aplicación front-end, una aplicación web Spring y una aplicación Flask escrita en Python. Esto plantea la cuestión de cómo el servicio debe comprender con qué tipo de pods necesita trabajar, es decir, cómo averiguar sobre la base de qué información el sistema debe generar una lista de puntos finales para los pods.

Esto se hace con otra abstracción de Kubernetes llamada Label. El trabajo con etiquetas consta de dos etapas:

  1. La asignación de etiquetas dará el servicio para trabajar.
  2. Aplicando un "selector" al servicio, que determina a qué pods se asignan las etiquetas, el servicio funcionará.

Quizás sea más fácil imaginarlo como ilustración que describirlo.


Pods etiquetados y sus archivos de manifiesto

Vemos aquí dos hogares que, utilizando la app: sa-frontend construcción de app: sa-frontend , se les asignan las mismas etiquetas. El servicio está interesado en las cápsulas con tales marcas.

▍Etiquetas


Las etiquetas ofrecen a los desarrolladores una forma sencilla de organizar los recursos de Kubernetes. Son pares clave-valor; puede asignarlos a cualquier recurso. Modifique los archivos de descripción del hogar de la aplicación frontend y llévelos a la vista que se muestra en la figura anterior. Después de eso, guarde estos archivos y ejecute los siguientes comandos:

 kubectl apply -f sa-frontend-pod.yaml Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply pod "sa-frontend" configured kubectl apply -f sa-frontend-pod2.yaml Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply pod "sa-frontend2" configured 

Cuando se ejecutan estos comandos, el sistema emitirá advertencias (no nos conviene que usemos apply lugar de create , entendemos esto), pero, después de una advertencia, informa que los pods correspondientes están configurados. Podemos verificar si las etiquetas fueron asignadas, filtrando los registros para los que queremos mostrar información:

 kubectl get pod -l app=sa-frontend NAME           READY STATUS    RESTARTS AGE sa-frontend    1/1 Running   0 2h sa-frontend2   1/1 Running   0 2h 

Otra forma de verificar que las etiquetas hayan sido asignadas es adjuntar la tecla --show-labels al comando anterior. Debido a esto, la información sobre sus pods también incluirá datos sobre sus marcas.

Ahora se han asignado etiquetas y estamos listos para configurar el servicio para trabajar con ellas. Por lo tanto, tomaremos la descripción de un servicio como LoadBalancer .


Balanceo de carga usando un servicio como LoadBalancer

▍ Descripción del servicio


Aquí hay una descripción YAML de un servicio como LoadBalancer :

 apiVersion: v1 kind: Service              # 1 metadata: name: sa-frontend-lb spec: type: LoadBalancer       # 2 ports: - port: 80               # 3   protocol: TCP          # 4   targetPort: 80         # 5 selector:                # 6   app: sa-frontend       # 7 

Explica este texto:

  1. Kind : creamos un servicio, un recurso de Service .
  2. Type : el tipo de recurso indicado en su especificación. Elegimos el tipo LoadBalancer , porque con este servicio queremos resolver el problema de equilibrar la carga entre los hogares.
  3. Port : puerto en el que el servicio acepta solicitudes.
  4. Protocol : el protocolo utilizado por el servicio.
  5. TargetPort : puerto al que se redirigen las solicitudes entrantes.
  6. Selector : un objeto que contiene información sobre con qué pods debería trabajar el servicio.
  7. app: sa-frontend : esta propiedad indica con qué pods funcionará el servicio. A saber, estos son los pods a los que se ha asignado la etiqueta app: sa-frontend .

Para crear un servicio, debe ejecutar el siguiente comando:

 kubectl create -f service-sa-frontend-lb.yaml service "sa-frontend-lb" created 

Puede verificar el estado del servicio de la siguiente manera:

 kubectl get svc NAME             TYPE CLUSTER-IP      EXTERNAL-IP PORT(S) AGE sa-frontend-lb   LoadBalancer 10.101.244.40   <pending> 80:30708/TCP 7m 

Aquí puede ver que la propiedad EXTERNAL-IP está en el estado <pending> , pero no puede esperar a que cambie. Esto se debe al hecho de que usamos Minikube. Si creamos un servicio similar mientras trabajamos con un determinado proveedor de servicios en la nube, como Azure o Google Cloud Platform, entonces el servicio tendría una dirección IP pública que permitiría acceder desde Internet.

A pesar de esto, Minikube no nos permitirá perder el tiempo, dándonos un comando útil para la depuración local del sistema:

 minikube service sa-frontend-lb Opening kubernetes service default/sa-frontend-lb in default browser... 

Gracias a este comando, se lanzará un navegador que accederá al servicio. Después de que el servicio recibe la solicitud, la redirigirá a uno de los hogares (no importa en cuál de ellos estará). Esta abstracción nos permite percibir un grupo de hogares como una entidad única y trabajar con ellos, utilizando el servicio como un único punto de acceso a ellos.

En esta sección, hablamos sobre cómo asignar etiquetas a los recursos, cómo usarlos al configurar servicios como selectores. Aquí describimos y creamos un servicio como LoadBalancer . Gracias a esto, resolvimos el problema de escalar la aplicación (el escalado consiste en agregar nuevos hogares con las etiquetas correspondientes al clúster) y organizar el equilibrio de carga entre los hogares utilizando el servicio como punto de entrada.

Práctica de Kubernetes: implementaciones


La implementación es una abstracción de Kubernetes que nos permite controlar lo que siempre está presente en el ciclo de vida de la aplicación. Se trata de gestionar los cambios de la aplicación. Las aplicaciones que no cambian son, por así decirlo, aplicaciones "muertas". Si la aplicación "vive", entonces puede encontrar el hecho de que sus requisitos cambian periódicamente, su código se expande, este código se empaqueta y se implementa. Además, se pueden cometer errores en cada paso del proceso.

Un recurso del tipo Implementación le permite automatizar el proceso de transición de una versión de una aplicación a otra. Esto se hace sin interrumpir el sistema, y ​​si se produce un error durante este proceso, tendremos la oportunidad de volver rápidamente a la versión anterior y funcional de la aplicación.

▍Uso de implementaciones


Ahora el clúster tiene dos hogares y un servicio que les da acceso desde el exterior y equilibra la carga en ellos.


Estado actual del clúster

Hablamos sobre el hecho de que ejecutar dos hogares diferentes con la misma funcionalidad no es una buena idea. Al utilizar dicho esquema, tenemos que trabajar con cada hogar individualmente, creando, actualizando, eliminando cada hogar específico, observando su estado. Con este enfoque, no hay necesidad de hablar sobre una actualización rápida del sistema o la reversión rápida de una actualización fallida. No estamos satisfechos con este estado de cosas, por lo tanto, vamos a recurrir a la posibilidad de un recurso de implementación, que tiene como objetivo resolver los problemas anteriores.

Antes de continuar con el trabajo, formulemos sus objetivos, que nos darán pautas que serán útiles al analizar el archivo de manifiesto de implementación. Entonces, esto es lo que necesitamos:

  1. Queremos poder crear dos hogares basados ​​en un contenedor rinormaloku/sentiment-analysis-frontend .
  2. Necesitamos un sistema de implementación de aplicaciones que le permita funcionar sin interrupciones cuando se actualiza.
  3. Queremos que se asigne la etiqueta de la app: sa-frontend , que permitirá que el servicio sa-frontend-lb detecte estos pods.

Ahora expresaremos estos requisitos como una descripción del recurso de implementación.

▍ Descripción de la implementación


Aquí hay una descripción de YAML de un recurso de tipo Implementación, que se creó teniendo en cuenta los requisitos del sistema anteriores:

 apiVersion: extensions/v1beta1 kind: Deployment                                          # 1 metadata: name: sa-frontend spec: replicas: 2                                             # 2 minReadySeconds: 15 strategy:   type: RollingUpdate                                   # 3   rollingUpdate:     maxUnavailable: 1                                   # 4     maxSurge: 1                                         # 5 template:                                               # 6   metadata:     labels:       app: sa-frontend                                  # 7   spec:     containers:       - image: rinormaloku/sentiment-analysis-frontend         imagePullPolicy: Always                         # 8         name: sa-frontend         ports:           - containerPort: 80 

Analicemos esta descripción:

  1. Kind : aquí dice que estamos describiendo un recurso de la vista Deployment .
  2. Replicas : una propiedad del objeto de especificación de implementación que define cuántas instancias (réplicas) de hogares se ejecutan.
  3. Type : describe la estrategia utilizada en esta implementación al cambiar de la versión actual a una nueva. RollingUpdate estrategia RollingUpdate proporciona cero tiempo de inactividad del sistema durante las actualizaciones.
  4. MaxUnavailable : esta es una propiedad del objeto RollingUpdate , que establece el número máximo de hogares no disponibles (en comparación con el número deseado de hogares) al realizar una actualización secuencial del sistema. En nuestro despliegue, que implica la presencia de 2 réplicas, el valor de esta propiedad indica que después de completar un pod, se ejecutará otro, lo que hace que la aplicación esté disponible durante la actualización.
  5. MaxSurge : esta es una propiedad del objeto RollingUpdate que describe el número máximo de hogares que se pueden agregar a una implementación (en comparación con un número determinado de hogares). En nuestro caso, su valor, 1, significa que, al cambiar a una nueva versión del programa, podemos agregar otro sub al clúster, lo que conducirá al hecho de que se pueden iniciar hasta tres hogares simultáneamente.
  6. Template : este objeto define la plantilla de hogar que el recurso de Deployment descrito usará para crear nuevos hogares. Probablemente encuentre esta configuración familiar.
  7. app: sa-frontend : etiqueta para hogares creados de acuerdo con un patrón dado.
  8. ImagePullPolicy : define el orden de trabajo con imágenes. En nuestro caso, esta propiedad se establece en Always , es decir, durante cada implementación, la imagen correspondiente se descargará del repositorio.

Habiendo examinado todo esto, pasemos a practicar. Ejecute la implementación:

 kubectl apply -f sa-frontend-deployment.yaml deployment "sa-frontend" created 

Verifique el estado del sistema:

 kubectl get pods NAME                           READY STATUS RESTARTS AGE sa-frontend                    1/1 Running 0 2d sa-frontend-5d5987746c-ml6m4   1/1 Running 0 1m sa-frontend-5d5987746c-mzsgg   1/1 Running 0 1m sa-frontend2                   1/1 Running 0 2d 

Como puede ver, ahora tenemos 4 vainas. Dos de ellos fueron creados utilizando el recurso de implementación, dos más son los que nosotros mismos creamos. Ahora puede eliminar los pods que creamos nosotros mismos utilizando comandos del siguiente tipo:

 kubectl delete pod <pod-name> 

Por cierto, aquí hay una tarea para trabajo independiente. Elimine uno de los hogares creados con el recurso de implementación y supervise el sistema. Piense en las razones de lo que está sucediendo antes de seguir leyendo.

Al eliminar un hogar, el recurso de implementación descubre que el estado actual del sistema (1 sub) es diferente del deseado (2 sub), por lo que se inicia otro sub.

¿Cuál es el uso de los recursos de implementación, además del hecho de que cuando se usa, el sistema se mantiene en el estado correcto? Considere las fortalezas de estos recursos.

▍ Realizar implementaciones con cero tiempo de inactividad del sistema


Supongamos que un gerente de producto se acerca y nos informa que el cliente para el que creamos este producto quiere un botón verde en la aplicación del cliente. Los desarrolladores implementan este requisito y nos dan lo único que necesitamos de ellos: un contenedor de imágenes llamado rinormaloku/sentiment-analysis-frontend:green . Ahora llega nuestro momento. Nosotros, el equipo de DevOps, necesitamos implementar el sistema actualizado y garantizar un tiempo de inactividad cero. Ahora veamos si los esfuerzos para desarrollar y configurar el recurso de implementación están justificados.

Edite el archivo sa-frontend-deployment.yaml , reemplazando el nombre del contenedor de imágenes por uno nuevo, con rinormaloku/sentiment-analysis-frontend:green , luego guarde este archivo como sa-frontend-deployment-green.yaml y ejecute el siguiente comando:

 kubectl apply -f sa-frontend-deployment-green.yaml --record deployment "sa-frontend" configured 

Verifique el estado del sistema con el siguiente comando:

 kubectl rollout status deployment sa-frontend Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 old replicas are pending termination... Waiting for rollout to finish: 1 of 2 updated replicas are available... deployment "sa-frontend" successfully rolled out 

De acuerdo con los datos que se muestran en respuesta a este comando, podemos concluir que la implementación de la actualización fue exitosa. Durante la actualización, las réplicas antiguas, una a la vez, fueron reemplazadas por otras nuevas.Esto significa que nuestra aplicación, durante el proceso de actualización, siempre estuvo disponible. Antes de continuar, asegurémonos de que las aplicaciones estén realmente actualizadas.

Verificación de implementación


Para ver cómo se ve la aplicación en el navegador, utilizaremos el comando que ya conoce:

 minikube service sa-frontend-lb 

En respuesta a esto, se iniciará un navegador y se abrirá la página de la aplicación.


Botón verde

Como puede ver, el botón realmente se volvió verde, lo que significa que la actualización del sistema fue realmente exitosa.

Actualizaciones del sistema detrás de escena de acuerdo con el esquema RollingUpdate


, kubectl apply -f sa-frontend-deployment-green.yaml --record , Kubernetes , , . , , rinormaloku/sentiment-analysis-frontend:green . , , .




RollingUpdate , , maxUnavailable: 1 maxSurge: 1 . , Deployment , , , . , , , .

Deployment. , . .

▍


, , . «! ! !», — . . , , :

 kubectl rollout history deployment sa-frontend deployments "sa-frontend" REVISION  CHANGE-CAUSE 1         <none>    2         kubectl.exe apply --filename=sa-frontend-deployment-green.yaml --record=true 

: «, , ?».

«. , ?», — .

, , :

 kubectl rollout undo deployment sa-frontend --to-revision=1 deployment "sa-frontend" rolled back 

. , .

.

.

!

, . Kubernetes , , . , !

. , . CHANGE-CAUSE <none> , — kubectl.exe apply –filename=sa-frontend-deployment-green.yaml –record=true ?

, -- record , .

, , , .

Kubernetes:


Kubernetes, , . , .




.

▍ sa-logic


resource-manifests :

 kubectl apply -f sa-logic-deployment.yaml --record deployment "sa-logic" created 

sa-logic . Python-. app: sa-logic . sa-logic , . sa-logic-deployment.yaml .

-, , — sa-logic .

▍ sa-logic


, Service. , Java-, sa-webapp , , Python-. , , , Python-, . , , , .

, , , , . , sa-logic , sa-logic .

:

 kubectl apply -f service-sa-logic.yaml service "sa-logic" created 

, .




sa-logic , sa-webapp , , .

sa-webapp .

▍ sa-webapp


, Deployment - . , sa-web-app-deployment.yaml , :

 - image: rinormaloku/sentiment-analysis-web-app imagePullPolicy: Always name: sa-web-app env:   - name: SA_LOGIC_API_URL     value: "http://sa-logic" ports:   - containerPort: 8080 

env ? , , , SA_LOGIC_API_URL http://sa-logic . , , . ?

kube-dns.

▍DNS- Kubernetes


Kubernetes , kube-dns . DNS-. kube-dns , DNS- .

, sa-logic , IP-. kube-dns IP- . http://sa-logic IP-.

Deployment sa-webapp .

▍ sa-webapp


:

 kubectl apply -f sa-web-app-deployment.yaml --record deployment "sa-web-app" created 

sa-webapp , . React- , sa-webapp .

▍ sa-webapp


service-sa-web-app-lb.yaml , , , , . , , :

 kubectl apply -f service-sa-web-app-lb.yaml service "sa-web-app-lb" created 

. , , . , sa-frontend , Java- sa-webapp , http://localhost:8080/sentiment . , , sa-webapp , React- , Java-.

, . , — , , .

, :

  1. IP- sa-webapp , :

    minikube service list
    |-------------|----------------------|-----------------------------|
    | NAMESPACE | NAME | URL |
    |-------------|----------------------|-----------------------------|
    | default | kubernetes | No node port |
    | default | sa-frontend-lb | http://192.168.99.100:30708 |
    | default | sa-logic | No node port |
    | default | sa-web-app-lb | http://192.168.99.100:31691 |
    | kube-system | kube-dns | No node port |
    | kube-system | kubernetes-dashboard | http://192.168.99.100:30000 |
    |-------------|----------------------|-----------------------------|
  2. IP- sa-frontend/src/App.js . , :

     analyzeSentence() {       fetch('http://192.168.99.100:31691/sentiment', { /*    */})           .then(response => response.json())           .then(data => this.setState(data));   } 
  3. React-, sa-frontend npm run build .
  4. :

     docker build -f Dockerfile -t $DOCKER_USER_ID/sentiment-analysis-frontend:minikube. 
  5. Docker Hub:

     docker push $DOCKER_USER_ID/sentiment-analysis-frontend:minikube 
  6. sa-frontend-deployment.yaml , .
  7. :

     kubectl apply -f sa-frontend-deployment.yaml 

, , , , minikube service sa-frontend-lb . , - .




Resumen


Kubernetes , , , , . Kubernetes , , . Kubernetes Supernetes.

, :

  • , , React, Java Python.
  • Docker, , Dockerfile .
  • , , Docker Hub.

, Kubernetes:


, , Kubernetes.

Estimados lectores! Kubernetes?

Source: https://habr.com/ru/post/438984/


All Articles