Hyppää sisältöön

Welcome to our weekly research support coffee hour on Zoom! Click here for more information.

Warning!

Puhti scratch disk is becoming very full (80+ % ) resulting in performance degradation. Everybody is advised to only keep actively processed data on scratch, all other data should be deleted, transferred to host institute or stored in Lumi-O. No new quota will be granted. Click here for a tool for examining your disk usage.

Keskitaso

Tarvitset OpenShiftin komentorivityökalun oc ja Helmin tuntemusta

Kuinka ottaa käyttöön korkean käytettävyyden sovellus Rahdissa

Tämä on yksinkertainen korkean käytettävyyden verkkosovelluksen käyttöönotto Rahdissa.

Kaavio

Rahti HA

Yllä olevassa kaaviossa näet lopputuloksen, jonka saavutat tämän ohjeen lopussa. Otamme käyttöön kaksi URL-osoitetta: yhden itse sovellukselle (app.rahtiapp.fi) ja toisen valvonnan koontinäytölle tai koontinäytöille (grafana-app.rahtiapp.fi). Sovellus toimii Frontend-osiossa, ja sillä on kaksi replikaa. Frontend on yhdistetty postgres-tietokantaan. Valvonta toteutetaan Grafanalla ja Prometheuksella, jotka ovat kaksi hyvin yleisesti käytettyä valvontaohjelmistoa. Prometheus kerää frontendin ja tietokannan tarjoamat metriikat, ja Grafana näyttää datan selkeinä kuvaajina.

Otamme jokaisen osan käyttöön vaihe vaiheelta ja kuvaamme niitä samalla tarkemmin.

Manuaalinen käyttöönotto

Frontend

Aloitamme ottamalla käyttöön sovelluksen, joka on tallennettu osoitteeseen:

Käytämme komentoa oc new-app. Jos sinulla ei ole oc:ta asennettuna, seuraa ohjeita sivulla Komentorivityökalun käyttö. Tässä koko ohjeessa käytämme nimiavaruutta tutorial, korvaa se omalla nimiavaruudellasi, kun suoritat komentoja. Komento ja sen tuloste ovat seuraavat:

$ oc new-app https://github.com/CSCfi/rahti-ha-tutorial/ -n tutorial
--> Found container image 955f4cc (9 days old) from Docker Hub for "python:3.11-slim"

    * An image stream tag will be created as "python:3.11-slim" that will track the source image
    * A Docker build using source code from https://github.com/CSCfi/rahti-ha-tutorial/ will be created
      * The resulting image will be pushed to image stream tag "rahti-ha-tutorial:latest"
      * Every time "python:3.11-slim" changes a new build will be triggered

--> Creating resources ...
    imagestream.image.openshift.io "python" created
    imagestream.image.openshift.io "rahti-ha-tutorial" created
    buildconfig.build.openshift.io "rahti-ha-tutorial" created
    deployment.apps "rahti-ha-tutorial" created
    service "rahti-ha-tutorial" created
--> Success
    Build scheduled, use 'oc logs -f buildconfig/rahti-ha-tutorial' to track its progress.
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose service/rahti-ha-tutorial' 
    Run 'oc status' to view your app.

Note

Voit ottaa tämän käyttöön myös selainkäyttöliittymästä kohdassa Import from Git

Kun käyttöönotto on tehty, meillä on:

$ oc get all -n tutorial
Warning: apps.openshift.io/v1 DeploymentConfig is deprecated in v4.14+, unavailable in v4.10000+
NAME                                     READY   STATUS             RESTARTS      AGE
pod/rahti-ha-tutorial-1-build            0/1     Completed          0             26m
pod/rahti-ha-tutorial-86467965d5-hn4hp   0/1     CrashLoopBackOff   9 (21s ago)   24m

NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/rahti-ha-tutorial   ClusterIP   172.30.61.169   <none>        5000/TCP   26m

NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/rahti-ha-tutorial   0/1     1            0           26m

NAME                                           DESIRED   CURRENT   READY   AGE
replicaset.apps/rahti-ha-tutorial-69f9d94dbb   0         0         0       26m
replicaset.apps/rahti-ha-tutorial-86467965d5   1         1         0       24m

NAME                                               TYPE     FROM   LATEST
buildconfig.build.openshift.io/rahti-ha-tutorial   Docker   Git    1

NAME                                           TYPE     FROM          STATUS     STARTED          DURATION
build.build.openshift.io/rahti-ha-tutorial-1   Docker   Git@80211bf   Complete   26 minutes ago   2m5s

