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.

Kubernetes-sovelluksen paketointi Helmillä

Helm on "Kubernetesin paketinhallintaohjelma", ja sen avulla voidaan hallita Kubernetes-sovelluksen elinkaarta (ottaa käyttöön, määrittää, päivittää, poistaa käytöstä, ...). Se on Infrastructure as Code (IaC) -työkalu, joten sen avulla voimme hallita sovelluksen versioita, seurata sen kehitystä ajan myötä, tehdä identtisiä kopioita (prod, preprod, dev, ...) ja ennakoitavia päivityksiä sekä tietenkin jakaa ja julkaista sovelluksen. Se on yksi tärkeimmistä upstreamissa käytetyistä työkaluista: jos työkalulla on "Kubernetes deployment", se käyttää hyvin todennäköisesti Helmiä.

Johdanto

Helm paketoi sovellukset Chart-paketeiksi. Helm chart on kokoelma YAML-malleja. Chartin luomiseksi täytyy ensin asentaa Helm -komentorivityökalu ja oc-komentorivityökalu. Kun tämä on tehty, jatka näin:

Varmista, että olet kirjautunut sisään:

oc whoami

tämän pitäisi palauttaa Rahti-käyttäjätunnuksesi. Luo sitten esimerkkichart:

$ helm create example
Creating example

tuloksena on:

$ find example
example
example/Chart.yaml
example/templates
example/templates/tests
example/templates/tests/test-connection.yaml
example/templates/deployment.yaml
example/templates/service.yaml
example/templates/ingress.yaml
example/templates/hpa.yaml
example/templates/serviceaccount.yaml
example/templates/_helpers.tpl
example/templates/NOTES.txt
example/values.yaml
example/charts
example/.helmignore

Se luo pääosin itsestään selittävän Chart-rungon. Rakenne on seuraava:

  • Tiedosto Chart.yaml sisältää peruskuvaustiedot: name, description, version, ...
  • Tiedosto values.yaml sisältää Chartin oletusarvot ja näyttää, mitä parametreja voidaan määrittää.
  • .helmignore sisältää ohitettavat kuviot; se on samankaltainen kuin gitignore. Emme muuta tätä tiedostoa.
  • Kansio charts sisältää muut chartit, joista tämä riippuu. Emme käytä tätä ominaisuutta.
  • Lopuksi kansio templates sisältää eri Kubernetes API -objektit, jotka otetaan käyttöön. Mallimoottorin syntaksi mahdollistaa suuren määrän muokattavuutta. Se tukee sisäänrakennettuja objekteja, jotka voivat esimerkiksi näyttää nykyisen klusterin ominaisuudet, ulkoisia values-tiedostoja, joissa jokaisella sovelluksen käyttöönotolla voi olla oma erillinen arvotiedostonsa, laajaa joukkoa mallifunktioita, vuonohjausta ja paljon muuta.

Käyttöönotetun sovelluksen paketointi

Ennen kuin voimme aloittaa prosessin, meidän täytyy "siivota" nykyinen Helmin esimerkkichart.

  1. Poista (tai siirrä muualle) kaikki tiedostot kansion templates sisältä.

  2. Tyhjennä tiedosto values.yaml.

  3. Muokkaa tiedostoa Chart.yaml ja täytä arvot tarpeen mukaan.

helm lint

Helm-työkalu tarjoaa komennon lint, joka raportoi kaikki nykyisen mallin syntaksivirheet.

$ helm lint example
==> Linting example
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

