{"id":33654,"date":"2019-10-31T21:53:58","date_gmt":"2019-10-31T18:53:58","guid":{"rendered":"https:\/\/prohoster.info\/blog\/deploj-prilozhenij-v-vm-nomad-i-kubernetes\/"},"modified":"2019-10-31T21:53:58","modified_gmt":"2019-10-31T18:53:58","slug":"deploj-prilozhenij-v-vm-nomad-i-kubernetes","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes","title":{"rendered":"Despliegue de aplicaciones en VM, Nomad y Kubernetes","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>\u00a1Hola a todos! Me llamo Pavel Agaletsky. Trabajo como l\u00edder de equipo en el grupo que desarrolla el sistema de entrega de Lamoda. En 2018, habl\u00e9 en la conferencia HighLoad++, y hoy quiero presentar la transcripci\u00f3n de mi presentaci\u00f3n.<\/p>\n<p>Mi tema se centra en la experiencia de nuestra empresa en el despliegue de sistemas y servicios en diferentes entornos. Desde nuestros tiempos prehist\u00f3ricos, cuando despleg\u00e1bamos todos los sistemas en servidores virtuales comunes, hasta la transici\u00f3n gradual de Nomad al despliegue en Kubernetes. Hablar\u00e9 sobre por qu\u00e9 lo hicimos y cu\u00e1les fueron los problemas que enfrentamos durante el proceso.<\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"oqrb7dWECSo\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/oqrb7dWECSo\/hqdefault.jpg\" alt=\"Reproducir video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1>Despliegue de aplicaciones en VM<\/h1>\n<p>\nComencemos por el hecho de que hace 3 a\u00f1os todos los sistemas y servicios de la empresa se desplegaban en servidores virtuales comunes. T\u00e9cnicamente, se organizaba de tal manera que todo el c\u00f3digo de nuestros sistemas se almacenaba y se constru\u00eda mediante un sistema de compilaci\u00f3n autom\u00e1tica con Jenkins. A trav\u00e9s de Ansible, se desplegaba desde nuestro sistema de control de versiones a los servidores virtuales. Cada sistema en nuestra empresa se desplegaba, al menos, en 2 servidores: uno en head y el otro en tail. Estos dos sistemas eran absolutamente id\u00e9nticos en todas sus configuraciones, capacidades y dem\u00e1s. La \u00fanica diferencia entre ellos era que head recib\u00eda el tr\u00e1fico de los usuarios, mientras que tail nunca recib\u00eda dicho tr\u00e1fico. <\/p>\n<p>\u00bfPor qu\u00e9 se hizo esto? <\/p>\n<p>Cuando despleg\u00e1bamos nuevas versiones de nuestra aplicaci\u00f3n, quer\u00edamos asegurar un despliegue sin costuras, es decir, sin consecuencias notables para los usuarios. Esto se lograba al desplegar la nueva versi\u00f3n construida con Ansible en tail. All\u00ed, las personas encargadas del despliegue pod\u00edan verificar y asegurarse de que todo funcionara bien: todas las m\u00e9tricas, secciones y aplicaciones estaban operativas; se ejecutaban los scripts necesarios. Solo despu\u00e9s de asegurarse de que todo estaba bien, el tr\u00e1fico se redirig\u00eda. Comenzaba a dirigir el tr\u00e1fico al servidor que anteriormente era tail. Y aquel que hab\u00eda sido head permanec\u00eda sin tr\u00e1fico de usuarios, continuando con la versi\u00f3n anterior de nuestra aplicaci\u00f3n.<\/p>\n<p>De esta manera, para los usuarios fue sin interrupciones. Porque el cambio es instant\u00e1neo, ya que solo es un cambio del equilibrador de carga. Es muy f\u00e1cil volver a la versi\u00f3n anterior simplemente cambiando el equilibrador de carga de nuevo. Tambi\u00e9n pudimos verificar la capacidad de la aplicaci\u00f3n en producci\u00f3n antes de que el tr\u00e1fico de usuarios comenzara a fluir, lo que result\u00f3 ser bastante conveniente. <\/p>\n<p>\u00bfCu\u00e1les fueron las ventajas que vimos en todo esto?<\/p>\n<ol>\n<li>Primero que nada, funciona suficientemente <b>bien.<\/b> Todo el mundo entiende c\u00f3mo funciona tal esquema de despliegue, porque la mayor\u00eda de las personas ha desplegado en servidores virtuales convencionales alguna vez.<\/li>\n<li>Es <b>bastante<\/b>fiable, ya que la tecnolog\u00eda de despliegue es sencilla, probada por miles de empresas. Millones de servidores se despliegan de esta manera. Es dif\u00edcil romper algo. <\/li>\n<li>Y finalmente, pudimos lograr <b>despliegues at\u00f3micos.<\/b>Despliegues que, para los usuarios, ocurren instant\u00e1neamente, sin una etapa de transici\u00f3n notable entre la versi\u00f3n antigua y la nueva. <\/li>\n<\/ol>\n<p>\nPero en todo esto tambi\u00e9n vimos algunas desventajas: <\/p>\n<ol>\n<li>Adem\u00e1s del entorno de producci\u00f3n y el entorno de desarrollo, hay otros entornos. Por ejemplo, QA y preproducci\u00f3n. En ese momento ten\u00edamos muchos servidores y alrededor de 60 servicios. Por esta raz\u00f3n, ten\u00edamos que <b>mantener la versi\u00f3n correspondiente de la m\u00e1quina virtual para cada servicio. <\/b>Adem\u00e1s, si deseas actualizar bibliotecas o instalar nuevas dependencias, debes hacerlo en todos los entornos. Tambi\u00e9n es necesario sincronizar el momento en que planeas desplegar la pr\u00f3xima versi\u00f3n de tu aplicaci\u00f3n con el tiempo en que DevOps realizar\u00e1 las configuraciones necesarias del entorno. En ese caso, es f\u00e1cil encontrarse en una situaci\u00f3n en la que el entorno var\u00ede ligeramente en todos los entornos seguidos. Por ejemplo, en el entorno de QA habr\u00e1 ciertas versiones de bibliotecas, mientras que en producci\u00f3n habr\u00e1 otras, lo que generar\u00e1 problemas. <\/li>\n<li><b>La dificultad en la actualizaci\u00f3n de las dependencias<\/b> de tu aplicaci\u00f3n. Esto no depende de ti, sino de otro equipo. A saber, del equipo de DevOps, que mantiene los servidores. Debes establecer una tarea adecuada para ellos y proporcionar una descripci\u00f3n de lo que deseas hacer.<\/li>\n<li>En ese momento, tambi\u00e9n quer\u00edamos dividir los grandes monolitos que ten\u00edamos en peque\u00f1os servicios, ya que entend\u00edamos que seguir\u00edan aumentando. En ese entonces, ya ten\u00edamos m\u00e1s de 100. Era necesario crear una nueva m\u00e1quina virtual separada para cada nuevo servicio, que tambi\u00e9n deb\u00eda ser administrada y desplegada. Adem\u00e1s, se necesitaban al menos dos m\u00e1quinas. A todo esto se a\u00f1ad\u00eda el entorno de QA. Esto genera problemas y hace que la creaci\u00f3n y el despliegue de nuevos sistemas sea m\u00e1s <b>complejo, costoso y largo.<\/b><\/li>\n<\/ol>\n<p>\nPor eso decidimos que ser\u00eda m\u00e1s conveniente pasar del despliegue de m\u00e1quinas virtuales normales al despliegue de nuestras aplicaciones en un contenedor Docker. Con Docker, se necesita un sistema que pueda ejecutar la aplicaci\u00f3n en un cl\u00faster, ya que no puedes simplemente levantar un contenedor. Generalmente, quieres monitorear cu\u00e1ntos contenedores est\u00e1n activos para que se levanten autom\u00e1ticamente. Por esta raz\u00f3n, necesit\u00e1bamos elegir un sistema de gesti\u00f3n. <\/p>\n<p>Reflexionamos mucho sobre cu\u00e1l podr\u00edamos elegir. La cuesti\u00f3n es que en ese momento este stack de despliegue en servidores virtuales comunes estaba algo desactualizado, ya que no contaba con las versiones m\u00e1s recientes de los sistemas operativos. En alg\u00fan momento, incluso hab\u00eda FreeBSD, que no era muy c\u00f3modo de mantener. Entend\u00edamos que era necesario migrar a Docker lo m\u00e1s r\u00e1pido posible. Nuestros DevOps revisaron su experiencia con diferentes soluciones y eligieron un sistema llamado Nomad. <\/p>\n<h1>Migraci\u00f3n a Nomad<\/h1>\n<p>\nNomad es un producto de la empresa \u201cHashiCorp\u201d. Tambi\u00e9n son conocidos por otras soluciones:<\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/25dfbfe20b92f6e6865bdd8a2f15d8fa.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>\u00abConsul\u00bb<\/b> \u2014 es una herramienta para descubrimiento de servicios.<\/p>\n<p><b>\u00abTerraform\u00bb<\/b> \u2014 es un sistema para gestionar servidores, permiti\u00e9ndote configurarlos a trav\u00e9s de una configuraci\u00f3n conocida como infrastructure-as-code.<\/p>\n<p><b>\u00abVagrant\u00bb<\/b> te permite desplegar m\u00e1quinas virtuales localmente o en la nube mediante archivos de configuraci\u00f3n determinados. <\/p>\n<p>En ese momento, Nomad nos pareci\u00f3 una soluci\u00f3n bastante sencilla, a la que podr\u00edamos migrar r\u00e1pidamente sin cambiar toda la infraestructura. Adem\u00e1s, es bastante f\u00e1cil de aprender. Por eso lo elegimos como el sistema para gestionar nuestro contenedor. <\/p>\n<p>\u00bfQu\u00e9 se necesita para desplegar tu sistema en Nomad? <\/p>\n<ol>\n<li>Primero que todo, necesitas <b>una imagen de docker<\/b> de su aplicaci\u00f3n. Es necesario compilarla y almacenarla en un repositorio de im\u00e1genes de Docker. En nuestro caso, se trata de Artifactory, un sistema que permite enviar diversos artefactos de diferentes tipos. Puede almacenar archivos comprimidos, im\u00e1genes de Docker, paquetes de Composer PHP, paquetes NPM y m\u00e1s. <\/li>\n<li>Tambi\u00e9n es necesario<b> archivo de configuraci\u00f3n<\/b>, que le dir\u00e1 a Nomad qu\u00e9, d\u00f3nde y en qu\u00e9 cantidad desea desplegar. <\/li>\n<\/ol>\n<p>\nCuando hablamos de Nomad, utiliza el lenguaje HCL como formato de archivo inform\u00e1tico, que se desglosa como <i>HashiCorp Configuration Language<\/i>. Es un superconjunto de YAML que le permite describir su servicio en t\u00e9rminos de Nomad. <\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/bee3d1feedd52249c4325d8a3984a766.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLe permite especificar cu\u00e1ntos contenedores desea desplegar, de qu\u00e9 im\u00e1genes, y pasarles varios par\u00e1metros durante la implementaci\u00f3n. As\u00ed, le proporciona este archivo a Nomad, y \u00e9l ejecuta contenedores de acuerdo a este. <\/p>\n<p>En nuestro caso, entendimos que simplemente escribir archivos HCL id\u00e9nticos para cada servicio no ser\u00eda muy conveniente, ya que hay muchos servicios y a veces se desea actualizarlos. A veces, un servicio no se implementa en una sola instancia, sino en varias. Por ejemplo, uno de los sistemas que tenemos en producci\u00f3n tiene m\u00e1s de 100 instancias en producci\u00f3n. Se inician a partir de las mismas im\u00e1genes, pero difieren en configuraciones y archivos de configuraci\u00f3n. <\/p>\n<p>Por lo tanto, decidimos que ser\u00eda conveniente almacenar todos nuestros archivos de configuraci\u00f3n para la implementaci\u00f3n en un \u00fanico repositorio com\u00fan. De esta manera, se volvieron auditables: eran f\u00e1ciles de mantener y se pod\u00eda ver qu\u00e9 sistemas ten\u00edamos. En caso de necesidad, tambi\u00e9n era f\u00e1cil actualizar o cambiar algo. Agregar un nuevo sistema tampoco ser\u00eda dif\u00edcil: simplemente hay que crear un archivo de configuraci\u00f3n dentro de un nuevo directorio. Dentro de \u00e9l se encuentran los archivos: service.hcl, que contiene la descripci\u00f3n de nuestro servicio, y algunos archivos env que permiten configurar ese servicio cuando se despliega en producci\u00f3n. <\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/c0b0bdb763d3c3bb84fbc9e5dfecff82.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSin embargo, algunos de nuestros sistemas est\u00e1n desplegados en producci\u00f3n no en una sola instancia, sino en varias a la vez. Por lo tanto, decidimos que ser\u00eda m\u00e1s conveniente almacenar no las configuraciones en su forma pura, sino su versi\u00f3n plantillada. Y para el lenguaje de plantillas elegimos <i>jinja 2<\/i>En este formato almacenamos tanto las configuraciones del propio servicio como los archivos env necesarios para \u00e9l. <\/p>\n<p>Adem\u00e1s, colocamos en el repositorio un script de despliegue com\u00fan para todos los proyectos, que permite iniciar y desplegar su servicio en producci\u00f3n, en el entorno deseado, en el objetivo adecuado. En el caso de que convirtamos nuestra configuraci\u00f3n HCL en una plantilla, el archivo HCL que anteriormente era una configuraci\u00f3n normal de Nomad, en este caso, se ver\u00e1 un poco diferente.<\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/202472f109ba09798d592418b1774a29.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEs decir, hemos reemplazado algunas variables en la configuraci\u00f3n por insertos de variables que se toman de archivos env o de otras fuentes. Adem\u00e1s, obtuvimos la opci\u00f3n de construir archivos HCL de manera din\u00e1mica, es decir, podemos aplicar no solo los insertos de variables comunes. Dado que jinja soporta ciclos y condiciones, tambi\u00e9n se pueden crear archivos de configuraci\u00f3n que cambian dependiendo de a d\u00f3nde despliegue sus aplicaciones. <\/p>\n<p>Por ejemplo, desea desplegar su servicio en preproducci\u00f3n y en producci\u00f3n. Supongamos que en preproducci\u00f3n no desea ejecutar scripts de cron, sino que simplemente quiere ver el servicio en un dominio separado para verificar que est\u00e1 funcionando. Para cualquiera que despliegue un servicio, el proceso se ve muy simple y transparente. Solo necesita ejecutar el archivo deploy.sh, indicando qu\u00e9 servicio desea desplegar y en qu\u00e9 objetivo. Por ejemplo, quiere desplegar un sistema en Rusia, Bielorrusia o Kazajist\u00e1n. Para esto, basta con cambiar uno de los par\u00e1metros, y se generar\u00e1 el archivo de configuraci\u00f3n correcto. <\/p>\n<p>Cuando el servicio Nomad ya est\u00e1 desplegado en su cl\u00faster, se ve de la siguiente manera.<\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/60e2e2b5502936809d643d73c6d853e2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPara comenzar, necesita alg\u00fan balanceador externo que reciba todo el tr\u00e1fico de usuario. Este trabajar\u00e1 junto con Consul y le preguntar\u00e1 d\u00f3nde, en qu\u00e9 nodo, por qu\u00e9 <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/es\/lir\/ipv4\/\"   title=\"IP\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"585\">IP<\/a> est\u00e1 ubicado el servicio espec\u00edfico que corresponde a un determinado nombre de dominio. Los servicios en Consul aparecen desde Nomad. Como son productos de la misma empresa, est\u00e1n bien interconectados. Se puede decir que Nomad puede registrar, por defecto, todos los servicios que se ejecutan en \u00e9l dentro de Consul. <\/p>\n<p>Despu\u00e9s de que su balanceador de carga externo determina a qu\u00e9 servicio redirigir el tr\u00e1fico, lo dirige al contenedor correspondiente o a varios contenedores que corresponden a su aplicaci\u00f3n. Por supuesto, tambi\u00e9n es necesario considerar la seguridad. A pesar de que todos los servicios se ejecutan en las mismas m\u00e1quinas virtuales dentro de contenedores, generalmente se requiere restringir el acceso libre entre servicios. Esto se logra mediante segmentaci\u00f3n. Cada servicio se ejecuta en su propia red virtual, donde se definen las reglas de enrutamiento y las pol\u00edticas de permiso\/prohibici\u00f3n de acceso a otros sistemas y servicios, que pueden estar dentro o fuera de este cl\u00faster. Por ejemplo, si desea prohibir que un servicio se conecte a una base de datos espec\u00edfica, esto se puede hacer mediante la segmentaci\u00f3n a nivel de red. Es decir, ni siquiera por error puede conectarse desde un ambiente de prueba a su base de datos de producci\u00f3n.<\/p>\n<p>\u00bfCu\u00e1l fue el costo del proceso de transici\u00f3n en t\u00e9rminos de recursos humanos? <\/p>\n<p>La transici\u00f3n de toda la empresa a Nomad tom\u00f3 aproximadamente 5-6 meses. Nos cambiamos por servicio, pero a un ritmo bastante r\u00e1pido. Cada equipo deb\u00eda crear sus propios contenedores para los servicios. <\/p>\n<p>Hemos adoptado el enfoque de que cada equipo es responsable de las im\u00e1genes de docker de sus propios sistemas. El equipo de DevOps proporciona la infraestructura general necesaria para el despliegue, es decir, el soporte del cl\u00faster, el soporte del sistema de CI, etc. Y en ese momento, m\u00e1s de 60 sistemas se hab\u00edan trasladado a Nomad, lo que result\u00f3 en alrededor de 2,000 contenedores. <\/p>\n<p>DevOps se encarga de la infraestructura general relacionada con el despliegue y los servidores. Por su parte, cada equipo de desarrollo es responsable de la implementaci\u00f3n de contenedores para su sistema espec\u00edfico, ya que el equipo sabe exactamente qu\u00e9 necesita en cada contenedor.<\/p>\n<h1>Razones para abandonar Nomad<\/h1>\n<p>\n\u00bfQu\u00e9 ventajas obtuvimos al pasar al despliegue utilizando Nomad y docker, entre otros?<\/p>\n<ol>\n<li>Nosotros<b> aseguramos condiciones iguales<\/b> para todos los entornos. En desarrollo, entorno de QA, preproducci\u00f3n y producci\u00f3n se utilizan las mismas im\u00e1genes de contenedores, con las mismas dependencias. En consecuencia, pr\u00e1cticamente no hay posibilidad de que en producci\u00f3n termine algo diferente a lo que antes testeaste localmente o en un entorno de pruebas. <\/li>\n<li>Tambi\u00e9n descubrimos que es suficiente <b>agregar un nuevo servicio<\/b>. Cualquier nuevo sistema, desde el punto de vista del despliegue, se lanza muy f\u00e1cilmente. Solo hay que ir al repositorio que almacena los configs, agregar all\u00ed un nuevo config para tu sistema y todo est\u00e1 listo. Puedes desplegar tu sistema en producci\u00f3n sin esfuerzos adicionales por parte de DevOps. <\/li>\n<li>Todos <b>archivos de configuraci\u00f3n<\/b> en un solo repositorio com\u00fan <b>resultaron ser observables<\/b>. En el momento en que desplegamos nuestros sistemas usando <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/es\/vps\/\"   title=\"servidores virtuales\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"791\">servidores virtuales<\/a>, utilizamos Ansible, en el que los configs estaban en un mismo repositorio. Sin embargo, para la mayor\u00eda de los desarrolladores, trabajar con esto era algo m\u00e1s complicado. Aqu\u00ed, el volumen de configs y c\u00f3digo que necesitas agregar para desplegar el servicio se volvi\u00f3 mucho menor. Adem\u00e1s, para DevOps es muy f\u00e1cil corregirlo o cambiarlo. En casos de migraciones, por ejemplo, a una nueva versi\u00f3n de Nomad, pueden tomar y actualizar masivamente todos los archivos operativos que est\u00e1n en el mismo lugar.<\/li>\n<\/ol>\n<p>\nPero tambi\u00e9n nos enfrentamos a algunas desventajas: <\/p>\n<p>Result\u00f3 que no <b>pudimos lograr un despliegue sin interrupciones <\/b>en el caso de Nomad. Al lanzar contenedores desde diferentes condiciones, pod\u00eda suceder que se est\u00e9n ejecutando, y Nomad lo percibiera como un contenedor listo para aceptar tr\u00e1fico. Esto ocurr\u00eda incluso antes de que la aplicaci\u00f3n dentro de \u00e9l hubiera tenido tiempo de iniciarse. Por esta raz\u00f3n, el sistema comenzaba a emitir errores 500 durante un corto per\u00edodo de tiempo, porque el tr\u00e1fico empezaba a dirigirse a un contenedor que a\u00fan no estaba listo para aceptarlo. <\/p>\n<p>Nos encontramos con algunos <b>errores<\/b>. El error m\u00e1s significativo es que Nomad no maneja muy bien un cl\u00faster grande si tiene muchos sistemas y contenedores. Cuando desea sacar uno de los servidores que forman parte del cl\u00faster Nomad para mantenimiento, hay una probabilidad bastante alta de que el cl\u00faster no funcione bien y se desmorone. Parte de los contenedores puede, por ejemplo, caer y no volver a levantarse, lo que le costar\u00e1 muy caro si todos sus sistemas de producci\u00f3n est\u00e1n en ese cl\u00faster gestionado por Nomad. <\/p>\n<p>Por eso decidimos pensar en a d\u00f3nde ir a continuaci\u00f3n. En ese momento comprendimos mucho mejor lo que quer\u00edamos lograr. Espec\u00edficamente: queremos fiabilidad, un poco m\u00e1s de funciones de las que ofrece Nomad y un sistema m\u00e1s maduro y estable. <\/p>\n<p>En este sentido, nuestra elecci\u00f3n recay\u00f3 en Kubernetes como la plataforma m\u00e1s popular para implementar cl\u00fasteres. Especialmente considerando que el tama\u00f1o y la cantidad de nuestros contenedores eran bastante grandes. Para estos fines, Kubernetes parec\u00eda ser el sistema m\u00e1s adecuado entre los que pod\u00edamos explorar. <\/p>\n<h1>Transici\u00f3n a Kubernetes<\/h1>\n<p>\nVoy a contar un poco sobre cu\u00e1les son los conceptos b\u00e1sicos de Kubernetes y en qu\u00e9 se diferencian de Nomad. <\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/5723a69309f387e6cc6c5959b62ca18b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn primer lugar, el concepto m\u00e1s b\u00e1sico en Kubernetes es el de pod. <b>Pod<\/b> \u2014 es un grupo de uno o varios contenedores que siempre se ejecutan juntos. Y funcionan como si estuvieran siempre estrictamente en una sola m\u00e1quina virtual. Se pueden comunicar entre s\u00ed a trav\u00e9s de la direcci\u00f3n IP 127.0.0.1 en diferentes puertos. <\/p>\n<p>Supongamos que tiene una aplicaci\u00f3n PHP que consiste en nginx y php-fpm: un esquema cl\u00e1sico. Es probable que desee que tanto los contenedores de nginx como de php-fpm est\u00e9n siempre juntos. Kubernetes permite lograr esto describi\u00e9ndolos como un pod com\u00fan. Esto era exactamente lo que no pod\u00edamos lograr con Nomad.<\/p>\n<p>El segundo concepto es <b>deployment<\/b>. El hecho es que un pod por s\u00ed solo es una entidad ef\u00edmera, se inicia y desaparece. Ya sea que quiera eliminar todos sus contenedores anteriores y luego iniciar de inmediato nuevas versiones o si desea implementarlos gradualmente, es precisamente para este proceso que se encarga el concepto de deployment. Describe c\u00f3mo implementa sus pods, en qu\u00e9 cantidad y c\u00f3mo actualizarlos. <\/p>\n<p>El tercer concepto es <b>el servicio<\/b>. Su servicio es, de hecho, su sistema, que recibe cierto tr\u00e1fico y luego lo dirige a uno o varios pods que corresponden a su servicio. Es decir, permite que todo el tr\u00e1fico entrante a un servicio con un nombre espec\u00edfico se env\u00ede a esos pods en particular. Y al mismo tiempo, le proporciona balanceo de carga. Esto significa que puede ejecutar dos pods de su aplicaci\u00f3n y todo el tr\u00e1fico entrante se equilibrar\u00e1 uniformemente entre los pods relacionados con ese servicio.<\/p>\n<p>Y el cuarto concepto principal es <b>Ingress<\/b>. Es un servicio que se ejecuta en un cl\u00faster de Kubernetes. Act\u00faa como un balanceador de carga externo que recibe todas las solicitudes. Gracias a la API de Kubernetes, Ingress puede determinar a d\u00f3nde enviar esas solicitudes. Adem\u00e1s, lo hace de manera muy flexible. Puede especificar que todas las solicitudes a este host y a esta URL se env\u00edan a este servicio. Y esas solicitudes que llegan a este host y a otra URL se env\u00edan a otro servicio. <\/p>\n<p>Lo m\u00e1s genial desde la perspectiva de quien desarrolla la aplicaci\u00f3n es que puede gestionar todo esto de manera independiente. Al configurar Ingress, puede enviar todo el tr\u00e1fico que llega a una API espec\u00edfica a contenedores separados, escritos, por ejemplo, en Go. Y este tr\u00e1fico, que llega al mismo dominio, pero a otra URL, se env\u00eda a contenedores escritos en PHP, donde hay mucha l\u00f3gica, pero no son muy r\u00e1pidos.<\/p>\n<p>Si comparamos todos estos conceptos con Nomad, se puede decir que los primeros tres conceptos constituyen el Servicio en conjunto. Y el \u00faltimo concepto no existe en Nomad. En su lugar, utilizamos un balanceador de carga externo: puede ser haproxy, nginx, nginx+ y as\u00ed sucesivamente. En el caso de Kubernetes, no necesita introducir este concepto adicional por separado. Sin embargo, al observar Ingress internamente, se trata ya sea de nginx, haproxy o traefik, pero incorporado en Kubernetes. <\/p>\n<p>Todos los conceptos que he descrito son, en esencia, recursos que existen dentro del cl\u00faster de Kubernetes. Para describirlos en kubectl, se utiliza el formato yaml, que es m\u00e1s legible y familiar que los archivos HCL en el caso de Nomad. Pero estructuralmente describen lo mismo en el caso, por ejemplo, de un pod. Dicen: quiero desplegar ciertos pods all\u00ed, con estas im\u00e1genes, en esta cantidad. <\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/13836e7474b377a5e6b05112a53bfedd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAdem\u00e1s de esto, nos dimos cuenta de que no quer\u00edamos crear cada recurso por separado: deployment, servicios, Ingress y dem\u00e1s. En lugar de eso, quer\u00edamos describir cada sistema que tenemos en t\u00e9rminos de Kubernetes durante el despliegue, para no tener que recrear manualmente todas las dependencias necesarias en el orden correcto. Para eso, elegimos Helm como el sistema que nos permite hacerlo. <\/p>\n<h1>Conceptos Clave en Helm<\/h1>\n<p>\nHelm es un <b>gestor de paquetes<\/b> para Kubernetes. Es muy similar a c\u00f3mo funcionan los gestores de paquetes en los lenguajes de programaci\u00f3n. Te permiten almacenar un servicio que consiste, por ejemplo, en un deployment de nginx, un deployment de php-fpm, una configuraci\u00f3n para Ingress, configmaps (que es una entidad que te permite establecer env y otros par\u00e1metros para tu sistema) en forma de lo que se conoce como charts. Mientras tanto, Helm <b>funciona sobre Kubernetes<\/b>. Es decir, no es un sistema independiente, sino simplemente otro servicio que se ejecuta dentro de la esfera. Te interact\u00faas con \u00e9l a trav\u00e9s de su API mediante un comando de consola. Su conveniencia y atractivo radican en que, incluso si helm falla o lo eliminas del cl\u00faster, tus servicios no desaparecer\u00e1n, ya que helm sirve esencialmente solo para iniciar el sistema. La operatividad y estado de los servicios son considerados por Kubernetes. <\/p>\n<p>Tambi\u00e9n entendimos que <b>la plantillizaci\u00f3n<\/b>, que antes ten\u00edamos que hacer manualmente mediante la implementaci\u00f3n de jinja en nuestras configuraciones, es una de las principales capacidades de helm. Todas las configuraciones que creas para tus sistemas se almacenan en helm como plantillas, que son un poco similares a jinja, pero que, en realidad, utilizan la plantillizaci\u00f3n del lenguaje Go, en el que est\u00e1 escrito helm, al igual que Kubernetes. <\/p>\n<p>Helm nos agrega algunos conceptos adicionales. <\/p>\n<p><b>Gr\u00e1fico<\/b> \u2014 es la descripci\u00f3n de tu servicio. En otros gestores de paquetes se le llamar\u00eda paquete, bundle o algo similar. Aqu\u00ed se llama chart. <\/p>\n<p><b>Values <\/b>\u2013 son las variables que deseas utilizar para construir tus configuraciones a partir de las plantillas. <\/p>\n<p><b>Release<\/b>Cada vez que un servicio se despliega usando helm, recibe una versi\u00f3n incremental del lanzamiento. Helm recuerda cu\u00e1l era la configuraci\u00f3n del servicio en el lanzamiento anterior, en el antepen\u00faltimo y as\u00ed sucesivamente. Por lo tanto, si es necesario revertir, basta con ejecutar el comando helm callback, especificando la versi\u00f3n anterior del lanzamiento. Incluso si en el momento de la reversi\u00f3n la configuraci\u00f3n correspondiente no est\u00e1 disponible en su repositorio, helm a\u00fan recuerda cu\u00e1l era y revertir\u00e1 su sistema al estado en que se encontraba en el lanzamiento anterior. <\/p>\n<p>En el caso de que estemos utilizando helm, las configuraciones normales para Kubernetes tambi\u00e9n se convierten en plantillas, en las que es posible usar variables, funciones y aplicar operadores condicionales. De esta forma, puede construir la configuraci\u00f3n de su servicio en funci\u00f3n del entorno.<\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/b70ba431211038eacf911ba3aee22363.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn la pr\u00e1ctica, decidimos actuar un poco diferente a como lo hicimos con Nomad. Si en Nomad se almacenaban tanto las configuraciones para el despliegue como las n-variables necesarias para desplegar nuestro servicio en un mismo repositorio, aqu\u00ed decidimos separarlas en dos repositorios distintos. En el repositorio 'deploy' se almacenan solo las n-variables necesarias para el despliegue, mientras que en el repositorio 'helm' se almacenan configuraciones o gr\u00e1ficos.<\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/4add11a8f9d9a9244127f0b07d027fa2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n\u00bfQu\u00e9 nos ha dado esto? <\/p>\n<p>A pesar de que en los propios archivos de configuraci\u00f3n no almacenamos datos realmente sensibles, como contrase\u00f1as de bases de datos, las cuales se guardan como secretos en Kubernetes, a\u00fan as\u00ed hay cosas espec\u00edficas a las que no queremos dar acceso a todos. Por lo tanto, el acceso al repositorio 'deploy' es m\u00e1s restringido, mientras que el repositorio 'helm' contiene simplemente la descripci\u00f3n del servicio. Por esta raz\u00f3n, se puede otorgar acceso de manera segura a un p\u00fablico m\u00e1s amplio. <\/p>\n<p>Dado que tenemos no solo producci\u00f3n sino tambi\u00e9n otros entornos, gracias a esta separaci\u00f3n podemos reutilizar nuestros gr\u00e1ficos de helm para desplegar servicios no solo en producci\u00f3n, sino tambi\u00e9n, por ejemplo, en entornos de QA. Incluso para desplegarlos localmente, usando <i>Minikube<\/i> \u2014 es una herramienta para el lanzamiento local de Kubernetes. <\/p>\n<p>Dentro de cada repositorio hemos mantenido una separaci\u00f3n en directorios individuales para cada servicio. Es decir, dentro de cada directorio se encuentran las plantillas que pertenecen a la carta correspondiente y que describen los recursos que deben ser desplegados para poner en marcha nuestro sistema. En el repositorio 'deploy' hemos dejado \u00fanicamente los entornos. En este caso, no utilizamos la templating con jinja, porque helm proporciona templating por s\u00ed mismo, siendo esta una de sus principales funciones. <\/p>\n<p>Hemos dejado un script para el despliegue \u2013 deploy.sh, que simplifica y estandariza el lanzamiento para el despliegue con helm. Por lo tanto, para cualquiera que desee desplegar, la interfaz de despliegue se ve exactamente igual a como era en el caso del despliegue a trav\u00e9s de Nomad. El mismo deploy.sh, el nombre de tu servicio y a d\u00f3nde deseas desplegarlo. Esto provoca que dentro se active helm. A su vez, re\u00fane las configuraciones de las plantillas, inserta los archivos de valores necesarios y luego despliega, envi\u00e1ndolos a Kubernetes. <\/p>\n<h1>Conclusiones<\/h1>\n<p>\nEl servicio de Kubernetes parece m\u00e1s complejo que Nomad. <\/p>\n<p><img decoding=\"async\" alt=\"Despliegue de aplicaciones en VM, Nomad y Kubernetes\" src=\"\/wp-content\/uploads\/2019\/05\/5a9b5636ab4721acde096fea986ba38b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAqu\u00ed, el tr\u00e1fico saliente llega a Ingress. Este es el controlador frontal que recibe todas las solicitudes y posteriormente las env\u00eda a los servicios correspondientes seg\u00fan los datos de la solicitud. Los determina bas\u00e1ndose en las configuraciones que son parte de la descripci\u00f3n de tu aplicaci\u00f3n en helm y que los desarrolladores establecen por s\u00ed mismos. El servicio a su vez env\u00eda solicitudes a sus pods, es decir, contenedores espec\u00edficos, equilibrando el tr\u00e1fico entrante entre todos los contenedores que pertenecen a este servicio. Y, por supuesto, no debemos olvidar que la seguridad a nivel de red no puede ser descuidada. Por lo tanto, en el cl\u00faster de Kubernetes se aplica segmentaci\u00f3n, basada en etiquetado. Todos los servicios tienen etiquetas espec\u00edficas a las cuales se vinculan los permisos de acceso de los servicios a determinados recursos externos\/internos dentro o fuera del cl\u00faster. <\/p>\n<p>Al hacer la transici\u00f3n, notamos que Kubernetes tiene todas las capacidades de Nomad, que utilizamos anteriormente, y adem\u00e1s agrega muchas nuevas. Se puede extender a trav\u00e9s de plugins, y en realidad a trav\u00e9s de tipos de recursos personalizados. Es decir, no solo tienes la opci\u00f3n de utilizar algo que viene en Kubernetes por defecto, sino que puedes crear tu propio recurso y servicio que leer\u00e1 su recurso. Esto ofrece oportunidades adicionales para ampliar tu sistema sin necesidad de reinstalar Kubernetes y sin requerir cambios. <\/p>\n<p>Un ejemplo de este tipo de uso es Prometheus, que se ejecuta dentro de nuestro cl\u00faster de Kubernetes. Para que comience a recopilar m\u00e9tricas de un servicio en particular, necesitamos agregar un tipo de recurso adicional en la descripci\u00f3n del servicio, llamado monitor de servicio. Prometheus, al poder leer un tipo de recursos personalizados cuando se ejecuta en Kubernetes, comienza autom\u00e1ticamente a recopilar m\u00e9tricas del nuevo sistema. Esto resulta bastante conveniente. <\/p>\n<p>El primer despliegue que hicimos en Kubernetes fue en marzo de 2018. Y durante este tiempo, nunca hemos tenido problemas con \u00e9l. Funciona de manera bastante estable sin errores significativos. Adem\u00e1s, podemos extenderlo a\u00fan m\u00e1s. Hasta la fecha, tenemos suficientes capacidades disponibles en \u00e9l, y nos gusta mucho el ritmo de desarrollo de Kubernetes. Actualmente, hay m\u00e1s de 3000 contenedores en Kubernetes. El cl\u00faster ocupa varios nodos. Aun as\u00ed, es manejable, estable y muy controlable.<br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/lamoda\/blog\/451644\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda. \u0412 2018 \u0433\u043e\u0434\u0443 \u044f \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u043b \u043d\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 HighLoad++, \u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430. \u041c\u043e\u044f \u0442\u0435\u043c\u0430 \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u043e\u043f\u044b\u0442\u0443 \u043d\u0430\u0448\u0435\u0439 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u043f\u043e \u0434\u0435\u043f\u043b\u043e\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432 \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b. \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u043d\u0430\u0448\u0438\u0445 \u0434\u043e\u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u0440\u0435\u043c\u0435\u043d, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u0435\u043f\u043b\u043e\u0438\u043b\u0438 \u0432\u0441\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":25343,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-33654","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0414\u0435\u043f\u043b\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 VM, Nomad \u0438 Kubernetes | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:53:58+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:53:58+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Despliegue de aplicaciones en VM, Nomad y Kubernetes | ProHoster","description":"\u00a1Hola a todos! Me llamo Pavel Agaletki. Soy l\u00edder de equipo en el grupo que desarrolla el sistema de entrega de Lamoda.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0414\u0435\u043f\u043b\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u0432 VM, Nomad \u0438 Kubernetes | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041f\u0430\u0432\u0435\u043b \u0410\u0433\u0430\u043b\u0435\u0446\u043a\u0438\u0439. \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0442\u0438\u043c\u043b\u0438\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Lamoda.","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/deploj-prilozhenij-v-vm-nomad-i-kubernetes","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:53:58+00:00","article:modified_time":"2019-10-31T18:53:58+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"33654","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-02-08 20:38:40","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:36:34","updated":"2026-02-08 20:38:40","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/33654","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=33654"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/33654\/revisions"}],"predecessor-version":[{"id":157982,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/33654\/revisions\/157982"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/25343"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=33654"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=33654"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=33654"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}