AWS, EC2 ja chathuone.
Tässä raportissa laitamme päälle Amazonin AWS EC2 ympäristöön chat-huoneen, tutkimme siihen liittyviä skaalauksia, temppuja sekä tekniikoita.
Tehtävä on osana Haaga-Helian pilvipalveluteknologia-kurssia jota vetää Olavi Korhonen. Tein yksinkertaisen konseptin, huoneen, sekä toteutuksen node.jsllä, apunani käyttäen gemma3:27b sekä mistral-small3:27b LLM malleja Ollaman kautta. Rakensin järjestelmän pohjalta jo toimimaan docker kuvassa ja testasin omalla koneella, että kuva käynnistyy.
Tämä kokonaisuus ei kuitenkaan ota kantaa koodaamiseen. Kokonaisutavoitteena tässä teemme palvelun joka suoraan toiminnassa AWS ympäristössä. Minulta löytyy jo Linux palvelimen luonnista kokonaisuus, jota käytämme osaksi myös tässä hyödyksi. Tämä kyseinen sivusto tehty juuri tuolla kurssilla.
Kurssin osana saimme 50-dollaria käyttöaikaa AWS ympäristössä, mutta esimerkiksi käyttäjä-oikeudet ja -rakenteen jäävät raportin ulkopuolelle. Niitä ei voi käyttä AWS opiskelijäympäristössä. Tämä estää meitä rakentamasta isompaa kontti-palvelua joka suoraan haetaan AWS ympäristöön, mutta voimme tehdä näiden ympäriltä.
Koska, järjestelmä rakennetaan docker/podman pohjalle, voimme ajaa siihen myös käänteisproxyn traefikin pyörittämään sertifikaatteja.
Avaimet!
Käytän tässä luomaani ’Äiti lähetä Rahaa’-chat konseptia. Ideana on, että kaikki voivat liittyä huoneeseen pyytelemään rahaa ja kaikki lähtevät pois rikkaina. Ainakin kokemuksia rikkaampina.
Huone tehty yksinkertaisella html pohjalla ja serveripuolelle nodella. Olin kiinnostunut myös rakentamaan database-järjestelmän vaikkapa käyttäjille ja viesteille, mutta AWS opiskelijatierillä tämä ei ollut mahdollista. Olisin tehnyt tämän AWS dynamoDB palveluun.
Nyt kuitenkin teemme tämän yksinkertaisena EC2 palveluna. Eli vuokraamme amazonilta palvelimen suoraan käyttöön.
Aloitetaan luomalla ec2 järjestelmä. Ainoa sallittu tähän on t2.micro jolloin sillä mennään. Minulla nyt paljon kokemusta debianin kanssa tässä, joten kokeillaan rakentaa tämä Aws Linuxin omaan kantaan.

Luon myös SSH avaimet jotka liitän omaan .zsh konsoliini. Laitan myös vain oman ip-osoitteeni vastaanottajaksi ssh yhteydelle. Kovalevytilaa tämä ei tarvitse paljoa, joten laitan vain minimimäärän (1x 8gb).

Avaamme myöhemmin muut porttikannat, mutta nyt vain 22 avattuna ssh yhteyttä varten.

Lisään nyt tähän instanssiin suoraan elastisen IP osoitteen. Luon tämän ’ec2 - elastic ip’. Ja liitän sen äsken luotuun instanssiin.

Minulla omistuksessani iskff.fi domain, johon lisään nyt A tietueen alr.iskff.fi osoitteeseen. Tämä tärkeä tehdä ennen SSH avaimen liittämistä, koska palvelun IP voi vaihdella pitkin prosessia (opiskelun elastinen ip - en tiedä kuinka toimii). A tietueella voin aina pitää oman avaimen konfiguraation päivitettynä pistetiedostossa (.ssh/config). Ja osoittaa A yhteyden ip-osoitteeseen.
Eli AWSn kautta luotu .pem tiedosto ladataan omaan .ssh kansioon ja siihe referoidaan yhteyden ottamisen yhteydessä. Itse teen tämän .ssh/config tiedoston kautta.

Ja olemme sisällä!
Docker, komposite ja portit
AWS oma linux ei tue APT asennusta, joten asennamme ohjeiden mukaisesti yumilla dockerin serveriin. Asennan myös docker-composen virallisten ohjeiden mukaisesti.
sudo yum update -y
sudo yum install -y docker
sudo usermod -a -G docker ec2-user
# Tämän jälkeen kannattaa aloittaa sessio uudestaan, käyttäjäoikeudet latautuvat oikein
# Docker-composen viimeisin versio
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose version
sudo service docker start
Docker on kontitus järjestelmä, jolla voimme ajaa tarvitsemamme koodin ja sen tarvitsemat ohjelmat itsenäisesti omassa ”kontissa”. Compose on lisäosa, jolla saan laitettua yhteen kontit. Tässä tapauksessa ALR ja traefik samaan kokonaisuuteen.