Nyt voimme luoda YAML-tiedostot, jotka sisältävät sovelluksen eri osat. Esimerkkinä käytämme yksinkertaista verkkopalvelinta, johon on liitetty taltio. Käytämme iteratiivista prosessia luodaksemme kopion nykyisestä käyttöönotostamme. Se on iteratiivinen, koska luomme ensin yksinkertaisen, ei-muokattavan ja todennäköisesti toimimattoman version, testaamme sen, palaamme takaisin ja teemme siitä täydellisemmän ja muokattavamman, testaamme uudelleen ja niin edelleen.

  1. Listaa kaikki API-objektit saadaksesi käsityksen siitä, mistä eri osista se koostuu:

    $ oc get dc,deployment,pvc,secret,configmaps,service,route -o name
    deployment.apps/nginx
    persistentvolumeclaim/html
    secret/builder-dockercfg-h4cwh
    secret/builder-token-6fngh
    secret/builder-token-n2rdm
    secret/default-dockercfg-dqfxm
    secret/default-token-kfjlb
    secret/default-token-znxls
    secret/deployer-dockercfg-rpsxj
    secret/deployer-token-gnvzt
    secret/deployer-token-pvws5
    service/glusterfs-dynamic-ed156002-8a7e-11ed-b60d-fa163e0d8841
    service/nginx
    route.route.openshift.io/nginx
    
  2. Yllä olevasta listasta olemme kiinnostuneita vain kohteista deployment.apps, persistentvolumeclaim/html, service/nginx ja route.route.openshift.io/nginx. Loput luodaan automaattisesti, kuten secret/-tokenit, tai muiden objektien toimesta, kuten objekti service/glusterfs-dynamic-ed156002-8a7e-11ed-b60d-fa163e0d8841, joka luotiin objektin persistentvolumeclaim/ (PVC) luonnin seurauksena.

Kirjoitamme mallit yksi kerrallaan aloittaen taltiosta. Tämän tehtävän suorittamiseen on kaksi yksinkertaista lähestymistapaa: "hae ja siivoa" tai "luo uudelleen mallista". Kokeilemme ensin menetelmää "hae ja siivoa".

Hae ja siivoa

Hae ja siivoa -menetelmän idea on yksinkertainen: haemme Kubernetes-klusterissa käynnissä olevan objektin yaml-esityksen ja poistamme sitten kaiken tarpeettoman tiedon, kuten tilatiedot ja oletusmääritysasetukset.

Pysyväistaltiohakemus

Hae PVC-objekti YAML-muodossa tiedostoon pvc.yaml:

oc get persistentvolumeclaim/html -o yaml > pvc.yaml

Suurin osa haetun YAML-tiedoston tiedoista on OpenShiftin luomia tilatietoja, jotka voidaan poistaa:

@@ -1,18 +1,7 @@
 apiVersion: v1
 kind: PersistentVolumeClaim
 metadata:
-  annotations:
-    pv.kubernetes.io/bind-completed: "yes"
-    pv.kubernetes.io/bound-by-controller: "yes"
-    volume.beta.kubernetes.io/storage-provisioner: kubernetes.io/glusterfs
-  creationTimestamp: "2023-01-02T09:22:06Z"
-  finalizers:
-  - kubernetes.io/pvc-protection
   name: html
-  namespace: test
-  resourceVersion: "1771053847"
-  selfLink: /api/v1/namespaces/test/persistentvolumeclaims/html
-  uid: ed156002-8a7e-11ed-b60d-fa163e0d8841
 spec:
   accessModes:
   - ReadWriteOnce
@@ -20,10 +9,4 @@
     requests:
       storage: 1Gi
   storageClassName: glusterfs-storage
-  volumeName: pvc-ed156002-8a7e-11ed-b60d-fa163e0d8841
-status:
-  accessModes:
-  - ReadWriteOnce
-  capacity:
-    storage: 1Gi
-  phase: Bound
+status: {}

Tärkeimmät kentät ovat metadata > name, spec > resources > requests > storage ja spec > storageClassName, ja tulos on:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard-csi
status: {}

Deployment

Sama prosessi voidaan toistaa kohteelle deployment.apps/nginx:

oc get deployment.apps/nginx -o yaml >deploy.yaml
  • Ensiksi käytetyn image-arvon osalta meidän täytyy korvata @sha256-tiiviste arvolla :latest. Näin saamme aina kuvan todellisen uusimman version. Sen voi myös korvata tietyllä versiolla, kuten :1.23.3.
  • Sen jälkeen poistamme tilatiedot. Esimerkkejä "status"-merkinnöistä ovat lastTransitionTime ja creationTimestamp. Niillä ei ole paikkaa mallissa, koska ne ovat 100-prosenttisesti Kubernetesin nykyisestä käynnissä olevasta objektista generoimaa tietoa, eivät siitä objektista, jonka haluamme luoda.
  • Lopuksi poistamme automaattisesti luodut määritysasetukset. Esimerkki "määritysasetuksista" on rollingParams. Nämä määritysasetukset generoidaan Kubernetes-klusterin oletusarvoista. Nämä oletusasetukset on myös mahdollista säilyttää, jotta chartin käyttäjä voi muuttaa niitä ennen luonnin aloittamista; esimerkiksi voi olla tarpeen kasvattaa arvoa timeoutSeconds, koska sovelluksen käynnistyminen kestää yli 10 minuuttia.