NAME                                               IMAGE REPOSITORY                                                 TAGS        UPDATED
imagestream.image.openshift.io/python              image-registry.apps.2.rahti.csc.fi/tutorial2/python              3.11-slim   26 minutes ago
imagestream.image.openshift.io/rahti-ha-tutorial   image-registry.apps.2.rahti.csc.fi/tutorial2/rahti-ha-tutorial   latest      24 minutes ago

new-app on luonut meille automaattisesti muutamia asioita. Ensinnäkin BuildConfig-resurssin, joka yhdessä kahden ImageStream-resurssin ja yhden Build-instanssin kanssa rakentaa ja tallentaa sovelluksemme imagen. Toiseksi Deployment-resurssin, joka yhdessä ReplicaSet- ja Pod-resurssien kanssa suorittaa sovelluksemme. Kolmanneksi ja viimeiseksi Service-resurssin, joka huolehtii verkkoyhteyksistä.

Mutta voit nähdä, että pod/rahti-ha-tutorial-86467965d5-hn4hp on tilassa CrashLoopBackOff. Katsotaan ongelmallisen Podin lokia:

$ oc logs rahti-ha-tutorial-86467965d5-hn4hp -n tutorial
Waiting for db:5432
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
nc: getaddrinfo for host "db" port 5432: Name or service not known
Timed out

Tämä on odotettua, koska yhteyttä varten ei ole tietokantaa. Korjataan se.

Tietokanta

Tietokantaa varten käytämme Rahdin tarjoamaa mallinetta:

$ oc new-app --template=postgresql-ephemeral \
  -p POSTGRESQL_USER=postgres \
  -p POSTGRESQL_PASSWORD=postgres \
  -p POSTGRESQL_DATABASE=postgres \
  -p DATABASE_SERVICE_NAME=db \
  -n tutorial
--> Deploying template "tutorial2/postgresql-ephemeral" to project tutorial

     PostgreSQL (Ephemeral)
     ---------
     PostgreSQL database service, without persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/postgresql-container/.

     WARNING: Any data stored will be lost upon pod destruction. Only use this template for testing

     The following service(s) have been created in your project: db.

            Username: postgres
            Password: postgres
       Database Name: postgres
      Connection URL: postgresql://db:5432/

     For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/postgresql-container/.

     * With parameters:
        * Memory Limit=512Mi
        * Namespace=openshift
        * Database Service Name=db
        * PostgreSQL Connection Username=postgres
        * PostgreSQL Connection Password=postgres
        * PostgreSQL Database Name=postgres
        * Version of PostgreSQL Image=10-el8

--> Creating resources ...
    secret "db" created
    service "db" created
Warning: apps.openshift.io/v1 DeploymentConfig is deprecated in v4.14+, unavailable in v4.10000+
    deploymentconfig.apps.openshift.io "db" created
--> Success
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose service/db' 
    Run 'oc status' to view your app.

Malline "PostgreSQL Ephemeral" käyttää muistia datan tallentamiseen, ja sitä käytetään vain testaukseen, koska tietokannan Podin käynnistyessä uudelleen data katoaa. Jos haluat oikean tuotantotietokannan, suosittelemme käyttämään Pukki DBaaS -palvelua.

Muutaman minuutin kuluttua rahti-ha-tutorial-Podin pitäisi käynnistyä itsestään uudelleen ja virheen korjaantua:

$ oc logs rahti-ha-tutorial-86467965d5-hn4hp -n tutorial
Waiting for db:5432
Connection to db (172.30.224.18) 5432 port [tcp/postgresql] succeeded!
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://10.131.7.213:5000
Press CTRL+C to quit

oc delete pod

Voit aina nopeuttaa prosessia ja poistaa kaatuvan Podin suorittamalla komennon: oc delete pod <YOUR_POD_NAME> -n tutorial.

Single point of failure

Asentamamme tietokanta ei ole todellisuudessa korkean käytettävyyden ratkaisu. PostgreSQL:n tekeminen korkean käytettävyyden ratkaisuksi ei ole yksinkertaista. Tämän komponentin korkean käytettävyyden toteutuksen selittäminen olisi tähän ohjeeseen liian monimutkaista, mutta aiheesta on runsaasti dokumentaatiota internetissä.

Skaalaus

Skaalaus Kubernetesissa ja siten myös Rahdissa on hyvin yksinkertaista. Suorita vain:

$ oc scale --replicas=3 deploy/rahti-ha-tutorial -n tutorial
deployment.apps/rahti-ha-tutorial scaled

Tämän jälkeen käynnistetään kaksi ylimääräistä Pod-kopiota:

$ oc get pod -n tutorial -o wide
NAME                                 READY   STATUS      RESTARTS      AGE   IP             NODE                        NOMINATED NODE   READINESS GATES
db-1-deploy                          0/1     Completed   0             21h   10.131.6.10    2-rcr6j-worker-io-1-cv824   <none>           <none>
db-1-rvtw4                           1/1     Running     1 (21h ago)   21h   10.131.6.11    2-rcr6j-worker-io-1-cv824   <none>           <none>
rahti-ha-tutorial-1-build            0/1     Completed   0             21h   10.131.7.196   2-rcr6j-worker-io-1-cv824   <none>           <none>
rahti-ha-tutorial-6488b5d958-45rr8   1/1     Running     0             17m   10.129.31.71   2-rcr6j-worker-0-lnm4d      <none>           <none>
rahti-ha-tutorial-6488b5d958-7l86w   1/1     Running     0             20h   10.131.6.69    2-rcr6j-worker-io-1-cv824   <none>           <none>
rahti-ha-tutorial-6488b5d958-pjzbf   1/1     Running     0             17m   10.129.23.88   2-rcr6j-worker-0-8z2q5      <none>           <none>

Kuten näet, jokaisen rahti-ha-tutorial-Podin NODE on eri. Näin yhden noden vikaantuminen ei vaikuta sovellukseen merkittävästi. Replikat ovat hyödyllisiä myös sovelluksen ylös- ja alasskaalauksessa sekä läpinäkyvämpien migraatioiden tekemisessä (Rahti päivittää Podit yksi kerrallaan).

Sovelluksen julkaiseminen

Tässä vaiheessa meillä on toivottavasti toimiva sovellus, mutta emme voi vielä tarkistaa sitä itse. Meidän täytyy julkaista sovellus internetiin:

$ oc expose service/rahti-ha-tutorial -n tutorial
route/rahti-ha-tutorial exposed

Muutos tapahtuu lähes välittömästi, ja esimerkissämme URL-osoite on:

http://rahti-ha-tutorial-tutorial.2.rahtiapp.fi/

Sinun tapauksessasi URL-osoite on erilainen, ja voit tarkistaa sen suorittamalla:

$ oc get route -n tutorial
NAME                HOST/PORT                                   PATH   SERVICES            PORT       TERMINATION   WILDCARD
rahti-ha-tutorial   rahti-ha-tutorial-tutorial.2.rahtiapp.fi           rahti-ha-tutorial   5000-tcp                 None

URL-osoite luotiin automaattisesti palvelun nimen ja nimiavaruuden nimen perusteella, mutta voit aina päättää itse, millä nimellä sovellus julkaistaan käyttämällä tätä valintaa:

    --hostname='':
    Set a hostname for the new route

Tässä vaiheessa meillä on toimiva sovellus, mutta valvonta puuttuu.

Postgres HTML Exporter

Valvonta

Valvontaan käytämme Grafanaa ja Prometheusta. Rahti tarjoaa "Chartin" (näin Helm kutsuu reseptejään tai mallineitaan). Sen käyttöönottoon käytämme helm-komentorivityökalua:

$ helm repo add helm-charts https://cscfi.github.io/helm-charts/     
"helm-charts" has been added to your repositories

Päivitä sitten repositorio saadaksesi chartit:

$ helm repo update      
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "helm-charts" chart repository
Update Complete. ⎈Happy Helming!⎈

Luo tiedosto nimeltä values.yaml, jonka sisältö on:

prometheus:
  serverFiles:
    prometheus.yml:
      scrape_configs:
        - job_name: kubernetes-pods
          kubernetes_sd_configs:
            - role: pod
              namespaces:
                names:
                - tutorial

Asenna se lopuksi:

$ helm upgrade --install graf-prom helm-charts/prometheus-grafana-helm -n tutorial -f values.yaml
Release "graf-prom" does not exist. Installing it now.
level=WARN msg="unable to find exact version; falling back to closest available version" chart=prometheus-grafana-helm requested="" selected=2.1.0
NAME: graf-prom
LAST DEPLOYED: Thu Jan 15 16:09:32 2026
NAMESPACE: tutorial
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
NOTES:
========================================
  CSC Prometheus-Grafana Helm deployed
========================================
===========
  GRAFANA
===========
Wait a few seconds. Time for the application to be fully deployed.

Get the Grafana application URL by running these commands:

  export GRAFANA=$(oc get route --namespace=tutorial -o yaml | yq '.items[] | select(.metadata.name == "grafana") .spec.host' -r)
  echo "GRAFANA server URL: http://$GRAFANA"

The password for the access is generated randomly.
To retrieve the information, run these commands:

  echo Username: $(oc get secret --namespace=tutorial2 graf-prom -o jsonpath="{.data.admin-user}" | base64 -d)
