Tehnologiile bazate pe containere și-au demonstrat valoarea clară în ultimii ani. Furnizorii de servicii de cloud, precum Amazon Web Services (AWS), și-au adaptat rapid produsele, astfel încât să ofere soluții multiple pentru gestionarea și administrarea containerelor. Operarea lor a devenit rapid o provocare. Cum gestionați 500 de aplicații care rulează în 10.000 de containere? Cum le monitorizați? Cum faceți backup/restore? Dar upgrade de la o versiune la alta?
Pentru aceasta s-a născut un domeniu nou, Orchestrarea Containerelor. Acesta se referă la administrarea și la coordonarea activităților de plasare, de gestionare și de operare eficientă a containerelor.
În funcție de cazul de utilizare, AWS oferă mai multe opțiuni de servicii cloud precum: AWS Elastic Beanstalk, Amazon Elastic Container Service (ECS), AWS Copilot, Amazon Elastic Kubernetes Service (EKS), AWS Elastic Computing (EC2), AWS OpsWorks AWS Lambda sau AWS Proton. Opțiunile variate dar și caracteristicile fiecăruia, pot face dificilă alegerea unui serviciu. Vom prezenta în continuare câteva criterii care, sperăm noi, să vă ajute în luarea unei decizii atunci când gestionați containere în AWS. Articolul presupune cunoștințe de Docker, PowerShell și configurare în prealabilă a utilitarelor Docker CLI și AWS CLI v2. Vom utiliza o aplicație numită org-chart-app care permite navigarea în organigrama AWS.
Pentru a împacheta această aplicație într-o imagine Docker am folosit următorul Dockerfile:
# prepare to build orgchart-app
FROM node:10-alpine as build-step
RUN mkdir -p /org-chart-app
WORKDIR /org-chart-app
COPY package.json /org-chart-app
# install app dependencies
RUN npm install
COPY . /org-chart-app
# package app
RUN npm run build --prod
# copy packaged app into nginx web # server
FROM nginx:1.17.1-alpine
COPY --from=build-step
/org-chart-app/dist/ux-aspects-
org-chart /usr/share/nginx/html
Odată ce imaginea Docker este gata, unde o puteți stoca? AWS Elastic Container Registry (ECR) este serviciul care facilitează stocarea imaginilor compatibile Docker și Open Container Initiative (OCI), atât public, folosind serviciul ECR Public, cât și privat, în ECR Private. Serviciile ECR Public și ECR Private sunt similare, diferența esențială este catalogul ECR Public Gallery care facilitează navigarea printre imaginile publice.
Figura 1. ECR Private și ECR Public
Figura 2 Galeria publică Amazon ECR
AWS ECR este compatibil cu Docker. Așadar, cel mai simplu mod de a încărca o imagine din ECR este prin utilitarele din linia de comandă Docker și AWS. Pentru aceasta este necesară autentificarea folosind un utilizator definit în serviciul Amazon Identity and Access Manager (IAM).
#create aws ecr repo
aws ecr create-repository –repository-name
<AWS_ECR_REPO>
#authenticate to aws
aws ecr get-login-password --region
<AWS_REGION> | docker login --username AWS
--password-stdin
<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com
#build docker image
docker build .
#list the docker images and get the DOCKER_IMAGE_ID
docker images
#tag docker image
docker tag <DOCKER_IMAGE_ID>
<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws
.com/<AWS_ECR_REPO>
#push to ecr
docker push <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>
.amazonaws.com/<AWS_ECR_REPO>
ECR stochează imaginile transparent pentru utilizator în serviciul AWS Simple Cloud Storage (S3). Prin urmare, nu puteți accesa aceste imagini direct din serviciul S3, dar beneficiați indirect de durabilitatea și reziliența oferită de acesta. Din punctul de vedere al securității, transmisia datelor de face criptat și ECR oferă posibilitatea scanării de securitate a imaginilor folosind tehnologia Clair.
Pentru a verifica că imaginea s-a încărcat cu succes:
aws ecr describe-images --repository-name
<AWS_ECR_REPO>/<DOCKER_IMAGE_NAME>
--image-ids imageTag=<DOCKER_IMAGE_VERSION>
Amazon Elastic Container Service(ECS) este unul dintre serviciile AWS care permite rularea și gestionarea containerelor. La baza acestui serviciu sunt clustere ECS care conțin servicii și sarcini. ECS are două moduri de operare: modul ECS EC2 și modul ECS Fargate. Diferența principală dintre ECS EC2 și ECS Fargate este faptul că ECS EC2 folosește instanțe EC2 gestionate de utilizator, iar ECS Fargate lucrează serverless fără a fi nevoie de gestionarea instanțelor de către utilizator. De ce au ales clienți precum Duolingo, Samsung sau General Electric, rularea de containere în Amazon ECS? Câteva motive ar fi: flexibilitatea dată de modurile de rulare EC2 și Fargate, securitatea, complexitatea relativ scăzută (vom vedea în articolele următoare servicii AWS mai simple), dar și viteza de scalare din Fargate. Performanța Fargate se datorează optimizărilor AWS, dar și tehnologiei Firecraker (dezvoltată și în România). Aceasta este o tehnologie de virtualizare, special creată pentru a rula containere și funcții Lambda în AWS. La baza Firecracker stă concepul de microVM care combină securitatea oferită de mașini virtuale cu viteza oferită de containere.
Figură 3 Modurile Amazon ECS: EC2 și Fargate
Un AWS ECS cluster definește resursele necesare pentru a rula containerele cum ar fi: tipul de instanțe, prin ce rețea se realizează comunicarea etc. Pentru a crea un cluster ECS folosiți AWS CLI:
aws ecs create-cluster
--cluster-name ecs-orgchart-cluster
Am decis rularea în modul EC2 pentru că aplicația va rula continuu, nu avem nevoie de scalare rapidă și dorim să accesăm instanțele EC2 pentru a instala un agent de monitorizare. Lansarea instanțelor se realizează folosind imagini Amazon (AMIs), special create și optimizate pentru serviciul AWS ECS. Aceste AMI-uri conțin câte un agent ECS, implementat în Go, care facilitează conectarea instanțelor la clusterele ECS. Puteți consulta lista completă de AMI-uri pentru ECS. De asemenea, instanțele au nevoie de permisiuni IAM de conectare la ECS. Aceasta se realizează folosind profilul IAM numit ecsInstanceProfile și prin alocarea unui IP public instanței.
aws ec2 run-instances `
--image-id ami-088d5884be8a84416 `
--iam-instance-profile Name=ecsInstanceRole `
--associate-public-ip-address `
--user-data “file://C:/ECS/ec2-userdata.txt” `
--key-name <AWS_KEY_NAME>
Există și opțiunea de a nu aloca un IP public instanței, când nu doriți accesul din internet la container, dar această configurare este în afara scopului acestui articol.
Am folosit următorul fișier ec2-userdata.txt. Prin acesta am configurat conexiunea dintre agentul ECS și clusterul ECS.
#!/bin/bash
echo ECS_CLUSTER=ecs-orgchart-cluster >> /etc/ecs/ecs.config
Lansarea unei instanței este foarte rapidă. Pentru a verifica rezultatul folosiți comandata de mai jos.
aws ecs list-container-instances
--cluster ecs-orgchart-cluster
Pentru a rula containere aveți nevoie de sarcini ECS. Sarcinile ECS reprezintă instanțe ale definițiilor de sarcini. Definițiile de sarcini sunt fișiere JSON care conțin parametri necesari pentru a rula containerele într-un cluster precum: URL-ul către locația imaginilor, memoria RAM necesară, CPU, spațiu de stocare, prin ce porturi de rețea se poate accesa containerul, compatibilitatea cu modul de operare EC2 și/sau Fargate și multe altele.
Mai jos, găsiți un exemplu simplificat de definiție sarcină ECS care folosește imaginea Docker încărcată mai devreme în ECR. Accesul la containerul Docker (care așteaptă conexiuni pe portul 80) se face prin alocarea dinamică de porturi de pe instanța EC2. Alocarea dinamică a porturilor ("hostPort":"0") facilitează rularea unui număr mai mare de containere, pe o singură instanță EC2, pentru că la fiecare lansare de container se alocă un port nou.
{
“family”:<TASK_NAME>,
“taskRoleArn”: “arn:aws:iam::<AWS_ACCOUNT_ID>
:role/ecsTaskExecutionRole”,
“executionRoleArn”: “arn:aws:iam::
<AWS_ACCOUNT_ID>:role/ecsTaskExecutionRole”,
“revision”: <TASK_VERSION>,
…
“containerDefinitions”: [{
“name”: <DOCKER_CONTAINER_NAME>,
“image”: “<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>
.amazonaws.com/<AWS_ECR_REPO_NAME>
/<DOCKER_IMAGE_NAME>
:<DOCKER_IMAGE_VERSION>”,
“cpu”: 0,
“memory”: 128,
“portMappings”: [ {
“containerPort”: 80,
“hostPort”: 0,
“protocol”: “tcp”
}
],
…
}
],
“requiresAttributes”: [
…
],
“placementConstraints”: [],
“compatibilities”: [
“EC2”
],
“requiresCompatibilities”: [
“EC2”
],
“cpu”: “1024”,
“memory”: “1024”
}
}
Înregistrarea definiției de sarcină în ECS urmată de rularea ei:
aws ecs register-task-definition --cli-input-json file:// <TASK_DEFINITION_JSON_FILE>
aws ecs run-task --cluster ecs-orgchart-cluster --task-definition <TASK_NAME>:<TASK_VERSION>
Pentru aplicații care rulează pentru puțin timp, este suficient doar să rulați sarcini ECS. Dar dacă aplicațiile necesită rulare continuă, disponibilitate și scalabilitate, aveți nevoie de o soluție de orchestrare a sarcinilor. Serviciile ECS reprezintă soluția în acest caz. Acestea definesc modalitățile de rulare a sarcinilor precum: câte să ruleze la un moment dat sau cum să se distribuie sarcinile într-un cluster.
Există două strategii principale de programare a sarcinilor:
Daemon - programează exact câte o sarcină pe instanță. Când o nouă instanță este adăugată în cluster, automat se pornește o nouă sarcină pe această instanță.
Replica - distribuie și menține constant un anumit număr de sarcini într-un cluster. Distribuirea se face în funcție de parametri (CPU, memorie etc.), strategia de plasare sau constrângeri de plasare. Implicit, strategia Replica distribuie sarcinile unitar între availability zones AWS. Pentru a rafina această regulă, puteți defini strategii de plasare precum:
Random - plasează sarcinile aleator între instanțe.
Spread - plasează sarcinile unitar între instanțe, în funcție de atribute specifice definite de voi. Dacă doriți să alocați sarcinile unitar între mai multe availability zones, aceasta este o strategie bună.
Un alt mod de a controla regulile de plasare a sarcinilor este folosind constrângeri specificate în ECS cluster query language (CQL), care nu este în scopul acestui articol.
Pentru a crea un serviciu ECS, începem cu un fișier ecs-create-service.json, care specifică configurația serviciului ECS:
{
„serviceName”: <SERVICE_NAME>,
“cluster”: “ecs-orgchart-cluster”,
“taskDefinition”: <TASK_DEF_NAME>
“clientToken”: “”,
“launchType”: “EC2”,
“role”: “”,
“deploymentConfiguration”: {
“maximumPercent”: 100,
“minimumHealthyPercent”: 0
},
“schedulingStrategy”: “DAEMON”,
“deploymentController”: {
“type”: “ECS”
},
“enableECSManagedTags”: true,
“propagateTags”: “TASK_DEFINITION”
}
Pentru a lansa serviciul ECS:
aws ecs create-service --cli-input-json file://ecs-create-service.json
În felul acesta, am lansat o aplicație care folosește serviciul AWS ECS, rulează pe instanțe EC2 și este orchestrat folosind sarcini și servicii ECS.
Alegerea serviciului AWS potrivit variază în funcție de cazul de utilizare. În tabelul de mai jos sunt câteva aspecte pe care le considerăm importante în alegerea ECS EC2 și ECS Fargate.
AWS ECS EC2 | AWS ECS Fargate | Comentarii | |
---|---|---|---|
Cazuri de | Containere care rulează pentru mai mult | Sisteme care rulează pentru o perioadă | ECS este o tehnologie proprietară AWS cu |
timp și unde aveți nevoie de acces la | scurtă de timp. | resurse specifice (sarcini ECS, servicii | |
instanțele EC2 (de ex. pentru a instala | etc.) care necesită o perioadă de | ||
anumiți agenți) | învățare. | ||
Sisteme care au nevoie de resurse semnificative de memorie, de CPU sau de rețea. | Containere care au nevoie de scalare rapidă, de exemplu în cazul unei aplicații cu trafic ridicat în anumite perioade. | Pentru soluții bazate pe containere, dar care trebuie să ruleze și în centrele de date private, sau pe serviciile altor furnizori de cloud, ECS s-ar putea să nu fie cea mai bună alegere. | |
Sisteme care rulează în containere Docker Windows. | |||
anumiți agenți) | învățare. | ||
Control | 3 | 1 | Puteți accesa instanțele EC2, dar nu |
puteți accesa Fargate. | |||
Cost | 3 | 1 | ECS EC2 permite rezervarea de instanțe |
sau utilizarea planurilor de economisire | |||
(saving plans) care ajută la reducerea | |||
costurilor. | |||
Cost de mentenanță | 1 | 3 | Fargate reduce semnificativ costul de |
mentenanță comparativ cu EC2. | |||
Scalabilitate | 1 | 3 | Datorită tehnologiei Firecracker, |
Fargate scalează foarte rapid. | |||
Securitate | 2 | 3 | În modul ECS EC2, este de gestionarea |
aspectelor precum grupuri de securitate. | |||
În modul Fargate, acestea sunt | |||
gestionate de AWS pentru voi. | |||
Simplitate | 2 | 3 | ECS Fargate nu necesită gestionarea |
instanțelor EC2 de către utilizator. |
Tabel 1 AWS ECS EC2 și ECS Fargate
Serviciul Amazon ECS reprezintă doar o opțiune pentru a rula și gestiona containere în AWS. Clienți precum The Washington Post, Verizon sau McDonalds au ales acest serviciu pentru că oferă securitate, flexibilitate și control, dar și performanță și simplitate în operare. Pentru că tehnologiile cloud schimbă modul în care gândim și distribuim aplicațiile software vă invităm să urmăriți seria de articole AWS și să participați la grupul de discuții, pe teme legate de tehnologii cloud, Transylvania Cloud.
AWS re:Invent 2020: Scaling Containers on AWS, Vlad Ionescu - Înregistrare YouTube
Richard Bullington-McGuire, Andrew K. Dennis, Michael Schwartz - Docker for Developers