@@ -1,44 +1,24 @@
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   labels:
     app: nginx
   name: nginx
-  namespace: test
-  resourceVersion: "1771055913"
-  selfLink: /apis/apps.openshift.io/v1/namespaces/test/deployments/nginx
-  uid: a828c0db-8a7e-11ed-b60d-fa163e0d8841
 spec:
   replicas: 1
   selector:
     matchLabels:
       app: nginx
   strategy:
-    activeDeadlineSeconds: 21600
-    resources: {}
-    rollingParams:
-      intervalSeconds: 1
-      maxSurge: 25%
-      maxUnavailable: 25%
-      timeoutSeconds: 600
-      updatePeriodSeconds: 1
     type: RollingUpdate
   template:
     metadata:
-      annotations:
-        openshift.io/generated-by: OpenShiftWebConsole
-      creationTimestamp: null
       labels:
           app: nginx
     spec:
       containers:
-      - image: bitnami/nginx@sha256:abe48bff022ec9c675612653292b2e685c91ce24bc4374199723c4f69603a127
-        imagePullPolicy: Always
+      - image: docker.io/bitnami/nginx:latest
     name: nginx
     ports:
     - containerPort: 8080
@@ -46,21 +26,12 @@
     - containerPort: 8443
       protocol: TCP
     resources: {}
-        terminationMessagePath: /dev/termination-log
-        terminationMessagePolicy: File
     volumeMounts:
     - mountPath: /opt/bitnami/nginx/html/
       name: html
-      dnsPolicy: ClusterFirst
-      restartPolicy: Always
-      schedulerName: default-scheduler
-      securityContext: {}
-      terminationGracePeriodSeconds: 30
       volumes:
       - name: html
     persistentVolumeClaim:
       claimName: html
-  test: false
@@ -71,29 +42,5 @@
-   kind: ImageStreamTag
-   name: nginx:latest
-   namespace: test
-      lastTriggeredImage: bitnami/nginx@sha256:abe48bff022ec9c675612653292b2e685c91ce24bc4374199723c4f69603a127
-     type: ImageChange

Tuloksena on:

apiVersion: apps.openshift.io/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: docker.io/bitnami/nginx:latest
        name: nginx
        ports:
        - containerPort: 8080
          protocol: TCP
        - containerPort: 8443
          protocol: TCP
        resources: {}
        volumeMounts:
        - mountPath: /opt/bitnami/nginx/html/
          name: html
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: html

Luo uudelleen mallista

Kahden jäljellä olevan objektin, service ja route, osalta käytämme menetelmää "luo uudelleen mallista", jossa aloitamme yksinkertaisesta objektista ja täytämme puuttuvat kohdat tarvitsemallamme määrityksellä.

Route

Tämä on minimaalinen route:

apiVersion: v1
kind: Route
metadata:
  name: XXXX
spec:
  host: YYYY
  to:
    kind: Service
    name: ZZZZ

Missä XXXX on routen nimi, YYYY on host-nimi, jossa sovellus määritetään kuuntelemaan, ja ZZZZ on siihen liitetty Service.

Service

Mahdollisimman minimaalinen service on:

apiVersion: v1
kind: Service
metadata:
  name: XXXX
spec:
  selector:
    app: YYYY
  ports:
  - nodePort: 0
    port: NNNN
    protocol: TCP
    targetPort: NNNN

Missä XXXX on routessa täyttämämme servicen nimi, YYYY on deploymentin nimi ja NNNN on portti, jota deployment kuuntelee.

Testaus