echo Password: $(oc get secret --namespace=tutorial2 graf-prom -o jsonpath="{.data.admin-password}" | base64 -d)


========================
  PROMETHEUS (OPTIONAL)
========================
The Route to Prometheus is not deployed by default. You can change the behaviour by setting `true` in the `values.yaml`
or you can type this command:

  oc --namespace tutorial2 create route edge prometheus --service=graf-prom-prometheus-server --insecure-policy='Redirect' --port=9090

You can retrieve the Prometheus URL by running these commands:

  export PROMETHEUS=$(oc get route --namespace=tutorial -o yaml | yq '.items[] | select(.metadata.name == "prometheus") .spec.host' -r)
  echo "PROMETHEUS server URL: http://$PROMETHEUS"

Olemme melkein valmiita. Ennen kuin yritämme kirjautua Grafanan selainkäyttöliittymään, meidän täytyy vielä kertoa Prometheukselle, mistä se löytää Podiemme valvontadatan. Jotta Prometheus voi valvoa podejasi, sinun täytyy lisätä sovelluksen Podeihin annotaatiot prometheus.io/scrape=true ja prometheus.io/port=5000. Voit käyttää tätä komentoa:

$ oc patch deployment rahti-ha-tutorial -n tutorial --type='merge' -p '{
  "spec": {
    "template": {
      "metadata": {
        "annotations": {
          "prometheus.io/scrape": "true",
          "prometheus.io/port": "5000"
        }
      }
    }
  }
}'

Grafana on esimerkissämme saatavilla osoitteessa:

https://grafana-tutorial2.rahtiapp.fi

Viimeinen tehtävä on testata Grafanan kuvaajia seuraavasti:

  1. Luo hieman keinotekoista liikennettä:

    $ future=$[$(date +%s)+600]
    $ while test $(date +%s) -lt $future; do 
      sleep 1;
      ab -n 200 -c 1 \
          http://rahti-ha-tutorial-tutorial.2.rahtiapp.fi/$RANDOM &
      ab -n 2000 -c 10 \
          http://rahti-ha-tutorial-tutorial.2.rahtiapp.fi/;
    done
    

    Käytämme työkalua ab (lyhenne sanoista Apache HTTP server benchmarking tool), joka asennetaan apache utils -paketista. Liikenteen luomiseen on monia tapoja; tämä on vain yksinkertainen tapa.

  2. Kirjaudu Grafanan selainkäyttöliittymään. Löydät käyttäjätunnuksen ja salasanan Secretistä nimeltä graf-prom-grafana.

  3. Napsauta Explore, jolloin metriikoiden Explore-paneeli avautuu. Tällä sivulla näet kaikki metriikat ja voit testata kyselyitä.

  4. Valitse buildin sijaan code, jotta voit syöttää kyselyn: rate(flask_app_request_count_total[5m]).

    Grafana explore

  5. Napsauta sinisiä nuolikuvakkeita, jolloin kuvaaja tulee näkyviin:

    Grafana request count rate

Yhteenveto

Tämä ohje on vain lyhyt esittely Rahdin mahdollisuuksista korkean käytettävyyden sovellusten alustana sekä siitä, kuinka helppoa siihen on alkaa lisätä valvontaa. Rahti tarjoaa valmiina kuormantasausta, integroidun rakennusjärjestelmän ja rekisterin, valmiiksi luotuja testidomainnimiä (*.rahtiapp.fi) sekä muita pieniä ominaisuuksia. Näiden kaikkien tavoitteena on vähentää sovelluksen DevOps-tiimin kuormaa.

Käyttöön ottamamme sovellus on leikkisovellus, jolla voit kokeilla käytännössä, mitä tapahtuu, kun node kaatuu, miten valvontanäkymiä ja hälytyksiä lisätään Grafanan kautta sekä mitä tapahtuu, kun muutat satunnaisia asetuksia.

Tätä käyttöönottoa voi laajentaa monella tavalla:

  • Tee PostgreSQL:stä korkean käytettävyyden ratkaisu tai siirrä tietokanta Pukki -palveluun.
  • Luo PostgreSQL-tietokantaan tauluja ja lisää niihin dataa.
  • Korvaa tämä sovellus toisella kehittämälläsi sovelluksella ja katso, miten replikat käyttäytyvät.
  • Kokeile automaattista skaalausta.

Katso myös Kubernetesin peruskäsitteitä käsittelevä dokumentaatiomme sivulla Kubernetesin peruskäsitteet.

Suomenkielinen tekoälykäännös

Sisällössä voi esiintyä virheellistä tietoa tekoälykäännöksestä johtuen.

Klikkaa tästä antaaksesi palautetta