Telepítés Google Cloudba Docker konténerből

Mostanában sokat kell a címben említett felhőben hegesztenem. Pár hete épp egy (sok) App Engine-en futó szervert kellett megreszelnem (oké, most már kezdenek furák lenni ezek az igék), és ennek kapcsán felmerült, hogy oké, tudom tudok telepíteni a gépemről, de hogyan mondom meg a CI/CD rendszernek, hogy tolja fel az appot a felhőbe?

Itt egy megoldás!

Kicsit olyan, mintha a Google összerakta volna magának a backendjét, aztán kiadta volna a gyakornokoknak, hogy szabadidejükben dolgozzanak publikusan használható API-n… és így lett a Chocapic. A dolog működik, de hogy őszinte legyek, az AWS és az Azure után kicsit még bétának érződik az egész Google Cloud.

Két módszert sorolt fel a hivatalos dokumentáció arra hogy hogyan telepítsek egy appot. (Manapság már a szervereket is appnak nevezzük, ne kérdezzétek, miért. Mindegy, legalább kevés szótag.)

  1. A gcloud CLI-on keresztül, vagyis telepítsek egy SDK-t, setupoljam fel, majd lépjek be az appot tartalmazó könyvtárba, billentyűzzek be 1-2 parancsot, és kész.
  2. Küldjek egy HTTP POST-ot egy API-jukra, megjelölve egy callback URL-t, majd a callback URL-en kapjam el az API válaszát, rakjam össze a telepítendő fájlokat, és indítsam meg onnan a telepítést egy másik hívással.
  3. Slussz. Mármint, hogy nincs harmadik út, normális Infrastructure as Code. 😦

Ja igen, természetesen megvizsgáltuk a lehetőségeket. A legjobbnak a Terraform tűnt, ámde az a mai napig nem támogatja az App Engine-t. 😦 Simán lehet, hogy soha nem is fogja – nekem nagyon úgy tűnik, hogy a Google (érthető módon) a Kubernetes irányába fejleszti mindenét, mivel idővel az lesz a backdoorjuk minden egyes cégbe, ami konténereket telepít bárhova.

A második megoldásnál nagyon úgy tűnt, hogy erre építeni kellene vagy egy szervert, vagy legalább egy Functiont, ami a Google Cloudon belül van, eléri a Storage-ot, van elég jogosultsága, hogy belekontárkodjon a többi projektbe való telepítésbe… szóval inkább úgy döntöttünk, hogy próbáljuk meg az első megoldást átültetni a build szerverekre.

A megoldáshoz kellett tehát:

  • 1 db konténer; az egyszerűség kedvéért legyen Linux
  • A gcloud telepítése a fentibe
  • A gcloud konfigurálása, hogy a megfelelő projektbe és régióba/zónába telepítsen
  • A tényleges app bemásolása a telepítő konténerbe és a telepítés elindítása
  • + a CI/CD pipeline a repót figyeli, ahova nyilván nem töltünk fel kulcsokat, jelszavakat, szóval majd ezt is figyelembe kell venni…

A gcloud telepítéséhez tulajdonképpen egy az egyben fel lehet használni a dokumentációban szereplő utasításokat.

curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz
mkdir -p /usr/local/gcloud
tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz
/usr/local/gcloud/google-cloud-sdk/install.sh
PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin

Viszont ahhoz, hogy ez lefusson, telepíteni kell előbb egy Pythont is. Sőt, ha a konténer image-ben nem volt benne a cURL, akkor azt is.

apt-get update && apt-get -y install curl python
A gcloud inicializálása/konfigurálása nem egyszerű… Vagyis egyszerű, csak valakik a Google-nél úgy gondolták, hogy jó ötlet egy CLI tool alapértelmezett inicializálását úgy megoldani, hogy a tool nyit egy böngészőt, és elnavigál egy oldalra, ahol a user szépen bejelentkezik. #facepalm
Van viszont egy utasítás, aminek a segítségével egy kész keyfile-t megadva megoldható az autentikálás anélkül, hogy kattintani/gépelni kellene.
gcloud auth activate-service-account --key-file=supersecret-keyfile.json
A projekt beállítása ezek után gyerekjáték.
gcloud config set project my-very-nice-project-666
Összességében tehát egy konténer, ami képes belépni a Google Cloudba, és telepíteni, valahogy így néz ki:
FROM ubuntu
RUN apt-get update && apt-get -y install curl python
RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz
RUN mkdir -p /usr/local/gcloud
RUN tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz
RUN /usr/local/gcloud/google-cloud-sdk/install.sh
ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin
WORKDIR /deployment
COPY supersecret-keyfile.json .
RUN gcloud auth activate-service-account --key-file=supersecret-keyfile.json
RUN gcloud config set project my-very-nice-project-666
ENTRYPOINT [ "bash" ]
Build, run, fel lehet rá csatlakozni, tud telepíteni, meg igazából bármit.
Ha Ubuntura építünk, akkor olyan 1GB körül lesz az image, ami hát ugye szuboptimális, bár tegyük hozzá, hogy ennek legalább a fele nem az Ubuntu, hanem a telepített cuccok. Utóbbiakból nagyon levágni nem lehet, viszont átrakhatjuk a konténert Alpine-ra. (Ezzel együtt a package manager is megváltozik, apt-get helyett apk-t kell használnunk.)
FROM alpine
RUN apk update && apk add curl python2
...
A maradék probléma, hogy akkor oldjuk meg a telepítendő app telepítését is. Ez ennyi dockerezés után szinte ujjgyakorlat.
COPY src/ ./app
RUN cd app && gcloud app deploy
Szóval akkor a nagytotál az alábbi:
FROM alpine
RUN apk update && apk add curl python2
RUN curl https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz > /tmp/google-cloud-sdk.tar.gz
RUN mkdir -p /usr/local/gcloud
RUN tar -C /usr/local/gcloud -xvf /tmp/google-cloud-sdk.tar.gz
RUN /usr/local/gcloud/google-cloud-sdk/install.sh
ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin
WORKDIR /deployment
COPY supersecret-keyfile.json .
RUN gcloud auth activate-service-account --key-file=supersecret-keyfile.json
RUN gcloud config set project my-very-nice-project-666
COPY src/ ./app
RUN cd app
ENTRYPOINT [ "gcloud", "app", "deploy" ]
Nem is olyan nagy… Az utolsó lépést azért emeltem ki Entrypointba, hogy ne a docker buildnél telepítse az appot, csak docker runnál.
Azt ne felejtsük el, hogy a fenti megoldásnál egy kész keyfile-t másoltunk be a konténerbe. Ez kb. minden esetben kerülendő, mivel érzékeny információkat tartalmaz! Ezért javasolt, hogy az érzékeny infókat cseréljük placeholdelekre, és a CI pipeline-unkban helyezzük el a tényleges jelszót, egyebeket, amiket aztán a pipeline illesszen be a placeholderek helyére, mielőtt a keyfile másolásra kerül.
Mára ennyi, remélem, vkinek megkönnyítettem a napját…

Szerző: Fülöp Dávid

I'm a software developer, trainer, Microsoft MVP interested in .NET and related technologies. Currently mostly .NET Core, Docker, Kubernetes...

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés /  Módosítás )

Google kép

Hozzászólhat a Google felhasználói fiók használatával. Kilépés /  Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés /  Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés /  Módosítás )

Kapcsolódás: %s