Kun kontitusjärjestelmä on pystyssä. Voimme keskittyä paketin lähettämiseen palvelimelle.
Tähän normaalisti käytettäisiin GIT clone järjestelmää, tai suoraan, esimerkiksi amazonin omaa ECR järjestelmää. Jossa aina uusin docker-kuva vedettäisiin palvelimelle.
Tähän demoon teemme kuitenkin yksinkertaisen rsync lähetyksen tälle.
Koska loimme oman SSH avaimen äskettäin ’aws’ osoitteella voin omalta koneeltani rsyncillä lähettää paketit AWS ympäristöön. Tietenkin vaatii, että rsync asennettu omalle koneelle.
rsync -avz projektikansio_path aws:~
-a arkistona -v lisätiedot lähetykselle ja -z pakkauksella
Tämän jälkeen AWS puolella käynnistän instanssit lähetetystä kansiokokonaisuudesta.
docker-compose pull
docker-compose up -d
Menen tämän jälkeen security group -> inbound rules -> ja lisään ipv4 80 portin instanssille.
Tämän jälkeen sivusto pystyssä!

Sertifikaatti kuntoon.
Tässä vaiheessa luon Traefikin konttiin ja lisään sisäisen proxyohjauksen SSL yhteydelle. Traefik hakee let’s encryptin sertfikaatit ja tämä ylläpitää näiden päivitystä. Käytämme traefikin omaa ohjeistusta.
Eli luon nyt oman docker kansion käyttäjäni juureen. Haluan, että traefik toimii chatin yläpuolella niin luon myös docker/traefik kansion jonka sisälle laitan ALR järjestelmän.
docker
traefik
ALR
Ja traefik kansioon luon kontin rakennustiedoston.
nano docker-compose.yml
services:
traefik:
image: "traefik:latest"
container_name: "traefik"
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- traefik_default
ports:
- "80:80"
- "443:443"
# - "8080:8080"
# jos tarvitaan traefikin omaa dashboardia - täytyy myös ohjata aws omista eteenpäin.
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./traefik.yml:/etc/traefik/traefik.yml:ro"
- "./data/acme.json:/etc/traefik/acme.json"
alr:
container_name: alr
build:
context: ./ALR
# mistä haetaan kontille tiedot, nyt laitoin samaan kansioon
restart: unless-stopped
networks:
- traefik_default
labels:
- "traefik.enable=true"
- "traefik.http.routers.alr-chat-secure.rule=Host(`alr.iskff.fi`)"
- "traefik.http.routers.alr-chat-secure.entrypoints=websecure"
- "traefik.http.routers.alr-chat-secure.tls=true" # tls toimimaan
- "traefik.http.routers.alr-chat-secure.tls.certresolver=letsencrypt" # traefik ymls kohta.
- "traefik.http.services.alr-chat-service.loadbalancer.server.port=3000"
networks:
traefik_default:
name: traefik_default
Networks osiossa pyöritän molemmat yhteen verkkoon. Rakensin ALR toimimaan portissa 3000. Joten dockerin logiikka toimii julkinen traefik 443 -> Kontti 80 -> ALR 3000.
Luon myös traefikille oman ohjetiedoston.
nano traefik.yml
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
api:
dashboard: false # jos dashboard päälle niin true
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik_default
certificatesResolvers:
letsencrypt:
acme:
email: # oma sähköpostisi jolla haetaan sertifikaatit
storage: /etc/traefik/acme.json
httpChallenge:
entryPoint: web
Näin traefikin logiikka täyttyy ja voimme hakea avaimet jo mountattuun acme pisteeseen etc kansiossa.
Tässä kannattaa tosissaan tutkia virallista ohjeistusta. Ainoastaan verkotuksen teko ja porttikäytävälogiikka itse tekemiä väliin.
Sitten traefik kansiosta ajetaan,
docker-compose pull
docker-compose up -d
#Ensimmäisellä käynnistyskerran jälkeen kannattaa myös tarkastaa, että kontin sisällä data/acme.json täyttyy ja toimii
#cat data/acme.json
Näin SSL sivusto on pystyssä ja toiminnassa.
AWS omat palvelut näiden ympärillä
Eli AWS oma sertificate authority olisi ollut helpommin saatavilla oleva kokonaisuus jos olisimme saaneet kontin natiivisti yhdistettyä järjestelmään Amazonin Elastic Container Registryn kautta.
Myös helpompi saas (software as service) ratkaisu, esimerkiksi AWS app runnerin kautta olisi näin onnistunut huomattavasti helpommin.