Testit tulisi tehdä erillisessä nimiavaruudessa, ja siihen on kaksi lähestymistapaa:

  • Testaa ne yksitellen komennolla:

    oc create -f pvc.yaml
    

    Yllä oleva komento luo PVC-objektin valittuun nimiavaruuteen. Tarkista, että se toimii odotetusti. Voit tuhota sen komennolla:

    oc delete pvc/XXXX
    

    missä XXXX on taltion nimi.

  • Tai kaikki yhdessä Helm-chartissa kopioimalla kaikki luomamme yaml-tiedostot kansioon templates.

    • Voimme sitten asentaa sen:
    helm install test-name example/
    

    Huom: Valitsimella --dry-run voit esikatsella, mitä helm ottaa käyttöön tekemättä mitään muutoksia.

    • Voimme nähdä asennetun chartin tilan komennolla:
    $ helm ls
    NAME        NAMESPACE       REVISION    UPDATED                                 STATUS      CHART           APP VERSION
    test-name   test        1           2023-01-03 14:59:04.026623633 +0200 EET deployed    example-0.1.0   1.16.0
    
    • Kun olemme tehneet muutoksen chartin malleihin, voimme päivittää sen:
    $ helm upgrade test-name example
    Release "test-name" has been upgraded. Happy Helming!
    NAME: test-name
    LAST DEPLOYED: Tue Jan  3 15:54:15 2023
    NAMESPACE: test
    STATUS: deployed
    REVISION: 2
    TEST SUITE: None
    
    • Ja lopuksi sen poistaminen:
    $ helm uninstall test-name
    release "test-name" uninstalled
    

Määritys

Yksi Helmin vahvuuksista on mahdollisuus käyttää kovakoodattujen arvojen sijaan parametreja tai tarjottuja sisäänrakennettuja arvoja. Poistamalla kovakoodatut arvot tarjoamme helpon muokattavuuden, jonka ansiosta mallia voidaan käyttää useammissa tilanteissa ja pidempään, esimerkiksi vaihtamalla mallin image. Mallin käyttäjän tarvitsee huolehtia vain tiedostosta values.yaml, ei siitä, miten nämä arvot sopivat Chartin monimutkaisuuteen. Helm käyttää tähän Go templates -malleja.

Sisäänrakennetut arvot voivat olla erittäin käteviä, mutta mainitsemme niistä vain kaksi ryhmää:

  • Release-muuttujat tarjoavat perustiedot tämän chartin käyttöönotosta. Tietoja kuten Namespace, johon otamme tämän mallin käyttöön, tai Chartin Name.
  • Capabilities on edistyneempi ominaisuus, joka tarjoaa tietoa siitä, mitä API-objekteja ja niiden versioita Kubernetes-klusteri tukee. Esimerkiksi Kubernetesin versio tai se, tuetaanko Ingress- tai Route-objekteja. Nämä kaksi tietoa mahdollistavat laajemmin yhteensopivien mallien tekemisen, koska eri Kubernetes-versiot tarvitsevat hieman erilaisia asetuksia.

Voimme myös määritellä omia määritysmuuttujiamme. Asetamme oletusarvon ja sallimme samalla tiedoston values.yaml korvata sen. Aloitetaan aiempien vaiheiden taltion yaml-tiedostosta:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: glusterfs-storage
status: {}

Tässä mallissa haluamme parametrisoida ainakin kaksi arvoa: storage-koon ja storage class -arvon. Ensimmäinen antaa käyttäjän käyttää enemmän tai vähemmän levytilaa, ja toinen mahdollistaa tallennukseen käytettävän ajurin vaihtamisen. Tuloksena oleva tiedosto voisi näyttää tältä:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: {{ .Values.storage.size | default "500Mi" }}
  storageClassName: {{ .Values.storage.class | default "glusterfs-storage" }}
status: {}

Ja sitten values.yaml-tiedosto kuten:

storage:
  size: 1Gi
  class: glusterfs-storage

