61 lines
6.6 KiB
TeX
61 lines
6.6 KiB
TeX
\chapter{F\"uggv\'enyek l\'etrehoz\'asa}
|
|
A rendszerek sajátosságai miatt ugyanazt a kódot nem lehet változtatás nélkül felhasználni a két eltérő rendszerben. Mindkét rendszerre két tesztfüggvényt valósítottam meg. Az egyik célja a lehető legrövidebb válaszidő és a legnagyobb áteresztőképesség. A másik célja a kérésenként nagyobb processzorterhelés generálása.
|
|
|
|
Az első egy Go nyelven megvalósított tesztfüggvény, amely a meghívás után “Hello Go!” szöveggel tér vissza. A Kubeless rendszerhez írt függvény szignatúrája egyezik a \aref{code:hello-kubeless-go} k\'odr\'eszletben l\'athat\'o függvényével. Függőségként importálni kell a Kubeless sztenderd könyvtárát.
|
|
|
|
Knative rendszerben szükség van a Go sztenderd könyvtárban megtalálható HTTP szerver implementációra, valamint egy belépési függvényre, amely elindítja a webszervert és beköti a függvényünket úgy, hogy az alapértelmezett URL, ahol elindul a webszerver, az ide érkező kéréseket továbbítsa neki. Mivel a Knative-ba Docker Image-eket lehet telepíteni, ezért azt is létre kell hozni. Annak érdekében, hogy a végső Image a lehető legkisebb méretű legyen, a Go program binárissá fordítását külön végezzük el, a végső Image-be csak bemásoljuk azt. Erre a Docker ad eszközt, az úgynevezett multi-stage buildek segítségével. Ez azt jelenti, hogy egy külön végrehajtási láncot leírva lefordítjuk a kódot, majd a végső Image-be csak bemásoljuk a fordítással végzett konténer Image-éből. Az elkészült Image-et - melyet le\'ir\'o Docker file \aref{code:dockerfile-hello-go} k\'odr\'eszleten l\'athat\'o - a Docker Hubra feltöltöttem, hogy ne kelljen minden frissen telepített Workernek megépítenie az Image-et.
|
|
|
|
\begin{lstlisting}[float=!ht,caption={Echo t\'ipus\'u f\"uggv\'eny Docker Image-\'et le\'ir\'o Dockerfile},label=code:dockerfile-hello-go]
|
|
FROM golang:1.13 as builder
|
|
|
|
WORKDIR /app
|
|
|
|
COPY go.* ./
|
|
RUN go mod download
|
|
|
|
COPY . ./
|
|
|
|
RUN CGO_ENABLED=0 GOOS=linux go build -v -o server
|
|
|
|
FROM alpine:3
|
|
|
|
RUN apk add --no-cache ca-certificates
|
|
|
|
COPY --from=builder /app/server /server
|
|
|
|
CMD ["/server"]
|
|
\end{lstlisting}
|
|
|
|
A várhatóan nagyobb processzorterhelést generáló függvényként egy Python nyelven implementált prímszám számoló szerepelt. E függvény viselkedése egyezik mindkét rendszerbe telepített verzió esetében, csupán a bemeneti érték kinyerése tér el. A függvény erről a bemeneti értékről dönti el, hogy az prímszám-e. Kubeless esetében a Go-val ellentétben nincs szükség semmilyen függőség megjelölésére, a megírt függvényt egyből lehet telepíteni.
|
|
|
|
A Knative esetében szintén eltérő módon érdemes Docker Image-et készíteni a megírt függvényből. Szükség van a Flask nevű könyvtárra, amely segítségével webes alkalmazásokat lehet készíteni Pythonban. Használata igen hasonló a Go-ban megtalálható implementációhoz. Úgynevezett dekorátor segítségével lehet a Flask számára jelezni, hogy az adott függvény milyen URL meghívásakor fusson le, valamint a használni kívánt port számát is itt lehet megadni. A Docker Image építése során multi-stage build használatára nincsen szükség, hiszen a Python értelmezőnek mindenképpen jelen kell lennie a végső Image-ben is. A Flask telepítése mellett úgy döntöttem, hogy a gunicorn Pythonban implementált webszervert is telepítem, valamint azt használom, mint webszervert a Docker Image-ben. Használatának előnye, hogy képes kihasználni a Python által nyújtott multiprocessing lehetőségeket, amely azt jelenti, hogy több Python értelmezőt indítva, több folyamat használatával jobb teljesítményt lehet elérni, mint több szál használatával, ugyanis a Python értelmező egyszerre egy szálon futó programkódot értelmez.
|
|
|
|
Minden Knative függvényhez definiáltam egy-egy YAML állományban egy olyan Service-t, amelyhez tartozó Podok számát nullára képes leskálázni a rendszer, valamint egy konkurencia alapú skálázást használó Service-t. Az ut\'obbit le\'ir\'o YAML \'allom\'any \aref{code:yaml-isprime-py} k\'odr\'eszleten l\'athat\'o.
|
|
|
|
\begin{lstlisting}[float=!ht,caption={P\'irm\'asz\'aml\'al\'o f\"uggv\'eny Knative Service obejktum\'at le\'ir\'o YAML},label=code:yaml-isprime-py]
|
|
apiVersion: serving.knative.dev/v1alpha1
|
|
kind: Service
|
|
metadata:
|
|
name: isprime-py-sc-cc
|
|
namespace: default
|
|
spec:
|
|
template:
|
|
metadata:
|
|
annotations:
|
|
autoscaling.knative.dev/class: kpa.autoscaling.knative.dev
|
|
autoscaling.knative.dev/metric: concurrency
|
|
autoscaling.knative.dev/target: "10"
|
|
autoscaling.knative.dev/minScale: "1"
|
|
autoscaling.knative.dev/maxScale: "100"
|
|
spec:
|
|
containers:
|
|
- image: tormachris/isprime-python
|
|
env:
|
|
- name: TARGET
|
|
value: "Py"
|
|
\end{lstlisting}
|
|
|
|
Az elkészített függvényen, valamint a Docker Image-eket leíró Dockerfile-okat Git verziókezelőrendszerrel kezeltem, a létrehozott repository-t a GitHub szolgáltatásba feltöltöttem. Ez lehetővé tette a Travis Continuos Integration/Continuos Delivery rendszer használatát. Ezt arra használtam, hogy a változások nyugtázása után, valamint azok GitHubra történő feltöltése után a Docker Image-ek automatikusan épüljenek meg, valamint kerüljenek fel a Docker Hubra. Fontos, hogy ez nem feltétlen jelenti, hogy a Kubernetesben éppen futó, vagy később létrejövő Podok a legfrissebb Image-et fogják használni. Ahhoz szükség van vagy a latest nevű címkét használni, vagy az ImagePullPolicy nevű opciót bekapcsolni a Knative Service, vagy Kubernetes Deployment definiálásánál.
|
|
|
|
Az elkészített függvények Kubelessbe telepítése a korábban telepített parancssori interfész segítségével lehetséges. A függvény telepítése, ahhoz http végpont csatolása, valamint a skálázás létrehozása különálló parancs. Skálázás esetében a processzor limit alkalmazása a függvény telepítését végző parancs argumentumaként adható meg. Ebből adódóan skálázás esetén nem lehet csak a skálázás telepítését végrehajtó parancsot kiadni. A Kubeless függvények telepítését megkönnyítendő, elkészítettem egy bash nyelven írt szkriptet, amely paramétereként elvárja a függvény és az állomány nevét, ami tartalmazza azt, illetve a futtató környezet nevét és azt, hogy kell-e skálázás. Ezek alapján kiadja a szükséges parancsokat helyesen paraméterezve. Ezáltal a parancssori interfész helyes használatát gyorsabbá és könnyebbé tettem.
|