{"id":87393,"date":"2020-07-08T01:42:02","date_gmt":"2020-07-07T23:42:02","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws"},"modified":"2020-07-08T01:42:02","modified_gmt":"2020-07-07T23:42:02","slug":"sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","title":{"rendered":"Creaci\u00f3n de una API escalable en instancias spot de AWS","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>\u00a1Hola a todos! Me llamo Kirill, soy CTO en Adapty. Gran parte de nuestra arquitectura est\u00e1 en AWS, y hoy les contar\u00e9 c\u00f3mo hemos reducido los costos de servidores en 3 veces gracias al uso de instancias spot en el entorno de producci\u00f3n, as\u00ed como c\u00f3mo configurarlas para autoescalado. Primero har\u00e9 una revisi\u00f3n de c\u00f3mo funciona, y luego una gu\u00eda detallada para el despliegue.<\/p>\n<p><\/p>\n<h2 id=\"chto-takoe-spotovye-instansy\">\u00bfQu\u00e9 son las instancias spot?<\/h2>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/ru\/ec2\/spot\/\">Las<\/a><\/noindex> instancias spot son servidores de otros usuarios de AWS que est\u00e1n inactivos en este momento y los venden con un gran descuento (Amazon dice hasta un 90%, seg\u00fan nuestra experiencia es aproximadamente 3x, var\u00eda seg\u00fan la regi\u00f3n, AZ y tipo de instancia). Su principal diferencia con las instancias normales es que pueden apagarse en cualquier momento. Por eso, durante mucho tiempo pensamos que era aceptable usarlas para entornos de desarrollo, o para tareas que requieren c\u00e1lculos de alg\u00fan tipo, guardando resultados intermedios en S3 o en una base de datos, pero no para producci\u00f3n. Existen soluciones de terceros que permiten usar instancias spot en producci\u00f3n, pero para nuestro caso tienen muchas limitaciones, as\u00ed que no las implementamos. El enfoque descrito en este art\u00edculo funciona completamente dentro de las funcionalidades est\u00e1ndar de AWS, sin scripts adicionales, cron jobs, etc.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>A continuaci\u00f3n, proporcionar\u00e9 algunas capturas de pantalla que muestran la historia de precios de las instancias spot.<\/p>\n<p><\/p>\n<p>m5.large en la regi\u00f3n eu-west-1 (Irlanda). El precio ha sido mayormente estable durante 3 meses, actualmente el ahorro es de 2.9x.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/901a259955c386493557280489f582fe.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>m5.large en la regi\u00f3n us-east-1 (Virginia del Norte). El precio cambia constantemente durante 3 meses, actualmente el ahorro est\u00e1 entre 2.3x y 2.8x dependiendo de la zona de disponibilidad.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/49c89430f03b2c7025355562d2873b6b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>t3.small en la regi\u00f3n us-east-1 (Virginia del Norte). El precio ha sido estable durante 3 meses, actualmente el ahorro es de 3.4x.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/2e139dcc6d44bd37caf9d75eb6ec4835.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"arhitektura-servisa\">Arquitectura del servicio<\/h2>\n<p><\/p>\n<p>La arquitectura b\u00e1sica del servicio, del que hablaremos en este art\u00edculo, se muestra en el diagrama a continuaci\u00f3n.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/d89bd595675400861360670adaacaf03.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"application-load-balancer--ec2-target-group--elastic-container-service\">Application Load Balancer \u2192 EC2 Target Group \u2192 Elastic Container Service<\/h3>\n<p><\/p>\n<p>Se utiliza un Application Load Balancer (ALB) como balanceador que env\u00eda solicitudes al EC2 Target Group (TG). TG se encarga de abrir los puertos en las instancias para el ALB y enlazarlos con los puertos de los contenedores del Elastic Container Service (ECS). ECS es an\u00e1logo a Kubernetes en AWS, dedicado a la gesti\u00f3n de contenedores Docker.<\/p>\n<p><\/p>\n<p>En una instancia pueden haber varios contenedores en funcionamiento con los mismos puertos, por lo que no podemos asignarlos de manera fija. ECS informa al TG que est\u00e1 iniciando una nueva tarea (en la terminolog\u00eda de Kubernetes se llama pod), verifica los puertos libres en la instancia y asigna uno de ellos para la tarea que se est\u00e1 iniciando. Adem\u00e1s, el TG verifica regularmente si la instancia y la API est\u00e1n operativas mediante un chequeo de salud, y si detecta alg\u00fan problema, deja de enviar solicitudes a dicha instancia.<\/p>\n<p><\/p>\n<h3 id=\"ec2-auto-scaling-groups--ecs-capacity-providers\">Grupos de Auto Scaling de EC2 + Proveedores de Capacidad de ECS<\/h3>\n<p><\/p>\n<p>En el diagrama anterior no se muestra el servicio de Grupos de Auto Scaling de EC2 (ASG). Por el nombre se puede entender que es responsable de escalar instancias. Sin embargo, hasta hace poco, AWS no ten\u00eda la capacidad integrada de gestionar la cantidad de m\u00e1quinas en funcionamiento desde ECS. ECS permit\u00eda escalar la cantidad de tareas, por ejemplo, en funci\u00f3n del uso de CPU, RAM o el n\u00famero de solicitudes. Pero si las tareas ocupaban todas las instancias libres, nuevas m\u00e1quinas no se levantaban autom\u00e1ticamente.<\/p>\n<p><\/p>\n<p>Esto cambi\u00f3 con la llegada de los Proveedores de Capacidad de ECS (ECS CP). Ahora, cada servicio en ECS se puede vincular a un ASG, y si las tareas no caben en las instancias en funcionamiento, se levantar\u00e1n nuevas (pero dentro de los l\u00edmites establecidos del ASG). Esto tambi\u00e9n funciona al rev\u00e9s; si ECS CP ve instancias inactivas sin tareas, le ordenar\u00e1 al ASG que las apague. ECS CP tiene la capacidad de especificar un porcentaje objetivo de carga de las instancias para que un n\u00famero determinado de m\u00e1quinas siempre est\u00e9 disponible para escalar r\u00e1pidamente las tareas, hablar\u00e9 de esto m\u00e1s adelante.<\/p>\n<p><\/p>\n<h3 id=\"ec2-launch-templates\">Plantillas de Lanzamiento de EC2<\/h3>\n<p><\/p>\n<p>El \u00faltimo servicio del que hablar\u00e9, antes de pasar a la descripci\u00f3n detallada de la creaci\u00f3n de esta infraestructura, son las Plantillas de Lanzamiento de EC2. Permiten crear una plantilla seg\u00fan la cual se iniciar\u00e1n todas las m\u00e1quinas, evitando tener que repetirlo cada vez desde cero. Aqu\u00ed se puede elegir el tipo de m\u00e1quina que se va a iniciar, el grupo de seguridad, la imagen de disco y muchos otros par\u00e1metros. Tambi\u00e9n se pueden especificar datos de usuario que se cargar\u00e1n en todas las instancias iniciadas. En los datos de usuario se pueden ejecutar scripts; por ejemplo, se puede editar el contenido del archivo <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ecs-agent-config.html\">de configuraci\u00f3n del agente de ECS<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Uno de los par\u00e1metros de configuraci\u00f3n m\u00e1s importantes en el contexto de este art\u00edculo es <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/container-instance-spot.html\">ECS_ENABLE_SPOT_INSTANCE_DRAINING<\/a><\/noindex>=true. Si este par\u00e1metro est\u00e1 habilitado, tan pronto como ECS recibe la se\u00f1al de que la instancia spot est\u00e1 siendo retirada, cambia el estado de todas las tareas que se est\u00e1n ejecutando en ella a Draining. No se asignar\u00e1n nuevas tareas a esta instancia; si hay tareas que quieren ser desplegadas en ella, se cancelan. Tambi\u00e9n dejar\u00e1n de llegar solicitudes del balanceador. La notificaci\u00f3n de eliminaci\u00f3n de la instancia llega 2 minutos antes del evento real. Por lo tanto, si su servicio no realiza tareas que duren m\u00e1s de 2 minutos y no guarda nada en el disco, puede usar instancias spot sin p\u00e9rdida de datos.<\/p>\n<p><\/p>\n<p>En cuanto al disco, AWS recientemente <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/about-aws\/whats-new\/2020\/04\/amazon-ecs-aws-fargate-support-amazon-efs-filesystems-generally-available\/#:~:text=To%20use%20EFS%20with%20ECS,or%20TLS%20encryption%20in%20transit.\">ha hecho<\/a><\/noindex> posible el uso de Elastic File System (EFS) junto con ECS, con este esquema ni siquiera el disco es un obst\u00e1culo, aunque no lo hemos probado, ya que en principio no necesitamos el disco para almacenar estado. Por defecto, despu\u00e9s de recibir SIGINT (que se env\u00eda en el momento en que la tarea cambia a estado Draining), todas las tareas en funcionamiento se detendr\u00e1n en 30 segundos, incluso si no han podido completarse; este tiempo puede ajustarse con el par\u00e1metro <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ecs-agent-config.html\">ECS_CONTAINER_STOP_TIMEOUT<\/a><\/noindex>. Lo principal es no configurarlo m\u00e1s de 2 minutos para las m\u00e1quinas spot.<\/p>\n<p><\/p>\n<h2 id=\"sozdanie-servisa\">Creaci\u00f3n del servicio<\/h2>\n<p><\/p>\n<p>Pasamos directamente a la creaci\u00f3n del servicio descrito. En el proceso, describir\u00e9 algunos puntos \u00fatiles adicionales que no se mencionaron anteriormente. En general, es una gu\u00eda paso a paso, pero no considerar\u00e9 casos muy b\u00e1sicos o, por el contrario, muy espec\u00edficos. Todas las acciones se realizan en la consola visual de AWS, pero se pueden reproducir program\u00e1ticamente utilizando CloudFormation o Terraform. En Adapty utilizamos Terraform.<\/p>\n<p><\/p>\n<h3 id=\"ec2-launch-template\"><strong>Plantilla de lanzamiento de EC2<\/strong><\/h3>\n<p><\/p>\n<p>En este servicio se crea la configuraci\u00f3n de las m\u00e1quinas que se utilizar\u00e1n. La gesti\u00f3n de las plantillas se lleva a cabo en la secci\u00f3n EC2 -&gt; Instances -&gt; Launch templates.<\/p>\n<p><\/p>\n<p><strong>Amazon Machine Image (AMI)<\/strong> \u2014 especificamos la imagen de disco con la que se iniciar\u00e1n todas las instancias. Para ECS, en la mayor\u00eda de los casos, se debe utilizar la imagen optimizada de Amazon. Se actualiza regularmente y contiene todo lo necesario para el funcionamiento de ECS. Para conocer el ID de imagen actual, accedemos a la p\u00e1gina <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ecs-optimized_AMI.html\">Amazon ECS-optimized AMIs<\/a><\/noindex>, seleccionamos la regi\u00f3n utilizada y copiamos el AMI ID correspondiente. Por ejemplo, para la regi\u00f3n us-east-1, el ID actual al momento de escribir este art\u00edculo es <em>ami-00c7c1cf5bdc913ed<\/em>. Este ID debe insertarse en el apartado Specify a custom value.<\/p>\n<p><\/p>\n<p><strong>Tipo de instancia<\/strong> \u2014 especificamos el tipo de instancia. Elija el que mejor se adapte a sus necesidades.<\/p>\n<p><\/p>\n<p><strong>Par de claves (inicio de sesi\u00f3n)<\/strong> \u2014 especificamos el certificado que se utilizar\u00e1 para conectarse a la instancia a trav\u00e9s de SSH, si es necesario.<\/p>\n<p><\/p>\n<p><strong>Configuraci\u00f3n de red<\/strong> \u2014 especificamos los par\u00e1metros de la red. <strong>Plataforma de redes<\/strong> en la mayor\u00eda de los casos debe ser Virtual Private Cloud (VPC). <strong>Grupos de seguridad<\/strong> \u2014 grupos de seguridad para sus instancias. Dado que utilizaremos un balanceador antes de las instancias, le recomiendo especificar aqu\u00ed un grupo que permita conexiones entrantes solo desde el balanceador. Es decir, tendr\u00e1 2 grupos de seguridad, uno para el balanceador que permite conexiones entrantes desde cualquier lugar a trav\u00e9s de los puertos 80 (http) y 443 (https), y el segundo para las m\u00e1quinas que permite conexiones entrantes a trav\u00e9s de cualquier puerto del grupo del balanceador. Las conexiones salientes en ambos grupos deben ser abiertas a trav\u00e9s del protocolo TCP en todos los puertos a todas las direcciones. Puede restringir los puertos y direcciones para las conexiones salientes, pero entonces debe monitorear constantemente que no intente acceder a ning\u00fan puerto cerrado.<\/p>\n<p><\/p>\n<p><strong>Almacenamiento (vol\u00famenes)<\/strong> \u2014 especificamos los par\u00e1metros de los discos para las m\u00e1quinas. El tama\u00f1o del disco no puede ser menor que lo establecido en el AMI, para ECS Optimized \u2014 30 GiB.<\/p>\n<p><\/p>\n<p><strong>Detalles avanzados<\/strong> \u2014 especificamos par\u00e1metros adicionales.<\/p>\n<p><\/p>\n<p><strong>Opci\u00f3n de compra<\/strong> \u2014 queremos comprar instancias de tipo spot. Queremos hacerlo, pero aqu\u00ed no marcaremos esta casilla, lo configuraremos en el Grupo de Auto Scaling, donde hay m\u00e1s opciones.<\/p>\n<p><\/p>\n<p><strong>Perfil de instancia IAM<\/strong> \u2014 especificamos el rol bajo el cual se lanzar\u00e1n las instancias. Para que las instancias funcionen en ECS, necesitan permisos que generalmente se encuentran en el rol <em>ecsInstanceRole<\/em>. En algunos casos, puede ser creada. Si no, aqu\u00ed <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/instance_IAM_role.html\">las instrucciones<\/a><\/noindex> hay informaci\u00f3n sobre c\u00f3mo hacerlo. Despu\u00e9s de crearla, la especificamos en la plantilla.<br \/>\nA continuaci\u00f3n hay muchos par\u00e1metros, en su mayor\u00eda se pueden dejar los valores por defecto, pero cada uno de ellos tiene una descripci\u00f3n clara. Siempre incluyo los par\u00e1metros de instancia optimizada para EBS y T2\/T3 Unlimited, si se utilizan <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AWSEC2\/latest\/UserGuide\/burstable-performance-instances.html\">burstable<\/a><\/noindex> instancias.<\/p>\n<p><\/p>\n<p><strong>Datos del usuario<\/strong> \u2014 especificamos los datos del usuario. Editaremos el archivo <code>\/etc\/ecs\/ecs.config<\/code>, donde se encuentra la configuraci\u00f3n del agente ECS.<br \/>\nEjemplo de c\u00f3mo podr\u00eda lucir los datos del usuario:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">#!\/bin\/bash\necho ECS_CLUSTER=DemoApiClusterProd &gt;&gt; \/etc\/ecs\/ecs.config\necho ECS_ENABLE_SPOT_INSTANCE_DRAINING=true &gt;&gt; \/etc\/ecs\/ecs.config\necho ECS_CONTAINER_STOP_TIMEOUT=1m &gt;&gt; \/etc\/ecs\/ecs.config\necho ECS_ENGINE_AUTH_TYPE=docker &gt;&gt; \/etc\/ecs\/ecs.config\necho &quot;ECS_ENGINE_AUTH_DATA={&quot;registry.gitlab.com&quot;:{&quot;username&quot;:&quot;username&quot;,&quot;password&quot;:&quot;password&quot;}}&quot; &gt;&gt; \/etc\/ecs\/ecs.config<\/code><\/pre>\n<p><\/p>\n<p><code>ECS_CLUSTER=DemoApiClusterProd<\/code> \u2014 el par\u00e1metro indica que la instancia pertenece a un cl\u00faster con el nombre especificado, es decir, este cl\u00faster podr\u00e1 ejecutar sus tareas en este servidor. A\u00fan no hemos creado un cl\u00faster, pero al crearlo usaremos este nombre.<\/p>\n<p><\/p>\n<p><code>ECS_ENABLE_SPOT_INSTANCE_DRAINING=true<\/code> \u2014 el par\u00e1metro indica que al recibir la se\u00f1al para apagar la instancia de spot, todas las tareas en ella deben pasar al estado Draining.<\/p>\n<p><\/p>\n<p><code>ECS_CONTAINER_STOP_TIMEOUT=1m<\/code> \u2014 el par\u00e1metro indica que tras recibir la se\u00f1al SIGINT, todas las tareas tienen 1 minuto antes de ser terminadas.<\/p>\n<p><\/p>\n<p><code>ECS_ENGINE_AUTH_TYPE=docker<\/code> \u2014 el par\u00e1metro indica que se utiliza el esquema de autorizaci\u00f3n de Docker como mecanismo de autorizaci\u00f3n.<\/p>\n<p><\/p>\n<p><code>ECS_ENGINE_AUTH_DATA=...<\/code> \u2014 par\u00e1metros de conexi\u00f3n a un registro de contenedores privado, donde se almacenan tus im\u00e1genes de Docker. Si es p\u00fablico, no es necesario indicar nada.<\/p>\n<p><\/p>\n<p>En este art\u00edculo usar\u00e9 una imagen p\u00fablica de Docker Hub, as\u00ed que no es necesario indicar par\u00e1metros. <code>ECS_ENGINE_AUTH_TYPE<\/code> y <code>ECS_ENGINE_AUTH_DATA<\/code> no es necesario.<\/p>\n<p><\/p>\n<p><strong>Es bueno saber<\/strong>: se recomienda actualizar regularmente el AMI, ya que en las nuevas versiones se actualizan las versiones de Docker, Linux, el agente ECS, etc. Para no olvidar esto, puedes <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/ECS-AMI-SubscribeTopic.html\">configurar notificaciones<\/a><\/noindex> sobre el lanzamiento de nuevas versiones. Puedes recibir notificaciones por correo electr\u00f3nico y actualizar manualmente, o puedes escribir una funci\u00f3n Lambda que cree autom\u00e1ticamente una nueva versi\u00f3n del Launch Template con el AMI actualizado.<\/p>\n<p><\/p>\n<h3 id=\"ec2-auto-scaling-group\"><strong>Grupo de escalado autom\u00e1tico de EC2<\/strong><\/h3>\n<p><\/p>\n<p>El Grupo de Escalado Autom\u00e1tico se encarga de iniciar y escalar instancias. La gesti\u00f3n de grupos se realiza en la secci\u00f3n EC2 -&gt; Escalado autom\u00e1tico -&gt; Grupos de escalado autom\u00e1tico.<\/p>\n<p><\/p>\n<p><strong>Plantilla de lanzamiento<\/strong> \u2014 seleccionamos la plantilla que se cre\u00f3 en el paso anterior. Dejamos la versi\u00f3n predeterminada.<\/p>\n<p><\/p>\n<p><strong>Opciones de compra y tipos de instancia<\/strong> \u2014 indicamos los tipos de instancias para el cl\u00faster. Adherirse a la plantilla de lanzamiento utiliza el tipo de instancia de la Plantilla de Lanzamiento. Combinar opciones de compra y tipos de instancia permite configurar los tipos de instancia de forma flexible. Lo usaremos.<\/p>\n<p><\/p>\n<p><strong>Base de On-Demand opcional<\/strong> \u2014 la cantidad de instancias normales, no de spot, que siempre estar\u00e1n funcionando.<\/p>\n<p><\/p>\n<p><strong>Porcentaje de On-Demand sobre la base<\/strong> \u2014 la proporci\u00f3n porcentual de instancias normales y de spot, 50-50 distribuir\u00e1 de manera uniforme, 20-80 significa que por cada instancia normal se lanzar\u00e1n 4 de spot. En este ejemplo, indicar\u00e9 50-50, pero en realidad, a menudo hacemos 20-80, en algunos casos 0-100.<\/p>\n<p><\/p>\n<p><strong>Tipos de instancia<\/strong> \u2014 aqu\u00ed se pueden especificar tipos adicionales de instancias que se utilizar\u00e1n en el cl\u00faster. Nunca lo hemos utilizado porque no entiendo muy bien el sentido de esta historia. Puede que se deba a los l\u00edmites en tipos espec\u00edficos de instancias, pero es f\u00e1cil aumentarlos a trav\u00e9s del soporte. Si conoces una aplicaci\u00f3n, estar\u00e9 encantado de leerla en los comentarios)<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/c1ee742d2059674f39a53cac6b9f2347.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Red<\/strong> \u2014 configuraciones de la red, elige VPC y subredes para las m\u00e1quinas, en la mayor\u00eda de los casos es mejor seleccionar todas las subredes disponibles.<\/p>\n<p><\/p>\n<p><strong>Balanceo de carga<\/strong> \u2014 configuraciones del balanceador, pero esto lo haremos por separado, aqu\u00ed no cambiamos nada. <strong>Comprobaciones de salud<\/strong> tambi\u00e9n se configurar\u00e1n m\u00e1s tarde.<\/p>\n<p><\/p>\n<p><strong>Tama\u00f1o del grupo<\/strong> \u2014 especificamos los l\u00edmites en el n\u00famero de m\u00e1quinas en el cl\u00faster y la cantidad deseada de m\u00e1quinas al inicio. El n\u00famero de m\u00e1quinas en el cl\u00faster nunca ser\u00e1 menor que el m\u00ednimo especificado y mayor que el m\u00e1ximo, incluso si las m\u00e9tricas indican que deber\u00eda producirse una escalabilidad.<\/p>\n<p><\/p>\n<p><strong>Pol\u00edticas de escalabilidad<\/strong> \u2014 par\u00e1metros de escalabilidad, pero escalaremos bas\u00e1ndonos en las tareas de ECS en ejecuci\u00f3n, as\u00ed que configuraremos la escalabilidad m\u00e1s tarde.<\/p>\n<p><\/p>\n<p><strong>Protecci\u00f3n contra la reducci\u00f3n de instancias<\/strong> \u2014 protecci\u00f3n de las instancias contra la eliminaci\u00f3n al escalar hacia abajo. Activamos esto para que el ASG no elimine la m\u00e1quina que tiene tareas en ejecuci\u00f3n. Desactivar la protecci\u00f3n para instancias sin tareas ser\u00e1 proporcionado por el Proveedor de Capacidad ECS.<\/p>\n<p><\/p>\n<p><strong>A\u00f1adir etiquetas<\/strong> \u2014 se pueden especificar etiquetas para las instancias (para esto debe estar marcada la opci\u00f3n Etiquetar nuevas instancias). Recomiendo especificar la etiqueta Nombre, as\u00ed todas las instancias que se inician en el grupo tendr\u00e1n el mismo nombre, lo que facilita su visualizaci\u00f3n en la consola.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/61fa0ccb38c11f61431db0938140efb7.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Despu\u00e9s de crear el grupo, \u00e1brelo y ve a la secci\u00f3n de Configuraciones avanzadas, porque en la etapa de creaci\u00f3n no se ven todas las opciones en la consola.<\/p>\n<p><\/p>\n<p><strong>Pol\u00edticas de terminaci\u00f3n<\/strong> \u2014 reglas que se consideran al eliminar instancias. Se aplican en orden. Normalmente utilizamos las reglas como en la imagen de abajo. Primero se eliminan las instancias con el Launch Template m\u00e1s antiguo (por ejemplo, si hemos actualizado el AMI, se cre\u00f3 una nueva versi\u00f3n, pero todas las instancias lograron actualizarse a ella). Luego se seleccionan las instancias que est\u00e1n m\u00e1s cerca de la pr\u00f3xima hora de c\u00e1lculo por facturaci\u00f3n. Y despu\u00e9s se eligen las m\u00e1s antiguas por fecha de lanzamiento.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/8236624fe08a03f36aedc7665e18b060.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Es bueno saber<\/strong>para actualizar todas las m\u00e1quinas en el cl\u00faster, es conveniente usar <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/autoscaling\/ec2\/userguide\/asg-instance-refresh.html\">Actualizaci\u00f3n de Instancias<\/a><\/noindex>. Si combinamos esto con la funci\u00f3n Lambda del paso anterior, tendremos un sistema de actualizaci\u00f3n de instancias completamente automatizado. Antes de actualizar todas las m\u00e1quinas, es necesario desactivar la protecci\u00f3n contra reducci\u00f3n de instancias para todas las instancias en el grupo. No la configuraci\u00f3n en el grupo, sino la protecci\u00f3n de las m\u00e1quinas mismas, lo que se realiza en la pesta\u00f1a de gesti\u00f3n de instancias.<\/p>\n<p><\/p>\n<h3 id=\"application-load-balancer-i-ec2-target-group\">Application Load Balancer y EC2 Target Group<\/h3>\n<p><\/p>\n<p>El balanceador se crea en la secci\u00f3n EC2 \u2192 Load Balancing \u2192 Load Balancers. Usaremos Application Load Balancer; puedes leer sobre la comparaci\u00f3n de diferentes tipos de balanceadores en <noindex><a rel=\"nofollow\" href=\"https:\/\/aws.amazon.com\/elasticloadbalancing\/features\/#compare\">la p\u00e1gina del servicio<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Listeners<\/strong> \u2014 tiene sentido habilitar los puertos 80 y 443 y hacer un redireccionamiento del 80 al 443 posteriormente mediante reglas del balanceador.<\/p>\n<p><\/p>\n<p><strong>Zonas de Disponibilidad<\/strong> \u2014 en la mayor\u00eda de los casos elegimos todas las zonas de disponibilidad.<\/p>\n<p><\/p>\n<p><strong>Configurar Seguridad<\/strong> \u2014 aqu\u00ed se especifica el certificado SSL para el balanceador, la opci\u00f3n m\u00e1s conveniente es <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/acm\/latest\/userguide\/gs-acm-request-public.html\">crear el certificado<\/a><\/noindex> en ACM. Sobre las diferencias <strong>Pol\u00edtica de Seguridad<\/strong> puedes leer en <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/elasticloadbalancing\/latest\/classic\/elb-security-policy-table.html\">la documentaci\u00f3n<\/a><\/noindex>, puedes dejar la seleccionada por defecto <code>ELBSecurityPolicy-2016-08<\/code>. Despu\u00e9s de crear el balanceador, ver\u00e1s su <strong>nombre DNS<\/strong>, al que se debe configurar un CNAME para tu dominio. Por ejemplo, as\u00ed se ve en Cloudflare.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/899ff0f30df4117fc0ccd91af135def3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Grupo de Seguridad<\/strong> \u2014 creamos o elegimos un grupo de seguridad para el balanceador, sobre esto ya se escribi\u00f3 un poco m\u00e1s arriba en la secci\u00f3n EC2 Launch Template \u2192 Configuraci\u00f3n de red.<\/p>\n<p><\/p>\n<p><strong>Grupo objetivo<\/strong> \u2014 creamos un grupo que se encarga de enrutar solicitudes del balanceador a las m\u00e1quinas y verificar su disponibilidad, para reemplazarlas en caso de problemas. <strong>Tipo de objetivo<\/strong> debe ser Instance, <strong>Protocolo<\/strong> y <strong>Puerto<\/strong> cualquiera, si utilizas HTTPS para la comunicaci\u00f3n entre el balanceador y las instancias, entonces debes cargar el certificado en ellas. En este ejemplo no lo haremos, simplemente dejaremos el puerto 80.<\/p>\n<p><\/p>\n<p><strong>Comprobaciones de salud<\/strong> \u2014 par\u00e1metros para comprobar la funcionalidad del servicio. En el servicio real, esto deber\u00eda ser una solicitud separada que implemente partes importantes de la l\u00f3gica de negocio; en este ejemplo, dejar\u00e9 la configuraci\u00f3n por defecto. Luego puedes seleccionar el intervalo de solicitudes, el tiempo de espera, c\u00f3digos de respuesta exitosos, etc. En nuestro ejemplo, indicaremos c\u00f3digos de \u00e9xito de 200-399, porque la imagen de Docker que se utilizar\u00e1 devuelve el c\u00f3digo 304.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/e295ab1c3bf1dfe13c76b4942a31c7ee.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Registrar Targets<\/strong> \u2014 aqu\u00ed se eligen las m\u00e1quinas para el grupo, pero en nuestro caso esto lo har\u00e1 ECS, as\u00ed que simplemente omitimos este paso.<\/p>\n<p><\/p>\n<p><strong>Es bueno saber<\/strong>: a nivel del balanceador se pueden habilitar registros que se guardar\u00e1n en S3 en un formato espec\u00edfico. <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/elasticloadbalancing\/latest\/application\/load-balancer-access-logs.html\">en formato<\/a><\/noindex>. Desde all\u00ed se pueden exportar a servicios externos de an\u00e1lisis, o se pueden realizar consultas SQL directamente sobre los datos en S3 con <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/athena\/latest\/ug\/application-load-balancer-logs.html\">la ayuda de Athena.<\/a><\/noindex>. Esto es conveniente y funciona sin ning\u00fan c\u00f3digo adicional. Tambi\u00e9n recomiendo configurar la eliminaci\u00f3n de registros del bucket S3 despu\u00e9s de un per\u00edodo de tiempo determinado.<\/p>\n<p><\/p>\n<h3 id=\"ecs-task-definition\">Definici\u00f3n de Tarea ECS<\/h3>\n<p><\/p>\n<p>En los pasos anteriores creamos todo lo relacionado con la infraestructura del servicio, ahora pasamos a describir los contenedores que vamos a ejecutar. Esto se hace en la secci\u00f3n ECS \u2192 Definiciones de Tareas.<\/p>\n<p><\/p>\n<p><strong>Compatibilidad de tipo de lanzamiento<\/strong> \u2014 seleccionamos EC2.<\/p>\n<p><\/p>\n<p><strong>Rol IAM de ejecuci\u00f3n de tareas<\/strong> \u2014 seleccionamos <code>ecsTaskExecutionRole<\/code>. Con \u00e9l se escriben registros, se otorga acceso a variables secretas, etc.<\/p>\n<p><\/p>\n<p>En la secci\u00f3n Definiciones de Contenedor, hacemos clic en A\u00f1adir Contenedor.<\/p>\n<p><\/p>\n<p><strong>Imagen<\/strong> \u2014 enlace a la imagen con el c\u00f3digo del proyecto, en este caso utilizar\u00e9 una imagen p\u00fablica de Docker Hub <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/bitnami\/node-example\">bitnami\/node-example:0.0.1<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>L\u00edmites de Memoria<\/strong> \u2014 l\u00edmites de memoria para el contenedor. <strong>L\u00edmite Duro<\/strong> \u2014 l\u00edmite duro, si el contenedor supera el valor indicado, se ejecutar\u00e1 el comando docker kill, el contenedor morir\u00e1 de inmediato. <strong>L\u00edmite Blando<\/strong> \u2014 l\u00edmite blando, el contenedor puede superar el valor indicado, pero al colocar tareas en las m\u00e1quinas se considerar\u00e1 este par\u00e1metro. Por ejemplo, si una m\u00e1quina tiene 4 GiB de memoria RAM, y el l\u00edmite blando del contenedor es de 2048 MiB, entonces se pueden ejecutar un m\u00e1ximo de 2 tareas con este contenedor en esa m\u00e1quina. En realidad, 4 GiB de memoria RAM son un poco menos que 4096 MiB, esto se puede ver en la pesta\u00f1a Instancias de ECS en el cl\u00faster. El l\u00edmite blando no puede ser mayor que el l\u00edmite duro. Es importante entender que si hay varios contenedores en una tarea, sus l\u00edmites se suman.<\/p>\n<p><\/p>\n<p><strong>Asignaciones de Puertos<\/strong> \u2014 en <strong>Puerto Host<\/strong> indicamos 0, esto significa que el puerto se asignar\u00e1 de manera din\u00e1mica, ser\u00e1 rastreado por el Grupo de Destino. <strong>Puerto del Contenedor<\/strong> \u2014 el puerto en el que funciona tu aplicaci\u00f3n, a menudo se establece en el comando de ejecuci\u00f3n o en el c\u00f3digo de tu aplicaci\u00f3n, Dockerfile, etc. Para nuestro ejemplo, utilizamos 3000, porque est\u00e1 indicado en <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bitnami\/bitnami-docker-node\/blob\/master\/example\/Dockerfile\">Dockerfile<\/a><\/noindex> la imagen utilizada.<\/p>\n<p><\/p>\n<p><strong>Chequeo de Salud<\/strong> \u2014 par\u00e1metros para verificar la operatividad del contenedor, no confundir con el que se configura en el Grupo de Destino.<\/p>\n<p><\/p>\n<p><strong>Entorno<\/strong> \u2014 configuraciones del entorno. <strong>Unidades de CPU<\/strong> \u2014 similar to Memory limits, but for the processor. Each CPU core equals 1024 units, so if there's a dual-core processor on the server and the container has a value of 512 set, then up to 4 tasks can be run on that server with this container. CPU units always correspond to the number of cores; there cannot be slightly fewer than in the case of memory.<\/p>\n<p><\/p>\n<p><strong>Comando<\/strong> \u2014 command to start a service within the container, with all parameters specified via commas. This can be gunicorn, npm, etc. If not specified, the CMD directive from Dockerfile will be used. We specify <code>npm,start<\/code>.<\/p>\n<p><\/p>\n<p><strong>Variables de entorno<\/strong> \u2014 container environment variables. These can be plain text data or secret variables from the <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/specifying-sensitive-data-secrets.html\">Secrets Manager<\/a><\/noindex> o <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/specifying-sensitive-data-parameters.html\">Parameter Store<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><strong>Almacenamiento y Registros<\/strong> \u2014 here we will set up logging in CloudWatch Logs (the logging service from AWS). Simply check the Auto-configure CloudWatch Logs option. After creating the Task Definition, a log group will automatically be created in CloudWatch. By default, logs are stored indefinitely in it; I recommend changing the Retention period from Never Expire to the required duration. This is done in CloudWatch Log groups; you need to click on the current period and select a new one.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/c9ad7ca39dfde9343be89eb9ab1aef10.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"ecs-cluster-i-ecs-capacity-provider\">ECS Cluster y ECS Capacity Provider<\/h3>\n<p><\/p>\n<p>We go to the ECS \u2192 Clusters section to create a cluster. As a template, we choose EC2 Linux + Networking.<\/p>\n<p><\/p>\n<p><strong>Nombre del cl\u00faster<\/strong> \u2014 very important, we use the same name here as specified in the Launch Template under the parameter <code>ECS_CLUSTER<\/code>, in our case \u2014 <code>DemoApiClusterProd<\/code>. We check the Create an empty cluster option. Optionally, you can enable Container Insights to view service metrics in CloudWatch. If you\u2019ve done everything correctly, you will see the machines created in the Auto Scaling group in the ECS Instances section.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/cd70062c9783ae359a2b27cbfc66cbe3.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>We move to the <strong>Capacity Providers<\/strong> tab and create a new one. Reminder, this is needed to manage the creation and shutdown of machines depending on the number of running ECS tasks. It is important to note that the provider can only be tied to one group.<\/p>\n<p><\/p>\n<p><strong>Auto Scaling group<\/strong> \u2014 we select the previously created group.<\/p>\n<p><\/p>\n<p><strong>Escalado gestionado<\/strong> \u2014 we enable this so the provider can scale the service.<\/p>\n<p><\/p>\n<p><strong>Capacidad objetivo %<\/strong> \u00bfQu\u00e9 porcentaje de carga de las m\u00e1quinas necesitamos para las tareas? Si se establece al 100%, todas las m\u00e1quinas siempre estar\u00e1n ocupadas con las tareas en ejecuci\u00f3n. Si se establece al 50%, la mitad de las m\u00e1quinas estar\u00e1n siempre libres. En este caso, si hay un repentino aumento en la carga, los nuevos taxis se asignar\u00e1n inmediatamente a las m\u00e1quinas libres, sin necesidad de esperar a que se desplieguen las instancias.<\/p>\n<p><\/p>\n<p><strong>Protecci\u00f3n de terminaci\u00f3n gestionada<\/strong> Si lo activamos, este par\u00e1metro permite al proveedor eliminar la protecci\u00f3n de eliminaci\u00f3n de las instancias. Esto ocurre cuando no hay tareas activas en la m\u00e1quina y permite el porcentaje de capacidad objetivo.<\/p>\n<p><\/p>\n<h3 id=\"ecs-service-i-nastroyka-masshtabirovaniya\">Servicio ECS y configuraci\u00f3n de escalado<\/h3>\n<p><\/p>\n<p>\u00daltimo paso :) Para crear un servicio, hay que acceder al cl\u00faster creado anteriormente en la pesta\u00f1a Servicios.<\/p>\n<p><\/p>\n<p><strong>Tipo de lanzamiento<\/strong> Hay que hacer clic en Cambiar a la estrategia del proveedor de capacidad y seleccionar el proveedor creado anteriormente.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/9d9dfdd8e333cce24bfb048ac84097e4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Definici\u00f3n de tareas<\/strong> Seleccionamos la Definici\u00f3n de Tareas creada anteriormente y su revisi\u00f3n.<\/p>\n<p><\/p>\n<p><strong>Nombre del servicio<\/strong> Para no confundirnos, siempre indicamos el mismo nombre que la Definici\u00f3n de Tareas.<\/p>\n<p><\/p>\n<p><strong>Tipo de servicio<\/strong> Siempre Replica.<\/p>\n<p><\/p>\n<p><strong>N\u00famero de tareas<\/strong> N\u00famero deseado de tareas activas en el servicio. Este par\u00e1metro se controla mediante el escalado, pero a\u00fan as\u00ed debe especificarse.<\/p>\n<p><\/p>\n<p><strong>Porcentaje m\u00ednimo saludable<\/strong> y <strong>Porcentaje m\u00e1ximo<\/strong> Determinan el comportamiento de las tareas durante el despliegue. Los valores por defecto son 100 y 200, lo que indica que en el momento del despliegue, el n\u00famero de tareas se duplicar\u00e1 y luego regresar\u00e1 al deseado. Si tienes 1 tarea funcionando, min=0 y max=100, entonces durante el despliegue ser\u00e1 eliminada y despu\u00e9s se levantar\u00e1 una nueva, es decir, habr\u00e1 inactividad. Si hay 1 tarea en funcionamiento, min=50 y max=150, entonces el despliegue no ocurrir\u00e1 porque no se puede dividir una tarea en dos partes ni aumentarla en un 50%.<\/p>\n<p><\/p>\n<p><strong>Tipo de despliegue<\/strong> Mantendremos la actualizaci\u00f3n continua.<\/p>\n<p><\/p>\n<p><strong>Plantillas de colocaci\u00f3n<\/strong> Reglas para la colocaci\u00f3n de tareas en las m\u00e1quinas. Por defecto est\u00e1 configurada como Distribuci\u00f3n Balanceada por AZ, lo que significa que cada nueva tarea se colocar\u00e1 en una nueva instancia hasta que se levantan m\u00e1quinas en todas las zonas de disponibilidad. Normalmente, hacemos BinPack para CPU y Spread para AZ; con esta pol\u00edtica, las tareas se colocan de manera compacta en una m\u00e1quina seg\u00fan el CPU. Si es necesaria una nueva m\u00e1quina, se crea en una nueva zona de disponibilidad.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/6430bdf046fc5b970e0afbbf0d9ef65e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Tipo de balanceador de carga<\/strong> Seleccionamos el Balanceador de Carga de Aplicaci\u00f3n.<\/p>\n<p><\/p>\n<p><strong>Rol IAM del servicio<\/strong> Elegimos <code>ecsServiceRole<\/code>.<\/p>\n<p><\/p>\n<p><strong>Nombre del balanceador de carga<\/strong> Seleccionamos el balanceador creado anteriormente.<\/p>\n<p><\/p>\n<p><strong>Per\u00edodo de gracia para la verificaci\u00f3n de salud<\/strong> Pausa antes de realizar las verificaciones de operatividad despu\u00e9s de la implementaci\u00f3n de una nueva tarea; normalmente establecemos 60 segundos.<\/p>\n<p><\/p>\n<p><strong>Contenedor a equilibrar<\/strong> En el campo Nombre del grupo objetivo, seleccionamos el grupo creado anteriormente, y todo se llenar\u00e1 autom\u00e1ticamente.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/c067868ff73c25c3d9b65e02be64f5c9.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Escalado autom\u00e1tico del servicio<\/strong> Par\u00e1metros de escalado del servicio. Seleccionamos Configurar escalado autom\u00e1tico del servicio para ajustar la cantidad deseada de su servicio. Establecemos el n\u00famero m\u00ednimo y m\u00e1ximo de tareas al escalar.<\/p>\n<p><\/p>\n<p><strong>Rol de IAM para el escalado autom\u00e1tico del servicio<\/strong> Elegimos <code>AWSServiceRoleForApplicationAutoScaling_ECSService<\/code>.<\/p>\n<p><\/p>\n<p><strong>Pol\u00edticas de escalado autom\u00e1tico de tareas<\/strong> Reglas para el escalado. Hay 2 tipos:<\/p>\n<p><\/p>\n<ol>\n<li><strong>Seguimiento de objetivos<\/strong> Seguimiento de una m\u00e9trica objetivo (uso de CPU\/RAM o n\u00famero de solicitudes por tarea). Por ejemplo, queremos que la carga promedio del procesador sea del 85%; cuando supere este valor, se a\u00f1adir\u00e1n nuevas tareas hasta alcanzar el valor objetivo. Si la carga es inferior, las tareas se eliminar\u00e1n, a menos que est\u00e9 habilitada la protecci\u00f3n contra escalado hacia abajo (<strong>Deshabilitar escalado hacia abajo<\/strong>).<\/li>\n<li><strong>Escalado por pasos<\/strong> Reacci\u00f3n a un evento arbitrario. Aqu\u00ed se puede configurar la reacci\u00f3n a cualquier evento (alarma de CloudWatch); cuando ocurra, se puede a\u00f1adir o eliminar la cantidad especificada de tareas, o indicar un n\u00famero exacto de tareas.<\/li>\n<\/ol>\n<p><\/p>\n<p>El servicio puede tener varias reglas de escalado, lo cual puede ser \u00fatil; lo principal es asegurarse de que no entren en conflicto entre s\u00ed.<\/p>\n<p><\/p>\n<h2 id=\"zaklyuchenie\">Conclusi\u00f3n<\/h2>\n<p><\/p>\n<p>Si seguiste las instrucciones y utilizaste la misma imagen de Docker, tu servicio deber\u00eda devolver esta p\u00e1gina.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Creaci\u00f3n de una API escalable en instancias spot de AWS\" src=\"\/wp-content\/uploads\/2020\/07\/ac592e3194480ac8b347a3a1faf0cee0.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ol>\n<li>Hemos creado una plantilla a partir de la cual se lanzan todas las m\u00e1quinas en el servicio. Tambi\u00e9n hemos aprendido a actualizar las m\u00e1quinas al modificar la plantilla.<\/li>\n<li>Hemos configurado el manejo de la se\u00f1al de detenci\u00f3n de la instancia spot, por lo que, dentro de un minuto, despu\u00e9s de recibirla, todas las tareas en ejecuci\u00f3n se eliminar\u00e1n de la m\u00e1quina, as\u00ed nada se pierde ni se interrumpe.<\/li>\n<li>Hemos levantado un balanceador para distribuir la carga equitativamente entre las m\u00e1quinas.<\/li>\n<li>Hemos creado un servicio que funciona en instancias spot, lo que reduce los costos de las m\u00e1quinas aproximadamente en 3 veces.<\/li>\n<li>Hemos configurado el escalado autom\u00e1tico en ambas direcciones para manejar el aumento de cargas, pero al mismo tiempo no pagar por inactividad.<\/li>\n<li>Estamos utilizando un Proveedor de Capacidad para que la aplicaci\u00f3n gestione la infraestructura (m\u00e1quinas), y no al rev\u00e9s.<\/li>\n<li>Hicimos bien.<\/li>\n<\/ol>\n<p><\/p>\n<p>Si tienes picos de carga predecibles, como cuando publicitas en un gran env\u00edo de correos electr\u00f3nicos, puedes configurar el escalado seg\u00fan <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.aws.amazon.com\/autoscaling\/application\/userguide\/application-auto-scaling-scheduled-scaling.html\">un horario<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Tambi\u00e9n se puede realizar escalado basado en datos de diferentes partes de su sistema. Por ejemplo, tenemos funcionalidad <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.adapty.io\/promo-campaigns\">de env\u00edo de promociones personalizadas<\/a><\/noindex> a los usuarios de la aplicaci\u00f3n m\u00f3vil. A veces, la campa\u00f1a se env\u00eda a m\u00e1s de 1 mill\u00f3n de personas. Despu\u00e9s de tal env\u00edo, siempre se observa un gran aumento en las solicitudes a la API, ya que muchos usuarios acceden a la aplicaci\u00f3n al mismo tiempo. As\u00ed que, si vemos que en la cola para el env\u00edo de promociones push hay un aumento significativo en comparaci\u00f3n con las m\u00e9tricas est\u00e1ndar, podemos iniciar varias m\u00e1quinas y tareas adicionales de inmediato para estar listos para la carga.<\/p>\n<p><\/p>\n<p>Estar\u00e9 encantado si comparten en los comentarios casos interesantes de uso de instancias spot y ECS o algo sobre escalado.<\/p>\n<p><\/p>\n<p>Pronto habr\u00e1 art\u00edculos sobre c\u00f3mo procesamos miles de eventos anal\u00edticos por segundo en una pila principalmente sin servidor (con dinero) y c\u00f3mo est\u00e1 organizado el despliegue de servicios utilizando GitLab CI y Terraform Cloud.<\/p>\n<p><\/p>\n<p>\u00a1S\u00edguenos, ser\u00e1 interesante!<\/p>\n<p class=\"for_users_only_msg\">Solo los usuarios registrados pueden participar en la encuesta. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Inicie sesi\u00f3n<\/a><\/noindex>, por favor.<\/p>\n<h2 class=\"default-block__polling-title\">\u00bfUtilizan instancias spot en producci\u00f3n?<\/h2>\n<ul class=\"poll-result\">\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent\">22,2%<\/strong>S\u00ed6<\/p>\n<\/li>\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent  poll-result__data-percent_winner\">66,7%<\/strong>No18<\/p>\n<\/li>\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent\">11,1%<\/strong>Me enter\u00e9 de ellos a trav\u00e9s de un art\u00edculo, planeo usarlos3<\/p>\n<\/li>\n<\/ul>\n<p>    Votaron 27 usuarios. 5 usuarios se abstuvieron.<br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/509790\/\">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 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty. \u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 AWS, \u0438 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0441\u043e\u043a\u0440\u0430\u0442\u0438\u043b\u0438 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 3 \u0440\u0430\u0437\u0430 \u0437\u0430 \u0441\u0447\u0451\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u043e\u0442\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u0432 \u043d\u0430 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0437\u043e\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":87394,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87393","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 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty.\" \/>\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\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws\" \/>\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\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e API \u043d\u0430 \u0441\u043f\u043e\u0442\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430\u0445 AWS | 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 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws\" \/>\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=\"2020-07-07T23:42:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-07T23:42:02+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\udd47Creaci\u00f3n de una API escalable en instancias spot de AWS | ProHoster","description":"\u00a1Hola a todos! Me llamo Kirill, soy CTO en Adapty.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","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\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e API \u043d\u0430 \u0441\u043f\u043e\u0442\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430\u0445 AWS | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041a\u0438\u0440\u0438\u043b\u043b, \u044f CTO \u0432 Adapty.","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/sozdanie-masshtabiruemogo-api-na-spotovyh-instansah-aws","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":"2020-07-07T23:42:02+00:00","article:modified_time":"2020-07-07T23:42:02+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87393","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:44:41","updated":"2022-09-28 14:12:20","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\/87393","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=87393"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/87393\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/87394"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=87393"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=87393"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=87393"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}