Kuten näet, kaikki tiedoston values.yaml muuttujat löytyvät kohdasta {{ .Values }}. Olemme myös asettaneet itse malliin oletusarvon 500Mi käyttämällä funktiota default ja määrittäneet tiedostossa values.yaml arvon 1Gi. Tässä esimerkissä käytetään tallennustilaa 1Gi, mutta jos poistaisimme rivin size: 1Gi, tallennustilan oletusarvoksi tulisi 500Mi.

Muita arvoja, joita voisi olla kiinnostavaa määrittää:

  • host, jossa sovellus on saatavilla.
  • käytettävä image.
  • sovelluksen replicas-määrä.

Ehdolliset rakenteet

Malleissa voi olla ehdollisia rakenteita klusterin ominaisuuksien tai määritysasetuksen perusteella. Esimerkiksi tls:n aktivointi tai pois jättäminen:

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: nginx
spec:
  host: {{ .Values.host }}
  {{ if eq .Values.tls "active" }}
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: edge
  {{ end }}
  to:
    kind: Service
    weight: 100
    name: nginx
status:
  ingress: []

Tämä vaatii tiedostoon values.yaml asetuksen kuten:

tls: active

Lopputulos

Lopullinen chart on:

$ find
.
./Chart.yaml
./templates
./templates/deployment.yaml
./templates/service.yaml
./templates/pvc.yaml
./templates/route.yaml
./values.yaml
./charts
./.helmignore
  • Chart.yaml:
apiVersion: v2
name: example
description_fi: Helm chart Kubernetesille
type: application

version: 0.1.0

appVersion: "1.16.0"
  • templates/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: Rolling
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: docker.io/bitnami/nginx:latest
        name: nginx
        ports:
        - containerPort: 8080
          protocol: TCP
        - containerPort: 8443
          protocol: TCP
        resources: {}
        volumeMounts:
        - mountPath: /opt/bitnami/nginx/html/
          name: html
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: html
  • templates/service.yaml:
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
  - nodePort: 0
    port: 8080
    protocol: TCP
    targetPort: 8080
  • templates/pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: html
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: {{ .Values.storage.size | default "500Mi" }}
  storageClassName: {{ .Values.storage.class | default "glusterfs-storage" }}
status: {}
  • templates/route.yaml:
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: nginx
spec:
  host: {{ .Values.host }}
  {{ if eq .Values.tls "active" }}
  tls:
    insecureEdgeTerminationPolicy: Redirect
    termination: edge
  {{ end }}
  to:
    kind: Service
    weight: 100
    name: nginx
status:
  ingress: []
  • ./values.yaml:
image: bitnami/nginx:latest
host: example.2.rahtiapp.fi
tls: active

storage:
  size: 1Gi
  class: glusterfs-storage

Online-Helm-repositorion käyttö

Repositorion lisääminen

On myös mahdollista asentaa repository ja käyttää niitä sovellusten käyttöönottoon.
Esimerkiksi JupyterHub: voit asentaa repo:n tällä komennolla:

helm repo add jupyterhub https://hub.jupyter.org/helm-chart/

Jos kirjoitat tämän komennon:

helm repo list   
Sinun pitäisi nähdä juuri lisäämäsi repositorio.

On myös mahdollista tarkistaa päivitykset (ja päivittää repo) tällä komennolla:

helm repo update

Voit hakea ja tarkistaa saatavilla olevat paketit:

helm search repo jupyterhub
NAME                            CHART VERSION   APP VERSION     DESCRIPTION                    
jupyterhub/jupyterhub           3.1.0           4.0.2           Multi-user Jupyter installation                   

Arvojen tarkistaminen

Kun asennat online-repo:n, voit tarkistaa oletusarvoiset values-asetukset, joita käytetään käyttöönotossa. Tee se seuraavalla komennolla:

helm show values jupyterhub/jupyterhub > values.yaml
ArtifactHub on hyvä sivusto, josta voit löytää paketteja

Muokkaaminen ja asentaminen reposta

Kun olet vienyt oletusarvoiset values-asetukset, voit muokata tai luoda config-tiedoston omilla arvoillasi.
Sen jälkeen voit asentaa Chart-paketin tällä komennolla:

helm install my-jupyterhub jupyterhub/jupyterhub -f config.yaml

Suomenkielinen tekoälykäännös

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

Klikkaa tästä antaaksesi palautetta