La lliçó anterior va contenidoritzar la botiga de MercadoFresco i la va posar a córrer en un clúster d'ECS. El resultat va ser bo però incomplet: sota el clúster continuen existint instàncies EC2 que cal dimensionar, l'AMI de les quals cal mantenir, que es paguen tant si són plenes com buides, i que triguen dos minuts a arrencar quan el clúster necessita capacitat nova. Vam amagar el problema darrere d'un proveïdor de capacitat; no el vam eliminar.
AWS Fargate l'elimina. És el motor de còmput sense servidor per a contenidors: es declara quanta CPU i quanta memòria necessita cada tasca, i AWS hi posa la resta —l'amfitrió, el kernel, els pedaços, l'aïllament— sense que existeixi cap instància que ningú pugui veure ni llistar. Aquesta lliçó migra el servei de la botiga a Fargate, ajusta el seu autoescalat al pic dels divendres, posa els treballadors de la cua a Fargate Spot i acaba amb la comparativa honesta entre Fargate, EC2 i Lambda.
Avís de cost. Fargate es factura per vCPU-hora i GB-hora consumits per la tasca, amb arrodoniment al segon i un mínim d'un minut. A
eu-west-1ronda els 0,047 USD per vCPU-hora i 0,0051 USD per GB-hora en x86, i aproximadament un 20 % menys en arm64/Graviton. Fargate Spot descompta al voltant del 70 % a canvi de poder ser interromput. No hi ha capa gratuïta per a Fargate: una tasca oblidada d'1 vCPU i 2 GB costa uns 41 USD al mes. Segueix la secció de neteja del final. Els preus són aproximats i orientatius; l'anàlisi de costos a fons és el mòdul 11. Dades i identificadors ficticis.
Contingut
- Què és Fargate i què deixa d'existir
- El mateix servei sobre EC2 i sobre Fargate
- Model de recursos: CPU, memòria i emmagatzematge efímer
- x86 i arm64: Graviton i l'estalvi real
- Diferències operatives: sense SSH, sense
hostPort, sense DaemonSet - ECS Exec: depurar sense servidor a tocar
- Registres amb FireLens i Fluent Bit
- L'arrencada de tasques i el pic dels divendres
- Migrar el servei de la botiga a Fargate
- Punts d'enllaç de VPC: deixar de dependre del NAT
- Autoescalat: seguiment, passos i programació
- Fargate Spot i els treballadors de la cua
- Tasques puntuals i programades amb EventBridge Scheduler
- Integració al pipeline i blue/green
- El servei en CDK amb un constructe L3
- Fargate enfront d'EC2 enfront de Lambda
- App Runner: un esglaó més de gestió
- Cost comparat i neteja
- Errors habituals i consells
- Exercicis
- Conclusió
Què és Fargate i què deixa d'existir
Fargate no és un servei que es contracti a part ni una consola diferent: és un tipus de llançament —i, amb més precisió, un proveïdor de capacitat— dins del mateix Amazon ECS de la lliçó anterior. Les definicions de tasca, els serveis, els grups de destinació, l'autoescalat i els rols són els mateixos objectes. El que canvia és on s'executa la tasca i qui és responsable de la màquina.
| El que deixa d'existir | Què significava abans | Què implica ara |
|---|---|---|
| L'AMI | Una imatge de sistema operatiu que cal mantenir i actualitzar | Només existeix la teva imatge de contenidor |
| L'apedaçament de l'amfitrió | Finestra mensual, reinicis esglaonats, CVE del kernel | AWS apedaça l'amfitrió sense que te n'assabentis |
| L'escalat del clúster | Un ASG, un proveïdor de capacitat, targetCapacity |
No hi ha clúster de màquines que escalar |
| L'empaquetatge de tasques | Estratègies binpack i spread, límits d'ENI, buits que no quadren |
Cada tasca és la seva pròpia unitat |
| La capacitat ociosa | Instàncies enceses a les 4 de la matinada d'un dimarts | Es paga la tasca, no el buit |
| L'accés a l'amfitrió | SSH, docker exec, volums de l'amfitrió |
ECS Exec; vegeu més avall |
| El que continua sent teu | Per què importa |
|---|---|
| La imatge | La seva mida, les seves dependències i les seves vulnerabilitats continuen sent responsabilitat teva |
| CPU i memòria de la tasca | Ja no hi ha instància que absorbeixi un error de dimensionament: aquí es paga exacte |
| La xarxa | Subxarxes, grups de seguretat, rutes i punts d'enllaç continuen sent decisions teves |
| Els permisos | Rol d'execució i rol de tasca, exactament igual que a 10-01 |
| La disponibilitat | Repartir tasques entre AZ, dimensionar el mínim, definir l'autoescalat |
La frase que resumeix el canvi: Fargate no elimina la feina d'operar una aplicació, elimina la feina d'operar un servidor. La Marta continua havent de decidir quantes tasques hi ha un divendres a les 19:00; el que ja no ha de decidir és de quina mida són les màquines que les allotgen.
Tècnicament, cada tasca de Fargate s'executa en el seu propi entorn aïllat per virtualització lleugera —la mateixa tecnologia que sustenta Lambda—, cosa que resol l'advertiment de 10-01 sobre el kernel compartit: dues tasques no comparteixen mai kernel, ni tan sols dues tasques teves.
El mateix servei sobre EC2 i sobre Fargate
graph TB
subgraph EC2["ECS sobre EC2 (10-01)"]
A1[ALB] --> S1[Servei ECS]
S1 --> I1["Instancia m5.large<br/>AMI + agent ECS<br/>APEDACAR"]
S1 --> I2["Instancia m5.large<br/>AMI + agent ECS<br/>APEDACAR"]
I1 --> T1[Tasca]
I1 --> T2[Tasca]
I2 --> T3[Tasca]
I2 --> H["Espai pagat<br/>i buit"]
ASG["ASG + proveidor de capacitat<br/>arrencada: 2 minuts"] -.gestiona.-> I1
ASG -.gestiona.-> I2
end
subgraph FG["ECS sobre Fargate (10-02)"]
A2[ALB] --> S2[Servei ECS]
S2 --> F1["Tasca 1 vCPU / 2 GB<br/>AZ a"]
S2 --> F2["Tasca 1 vCPU / 2 GB<br/>AZ a"]
S2 --> F3["Tasca 1 vCPU / 2 GB<br/>AZ b"]
S2 --> F4["Tasca 1 vCPU / 2 GB<br/>AZ b"]
AAS["Application Auto Scaling<br/>arrencada: 30-45 segons"] -.gestiona.-> S2
end
Els dos diagrames tenen el mateix ALB, el mateix servei i les mateixes tasques. La diferència és a la capa intermèdia: al primer hi ha dues caixes que representen màquines —amb la seva AMI, el seu agent i el seu buit pagat—; al segon no n'hi ha cap.
Model de recursos: CPU, memòria i emmagatzematge efímer
A Fargate, cpu i memory a escala de tasca són obligatoris i només admeten combinacions concretes. No es pot demanar 1 vCPU amb 1 GB, ni 3 vCPU amb el que sigui.
vCPU (cpu) |
Memòria vàlida (memory) |
Increment | Cas típic a MercadoFresco |
|---|---|---|---|
256 (0,25) |
512 MB, 1 GB, 2 GB | fix | Sidecar, tasca puntual petita |
512 (0,5) |
1 a 4 GB | 1 GB | Treballador de cola-mercadofresco-correo |
1024 (1) |
2 a 8 GB | 1 GB | La botiga i els treballadors de comandes |
2048 (2) |
4 a 16 GB | 1 GB | Càrrega nocturna cap a Redshift |
4096 (4) |
8 a 30 GB | 1 GB | Processos d'anàlisi puntuals |
8192 (8) |
16 a 60 GB | 4 GB | Poques vegades: convé repartir en més tasques |
16384 (16) |
32 a 120 GB | 8 GB | Gairebé mai |
Dues conseqüències pràctiques:
- La combinació es tria abans de conèixer la càrrega real, i gairebé sempre malament. El mètode correcte és el del mòdul 5: mirar
CpuUtilizediMemoryUtilizedde Container Insights durant dues setmanes, prendre el percentil 95 i afegir-hi un 30 % de marge. Sobredimensionar a Fargate costa diners des del primer segon, perquè no hi ha cap instància ja pagada on amagar l'excés. - La granularitat castiga les aplicacions amb poca CPU i molta memòria. Una tasca que necessita 6 GB obliga a demanar almenys 1 vCPU, encara que en faci servir el 5 %. Quan això passa molt, convé revisar si l'aplicació hauria de ser una Lambda o si hi ha una fuita de memòria.
L'emmagatzematge efímer són 20 GB per omissió, ampliables fins a 200 GB amb ephemeralStorage. Es cobra només el que excedeixi els 20 GB gratuïts. És un disc temporal que desapareix en acabar la tasca: serveix per descomprimir un fitxer o per a una memòria cau local, mai per a estat. Quan cal persistència compartida, es munta EFS (02-02), que Fargate admet de manera nativa.
{
"family": "mercadofresco-carga-analitica",
"requiresCompatibilities": ["FARGATE"],
"networkMode": "awsvpc",
"cpu": "2048", "memory": "8192",
"ephemeralStorage": { "sizeInGiB": 60 },
"runtimePlatform": { "cpuArchitecture": "ARM64", "operatingSystemFamily": "LINUX" }
}x86 i arm64: Graviton i l'estalvi real
Fargate executa tasques en dues arquitectures: X86_64 i ARM64, aquesta última sobre processadors AWS Graviton. El canvi es fa amb un camp de la definició de tasca, però exigeix que la imatge estigui construïda per a aquesta arquitectura.
| Aspecte | x86_64 | arm64 (Graviton) |
|---|---|---|
| Preu per vCPU-hora | ~0,047 USD | ~0,037 USD (-20 %) |
| Rendiment | Referència | Igual o millor en càrregues web, Python, Java, Node |
| Imatge | L'habitual | Cal construir-la per a linux/arm64 |
| Compatibilitat | Total | Falla amb binaris natius només x86 o rodes de Python sense versió arm |
| Disponible a Fargate Spot | Sí | Sí |
La construcció multiarquitectura es resol a CodeBuild amb docker buildx:
docker buildx create --use --name multiarc
docker buildx build --platform linux/amd64,linux/arm64 \
--tag "${URI}:${ETIQUETA}" --push .
# Publica un index de manifests: ECR guarda les dues imatges sota la mateixa etiqueta
# i cada tasca descarrega la que correspon a la seva arquitectura.Per a MercadoFresco l'estalvi és real i mesurable: la botiga són 2 tasques base més fins a 2 al pic, d'1 vCPU i 2 GB. Passar a Graviton baixa el cost mensual del servei d'uns 85 USD a uns 68 USD, un 20 % sense tocar una línia de codi de negoci. El requisit és provar-ho: el Luis construeix la imatge per a les dues arquitectures, desplega arm64 a preproducció durant una setmana, compara latència i errors al tauler mercadofresco-produccion, i només llavors canvia producció.
El risc concret és el de les dependències: una roda de Python que només publica binaris x86 obliga a compilar en la construcció —cosa que l'etapa constructor del Dockerfile de 10-01 ja permet— o a bloquejar el canvi. És preferible descobrir-ho a CodeBuild que en un desplegament.
Diferències operatives: sense SSH, sense hostPort, sense DaemonSet
Fargate imposa restriccions que no són arbitràries: es deriven del fet que l'amfitrió no existeix per a tu.
| Restricció | Per què | Què es fa en el seu lloc |
|---|---|---|
Sense SSH ni docker exec |
No hi ha màquina a la qual connectar-se | ECS Exec (a continuació) |
Sense hostPort diferent del containerPort |
No hi ha ports de l'amfitrió que mapar | awsvpc dona una IP per tasca; no hi ha conflicte |
Només mode de xarxa awsvpc |
Cada tasca és la seva pròpia ENI | Grups de seguretat per tasca, grup de destinació de tipus ip |
Sense DaemonSet ni tasques de tipus DAEMON |
No hi ha nodes on posar-ne un per node | Sidecars: FireLens, X-Ray, OTel dins de cada tasca |
Sense volums de l'amfitrió ni privileged |
L'amfitrió no és teu | Volums efímers, EFS, i linuxParameters limitats |
| Sense GPU ni famílies d'instància especials | No tries la màquina | EC2 continua existint per a aquests casos |
Sense awsvpcTrunking per gestionar |
No hi ha instància amb límit d'ENI | Desapareix un dels paranys cars de 10-01 |
La restricció que més incomoda al principi és la primera, i la segona que més, la del DaemonSet: molta gent executava un contenidor de recollida de registres per instància. A Fargate aquest patró se substitueix per un sidecar dins de cada tasca, cosa que costa una mica de CPU i memòria per tasca però elimina la coordinació entre nodes.
ECS Exec: depurar sense servidor a tocar
ECS Exec obre una sessió d'ordres dins d'un contenidor en execució fent servir AWS Systems Manager, sense ports oberts, sense claus SSH i sense bastió. Requereix tres coses:
- El servei o la tasca amb
--enable-execute-command. - El rol de la tasca —no el d'execució— amb permisos de canal d'SSM.
- L'agent d'SSM, que Fargate ja inclou a partir de la versió de plataforma 1.4.
{"Version": "2012-10-17", "Statement": [{
"Effect": "Allow", "Resource": "*",
"Action": ["ssmmessages:CreateControlChannel", "ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel", "ssmmessages:OpenDataChannel"]
}]}aws ecs execute-command --cluster ecs-mercadofresco \
--task 9f2c1b7a4e0d4a6f8b3c5d7e1a2b3c4d \
--container tienda --interactive --command "/bin/sh"Tres advertiments que cal interioritzar abans de fer-lo servir a producció:
- Tot queda auditat a CloudTrail (05-03) amb l'esdeveniment
ExecuteCommand: qui, quan, en quina tasca i amb quina ordre. A més es pot exigir que la sessió es registri a CloudWatch Logs o a S3 ambexecuteCommandConfigurational clúster, xifrant ambalias/mercadofresco-datos. A MercadoFresco, fer servir ECS Exec a producció dispara una notificació aalertas-mercadofresco: no està prohibit, està vigilat. - Els canvis fets dins d'un contenidor no sobreviuen. Editar un fitxer de configuració a la tasca funciona fins que la tasca es reposa, i llavors desapareix silenciosament. ECS Exec serveix per diagnosticar, no per arreglar.
- Amb
readonlyRootFilesystem: trueel sistema de fitxers és de només lectura, que és exactament el que es vol: si necessites escriure per depurar, la resposta sol ser que falta un registre.
A la pràctica, el 90 % del que la gent anava a buscar per SSH ja és a CloudWatch Logs Insights o a X-Ray. ECS Exec és per al 10 % restant: comprovar una resolució DNS, verificar que una variable d'entorn va arribar com s'esperava o confirmar que el procés escolta al port correcte.
Registres amb FireLens i Fluent Bit
El controlador awslogs de 10-01 continua funcionant i és el correcte per omissió. Quan cal més —encaminar cap a diversos destins, filtrar abans d'enviar, reescriure el format o enviar còpia a un sistema extern—, la resposta a Fargate és FireLens: un sidecar de Fluent Bit que ECS configura automàticament.
[
{
"name": "registro",
"image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:stable",
"essential": true,
"firelensConfiguration": { "type": "fluentbit", "options": { "enable-ecs-log-metadata": "true" } },
"cpu": 64, "memoryReservation": 128
},
{
"name": "tienda",
"image": "555566667777.dkr.ecr.eu-west-1.amazonaws.com/mercadofresco/tienda@sha256:9c1e...f4a2",
"essential": true,
"logConfiguration": {
"logDriver": "awsfirelens",
"options": { "Name": "cloudwatch_logs", "region": "eu-west-1",
"log_group_name": "/ecs/mercadofresco-tienda", "log_stream_prefix": "tienda-",
"auto_create_group": "false" }
}
}
]El cost de FireLens és un contenidor més per tasca, uns 64 CPU i 128 MB, que en un servei de quatre tasques són diners de debò. La regla de MercadoFresco: awslogs per omissió, FireLens només quan hi hagi un requisit que awslogs no cobreixi, com filtrar els registres d'accés amb dades personals abans que surtin de la tasca.
L'arrencada de tasques i el pic dels divendres
Aquest és el punt pel qual existeix la lliçó. Una tasca de Fargate travessa aquestes fases:
- Aprovisionament (
PROVISIONING): es crea l'ENI a la subxarxa i se li associa el grup de seguretat. De 3 a 10 segons. - Descàrrega de la imatge (
PENDING): s'autentica a ECR i es descarreguen les capes que faltin. De 5 a 25 segons segons la mida de la imatge i si hi ha punt d'enllaç de VPC. - Arrencada del contenidor: s'executa l'
ENTRYPOINT. D'1 a 5 segons. - Comprovacions d'estat: l'ALB registra la destinació i espera els encerts consecutius. De 15 a 40 segons segons la configuració del grup de destinació.
| Fase | ASG amb AMI (abans) | Fargate (ara) |
|---|---|---|
| Arrencada de la màquina | 60-75 s (BIOS, kernel, cloud-init) |
0 s: no hi ha màquina |
| Preparació de xarxa | Inclosa | 3-10 s (ENI) |
| Obtenció de l'artefacte | Inclosa a l'AMI | 5-25 s (imatge des d'ECR) |
| Arrencada de l'aplicació | 20-30 s | 1-5 s |
| Registre i comprovacions | 20-40 s | 15-40 s |
| Total fins a rebre trànsit | ≈ 120 s | ≈ 35-45 s |
El que significa per al divendres a les 19:00 amb 900 comandes/hora és concret: quan l'alarma d'ALBRequestCountPerTarget supera el llindar, la capacitat nova comença a atendre peticions als 40 segons en lloc dels dos minuts. Amb la pujada de trànsit mesurada a MercadoFresco —de 300 a 900 comandes/hora en uns vuit minuts—, aquests 80 segons de diferència són la frontera entre una latència que puja una mica i una latència que dispara mercadofresco-alb-latencia-alta.
I hi ha una conseqüència menys òbvia i més valuosa: amb arrencades de 40 segons, es pot permetre un mínim més baix. Abans calien 2 instàncies sempre enceses per absorbir el que l'ASG trigava a reaccionar. Amb Fargate, el mínim pot continuar sent 2 tasques per disponibilitat —mai menys, per sobreviure a la pèrdua d'una AZ—, però el marge extra que es mantenia «per si de cas» deixa de ser necessari.
La palanca que redueix la fase 2 és la mida de la imatge i la ruta fins a ECR. La imatge de 220 MB de la botiga triga uns 8 segons des d'un punt d'enllaç de VPC i uns 20 a través del NAT. És un altre argument per al Dockerfile acurat de 10-01 i per a la secció següent.
Migrar el servei de la botiga a Fargate
El canvi, sorprenentment, és petit: la definició de tasca de 10-01 ja declarava requiresCompatibilities: ["EC2", "FARGATE"] i mode awsvpc, precisament per a això.
Pas 1: fixar CPU i memòria amb dades, no amb intuïció. Container Insights fa dues setmanes que mesura. La consulta que la Marta executa:
aws cloudwatch get-metric-statistics --namespace ECS/ContainerInsights \
--metric-name CpuUtilized --statistics Maximum p95 --period 300 \
--dimensions Name=ServiceName,Value=svc-mercadofresco-tienda Name=ClusterName,Value=ecs-mercadofresco \
--start-time 2026-07-15T00:00:00Z --end-time 2026-07-29T00:00:00ZEl percentil 95 de CPU és de 0,62 vCPU i el de memòria d'1,4 GB, amb un màxim absolut de 0,81 vCPU al pic del divendres. La combinació vàlida més ajustada per sobre d'això amb marge és 1 vCPU i 2 GB. Baixar a 0,5 vCPU / 2 GB seria temptador —estalvia un 25 %— però deixa la tasca del divendres al 160 % de la seva CPU: la latència es degradaria exactament quan importa.
Pas 2: crear el servei amb el proveïdor de capacitat de Fargate.
aws ecs create-service --cluster ecs-mercadofresco --region eu-west-1 \
--service-name svc-mercadofresco-tienda-fg --task-definition mercadofresco-tienda:24 \
--desired-count 4 \
--capacity-provider-strategy capacityProvider=FARGATE,weight=1,base=2 \
--platform-version LATEST \
--network-configuration 'awsvpcConfiguration={subnets=[snet-mercadofresco-app-a,snet-mercadofresco-app-b],
securityGroups=[sg-mercadofresco-tienda],assignPublicIp=DISABLED}' \
--load-balancers 'targetGroupArn=...targetgroup/tg-mercadofresco-tienda/abc123,containerName=tienda,containerPort=8080' \
--health-check-grace-period-seconds 45 \
--deployment-configuration '{"minimumHealthyPercent": 100, "maximumPercent": 200,
"deploymentCircuitBreaker": {"enable": true, "rollback": true}}' \
--enable-execute-command --propagate-tags SERVICETres detalls de l'ordre:
assignPublicIp=DISABLEDamb subxarxes privades. Les tasques van asnet-mercadofresco-app-ai-b, sense IP pública. Això és el correcte i el que obliga a la secció següent: sense IP pública, la tasca necessita una ruta cap a ECR, S3, CloudWatch Logs i Secrets Manager, i aquesta ruta és un NAT car o uns punts d'enllaç barats.- No hi ha
--placement-strategy. Les estratègies de col·locació són d'EC2. Fargate reparteix les tasques entre les subxarxes declarades, de manera que la disponibilitat s'obté declarant subxarxes de les dues AZ, no amb una estratègia. --platform-version LATEST. La versió de plataforma és l'equivalent a l'AMI de l'amfitrió, i la gestiona AWS. Fixar-la a una versió concreta només té sentit si una novetat trenca alguna cosa, i llavors és una mesura temporal, no permanent.
Pas 3: convivència i tall. Igual que a 10-01, l'ALB reparteix per pesos entre el servei d'EC2 i el de Fargate: 90/10, després 50/50, després 0/100 al llarg de dues setmanes, vigilant TargetResponseTime i HTTPCode_Target_5XX. El dia que el pes arriba a 100, l'ASG del clúster d'EC2 s'esborra i amb ell l'AMI, la plantilla de llançament i el cicle d'apedaçament.
Punts d'enllaç de VPC: deixar de dependre del NAT
Una tasca de Fargate en subxarxa privada parla amb diversos serveis d'AWS només per arrencar. Si aquesta comunicació surt pel NAT, es paga dues vegades: l'hora del NAT i cada gigabyte processat.
| Punt d'enllaç | Tipus | Per a què | Què falla sense ell |
|---|---|---|---|
com.amazonaws.eu-west-1.ecr.api |
Interfície | Autenticació i metadades d'ECR | CannotPullContainerError |
com.amazonaws.eu-west-1.ecr.dkr |
Interfície | Protocol de descàrrega d'imatges | CannotPullContainerError |
com.amazonaws.eu-west-1.s3 |
Passarel·la | Les capes d'imatge viuen a S3 | La descàrrega es penja i expira |
com.amazonaws.eu-west-1.logs |
Interfície | CloudWatch Logs | La tasca arrenca i no es veu ni un registre |
com.amazonaws.eu-west-1.secretsmanager |
Interfície | Resoldre els secrets |
ResourceInitializationError |
com.amazonaws.eu-west-1.ssm |
Interfície | Parameter Store | Igual que l'anterior |
com.amazonaws.eu-west-1.ssmmessages |
Interfície | ECS Exec | ECS Exec no connecta |
com.amazonaws.eu-west-1.kms |
Interfície | Desxifrar secrets i imatge | Falla el desxifratge |
El d'S3 és el que més s'oblida i el més important: és de tipus passarel·la, és gratuït i sense ell la descàrrega d'imatges no funciona encara que els dos d'ECR estiguin posats. MercadoFresco ja tenia vpce-mercadofresco-s3 des del mòdul 3, així que aquest està resolt.
for SERVEI in ecr.api ecr.dkr logs secretsmanager ssm ssmmessages kms; do
aws ec2 create-vpc-endpoint --vpc-id vpc-mercadofresco \
--vpc-endpoint-type Interface \
--service-name "com.amazonaws.eu-west-1.${SERVEI}" \
--subnet-ids snet-mercadofresco-app-a snet-mercadofresco-app-b \
--security-group-ids sg-mercadofresco-endpoints \
--private-dns-enabled \
--tag-specifications 'ResourceType=vpc-endpoint,Tags=[{Key=Proyecto,Value=mercadofresco},
{Key=Entorno,Value=produccion},{Key=Componente,Value=endpoints},
{Key=Propietario,Value=plataforma},{Key=CentroCoste,Value=tecnologia}]'
doneEl càlcul de l'estalvi per a MercadoFresco, amb 4,8 desplegaments per setmana, reposicions de tasques i escalat diari:
| Concepte | Amb NAT | Amb punts d'enllaç d'interfície |
|---|---|---|
| Descàrrega d'imatges | ~55 GB/mes × 0,045 USD = 2,50 USD | Trànsit pel punt d'enllaç: ~0,55 USD |
| Registres i crides a l'API | ~30 GB/mes × 0,045 = 1,35 USD | ~0,30 USD |
| Cost fix | 2 NAT × 0,045 USD/h ≈ 66 USD/mes | 7 punts d'enllaç × 2 AZ × 0,011 USD/h ≈ 112 USD/mes |
| Total | ≈ 70 USD/mes | ≈ 113 USD/mes |
I aquí convé ser honest en lloc de repetir l'eslògan: amb set punts d'enllaç en dues AZ, els punts d'enllaç surten més cars que el NAT en una arquitectura de la mida de MercadoFresco. L'argument a favor no és només el preu, en són altres tres: el trànsit no surt de la xarxa d'AWS, cosa que és un requisit de seguretat defensable davant d'una auditoria; l'arrencada de tasques és més ràpida i més previsible; i el NAT deixa de ser un punt únic de fallada per a l'arrencada. La decisió de la Marta és intermèdia i raonada: punts d'enllaç per a ECR, S3 i Logs —els del camí crític d'arrencada, que són quatre i costen uns 64 USD— i mantenir el NAT per a la resta, sabent que al mòdul 11 es revisarà si compensa.
Autoescalat: seguiment, passos i programació
Els tres tipus de política es combinen, i cadascun resol un problema diferent.
| Tipus | Com decideix | Fortalesa | Debilitat |
|---|---|---|---|
| Seguiment de destinació | Manté una mètrica en un valor | Simple, s'autoregula | Reacciona després del canvi |
| Escalat per passos | Llindars amb salts diferents | Resposta agressiva davant de salts grans | Cal calibrar els esglaons a mà |
| Escalat programat | Rellotge | Actua abans que arribi la càrrega | Cec davant de l'inesperat |
La configuració completa de MercadoFresco fa servir els tres. El seguiment de destinació sobre ALBRequestCountPerTarget de 10-01 es manté com a base. A sobre, l'escalat programat del divendres, que és la peça que faltava:
DESTI="--service-namespace ecs --scalable-dimension ecs:service:DesiredCount \
--resource-id service/ecs-mercadofresco/svc-mercadofresco-tienda-fg"
# 16:45, quinze minuts abans del pic: pujar el minim a 6 tasques.
aws application-autoscaling put-scheduled-action $DESTI \
--scheduled-action-name pico-viernes-inicio \
--schedule "cron(45 16 ? * FRI *)" --timezone "Europe/Madrid" \
--scalable-target-action MinCapacity=6,MaxCapacity=20
# 21:30, mitja hora despres del pic: tornar el minim a 2.
aws application-autoscaling put-scheduled-action $DESTI \
--scheduled-action-name pico-viernes-fin \
--schedule "cron(30 21 ? * FRI *)" --timezone "Europe/Madrid" \
--scalable-target-action MinCapacity=2,MaxCapacity=20Tres decisions de disseny en aquestes vuit línies:
- Es programa el mínim, no el nombre desitjat. Fixar
DesiredCountdesactivaria de fet el seguiment de destinació durant la finestra. Pujant el mínim, la capacitat està garantida i el seguiment continua podent créixer per sobre si el divendres és millor del previst. --timezone "Europe/Madrid". Sense això, el cron és UTC i a l'estiu el pic s'avança una hora respecte de l'acció programada. És un error que només apareix en canviar l'hora, a l'octubre, quan ningú no recorda haver tocat res.- Quinze minuts abans i mitja hora després. Abans, perquè les tasques estiguin sanes quan arribi el trànsit; després, amb generositat, perquè baixar massa aviat és el que provoca l'oscil·lació que es veu com a pics de latència a les 21:05.
El cost d'aquesta finestra és fàcil de calcular i de defensar: 4 tasques extra × 5 hores × 4,3 divendres × 0,057 USD/h ≈ 4,9 USD al mes. És probablement els millors diners que gasta MercadoFresco.
Fargate Spot i els treballadors de la cua
Fargate Spot executa tasques sobre capacitat sobrant d'AWS amb un descompte proper al 70 %, a canvi que AWS la pugui reclamar. Quan ho fa:
- Emet un esdeveniment de canvi d'estat a EventBridge i envia
SIGTERMal contenidor. - Espera el
stopTimeoutde la definició de tasca, amb un màxim de dos minuts. - Envia
SIGKILLi la tasca desapareix.
Dos minuts d'avís són molt o poc segons la càrrega:
| Càrrega de MercadoFresco | Fargate Spot? | Raó |
|---|---|---|
Botiga (svc-mercadofresco-tienda-fg) |
No | És trànsit d'usuari: una interrupció durant el pic del divendres és exactament el que estem evitant |
Treballadors de cola-mercadofresco-pedidos |
Sí, parcialment | El missatge torna a la cua en expirar la visibilitat i un altre treballador el processa; amb idempotència (07-05) no hi ha duplicats |
Treballadors de -correo, -almacen, -analitica |
Sí, gairebé tot | Tolerància màxima: res no és síncron ni urgent |
| Càrrega nocturna a Redshift | Sí | Es reintenta; si triga deu minuts més, no ho nota ningú |
| Tasques puntuals de migració de dades | No | Una interrupció a mitges pot deixar estat inconsistent |
La manera correcta d'aplicar-ho no és «tot Spot» sinó un repartiment per proveïdors de capacitat, que garanteix un terra sota demanda:
aws ecs update-service --cluster ecs-mercadofresco \
--service svc-mercadofresco-trabajadores \
--capacity-provider-strategy \
capacityProvider=FARGATE,weight=1,base=1 \
capacityProvider=FARGATE_SPOT,weight=4,base=0 \
--force-new-deploymentbase=1 al proveïdor sota demanda significa que la primera tasca sempre és estable; el weight reparteix totes les altres en proporció 1 a 4. Amb 10 tasques: 1 base + 9 repartides com a 1,8 sota demanda i 7,2 Spot, és a dir, aproximadament 3 sota demanda i 7 Spot.
| Escenari de treballadors | Composició | Cost mensual aproximat |
|---|---|---|
| Tot sota demanda | 10 × (0,5 vCPU / 1 GB) | ≈ 190 USD |
| Repartiment 1:4 amb base 1 | 3 sota demanda + 7 Spot | ≈ 97 USD |
| Tot Spot (no recomanat) | 10 Spot | ≈ 57 USD |
L'estalvi del repartiment 1:4 és de gairebé el 50 % i manté un terra que sobreviu a una retirada massiva de capacitat Spot. El requisit tècnic que ho fa segur és el de l'exercici de 10-01: gestor de SIGTERM que acaba el missatge en curs i no en demana un altre, amb stopTimeout: 120 i temps de visibilitat de la cua folgat.
Tasques puntuals i programades amb EventBridge Scheduler
No tot és un servei. La càrrega nocturna que alimenta wg-mercadofresco-analitica (06-04) s'executa un cop al dia i acaba. A EC2 això era una instància encesa o un cron en una màquina que algú havia de cuidar; a Fargate és una tasca puntual programada.
aws scheduler create-schedule --name mercadofresco-carga-analitica-nocturna \
--schedule-expression "cron(0 3 * * ? *)" --schedule-expression-timezone "Europe/Madrid" \
--flexible-time-window '{"Mode": "FLEXIBLE", "MaximumWindowInMinutes": 30}' \
--target '{
"Arn": "arn:aws:ecs:eu-west-1:111122223333:cluster/ecs-mercadofresco",
"RoleArn": "arn:aws:iam::111122223333:role/rol-scheduler-mercadofresco",
"EcsParameters": {
"TaskDefinitionArn": "arn:aws:ecs:eu-west-1:111122223333:task-definition/mercadofresco-carga-analitica:7",
"LaunchType": "FARGATE", "TaskCount": 1,
"CapacityProviderStrategy": [{"capacityProvider": "FARGATE_SPOT", "weight": 1}],
"NetworkConfiguration": {"awsvpcConfiguration": {
"Subnets": ["snet-mercadofresco-app-a", "snet-mercadofresco-app-b"],
"SecurityGroups": ["sg-mercadofresco-tienda"], "AssignPublicIp": "DISABLED"}}
},
"RetryPolicy": {"MaximumRetryAttempts": 2, "MaximumEventAgeInSeconds": 3600},
"DeadLetterConfig": {"Arn": "arn:aws:sqs:eu-west-1:111122223333:mercadofresco-pedidos-fallidos"}
}'El que és rellevant d'aquesta configuració: la finestra flexible de 30 minuts deixa que AWS triï el moment dins de la finestra, cosa que redueix la contenció i encaixa perfectament amb Spot; la política de reintents converteix una fallada transitòria en un reintent automàtic; i la DLQ garanteix que una fallada persistent deixa rastre en lloc de desaparèixer. És el mateix patró que 07-05 aplicat a una tasca programada.
Per a una execució puntual —una migració, una reparació de dades— n'hi ha prou amb aws ecs run-task amb la mateixa configuració de xarxa i --launch-type FARGATE. Si la feina té diversos passos amb dependències entre ells, l'eina correcta és Step Functions (07-04), que pot llançar tasques d'ECS i esperar que acabin.
Integració al pipeline i blue/green
El pipeline-mercadofresco-tienda del mòdul 8 canvia poc: on abans hi havia un desplegament de CodeDeploy sobre un ASG, ara hi ha un desplegament sobre un servei d'ECS.
graph LR G["GitHub<br/>mercadofresco-tienda<br/>conn-mercadofresco-github"] --> B["CodeBuild<br/>build-mercadofresco-tienda<br/>docker build + push"] B --> E["ECR 555566667777<br/>mercadofresco/tienda:v1.7.0-c4d8e12"] E --> R["Replicacio<br/>a 111122223333"] R --> P["CodePipeline<br/>desplegament"] P --> Q["Lambda<br/>mercadofresco-puerta-calidad<br/>escaneig + proves"] Q --> D["CodeDeploy blue/green<br/>app-mercadofresco-tienda"] D --> V["tg-mercadofresco-verde<br/>port de proves 8443"] V --> S["build-mercadofresco-humo"] S --> T["tg-mercadofresco-tienda<br/>transit real"]
El blue/green de CodeDeploy sobre ECS funciona diferent que sobre EC2, i la diferència és una millora: CodeDeploy crea un conjunt de tasques nou complet amb la revisió nova, el registra a tg-mercadofresco-verde, permet executar les proves de fum contra el port de proves de l'ALB sense trànsit real, i només llavors desplaça l'oient de producció cap al grup verd. El conjunt blau es manté durant el temps d'espera de terminació, de manera que una reversió és un canvi d'oient: segons.
# appspec.yaml per a CodeDeploy sobre ECS
version: 0.0
Resources:
- TargetService:
Type: AWS::ECS::Service
Properties:
TaskDefinition: <TASK_DEFINITION> # ho substitueix el pipeline
LoadBalancerInfo:
ContainerName: "tienda"
ContainerPort: 8080
PlatformVersion: "LATEST"
Hooks:
- AfterAllowTestTraffic: "arn:aws:lambda:eu-west-1:111122223333:function:mercadofresco-puerta-calidad"Amb la configuració de desplegament canària ECSCanary10Percent5Minutes, el 10 % del trànsit va al conjunt verd durant 5 minuts; si mercadofresco-alb-latencia-alta o mercadofresco-pedidos-fallidos salten en aquest interval, CodeDeploy reverteix sol. És la millora sobre el circuit breaker de 10-01: aquell detecta tasques que no arrenquen; aquest detecta tasques que arrenquen i responen malament.
Les mètriques DORA de MercadoFresco milloren on era d'esperar: la restauració passa de 4 minuts a menys d'1, perquè revertir ja no significa desplegar res, només moure un oient.
El servei en CDK amb un constructe L3
Tot l'anterior són unes vint línies al projecte infra-cdk/ de 09-02, gràcies a un constructe de nivell 3 que crea l'ALB, el grup de destinació, el servei, la definició de tasca, els rols i el grup de registres.
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecsp from 'aws-cdk-lib/aws-ecs-patterns';
const servei = new ecsp.ApplicationLoadBalancedFargateService(this, 'Tienda', {
cluster,
serviceName: `svc-mercadofresco-tienda-${config.nombre}`,
cpu: 1024,
memoryLimitMiB: 2048,
desiredCount: config.nombre === 'produccion' ? 4 : 2,
runtimePlatform: { cpuArchitecture: ecs.CpuArchitecture.ARM64 },
taskImageOptions: {
image: ecs.ContainerImage.fromEcrRepository(repositori, etiqueta), // per digest en produccio
containerPort: 8080,
environment: { ENTORNO: config.nombre, COLA_PEDIDOS: cola.queueName },
secrets: {
BD_CONTRASENA: ecs.Secret.fromSecretsManager(secretRds, 'password'),
ENDPOINT_CACHE: ecs.Secret.fromSsmParameter(parametreCache),
},
logDriver: ecs.LogDrivers.awsLogs({ streamPrefix: 'tienda', logRetention: 30 }),
},
taskSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
publicLoadBalancer: true,
circuitBreaker: { rollback: true },
enableExecuteCommand: config.nombre !== 'produccion',
});
servei.targetGroup.configureHealthCheck({
path: '/salud', healthyThresholdCount: 2, interval: cdk.Duration.seconds(15),
});
// Permisos minims amb els metodes grant*: inclouen els de KMS que gairebe ningu recorda.
cola.grantSendMessages(servei.taskDefinition.taskRole);
taulaCistelles.grantReadWriteData(servei.taskDefinition.taskRole);
const escalat = servei.service.autoScaleTaskCount({ minCapacity: 2, maxCapacity: 20 });
escalat.scaleOnRequestCount('PerPeticions', {
requestsPerTarget: 120,
targetGroup: servei.targetGroup,
scaleOutCooldown: cdk.Duration.seconds(30),
scaleInCooldown: cdk.Duration.minutes(5),
});
escalat.scaleOnSchedule('PicDivendres', {
schedule: appscaling.Schedule.cron({ weekDay: 'FRI', hour: '16', minute: '45' }),
minCapacity: 6,
});L'advertiment de 09-02 continua vigent: cdk synth i llegir la plantilla la primera vegada. Aquest constructe pren decisions per tu —crea un ALB públic, obre el seu grup de seguretat al 0.0.0.0/0 al port 80, crea un grup de registres amb retenció per omissió— i cal verificar que coincideixen amb el que vols. A producció, MercadoFresco hi afegeix el certificat i el redirectHTTP: true per no servir mai per HTTP.
Fixa't també en enableExecuteCommand: config.nombre !== 'produccion': ECS Exec activat a desenvolupament i preproducció, i desactivat a producció tret d'activació explícita durant un incident. És una decisió de govern expressada en una línia d'infraestructura.
Fargate enfront d'EC2 enfront de Lambda
Tots tres executen codi sense que tu compris maquinari, i l'elecció es fa per criteris objectius.
| Criteri | EC2 | Fargate | Lambda |
|---|---|---|---|
| Unitat | La instància | La tasca (contenidor) | La invocació |
| Model de cost | Per instància-hora, plena o buida | Per vCPU-hora i GB-hora de la tasca | Per invocació i GB-segon, amb capa gratuïta |
| Cost amb càrrega constant 24/7 | El més baix amb bon empaquetatge i Savings Plans | Intermedi | El més alt |
| Cost amb càrrega intermitent | El més alt (paga l'oci) | Intermedi | El més baix (no paga l'oci) |
| Arrencada en fred | 2 min (instància nova) | 35-45 s | 100 ms - 2 s |
| Durada màxima | Il·limitada | Il·limitada | 15 minuts |
| Memòria màxima | Fins a TB | 120 GB | 10 GB |
| Estat local | Disc persistent | Efímer (o EFS) | Efímer (o EFS) |
| Control de l'entorn | Total: kernel, GPU, famílies | Imatge i recursos | Runtime gestionat o imatge |
| Feina operativa | Alta: AMI, pedaços, escalat | Baixa: només la imatge | Mínima |
| Portabilitat | AMI, lligada a AWS | Imatge OCI: corre a qualsevol lloc | Lligada al model de Lambda |
| Quan triar-lo | GPU, llicències per nucli, càrregues enormes i constants, requisits de kernel | Serveis de llarga durada contenidoritzats: l'opció per omissió | Esdeveniments, pics irregulars, integracions curtes |
La decisió raonada de MercadoFresco, component a component:
| Component | Elecció | Per què |
|---|---|---|
| Botiga | Fargate sota demanda | Procés de llarga durada, trànsit continu, arrencada de 40 s suficient, sense oci per pagar |
| Treballadors de comandes | Fargate, 1 sota demanda + 4 Spot | Tolerant a interrupció amb idempotència; -50 % de cost |
| Treballadors de correu i magatzem | Fargate Spot | Res urgent ni síncron |
mercadofresco-generar-miniaturas |
Lambda | Es dispara per esdeveniment d'S3, dura segons, amb llargs períodes sense feina |
-cobrar-pago, -reservar-stock, -asignar-reparto |
Lambda | Passos curts de la màquina mercadofresco-procesar-pedido; contenidoritzar-los seria un retrocés |
| Càrrega nocturna a Redshift | Tasca puntual a Fargate Spot | Dura 25 minuts: passa dels 15 de Lambda |
| Res | EC2 | Cap component no necessita ja kernel, GPU ni llicència per nucli |
El criteri que resol la majoria dels dubtes: si el procés viu esperant peticions, és Fargate; si el procés es desperta davant d'un esdeveniment i mor, és Lambda; si necessites el control de la màquina, és EC2. I el criteri econòmic, que s'afina al mòdul 11: per sota d'una utilització sostinguda alta, Fargate guanya a EC2 perquè no paga l'oci; per sobre, EC2 amb Savings Plans (11-05) recupera l'avantatge.
App Runner: un esglaó més de gestió
AWS App Runner va un pas més enllà: se li dona una imatge de contenidor o un repositori de codi, i crea el servei, el balancejador, el certificat, el domini i l'autoescalat, inclòs escalar a zero. No hi ha VPC que dissenyar, ni grup de destinació, ni definició de tasca.
El que és rellevant és on deixa d'encaixar, i per això MercadoFresco no el fa servir: dona molt menys control de xarxa —l'accés a la VPC exigeix un connector i continua havent-hi limitacions—, no admet sidecars ni tasques multicontenidor, el model de desplegament no ofereix el blue/green canari de CodeDeploy, i el seu cost per unitat és superior al de Fargate. És una opció excel·lent per a un servei HTTP senzill o un prototip, i un mal encaix per a una botiga amb Aurora en subxarxa privada, cues, memòria cau i un pipeline amb porta de qualitat. Se'n parla perquè és la pregunta que sempre apareix: la resposta és que l'escala de gestió no és una classificació, és un intercanvi entre comoditat i control.
Cost comparat i neteja
El càlcul complet del servei de la botiga, amb preus aproximats d'eu-west-1:
Fargate x86, tasca d'1 vCPU i 2 GB: 1 × 0,04656 + 2 × 0,00511 = 0,05678 USD/hora.
| Escenari | Càlcul | Mensual |
|---|---|---|
| 2 tasques base 24/7 | 2 × 0,05678 × 730 | 82,9 USD |
| + finestra del divendres (4 extra × 5 h × 4,3) | 4 × 5 × 4,3 × 0,05678 | 4,9 USD |
| Total Fargate x86 | ≈ 88 USD | |
| Total Fargate arm64 (-20 %) | ≈ 70 USD | |
ASG anterior: 2 × m5.large sota demanda |
2 × 0,107 × 730 | 156 USD |
| + EBS 2 × 30 GB gp3 | 2,4 USD | |
| Total EC2 anterior | ≈ 158 USD |
MercadoFresco passa d'uns 158 USD a uns 70 USD al mes a la botiga, amb arm64, i elimina de passada la feina de mantenir AMI i pedaços. Amb els treballadors a Spot, l'estalvi total del mòdul ronda els 150 USD mensuals.
Amb dos matisos honestos, perquè la comparació no és completa sense ells. El primer: les instàncies EC2 es podrien comprar amb Savings Plans i baixar un 30-40 %, cosa que estreny molt la diferència —i Fargate també admet Compute Savings Plans, tema d'11-05—. El segon: si el clúster d'EC2 estigués molt ben empaquetat, amb la botiga i els treballadors compartint instàncies al 85 % d'ocupació, EC2 seria competitiu. El problema és que aquest empaquetatge cal aconseguir-lo i mantenir-lo, i aquesta és exactament la classe de feina que Fargate elimina.
Neteja, en ordre estricte:
# 1. Accions programades i politiques d'escalat: si no, reposen tasques
aws application-autoscaling delete-scheduled-action $DESTI --scheduled-action-name pico-viernes-inicio
aws application-autoscaling deregister-scalable-target $DESTI
# 2. El servei a zero i esborrat
aws ecs update-service --cluster ecs-mercadofresco --service svc-mercadofresco-tienda-fg --desired-count 0
aws ecs delete-service --cluster ecs-mercadofresco --service svc-mercadofresco-tienda-fg --force
# 3. Programacions d'EventBridge Scheduler
aws scheduler delete-schedule --name mercadofresco-carga-analitica-nocturna
# 4. ELS PUNTS D'ENLLAC D'INTERFICIE: costen per hora encara que no hi passi transit
aws ec2 describe-vpc-endpoints --filters Name=vpc-id,Values=vpc-mercadofresco \
--query 'VpcEndpoints[?VpcEndpointType==`Interface`].VpcEndpointId' --output text \
| xargs -r aws ec2 delete-vpc-endpoints --vpc-endpoint-ids
# 5. El cluster i el grup de registres
aws ecs delete-cluster --cluster ecs-mercadofresco
aws logs delete-log-group --log-group-name /ecs/mercadofresco-tiendaEl pas 4 és el residu car d'aquesta lliçó: set punts d'enllaç d'interfície en dues AZ costen uns 112 USD al mes encara que no hi passi ni un sol byte. Un punt d'enllaç oblidat és la fuita silenciosa més habitual després de les adreces IP elàstiques sense associar.
Errors Habituals i Consells
Error: demanar una combinació de CPU i memòria invàlida. RegisterTaskDefinition falla amb un missatge poc clar. Consell: tingues la taula a mà; amb el CDK, memoryLimitMiB i cpu es validen en la síntesi, que és abans.
Error: dimensionar per intuïció. Sobredimensionar a Fargate es paga des del primer segon. Consell: percentil 95 de Container Insights durant dues setmanes, més un 30 %, i revisar-ho al cap d'un mes.
Error: subxarxes privades sense punts d'enllaç ni NAT. La tasca es queda a PROVISIONING i mor amb CannotPullContainerError. Consell: abans de migrar, comprova la ruta a ECR api, ECR dkr, S3, Logs i Secrets Manager; el d'S3 és de passarel·la, és gratis i és el que més s'oblida.
Error: creure que sense NAT sempre és més barat. Set punts d'enllaç d'interfície en dues AZ superen el NAT en una arquitectura mitjana. Consell: posa punts d'enllaç només per al camí crític d'arrencada i decideix la resta amb dades del mòdul 11.
Error: programar DesiredCount en lloc del mínim. Desactiva de fet el seguiment de destinació durant la finestra. Consell: programa MinCapacity i deixa que la política reactiva continuï treballant per sobre.
Error: oblidar --timezone a l'escalat programat. El pic es desplaça una hora en canviar l'hora. Consell: Europe/Madrid explícit en tota acció programada, i revisar l'última setmana d'octubre.
Error: posar la botiga a Fargate Spot per estalviar. Una interrupció amb dos minuts d'avís durant el pic del divendres és just el que el curs porta deu mòduls evitant. Consell: Spot només on la interrupció es reintenta sola, i sempre amb base sota demanda.
Error: no gestionar SIGTERM als treballadors. Amb Spot, cada interrupció es converteix en un missatge reprocessat o perdut. Consell: gestor que acaba el missatge en curs i no en demana un altre, stopTimeout: 120 i temps de visibilitat folgat.
Error: fer servir ECS Exec per arreglar alguna cosa. El canvi desapareix en la reposició següent i deixa un sistema que ningú no pot reproduir. Consell: ECS Exec per diagnosticar; l'arranjament va pel pipeline. I a producció, amb notificació a alertas-mercadofresco.
Error: canviar a arm64 sense provar-ho. Una roda de Python sense binari arm trenca l'arrencada. Consell: docker buildx amb les dues plataformes, una setmana a preproducció i comparació de latència abans de tocar producció.
Consell: fixa --platform-version LATEST i no l'ancoris. Ancorar una versió de plataforma és renunciar a les millores i als pedaços, que és just el que has vingut a comprar.
Consell: mantén minimumHealthyPercent: 100 a producció. Amb Fargate ja no hi ha un buit d'instància que limiti el maximumPercent, així que 100/200 no costa capacitat reservada, només uns minuts de doble facturació per desplegament.
Consell: posa una alarma sobre RunningTaskCount enfront de DesiredTaskCount. És el senyal més primerenc d'un problema d'arrencada, de quota de Fargate o d'esgotament d'IP a la subxarxa.
Exercicis
Exercici 1: dimensionar i decidir el repartiment de capacitat
Els treballadors de cola-mercadofresco-pedidos processen cada missatge en 12 segons de mitjana, amb un pic de 900 missatges/hora els divendres de 17:00 a 21:00 i uns 150 missatges/hora la resta del temps. Container Insights indica que cada treballador fa servir el percentil 95 de 0,31 vCPU i 780 MB. L'acord de servei intern és que cap comanda no esperi més de 3 minuts a la cua. Dissenya: (a) la combinació de CPU i memòria de la tasca, justificada; (b) quantes tasques calen al pic i fora del pic, amb el càlcul; (c) la política d'autoescalat completa, indicant quina mètrica fas servir i per què no la CPU; (d) el repartiment entre FARGATE i FARGATE_SPOT amb la seva base i els seus weight, i què passa si AWS retira tota la capacitat Spot durant el pic; i (e) el cost mensual aproximat del teu disseny.
Exercici 2: la migració que es va quedar a PROVISIONING
El Luis migra el servei de la botiga a Fargate en preproducció. Les tasques es queden diversos minuts a PROVISIONING i acaben amb ResourceInitializationError: unable to pull secrets or registry auth. Comprova el següent i tot sembla correcte: el rol d'execució té els permisos d'ECR i de Secrets Manager, la definició de tasca és la mateixa que funcionava a EC2, i les subxarxes són snet-mercadofresco-app-a i -b. Diagnostica (a) les tres causes de xarxa possibles, en ordre de probabilitat, amb la comprovació concreta de cadascuna; (b) per què el mateix rol i la mateixa definició sí que funcionaven al tipus de llançament EC2; (c) quin punt d'enllaç de VPC concret arreglaria el cas més probable i per què el seu tipus importa; i (d) quines dues comprovacions afegiries al pipeline perquè aquesta fallada no torni a arribar a un desplegament.
Exercici 3: la proposta de passar-ho tot a Lambda
La Sara torna d'una conferència amb una proposta: eliminar Fargate i passar tota la botiga a Lambda darrere d'API Gateway, «perquè només es paga per petició i escala a zero». Aporta la dada que la botiga rep unes 300 comandes/hora fora de pic i que a les 4 de la matinada no hi ha trànsit. Respon amb criteri tècnic i econòmic: (a) tres raons tècniques concretes per les quals la botiga de MercadoFresco no encaixa bé a Lambda; (b) el càlcul aproximat que compara el cost de totes dues opcions amb el trànsit real; (c) quina part de la seva proposta sí que té raó i on ja s'està aplicant a l'arquitectura actual; (d) què mesuraries abans de descartar-la del tot; i (e) com l'hi explicaries en una frase que no soni a «no».
Solucions
Solució 1
(a) La combinació. El percentil 95 és 0,31 vCPU i 780 MB. Afegint-hi un 30 % de marge: 0,40 vCPU i 1,01 GB. La combinació vàlida immediatament superior és 512 (0,5 vCPU) amb 1 GB de memòria. Pujar a 1 vCPU duplicaria el cost per a un 20 % de CPU sense fer servir, i baixar a 0,25 vCPU no és possible perquè no hi arriba. Cost per tasca: 0,5 × 0,04656 + 1 × 0,00511 = 0,0279 USD/hora.
(b) Quantes tasques. Un treballador processa 3600 / 12 = 300 missatges/hora. Fora de pic, 150 missatges/hora exigeixen 1 tasca, però el mínim ha de ser 2 per disponibilitat: una sola tasca significa zero capacitat mentre es reposa. Al pic, 900 missatges/hora exigeixen 900 / 300 = 3 tasques per anar al dia, i aquest és exactament el punt on la cua no creix però tampoc no es recupera d'un retard. Per complir els 3 minuts amb marge i absorbir la variabilitat es fan servir 5 tasques al pic, que donen 1500 missatges/hora de capacitat i permeten drenar un retard acumulat.
(c) La política d'autoescalat. La CPU no serveix: un treballador que consumeix missatges està sempre igual d'ocupat, tingui la cua 10 o 10.000 missatges, així que la CPU no reflecteix el retard. La mètrica correcta és el retard per tasca, que es calcula amb una mètrica matemàtica de CloudWatch: ApproximateNumberOfMessagesVisible / RunningTaskCount. Amb un objectiu de 3 minuts i 300 missatges/hora per tasca, la destinació és 300 / 60 × 3 = 15 missatges per tasca.
{"TargetValue": 15.0, "ScaleOutCooldown": 60, "ScaleInCooldown": 300,
"CustomizedMetricSpecification": {"Metrics": [
{"Id": "visibles", "MetricStat": {"Metric": {"Namespace": "AWS/SQS",
"MetricName": "ApproximateNumberOfMessagesVisible",
"Dimensions": [{"Name": "QueueName", "Value": "cola-mercadofresco-pedidos"}]},
"Stat": "Average"}, "ReturnData": false},
{"Id": "tareas", "MetricStat": {"Metric": {"Namespace": "ECS/ContainerInsights",
"MetricName": "RunningTaskCount",
"Dimensions": [{"Name": "ServiceName", "Value": "svc-mercadofresco-trabajadores"},
{"Name": "ClusterName", "Value": "ecs-mercadofresco"}]},
"Stat": "Average"}, "ReturnData": false},
{"Id": "retraso", "Expression": "visibles / MAX([tareas, 1])", "ReturnData": true}]}}S'hi afegeix una acció programada per als divendres que puja MinCapacity a 5 a les 16:45 i la torna a 2 a les 21:30, amb --timezone "Europe/Madrid": pujar per rellotge evita els primers minuts de retard que la política reactiva no pot evitar per definició.
(d) El repartiment de capacitat. capacityProvider=FARGATE,weight=1,base=2 més capacityProvider=FARGATE_SPOT,weight=3,base=0. Les dues tasques del terra són estables, i de les tres extra del pic aproximadament 0,75 van sota demanda i 2,25 a Spot. Si AWS retira tota la capacitat Spot durant el pic, queden les 2 tasques sota demanda amb capacitat per a 600 missatges/hora enfront de 900 entrants: la cua creix uns 300 missatges/hora i l'acord de 3 minuts s'incompleix en uns vint minuts. La mitigació té dues parts: la política d'autoescalat detecta el retard i demana tasques noves, que el proveïdor sota demanda sí que pot servir —el repartiment per weight s'aplica a les tasques noves, i amb Spot no disponible ECS llança sota demanda—; i una alarma sobre ApproximateAgeOfOldestMessage avisa alertas-mercadofresco si el missatge més antic supera els 3 minuts. El que no cal fer és posar base=0: el terra estable és el que converteix una retirada de Spot en una degradació en comptes d'una caiguda.
(e) Cost mensual. Fora de pic: 2 tasques × 0,0279 × (730 − 17) ≈ 39,8 USD. Al pic (4 h × 4,3 divendres = 17,2 h): 2 sota demanda × 0,0279 × 17,2 ≈ 0,96 USD, més 3 tasques extra majoritàriament Spot ≈ 3 × 0,0084 × 17,2 ≈ 0,43 USD. Total ≈ 41 USD al mes, enfront dels 156 USD de l'ASG dedicat de treballadors que hi havia abans.
Solució 2
(a) Les tres causes de xarxa, per probabilitat.
- Falten els punts d'enllaç d'interfície d'ECR i Secrets Manager, i no hi ha NAT a la subxarxa de preproducció. És la causa més probable perquè l'error esmenta registry auth i secrets, que són exactament les dues primeres crides sortints d'una tasca. Comprovació:
aws ec2 describe-route-tablessobre les subxarxes-app-ai-bbuscant la ruta0.0.0.0/0, iaws ec2 describe-vpc-endpointsfiltrant per la VPC. - El grup de seguretat dels punts d'enllaç no permet l'entrada des del de les tasques. Els punts d'enllaç d'interfície són ENI amb grup de seguretat propi: si
sg-mercadofresco-endpointsno accepta el port 443 des desg-mercadofresco-tienda, existeixen però no es poden fer servir. Comprovació: regles d'entrada desg-mercadofresco-endpoints. - El DNS privat del punt d'enllaç està desactivat. Sense
--private-dns-enabled, el nomsecretsmanager.eu-west-1.amazonaws.comcontinua resolent a la IP pública i el trànsit intenta sortir per on no hi ha sortida. Comprovació: el campPrivateDnsEnableddel punt d'enllaç.
(b) Per què sí que funcionava a EC2. Perquè al tipus de llançament EC2, qui descarrega la imatge i resol els secrets és l'agent d'ECS de la instància, que fa servir la ruta de xarxa de la instància i el seu grup de seguretat. Si aquestes instàncies eren en una subxarxa amb NAT o tenien un grup de seguretat més permissiu, tot funcionava. En passar a Fargate, la connectivitat passa a dependre de l'ENI de la tasca, amb les subxarxes i el grup de seguretat declarats a networkConfiguration. És el mateix canvi de frontera del qual parlava awsvpc a 10-01, ara visible: la xarxa ja no és de la màquina, és de la tasca.
(c) El punt d'enllaç concret i per què importa el seu tipus. Per al cas més probable en calen tres: ecr.api, ecr.dkr i secretsmanager, tots tres d'interfície (ENI privada amb grup de seguretat, es paga per hora i per GB). Però el que sol faltar i no dona la cara és s3, que és de passarel·la: no és una ENI sinó una entrada a la taula de rutes, és gratuït, i sense ell les capes de la imatge —que s'emmagatzemen a S3— no es descarreguen encara que els dos punts d'enllaç d'ECR siguin perfectes. Confondre els dos tipus porta a posar un punt d'enllaç d'interfície per a S3, que funciona però costa diners innecessàriament en aquest cas.
(d) Dues comprovacions al pipeline. La primera, una prova de desplegament a preproducció amb la mateixa configuració de xarxa que producció: la fallada apareix on ha d'aparèixer. La segona, una regla d'AWS Config (05-04) o una prova del CDK (09-02) que verifiqui que tota subxarxa feta servir per un servei d'ECS té, o bé ruta cap a un NAT, o bé els cinc punts d'enllaç del camí crític. És una invariant d'arquitectura i per tant es prova com a codi, no es recorda. Com a reforç, la comprovació que el circuit breaker està activat amb rollback: true hauria convertit aquest incident en una reversió automàtica en lloc de en tasques girant en va.
Solució 3
(a) Tres raons tècniques.
- La connexió a Aurora. Cada Lambda concurrent obre la seva pròpia connexió, i amb 300 comandes/hora en pics de concurrència això esgota el pool d'
aurora-mercadofresco-pedidosràpidament. Es resol amb RDS Proxy, que afegeix cost i una peça més; a Fargate, cada tasca manté un pool estable i el problema no existeix. - L'arrencada en fred amb estat calent. La botiga manté en memòria la memòria cau del catàleg que precarrega des de
mercadofresco-catalogoen arrencar. A Fargate aquest cost es paga un cop per tasca i dura hores; a Lambda es pagaria a cada arrencada en fred, i la primera petició de cada entorn d'execució seria lenta just quan arriba un pic. - La reescriptura. La botiga és una aplicació WSGI amb Gunicorn; portar-la a Lambda exigeix un adaptador o partir-la en funcions, més un canvi del model de sessions, dels fitxers estàtics i de l'observabilitat. És un projecte de setmanes el benefici del qual és dubtós, just després d'acabar la migració a contenidors.
(b) El càlcul. Amb 300 comandes/hora de mitjana i unes 8 peticions HTTP per comanda, en surten unes 2.400 peticions/hora, és a dir, 1,75 milions al mes. Suposant 250 ms de mitjana i 2 GB de memòria: 1,75 M × 0,25 s × 2 GB = 875.000 GB-s. A 0,0000167 USD per GB-s són uns 14,6 USD, més 0,35 USD d'invocacions, més API Gateway: 1,75 M × 3,5 USD/milió ≈ 6,1 USD. Total ≈ 21 USD, enfront dels 70 USD de Fargate arm64. La Sara té raó en el número brut. Però hi falten tres partides que canvien la conclusió: RDS Proxy (uns 30 USD/mes), el cost de la reescriptura (setmanes de feina, que a cost d'equip supera de llarg l'estalvi anual de 588 USD) i el risc de latència per arrencades en fred durant el pic del divendres, que és precisament el problema que aquest mòdul acaba de resoldre.
(c) En què té raó i on ja s'aplica. Té raó en el principi: no pagar per capacitat ociosa. I aquest principi ja està aplicat on encaixa: mercadofresco-generar-miniaturas es dispara per esdeveniment d'S3 i no es paga entre pujades de foto; -cobrar-pago, -reservar-stock i -asignar-reparto són passos curts de la màquina d'estats; i els treballadors de la cua escalen fins al mínim fora del pic. L'arquitectura ja és híbrida per disseny: Lambda on la feina és esporàdica i curta, Fargate on el procés viu esperant peticions.
(d) Què mesuraria abans de descartar-la. Tres coses concretes: la distribució real de la latència de la botiga per percentils a X-Ray, per saber quant pesaria una arrencada en fred al p99; el nombre de connexions simultànies a Aurora al pic del divendres, per dimensionar si RDS Proxy seria suficient; i el cost real de Fargate durant un mes complet amb arm64 i l'escalat programat ja aplicat, perquè la comparació s'està fent contra un número que encara no s'ha mesurat. Sense aquestes tres dades, totes dues postures són opinions.
(e) La frase. «Tens raó en el principi i per això ja ho estem aplicant: tot el que es dispara per un esdeveniment i mor en segons ja és a Lambda. La botiga és el contrari —un procés que viu esperant peticions i manté memòria cau i connexions—, i per a això Fargate costa cinquanta dòlars més al mes i ens estalvia una reescriptura, un RDS Proxy i les arrencades en fred del divendres a les set.»
Conclusió
Les instàncies han desaparegut. La botiga de MercadoFresco s'executa ara sobre Fargate, i ja no existeix cap màquina que la Marta pugui llistar, dimensionar, apedaçar o deixar-se encesa.
Tens clar què desapareix —l'AMI, l'apedaçament de l'amfitrió, l'escalat del clúster, l'empaquetatge de tasques, la capacitat ociosa i fins i tot el límit d'ENI per instància— i què continua sent teu: la imatge, la CPU i la memòria, la xarxa i els permisos. Amb la frase que ordena la resta: Fargate no elimina la feina d'operar una aplicació, elimina la feina d'operar un servidor. I amb el model de recursos real: les combinacions vàlides de CPU i memòria, els 20 GB d'emmagatzematge efímer ampliables a 200, i la decisió de dimensionar amb el percentil 95 de Container Insights més un 30 %, perquè aquí sobredimensionar es paga des del primer segon. Més arm64 amb Graviton, que baixa el servei de 88 a 70 USD mensuals amb docker buildx i una setmana de prova a preproducció.
Tens les diferències operatives i què fer amb cadascuna: ECS Exec en lloc d'SSH, auditat a CloudTrail i amb la regla que serveix per diagnosticar i no per arreglar; FireLens amb Fluent Bit com a sidecar on abans hi havia un DaemonSet, amb awslogs com a opció per omissió perquè el sidecar costa CPU a cada tasca; i awsvpc com a únic mode de xarxa, que ja no és una restricció sinó la manera normal de treballar. I tens el número que justifica el mòdul sencer: de 120 segons a 35-45 fins que una tasca nova rep trànsit, amb el desglossament per fases i el que significa el divendres a les 19:00 quan el trànsit passa de 300 a 900 comandes/hora en vuit minuts.
Tens la migració completa: definició de tasca sense canvis perquè ja declarava FARGATE, subxarxes privades snet-mercadofresco-app-a i -b sense IP pública, grup de seguretat per tasca, i els punts d'enllaç de VPC del camí crític —amb l'anàlisi honesta que set punts d'enllaç en dues AZ surten més cars que el NAT, i la decisió raonada de posar només els quatre que importen—. L'autoescalat en tres capes: seguiment de destinació com a base, i sobretot l'escalat programat del divendres, que puja el mínim a 6 a les 16:45 amb Europe/Madrid explícit i costa 4,9 USD al mes. Fargate Spot amb el repartiment base=1, weight 1:4 per als treballadors i el criteri que decideix on entra: només on la interrupció amb dos minuts d'avís es reintenta sola. Les tasques programades amb EventBridge Scheduler per a la càrrega nocturna a Redshift, amb finestra flexible, reintents i DLQ. I el pipeline amb blue/green canari de CodeDeploy sobre tg-mercadofresco-tienda i -verde, que baixa la restauració de 4 minuts a menys d'1 perquè revertir és moure un oient; tot això en vint línies de CDK amb ApplicationLoadBalancedFargateService.
I tens la comparativa honesta Fargate enfront d'EC2 enfront de Lambda, amb el criteri que resol la majoria dels dubtes —si el procés viu esperant peticions, és Fargate; si es desperta davant d'un esdeveniment i mor, és Lambda; si necessites el control de la màquina, és EC2— i la decisió component a component de MercadoFresco, en la qual EC2 ja no apareix en cap fila.
Queda una pregunta que algú de l'equip farà aquesta mateixa setmana, i que mereix una resposta seriosa en lloc d'un arronsament d'espatlles: tothom parla de Kubernetes. És l'estàndard de facto de l'orquestració de contenidors, té un ecosistema enorme, funciona igual a qualsevol núvol i hi ha moltíssima gent que en sap. Ens estem equivocant quedant-nos a ECS?
A 10-03, «Amazon EKS», es respon amb dades i no amb preferències. Veuràs què és Kubernetes i què resol que ECS no, el seu vocabulari mínim però real, què gestiona EKS i què continua sent teu, les quatre opcions de còmput inclòs Auto Mode, els manifests complets del desplegament de la botiga amb sondes, Ingress i l'AWS Load Balancer Controller, IRSA i Pod Identity com a equivalents del rol de tasca, Karpenter per als nodes, i l'argument central que gairebé ningú no posa per escrit: el cost ocult de les actualitzacions de versió. Amb la comparativa ECS enfront d'EKS i la decisió raonada de MercadoFresco, juntament amb els criteris objectius que la canviarien.
Curs d'AWS
Mòdul 1: Introducció a AWS
- Què és AWS?
- Configuració del teu compte d'AWS
- Infraestructura global d'AWS
- Consola d'administració d'AWS
- AWS CLI i SDK
Mòdul 2: Serveis principals d'AWS
Mòdul 3: Xarxes i lliurament de contingut
- Amazon VPC
- Grups de seguretat i llistes de control d'accés
- Elastic Load Balancing
- Amazon CloudFront
- Route 53
Mòdul 4: Seguretat i identitat
- AWS Identity and Access Management (IAM)
- AWS Key Management Service (KMS)
- Secrets Manager i Parameter Store
- AWS Shield
- AWS WAF
Mòdul 5: Monitoratge i gestió
- Amazon CloudWatch
- AWS X-Ray i traçabilitat distribuïda
- AWS CloudTrail
- AWS Config
- AWS Trusted Advisor
Mòdul 6: Bases de dades
- Com triar la base de dades adequada
- Amazon DynamoDB
- Amazon Aurora
- Amazon Redshift
- Amazon ElastiCache
Mòdul 7: Integració d'aplicacions
- Amazon SQS
- Amazon SNS
- Amazon EventBridge
- AWS Step Functions
- Patrons d'integració: idempotència, reintents i cues de missatges fallits
